<commit_before>#!/usr/bin/python

# Copyright (c) 2014, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

import os
import re

import lldb
import fblldbbase as fb
import fblldbviewcontrollerhelpers as vcHelpers
import fblldbobjcruntimehelpers as objc

def lldbcommands():
  return [
    FBFindViewControllerCommand(),
    FBFindOwningViewControllerCommand(),
    FBFindViewCommand(),
    FBFindViewByAccessibilityLabelCommand(),
    FBTapLoggerCommand(),
  ]

class FBFindViewControllerCommand(fb.FBCommand):
  def name(self):
    return 'fvc'

  def description(self):
    return 'Find the view controllers whose class names match classNameRegex and puts the address of first on the clipboard.'

  def args(self):
    return [ fb.FBCommandArgument(arg='classNameRegex', type='string', help='The view-controller-class regex to search the view controller hierarchy for.') ]

  def run(self, arguments, options):
    output = vcHelpers.viewControllerRecursiveDescription('(id)[[UIWindow keyWindow] rootViewController]')
    printMatchesInViewOutputStringAndCopyFirstToClipboard(arguments[0], output)

class FBFindOwningViewControllerCommand(fb.FBCommand):
  def name(self):
    return 'fovc'

  def descriptino(self):
    return 'Find the view controller that owns the input view'

  def args(self):
    return [ fb.FBCommandArgument(arg='view', type='UIView', help='This function will print the View Controller that owns this view')]

  def run(self, arguments, options):
    object = arguments[0]
    while object:
      if self.isViewController(object):
        description = fb.evaluateExpressionValue(object).GetObjectDescription()
        print("Found the owning view controller.\n{}".format(description))
        return
      else:
        object = self.nextResponder(object)

    print("Could not find an owning view controller")

  @staticmethod
  def isViewController(object):
    command = '[(id){} isKindOfClass:[UIViewController class]]'.format(object)
    isVC = fb.evaluateBooleanExpression(command)
    return isVC

  @staticmethod
  def nextResponder(object):
    command = '[((id){}) nextResponder]'.format(object)
    nextResponder = fb.evaluateObjectExpression(command)
    if int(nextResponder, 0):
      return nextResponder
    else:
      return None

class FBFindViewCommand(fb.FBCommand):
  def name(self):
    return 'fv'

  def description(self):
      return 'Find the views whose class names match classNameRegex and puts the address of first on the clipboard.'

  def args(self):
    return [ fb.FBCommandArgument(arg='classNameRegex', type='string', help='The view-class regex to search the view hierarchy for.') ]

  def run(self, arguments, options):
    output = fb.evaluateExpressionValue('(id)[[UIWindow keyWindow] recursiveDescription]').GetObjectDescription()
    printMatchesInViewOutputStringAndCopyFirstToClipboard(arguments[0], output)

def printMatchesInViewOutputStringAndCopyFirstToClipboard(needle, haystack):
  matches = re.findall('.*<.*' + needle + '.*: (0x[0-9a-fA-F]*);.*', haystack, re.IGNORECASE)
  for match in matches:
    className = fb.evaluateExpressionValue('(id)[(' + match + ') class]').GetObjectDescription()
    print('{} {}'.format(match, className))

  if len(matches) > 0:
    cmd = 'echo %s | tr -d "\n" | pbcopy' % matches[0]
    os.system(cmd)

class FBFindViewByAccessibilityLabelCommand(fb.FBCommand):
  def name(self):
    return 'fa11y'

  def description(self):
      return 'Find the views whose accessibility labels match labelRegex and puts the address of the first result on the clipboard.'

  def args(self):
    return [ fb.FBCommandArgument(arg='labelRegex', type='string', help='The accessibility label regex to search the view hierarchy for.') ]

  def run(self, arguments, options):
    first = None
    haystack = fb.evaluateExpressionValue('(id)[[UIWindow keyWindow] recursiveDescription]').GetObjectDescription()
    needle = arguments[0]

    allViews = re.findall('.* (0x[0-9a-fA-F]*);.*', haystack)
    for view in allViews:
      a11yLabel = fb.evaluateExpressionValue('(id)[(' + view + ') accessibilityLabel]').GetObjectDescription()
      if re.match(r'.*' + needle + '.*', a11yLabel, re.IGNORECASE):
        print('{} {}'.format(view, a11yLabel))

        if first == None:
          first = view
          cmd = 'echo %s | tr -d "\n" | pbcopy' % first
          os.system(cmd)

class FBTapLoggerCommand(fb.FBCommand):
  def name(self):
    return 'taplog'

  def description(self):
    return 'Log tapped view to the console.'

  def run(self, arguments, options):
    parameterExpr = objc.functionPreambleExpressionForObjectParameterAtIndex(0)
    breakpoint = lldb.debugger.GetSelectedTarget().BreakpointCreateByName("-[UIApplication sendEvent:]")
    breakpoint.SetCondition('(int)[' + parameterExpr + ' type] == 0 && (int)[[[' + parameterExpr + ' allTouches] anyObject] phase] == 0')
    breakpoint.SetOneShot(True)
    lldb.debugger.HandleCommand('breakpoint command add -s python -F "sys.modules[\'' + __name__ + '\'].' + self.__class__.__name__ + '.taplog_callback" ' + str(breakpoint.id))
    lldb.debugger.SetAsync(True)
    lldb.debugger.HandleCommand('continue')

  @staticmethod
  def taplog_callback(frame, bp_loc, internal_dict):
    parameterExpr = objc.functionPreambleExpressionForObjectParameterAtIndex(0)
    lldb.debugger.HandleCommand('po [[[%s allTouches] anyObject] view]' % (parameterExpr))
    # We don't want to proceed event (click on button for example), so we just skip it
    lldb.debugger.HandleCommand('thread return')
<commit_msg>Fix description for fovc command<commit_after>#!/usr/bin/python

# Copyright (c) 2014, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

import os
import re

import lldb
import fblldbbase as fb
import fblldbviewcontrollerhelpers as vcHelpers
import fblldbobjcruntimehelpers as objc

def lldbcommands():
  return [
    FBFindViewControllerCommand(),
    FBFindOwningViewControllerCommand(),
    FBFindViewCommand(),
    FBFindViewByAccessibilityLabelCommand(),
    FBTapLoggerCommand(),
  ]

class FBFindViewControllerCommand(fb.FBCommand):
  def name(self):
    return 'fvc'

  def description(self):
    return 'Find the view controllers whose class names match classNameRegex and puts the address of first on the clipboard.'

  def args(self):
    return [ fb.FBCommandArgument(arg='classNameRegex', type='string', help='The view-controller-class regex to search the view controller hierarchy for.') ]

  def run(self, arguments, options):
    output = vcHelpers.viewControllerRecursiveDescription('(id)[[UIWindow keyWindow] rootViewController]')
    printMatchesInViewOutputStringAndCopyFirstToClipboard(arguments[0], output)

class FBFindOwningViewControllerCommand(fb.FBCommand):
  def name(self):
    return 'fovc'

  def descriptino(self):
    return 'Find the view controller that owns the input view.'

  def args(self):
    return [ fb.FBCommandArgument(arg='view', type='UIView', help='This function will print the View Controller that owns this view')]

  def run(self, arguments, options):
    object = arguments[0]
    while object:
      if self.isViewController(object):
        description = fb.evaluateExpressionValue(object).GetObjectDescription()
        print("Found the owning view controller.\n{}".format(description))
        return
      else:
        object = self.nextResponder(object)

    print("Could not find an owning view controller")

  @staticmethod
  def isViewController(object):
    command = '[(id){} isKindOfClass:[UIViewController class]]'.format(object)
    isVC = fb.evaluateBooleanExpression(command)
    return isVC

  @staticmethod
  def nextResponder(object):
    command = '[((id){}) nextResponder]'.format(object)
    nextResponder = fb.evaluateObjectExpression(command)
    if int(nextResponder, 0):
      return nextResponder
    else:
      return None

class FBFindViewCommand(fb.FBCommand):
  def name(self):
    return 'fv'

  def description(self):
      return 'Find the views whose class names match classNameRegex and puts the address of first on the clipboard.'

  def args(self):
    return [ fb.FBCommandArgument(arg='classNameRegex', type='string', help='The view-class regex to search the view hierarchy for.') ]

  def run(self, arguments, options):
    output = fb.evaluateExpressionValue('(id)[[UIWindow keyWindow] recursiveDescription]').GetObjectDescription()
    printMatchesInViewOutputStringAndCopyFirstToClipboard(arguments[0], output)

def printMatchesInViewOutputStringAndCopyFirstToClipboard(needle, haystack):
  matches = re.findall('.*<.*' + needle + '.*: (0x[0-9a-fA-F]*);.*', haystack, re.IGNORECASE)
  for match in matches:
    className = fb.evaluateExpressionValue('(id)[(' + match + ') class]').GetObjectDescription()
    print('{} {}'.format(match, className))

  if len(matches) > 0:
    cmd = 'echo %s | tr -d "\n" | pbcopy' % matches[0]
    os.system(cmd)

class FBFindViewByAccessibilityLabelCommand(fb.FBCommand):
  def name(self):
    return 'fa11y'

  def description(self):
      return 'Find the views whose accessibility labels match labelRegex and puts the address of the first result on the clipboard.'

  def args(self):
    return [ fb.FBCommandArgument(arg='labelRegex', type='string', help='The accessibility label regex to search the view hierarchy for.') ]

  def run(self, arguments, options):
    first = None
    haystack = fb.evaluateExpressionValue('(id)[[UIWindow keyWindow] recursiveDescription]').GetObjectDescription()
    needle = arguments[0]

    allViews = re.findall('.* (0x[0-9a-fA-F]*);.*', haystack)
    for view in allViews:
      a11yLabel = fb.evaluateExpressionValue('(id)[(' + view + ') accessibilityLabel]').GetObjectDescription()
      if re.match(r'.*' + needle + '.*', a11yLabel, re.IGNORECASE):
        print('{} {}'.format(view, a11yLabel))

        if first == None:
          first = view
          cmd = 'echo %s | tr -d "\n" | pbcopy' % first
          os.system(cmd)

class FBTapLoggerCommand(fb.FBCommand):
  def name(self):
    return 'taplog'

  def description(self):
    return 'Log tapped view to the console.'

  def run(self, arguments, options):
    parameterExpr = objc.functionPreambleExpressionForObjectParameterAtIndex(0)
    breakpoint = lldb.debugger.GetSelectedTarget().BreakpointCreateByName("-[UIApplication sendEvent:]")
    breakpoint.SetCondition('(int)[' + parameterExpr + ' type] == 0 && (int)[[[' + parameterExpr + ' allTouches] anyObject] phase] == 0')
    breakpoint.SetOneShot(True)
    lldb.debugger.HandleCommand('breakpoint command add -s python -F "sys.modules[\'' + __name__ + '\'].' + self.__class__.__name__ + '.taplog_callback" ' + str(breakpoint.id))
    lldb.debugger.SetAsync(True)
    lldb.debugger.HandleCommand('continue')

  @staticmethod
  def taplog_callback(frame, bp_loc, internal_dict):
    parameterExpr = objc.functionPreambleExpressionForObjectParameterAtIndex(0)
    lldb.debugger.HandleCommand('po [[[%s allTouches] anyObject] view]' % (parameterExpr))
    # We don't want to proceed event (click on button for example), so we just skip it
    lldb.debugger.HandleCommand('thread return')
<|endoftext|>


<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4
#
#  Copyright (c) 2011 Openstack, LLC.
#  All Rights Reserved.
#
#     Licensed under the Apache License, Version 2.0 (the "License"); you may
#     not use this file except in compliance with the License. You may obtain
#     a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#     WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#     License for the specific language governing permissions and limitations
#     under the License.
#

"""
debian/ubuntu network helper module
"""

# Debian/Ubuntu network configuration uses:
# - 1 network configuration file (/etc/network/interfaces)
# - 1 IP per interface
# - routes are per interface
# - gateways are per interface
# - DNS is per interface (but see comments below about /etc/resolv.conf)

import logging
import os
import subprocess
import time
from cStringIO import StringIO

import commands.network

HOSTNAME_FILE = "/etc/hostname"
INTERFACE_FILE = "/etc/network/interfaces"

INTERFACE_HEADER = \
"""
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or
# /usr/share/doc/ifupdown/examples for more information.
# The loopback network interface
auto lo
iface lo inet loopback
""".lstrip('\n')

def configure_network(hostname, interfaces):
    # Generate new interface files
    data = _get_file_data(interfaces)
    update_files = {INTERFACE_FILE: data}

    # Generate new hostname file
    data = get_hostname_file(hostname)
    update_files[HOSTNAME_FILE] = data

    # Generate new /etc/resolv.conf file
    # Uses resolvconf utility if present else creates /etc/resolv.conf
    if not commands.network.update_resolvconf():
        filepath, data = commands.network.get_resolv_conf(interfaces)
        if data:
            update_files[filepath] = data

    # Generate new /etc/hosts file
    filepath, data = commands.network.get_etc_hosts(interfaces, hostname)
    update_files[filepath] = data

    pipe = subprocess.PIPE

    # Set hostname
    try:
        commands.network.sethostname(hostname)
    except Exception, e:
        logging.error("Couldn't sethostname(): %s" % str(e))
        return (500, "Couldn't set hostname: %s" % str(e))

    #
    # So, debian is kinda dumb in how it manages its interfaces.
    # A 'networking restart' doesn't actually down all interfaces that
    # might have been removed from the interfaces file.  So, we first
    # need to 'ifdown' everything we find.
    #
    # Now it's possible we'll fail to update files.. and if we do,
    # we need to try to bring the networking back up, anyway.  So,
    # no matter what, after we run 'ifdown' on everything, we need to
    # restart networking.
    #
    # Also: restart networking doesn't always seem to bring all
    # interfaces up, either!  Argh. :)  So, we also need to run 'ifup'
    # on everything.
    #
    # Now, ifdown and ifup can fail when it shouldn't be dealing with
    # a certain interface.. so we have to ignore all errors from them.
    #

    _run_on_interfaces("/sbin/ifdown")

    files_update_error = None
    # Write out new files
    try:
        commands.network.update_files(update_files)
    except Exception, e:
        files_update_error = e

    # Restart network
    status = _run_system_command("/etc/init.d/networking restart")
    if status != 0:
        status = _run_system_command("/usr/sbin/service networking restart")

    # Bring back up what we can
    _run_on_interfaces("/sbin/ifup")

    if files_update_error:
        raise files_update_error

    if status != 0:
        return (500, "Couldn't restart network: %d" % status)

    return (0, "")

def _run_system_command(cmd):
    logging.debug('executing "%s"' % cmd)
    p = subprocess.Popen(cmd.split(),
                         stdin=pipe, stdout=pipe, stderr=pipe, env={})
    logging.debug('waiting on pid %d' % p.pid)
    p.wait()
    logging.debug('"%s" exited with code %d' % (cmd, p.returncode))
    return p.returncode

def get_hostname_file(hostname):
    return hostname + '\n'

def _get_current_interfaces():
    """Get the current list of interfaces ignoring lo"""

    if not os.path.exists(INTERFACE_FILE):
        return set()

    interfaces = set()
    with open(INTERFACE_FILE, 'r') as f:
        for line in f.readlines():
            line = line.strip().lstrip()
            if line.startswith('iface') or \
                    line.startswith('auto') or \
                    line.startswith('allow-hotplug'):
                interface = line.split()[1]
                if not interface.startswith('lo'):
                    interfaces.add(interface)
    return interfaces

def _run_on_interfaces(cmd):
    """For all interfaces found, run a command with the interface as an
    argument
    """

    interfaces = _get_current_interfaces()
    pipe = subprocess.PIPE
    for i in interfaces:
        logging.debug('executing "%s %s"' % (cmd, i))
        p = subprocess.Popen([cmd, i],
            stdin=pipe, stdout=pipe, stderr=pipe, env={})
        logging.debug('waiting on pid %d' % p.pid)
        p.wait()
        status = p.returncode
        logging.debug('"%s %s" exited with code %d' % (
                cmd, i, status))

def _get_file_data(interfaces):
    """
    Return interfaces file data in 1 long string
    """

    file_data = INTERFACE_HEADER

    ifnames = interfaces.keys()
    ifnames.sort()

    for ifname_prefix in ifnames:
        interface = interfaces[ifname_prefix]

        label = interface['label']

        ip4s = interface['ip4s']
        ip6s = interface['ip6s']

        gateway4 = interface['gateway4']
        gateway6 = interface['gateway6']

        dns = interface['dns']

        ifname_suffix_num = 0

        for ip4, ip6 in map(None, ip4s, ip6s):
            if ifname_suffix_num:
                ifname = "%s:%d" % (ifname_prefix, ifname_suffix_num)
            else:
                ifname = ifname_prefix

            file_data += "\n"
            if label:
                file_data += "# Label %s\n" % label
            file_data += "auto %s\n" % ifname

            if ip4:
                file_data += "iface %s inet static\n" % ifname
                file_data += "    address %(address)s\n" % ip4
                file_data += "    netmask %(netmask)s\n" % ip4

                if gateway4:
                    file_data += "    gateway %s\n" % gateway4
                    gateway4 = None

            if ip6:
                file_data += "iface %s inet6 static\n" % ifname
                file_data += "    address %(address)s\n" % ip6
                file_data += "    netmask %(prefixlen)s\n" % ip6

                if gateway6:
                    file_data += "    gateway %s\n" % gateway6
                    gateway6 = None

            if dns:
                file_data += "    dns-nameservers %s\n" % ' '.join(dns)
                dns = None

            ifname_suffix_num += 1

        for route in interface['routes']:
            file_data += "    post-up route add -net %(network)s " \
                         "netmask %(netmask)s gw %(gateway)s || true\n" % route
            file_data += "    pre-down route del -net %(network)s " \
                         "netmask %(netmask)s gw %(gateway)s || true\n" % route

    return file_data

def get_interface_files(interfaces):
    return {'interfaces': _get_file_data(interfaces)}
<commit_msg>[debian][network] _run_system_command fixed subprocess.PIPE :nut_and_bolt:<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4
#
#  Copyright (c) 2011 Openstack, LLC.
#  All Rights Reserved.
#
#     Licensed under the Apache License, Version 2.0 (the "License"); you may
#     not use this file except in compliance with the License. You may obtain
#     a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#     WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#     License for the specific language governing permissions and limitations
#     under the License.
#

"""
debian/ubuntu network helper module
"""

# Debian/Ubuntu network configuration uses:
# - 1 network configuration file (/etc/network/interfaces)
# - 1 IP per interface
# - routes are per interface
# - gateways are per interface
# - DNS is per interface (but see comments below about /etc/resolv.conf)

import logging
import os
import subprocess
import time
from cStringIO import StringIO

import commands.network

HOSTNAME_FILE = "/etc/hostname"
INTERFACE_FILE = "/etc/network/interfaces"

INTERFACE_HEADER = \
"""
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or
# /usr/share/doc/ifupdown/examples for more information.
# The loopback network interface
auto lo
iface lo inet loopback
""".lstrip('\n')

def configure_network(hostname, interfaces):
    # Generate new interface files
    data = _get_file_data(interfaces)
    update_files = {INTERFACE_FILE: data}

    # Generate new hostname file
    data = get_hostname_file(hostname)
    update_files[HOSTNAME_FILE] = data

    # Generate new /etc/resolv.conf file
    # Uses resolvconf utility if present else creates /etc/resolv.conf
    if not commands.network.update_resolvconf():
        filepath, data = commands.network.get_resolv_conf(interfaces)
        if data:
            update_files[filepath] = data

    # Generate new /etc/hosts file
    filepath, data = commands.network.get_etc_hosts(interfaces, hostname)
    update_files[filepath] = data

    # Set hostname
    try:
        commands.network.sethostname(hostname)
    except Exception, e:
        logging.error("Couldn't sethostname(): %s" % str(e))
        return (500, "Couldn't set hostname: %s" % str(e))

    #
    # So, debian is kinda dumb in how it manages its interfaces.
    # A 'networking restart' doesn't actually down all interfaces that
    # might have been removed from the interfaces file.  So, we first
    # need to 'ifdown' everything we find.
    #
    # Now it's possible we'll fail to update files.. and if we do,
    # we need to try to bring the networking back up, anyway.  So,
    # no matter what, after we run 'ifdown' on everything, we need to
    # restart networking.
    #
    # Also: restart networking doesn't always seem to bring all
    # interfaces up, either!  Argh. :)  So, we also need to run 'ifup'
    # on everything.
    #
    # Now, ifdown and ifup can fail when it shouldn't be dealing with
    # a certain interface.. so we have to ignore all errors from them.
    #

    _run_on_interfaces("/sbin/ifdown")

    files_update_error = None
    # Write out new files
    try:
        commands.network.update_files(update_files)
    except Exception, e:
        files_update_error = e

    # Restart network
    status = _run_system_command("/etc/init.d/networking restart")
    if status != 0:
        status = _run_system_command("/usr/sbin/service networking restart")

    # Bring back up what we can
    _run_on_interfaces("/sbin/ifup")

    if files_update_error:
        raise files_update_error

    if status != 0:
        return (500, "Couldn't restart network: %d" % status)

    return (0, "")

def _run_system_command(cmd):
    logging.debug('executing "%s"' % cmd)

    pipe = subprocess.PIPE
    p = subprocess.Popen(cmd.split(),
                         stdin=pipe, stdout=pipe, stderr=pipe, env={})
    logging.debug('waiting on pid %d' % p.pid)
    p.wait()
    logging.debug('"%s" exited with code %d' % (cmd, p.returncode))
    return p.returncode

def get_hostname_file(hostname):
    return hostname + '\n'

def _get_current_interfaces():
    """Get the current list of interfaces ignoring lo"""

    if not os.path.exists(INTERFACE_FILE):
        return set()

    interfaces = set()
    with open(INTERFACE_FILE, 'r') as f:
        for line in f.readlines():
            line = line.strip().lstrip()
            if line.startswith('iface') or \
                    line.startswith('auto') or \
                    line.startswith('allow-hotplug'):
                interface = line.split()[1]
                if not interface.startswith('lo'):
                    interfaces.add(interface)
    return interfaces

def _run_on_interfaces(cmd):
    """For all interfaces found, run a command with the interface as an
    argument
    """

    interfaces = _get_current_interfaces()
    pipe = subprocess.PIPE
    for i in interfaces:
        logging.debug('executing "%s %s"' % (cmd, i))
        p = subprocess.Popen([cmd, i],
            stdin=pipe, stdout=pipe, stderr=pipe, env={})
        logging.debug('waiting on pid %d' % p.pid)
        p.wait()
        status = p.returncode
        logging.debug('"%s %s" exited with code %d' % (
                cmd, i, status))

def _get_file_data(interfaces):
    """
    Return interfaces file data in 1 long string
    """

    file_data = INTERFACE_HEADER

    ifnames = interfaces.keys()
    ifnames.sort()

    for ifname_prefix in ifnames:
        interface = interfaces[ifname_prefix]

        label = interface['label']

        ip4s = interface['ip4s']
        ip6s = interface['ip6s']

        gateway4 = interface['gateway4']
        gateway6 = interface['gateway6']

        dns = interface['dns']

        ifname_suffix_num = 0

        for ip4, ip6 in map(None, ip4s, ip6s):
            if ifname_suffix_num:
                ifname = "%s:%d" % (ifname_prefix, ifname_suffix_num)
            else:
                ifname = ifname_prefix

            file_data += "\n"
            if label:
                file_data += "# Label %s\n" % label
            file_data += "auto %s\n" % ifname

            if ip4:
                file_data += "iface %s inet static\n" % ifname
                file_data += "    address %(address)s\n" % ip4
                file_data += "    netmask %(netmask)s\n" % ip4

                if gateway4:
                    file_data += "    gateway %s\n" % gateway4
                    gateway4 = None

            if ip6:
                file_data += "iface %s inet6 static\n" % ifname
                file_data += "    address %(address)s\n" % ip6
                file_data += "    netmask %(prefixlen)s\n" % ip6

                if gateway6:
                    file_data += "    gateway %s\n" % gateway6
                    gateway6 = None

            if dns:
                file_data += "    dns-nameservers %s\n" % ' '.join(dns)
                dns = None

            ifname_suffix_num += 1

        for route in interface['routes']:
            file_data += "    post-up route add -net %(network)s " \
                         "netmask %(netmask)s gw %(gateway)s || true\n" % route
            file_data += "    pre-down route del -net %(network)s " \
                         "netmask %(netmask)s gw %(gateway)s || true\n" % route

    return file_data

def get_interface_files(interfaces):
    return {'interfaces': _get_file_data(interfaces)}
<|endoftext|>


<commit_before>"""
MassOpenCloud / Hardware Isolation Layer (MOC/HIL)

HIL Client Interface

August 2017, Tim Donahue	tpd001@gmail.com
"""

import urllib

from hil.client.client import Client, RequestsHTTPClient
from hil.client.base import FailedAPICallException
from hil_slurm_logging import log_info, log_debug, log_error
from hil_slurm_settings import HIL_ENDPOINT, HIL_USER, HIL_PW

class HILClientFailure(Exception):
    """Exception indicating that the HIL client failed"""

class ProjectMismatchError(Exception):
    """Raised when projects don't match"""

def hil_client_connect(endpoint_ip, name, pw):
    '''
    Connect to the HIL server and return a HIL Client instance
    '''
    hil_http_client = RequestsHTTPClient()
    if not hil_http_client:
        log_error('Unable to create HIL HTTP Client')
        return None

    hil_http_client.auth = (name, pw)

    return Client(endpoint_ip, hil_http_client)

def check_hil_interface():
    hil_client = hil_init()

def hil_reserve_nodes(nodelist, from_project, hil_client=None):
    '''
    Cause HIL nodes to move from the 'from' project to the HIL free pool.
    Typically, the 'from' project is the Slurm loaner project.

    This methods first powers off the nodes, then disconnects all networks,
    then moves the node from the 'from' project to the free pool.

    We power off the nodes before removing the networks because the IPMI
    network is also controlled by HIL. If we removed all networks, then we will
    not be able to perform any IPMI operations on nodes.
    '''
    # this might cause a loop? since hil_init calls hil_client_connect
    # which can return None. We can either have a counter to give it a
    # reasonable number of tries before raising an exception.
    if not hil_client:
        hil_client = hil_init()

    # Get information from node and ensure that the node is actually connected
    # to <from_project> before proceeding.
    for node in nodelist:
        node_info = show_node(hil_client, node)

        project = node_info['project']
        if (project != from_project):
            log_error('HIL reservation failure: Node `%s` (in project `%s`) not in `%s` project' % (node, project, from_project))
            raise ProjectMismatchError()

    # Power off all nodes.
    for node in nodelist:
        power_off_node(hil_client, node)

    # Remove all networks from nodes.
    for node in nodelist:
        _remove_all_networks(hil_client, node)

    # Finally, remove node from project.
    for node in nodelist:
        try:
            hil_client.project.detach(from_project, node)
            log_info('Node `%s` removed from project `%s`' % (node, from_project))
        except FailedAPICallException, ConnectionError:
            log_error('HIL reservation failure: Unable to detach node `%s` from project `%s`' % (node, from_project))
            raise HILClientFailure()

def hil_free_nodes(nodelist, to_project, hil_client=None):
    '''
    Cause HIL nodes to move the HIL free pool to the 'to' project.
    Typically, the 'to' project is the Slurm loaner project.

    This method first powers off the nodes, then disconnects all networks,
    then moves the node from the free pool to the 'to' project.

    We power off the nodes before removing the networks because the IPMI
    network is also controlled by HIL. If we removed all networks, then we will
    not be able to perform any IPMI operations on nodes.
    '''

    if not hil_client:
        hil_client = hil_init()

    # Get information from node and ensure that the node is actually connected
    # to <from_project> before proceeding.
    for node in nodelist:
        node_info = show_node(hil_client, node)

        # If the node is in the Slurm project now, skip further processing, but don't indicate
        # failure.
        project = node_info['project']
        if (project == to_project):
            log_info('HIL release: Node `%s` already in `%s` project, skipping' % (node, to_project))
            nodelist.remove(node)

    # Power off all nodes.
    for node in nodelist:
        power_off_node(hil_client, node)

    # Remove all networks from nodes.
    for node in nodelist:
        _remove_all_networks(hil_client, node)

    # Finally, connect node to <to_project>
    for node in nodelist:
        try:
            hil_client.project.connect(to_project, node)
            log_info('Node `%s` connected to project `%s`' % (node, to_project))
        except FailedAPICallException, ConnectionError:
            log_error('HIL reservation failure: Unable to connect node `%s` to project `%s`' % (node, to_project))
            raise HILClientFailure()

def hil_init():
    return hil_client_connect(HIL_ENDPOINT, HIL_USER, HIL_PW)

def _remove_all_networks(hil_client, node):
    '''
    Disconnect all networks from all of the node's NICs
    '''
    node_info = show_node(hil_client, node)

    # get node information and then iterate on the nics
    for nic in node_info['nics']:
        # get the port and switch to which the nics are connected to
        port = nic['port']
        switch = nic['switch']
        if port and switch:
            try:
                hil_client.port.port_revert(switch, port)
                log_info('Removed all networks from node `%s`' % node)
            except FailedAPICallException, ConnectionError:
                log_error('Failed to revert port `%s` on node `%s` switch `%s`' % (port, node, switch))
                raise HILClientFailure()

def show_node(hil_client, node):
    """Returns node information and takes care of handling exceptions"""
    try:
        node_info = hil_client.node.show(node)
        return node_info
    except FailedAPICallException, ConnectionError:
        # log a note for the admins, and the exact exception before raising
        # an error.
        log_error('HIL reservation failure: HIL node info unavailable, node `%s`' % node)
        raise HILClientFailure()

def power_off_node(hil_client, node):
    try:
        hil_client.node.power_off(node)
        log_info('Node `%s` succesfully powered off' % node)
    except FailedAPICallException, ConnectionError:
        log_error('HIL reservation failure: Unable to power off node `%s`' % node)
        raise HILClientFailure()
<commit_msg>Add checks to ensure that all networks are disconnected in a reasonable time<commit_after>"""
MassOpenCloud / Hardware Isolation Layer (MOC/HIL)

HIL Client Interface

August 2017, Tim Donahue	tpd001@gmail.com
"""

import urllib

import time

from hil.client.client import Client, RequestsHTTPClient
from hil.client.base import FailedAPICallException
from hil_slurm_logging import log_info, log_debug, log_error
from hil_slurm_settings import HIL_ENDPOINT, HIL_USER, HIL_PW

# timeout ensures that networking actions are completed in a resonable time.
HIL_TIMEOUT = 13

class HILClientFailure(Exception):
    """Exception indicating that the HIL client failed"""

class ProjectMismatchError(Exception):
    """Raised when projects don't match"""

def hil_client_connect(endpoint_ip, name, pw):
    '''
    Connect to the HIL server and return a HIL Client instance
    '''
    hil_http_client = RequestsHTTPClient()
    if not hil_http_client:
        log_error('Unable to create HIL HTTP Client')
        return None

    hil_http_client.auth = (name, pw)

    return Client(endpoint_ip, hil_http_client)

def check_hil_interface():
    hil_client = hil_init()

def hil_reserve_nodes(nodelist, from_project, hil_client=None):
    '''
    Cause HIL nodes to move from the 'from' project to the HIL free pool.
    Typically, the 'from' project is the Slurm loaner project.

    This methods first powers off the nodes, then disconnects all networks,
    then moves the node from the 'from' project to the free pool.

    We power off the nodes before removing the networks because the IPMI
    network is also controlled by HIL. If we removed all networks, then we will
    not be able to perform any IPMI operations on nodes.
    '''
    if not hil_client:
        hil_client = hil_init()

    # Get information from node and ensure that the node is actually connected
    # to <from_project> before proceeding.
    for node in nodelist:
        node_info = show_node(hil_client, node)

        project = node_info['project']
        if (project != from_project):
            log_error('HIL reservation failure: Node `%s` (in project `%s`) not in `%s` project' % (node, project, from_project))
            raise ProjectMismatchError()

    # Power off all nodes.
    for node in nodelist:
        power_off_node(hil_client, node)

    # Remove all networks from nodes.
    for node in nodelist:
        _remove_all_networks(hil_client, node)

    # Finally, remove node from project.
    for node in nodelist:
        remove_node_from_project(hil_client, node, from_project)

def hil_free_nodes(nodelist, to_project, hil_client=None):
    '''
    Cause HIL nodes to move the HIL free pool to the 'to' project.
    Typically, the 'to' project is the Slurm loaner project.

    This method first powers off the nodes, then disconnects all networks,
    then moves the node from the free pool to the 'to' project.

    We power off the nodes before removing the networks because the IPMI
    network is also controlled by HIL. If we removed all networks, then we will
    not be able to perform any IPMI operations on nodes.
    '''

    if not hil_client:
        hil_client = hil_init()

    # Get information from node and ensure that the node is actually connected
    # to <from_project> before proceeding.
    for node in nodelist:
        node_info = show_node(hil_client, node)

        # If the node is in the Slurm project now, skip further processing, but don't indicate
        # failure.
        project = node_info['project']
        if (project == to_project):
            log_info('HIL release: Node `%s` already in `%s` project, skipping' % (node, to_project))
            nodelist.remove(node)

    # Power off all nodes.
    for node in nodelist:
        power_off_node(hil_client, node)

    # Remove all networks from nodes.
    for node in nodelist:
        _remove_all_networks(hil_client, node)

    # Finally, connect node to <to_project>
    for node in nodelist:
        try:
            hil_client.project.connect(to_project, node)
            log_info('Node `%s` connected to project `%s`' % (node, to_project))
        except FailedAPICallException, ConnectionError:
            log_error('HIL reservation failure: Unable to connect node `%s` to project `%s`' % (node, to_project))
            raise HILClientFailure()

def hil_init():
    return hil_client_connect(HIL_ENDPOINT, HIL_USER, HIL_PW)

def _remove_all_networks(hil_client, node):
    '''
    Disconnect all networks from all of the node's NICs
    '''
    node_info = show_node(hil_client, node)

    # get node information and then iterate on the nics
    for nic in node_info['nics']:
        # get the port and switch to which the nics are connected to
        port = nic['port']
        switch = nic['switch']
        if port and switch:
            try:
                hil_client.port.port_revert(switch, port)
                log_info('Removed all networks from node `%s`' % node)
            except FailedAPICallException, ConnectionError:
                log_error('Failed to revert port `%s` on node `%s` switch `%s`' % (port, node, switch))
                raise HILClientFailure()

def _ensure_no_networks(hil_client, node):
    """Polls on the output of show node to check if networks have been removed.
    It will timeout and raise an exception if it's taking too long.
    """
    connected_to_network = True
    end_time = time.time() + HIL_TIMEOUT
    while connected_to_network:
        if time.time() > end_time:
            raise HILClientFailure('Networks not removed from node in reasonable time')
        node_info = show_node(hil_client, node)
        for nic in node_info['nics']:
            if nic['networks']:
                connected_to_network = True
                break
            else:
                connected_to_network = False
        # don't tight loop.
        time.sleep(1)
    return

def remove_node_from_project(hil_client, node, from_project):
    """Remove node from <from_project>
    Handles the case when there's an active networking action on the nic
    """
    try:
        _ensure_no_networks(hil_client, node)
        hil_client.project.detach(from_project, node)
        log_info('Node `%s` removed from project `%s`' % (node, from_project))
    except FailedAPICallException as ex:
        # check what the type of error it is and retry until network actions
        # are taken care of.
        if ex.message == 'Node has pending network actions':
            remove_node_from_project(hil_client, node, from_project)
            return
        log_error('HIL reservation failure: Unable to detach node `%s` from project `%s`' % (node, from_project))
        raise HILClientFailure()

def show_node(hil_client, node):
    """Returns node information and takes care of handling exceptions"""
    try:
        node_info = hil_client.node.show(node)
        return node_info
    except FailedAPICallException, ConnectionError:
        # log a note for the admins, and the exact exception before raising
        # an error.
        log_error('HIL reservation failure: HIL node info unavailable, node `%s`' % node)
        raise HILClientFailure()

def power_off_node(hil_client, node):
    try:
        hil_client.node.power_off(node)
        log_info('Node `%s` succesfully powered off' % node)
    except FailedAPICallException, ConnectionError:
        log_error('HIL reservation failure: Unable to power off node `%s`' % node)
        raise HILClientFailure()
<|endoftext|>


<commit_before>import uuid

from django import forms
from django.conf import settings
from django.utils.text import slugify

from ..users.models import User
from ..sites.models import Site
from .models import VirtualMachine
from .helpers import call_api

from raven.contrib.django.raven_compat.models import client

class VirtualMachineForm(forms.ModelForm):
    name = forms.CharField(max_length=255, widget=forms.TextInput(attrs={"class": "form-control"}))
    description = forms.CharField(widget=forms.TextInput(attrs={"class": "form-control"}), required=False)
    users = forms.ModelMultipleChoiceField(required=False, queryset=User.objects.filter(service=False))
    site = forms.ModelChoiceField(required=False, queryset=Site.objects.filter(category="vm"), widget=forms.Select(attrs={"class": "form-control"}))

    class Meta:
        model = VirtualMachine
        fields = ["name", "description", "users", "site"]

    def save(self, commit=True):
        instance = forms.ModelForm.save(self, commit=False)
        hostname = slugify(instance.name).replace("_", "-")

        if commit:
            instance.save()
            self.save_m2m()
            ret = call_api("container.create", name=hostname)
            if ret is None or ret[0] == 1:
                instance.delete()
                return None
            else:
                if ret[0] != 2:
                    instance.uuid = uuid.UUID(ret[1])
                    instance.save()

        return instance
<commit_msg>set memory limit<commit_after>import uuid

from django import forms
from django.conf import settings
from django.utils.text import slugify

from ..users.models import User
from ..sites.models import Site
from .models import VirtualMachine
from .helpers import call_api

from raven.contrib.django.raven_compat.models import client

class VirtualMachineForm(forms.ModelForm):
    name = forms.CharField(max_length=255, widget=forms.TextInput(attrs={"class": "form-control"}))
    description = forms.CharField(widget=forms.TextInput(attrs={"class": "form-control"}), required=False)
    users = forms.ModelMultipleChoiceField(required=False, queryset=User.objects.filter(service=False))
    site = forms.ModelChoiceField(required=False, queryset=Site.objects.filter(category="vm"), widget=forms.Select(attrs={"class": "form-control"}))

    class Meta:
        model = VirtualMachine
        fields = ["name", "description", "users", "site"]

    def save(self, commit=True):
        instance = forms.ModelForm.save(self, commit=False)
        hostname = slugify(instance.name).replace("_", "-")

        if commit:
            instance.save()
            self.save_m2m()
            ret = call_api("container.create", name=hostname)
            if ret is None or ret[0] == 1:
                instance.delete()
                return None
            else:
                if ret[0] != 2:
                    instance.uuid = uuid.UUID(ret[1])
                    instance.save()
                ret = call_api("container.set_config", key="lxc.cgroup.memory.limit_in_bytes", value="4G")
                if ret != 0:
                    client.captureMessage("Failed to set VM memory limit: {}".format(ret))

        return instance
<|endoftext|>


<commit_before>from __future__ import absolute_import

import json
import itertools

from eth_utils import (
    force_bytes,
    force_obj_to_text,
    force_text,
)

class BaseProvider(object):
    _middlewares = None

    @property
    def middlewares(self):
        return self._middlewares or tuple()

    @middlewares.setter
    def middlewares(self, value):
        self._middlewares = tuple(value)

    def add_middleware(self, middleware):
        self.middlewares = tuple(itertools.chain(
            [middleware],
            self.middlewares,
        ))

    def clear_middlewares(self):
        self.middlewares = tuple()

    def make_request(self, method, params):
        raise NotImplementedError("Providers must implement this method")

    def isConnected(self):
        raise NotImplementedError("Providers must implement this method")

class JSONBaseProvider(BaseProvider):
    def __init__(self):
        self.request_counter = itertools.count()

    def decode_rpc_response(self, response):
        return json.loads(force_text(response))

    def encode_rpc_request(self, method, params):
        return force_bytes(json.dumps(force_obj_to_text({
            "jsonrpc": "2.0",
            "method": method,
            "params": params or [],
            "id": next(self.request_counter),
        })))

    def isConnected(self):
        try:
            response_raw = self.make_request('web3_clientVersion', [])
            response = json.loads(force_text(response_raw))
        except IOError:
            return False
        else:
            assert response['jsonrpc'] == '2.0'
            assert 'error' not in response
            return True
        assert False
<commit_msg>fix JSONBaseProvide.isConnected<commit_after>from __future__ import absolute_import

import json
import itertools

from eth_utils import (
    force_bytes,
    force_obj_to_text,
    force_text,
)

class BaseProvider(object):
    _middlewares = None

    @property
    def middlewares(self):
        return self._middlewares or tuple()

    @middlewares.setter
    def middlewares(self, value):
        self._middlewares = tuple(value)

    def add_middleware(self, middleware):
        self.middlewares = tuple(itertools.chain(
            [middleware],
            self.middlewares,
        ))

    def clear_middlewares(self):
        self.middlewares = tuple()

    def make_request(self, method, params):
        raise NotImplementedError("Providers must implement this method")

    def isConnected(self):
        raise NotImplementedError("Providers must implement this method")

class JSONBaseProvider(BaseProvider):
    def __init__(self):
        self.request_counter = itertools.count()

    def decode_rpc_response(self, response):
        return json.loads(force_text(response))

    def encode_rpc_request(self, method, params):
        return force_bytes(json.dumps(force_obj_to_text({
            "jsonrpc": "2.0",
            "method": method,
            "params": params or [],
            "id": next(self.request_counter),
        })))

    def isConnected(self):
        try:
            response = self.make_request('web3_clientVersion', [])
        except IOError:
            return False
        else:
            assert response['jsonrpc'] == '2.0'
            assert 'error' not in response
            return True
        assert False
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

#
# Please note that these reports are not multi-currency !!!
#

from odoo import api, fields, models

class PurchaseReport(models.Model):
    _name = "purchase.report"
    _description = "Purchases Orders"
    _auto = False
    _order = 'date_order desc, price_total desc'

    date_order = fields.Datetime('Order Date', readonly=True, help="Date on which this document has been created", oldname='date')
    state = fields.Selection([
        ('draft', 'Draft RFQ'),
        ('sent', 'RFQ Sent'),
        ('to approve', 'To Approve'),
        ('purchase', 'Purchase Order'),
        ('done', 'Done'),
        ('cancel', 'Cancelled')
        ], 'Order Status', readonly=True)
    product_id = fields.Many2one('product.product', 'Product', readonly=True)
    picking_type_id = fields.Many2one('stock.warehouse', 'Warehouse', readonly=True)
    partner_id = fields.Many2one('res.partner', 'Vendor', readonly=True)
    date_approve = fields.Date('Date Approved', readonly=True)
    product_uom = fields.Many2one('product.uom', 'Reference Unit of Measure', required=True)
    company_id = fields.Many2one('res.company', 'Company', readonly=True)
    currency_id = fields.Many2one('res.currency', 'Currency', readonly=True)
    user_id = fields.Many2one('res.users', 'Responsible', readonly=True)
    delay = fields.Float('Days to Validate', digits=(16, 2), readonly=True)
    delay_pass = fields.Float('Days to Deliver', digits=(16, 2), readonly=True)
    unit_quantity = fields.Float('Product Quantity', readonly=True, oldname='quantity')
    price_total = fields.Float('Total Price', readonly=True)
    price_average = fields.Float('Average Price', readonly=True, group_operator="avg")
    negociation = fields.Float('Purchase-Standard Price', readonly=True, group_operator="avg")
    price_standard = fields.Float('Products Value', readonly=True, group_operator="sum")
    nbr_lines = fields.Integer('# of Lines', readonly=True, oldname='nbr')
    category_id = fields.Many2one('product.category', 'Product Category', readonly=True)
    product_tmpl_id = fields.Many2one('product.template', 'Product Template', readonly=True)
    country_id = fields.Many2one('res.country', 'Partner Country', readonly=True)
    fiscal_position_id = fields.Many2one('account.fiscal.position', string='Fiscal Position', oldname='fiscal_position', readonly=True)
    account_analytic_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True)
    commercial_partner_id = fields.Many2one('res.partner', 'Commercial Entity', readonly=True)
    weight = fields.Float('Gross Weight', readonly=True)
    volume = fields.Float('Volume', readonly=True)

    @api.model_cr
    def init(self):
        self._cr.execute("""
            create or replace view purchase_report as (
                WITH currency_rate as (%s)
                select
                    min(l.id) as id,
                    s.date_order as date_order,
                    s.state,
                    s.date_approve,
                    s.dest_address_id,
                    spt.warehouse_id as picking_type_id,
                    s.partner_id as partner_id,
                    s.create_uid as user_id,
                    s.company_id as company_id,
                    s.fiscal_position_id as fiscal_position_id,
                    l.product_id,
                    p.product_tmpl_id,
                    t.categ_id as category_id,
                    s.currency_id,
                    t.uom_id as product_uom,
                    sum(l.product_qty/u.factor*u2.factor) as unit_quantity,
                    extract(epoch from age(s.date_approve,s.date_order))/(24*60*60)::decimal(16,2) as delay,
                    extract(epoch from age(l.date_planned,s.date_order))/(24*60*60)::decimal(16,2) as delay_pass,
                    count(*) as nbr_lines,
                    sum(l.price_unit / COALESCE(cr.rate, 1.0) * l.product_qty)::decimal(16,2) as price_total,
                    avg(100.0 * (l.price_unit / COALESCE(cr.rate,1.0) * l.product_qty) / NULLIF(ip.value_float*l.product_qty/u.factor*u2.factor, 0.0))::decimal(16,2) as negociation,
                    sum(ip.value_float*l.product_qty/u.factor*u2.factor)::decimal(16,2) as price_standard,
                    (sum(l.product_qty * l.price_unit / COALESCE(cr.rate, 1.0))/NULLIF(sum(l.product_qty/u.factor*u2.factor),0.0))::decimal(16,2) as price_average,
                    partner.country_id as country_id,
                    partner.commercial_partner_id as commercial_partner_id,
                    analytic_account.id as account_analytic_id,
                    sum(p.weight * l.product_qty/u.factor*u2.factor) as weight,
                    sum(p.volume * l.product_qty/u.factor*u2.factor) as volume
                from purchase_order_line l
                    join purchase_order s on (l.order_id=s.id)
                    join res_partner partner on s.partner_id = partner.id
                        left join product_product p on (l.product_id=p.id)
                            left join product_template t on (p.product_tmpl_id=t.id)
                            LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.template,',t.id) AND ip.company_id=s.company_id)
                    left join product_uom u on (u.id=l.product_uom)
                    left join product_uom u2 on (u2.id=t.uom_id)
                    left join stock_picking_type spt on (spt.id=s.picking_type_id)
                    left join account_analytic_account analytic_account on (l.account_analytic_id = analytic_account.id)
                    left join currency_rate cr on (cr.currency_id = s.currency_id and
                        cr.company_id = s.company_id and
                        cr.date_start <= coalesce(s.date_order, now()) and
                        (cr.date_end is null or cr.date_end > coalesce(s.date_order, now())))
                group by
                    s.company_id,
                    s.create_uid,
                    s.partner_id,
                    u.factor,
                    s.currency_id,
                    l.price_unit,
                    s.date_approve,
                    l.date_planned,
                    l.product_uom,
                    s.dest_address_id,
                    s.fiscal_position_id,
                    l.product_id,
                    p.product_tmpl_id,
                    t.categ_id,
                    s.date_order,
                    s.state,
                    spt.warehouse_id,
                    u.uom_type,
                    u.category_id,
                    t.uom_id,
                    u.id,
                    u2.factor,
                    partner.country_id,
                    partner.commercial_partner_id,
                    analytic_account.id
            )
        """ % self.pool['res.currency']._select_companies_rates())
<commit_msg>[MIG] purchase: Remaining self.pool in purchase_report.py<commit_after># -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

#
# Please note that these reports are not multi-currency !!!
#

from odoo import api, fields, models

class PurchaseReport(models.Model):
    _name = "purchase.report"
    _description = "Purchases Orders"
    _auto = False
    _order = 'date_order desc, price_total desc'

    date_order = fields.Datetime('Order Date', readonly=True, help="Date on which this document has been created", oldname='date')
    state = fields.Selection([
        ('draft', 'Draft RFQ'),
        ('sent', 'RFQ Sent'),
        ('to approve', 'To Approve'),
        ('purchase', 'Purchase Order'),
        ('done', 'Done'),
        ('cancel', 'Cancelled')
        ], 'Order Status', readonly=True)
    product_id = fields.Many2one('product.product', 'Product', readonly=True)
    picking_type_id = fields.Many2one('stock.warehouse', 'Warehouse', readonly=True)
    partner_id = fields.Many2one('res.partner', 'Vendor', readonly=True)
    date_approve = fields.Date('Date Approved', readonly=True)
    product_uom = fields.Many2one('product.uom', 'Reference Unit of Measure', required=True)
    company_id = fields.Many2one('res.company', 'Company', readonly=True)
    currency_id = fields.Many2one('res.currency', 'Currency', readonly=True)
    user_id = fields.Many2one('res.users', 'Responsible', readonly=True)
    delay = fields.Float('Days to Validate', digits=(16, 2), readonly=True)
    delay_pass = fields.Float('Days to Deliver', digits=(16, 2), readonly=True)
    unit_quantity = fields.Float('Product Quantity', readonly=True, oldname='quantity')
    price_total = fields.Float('Total Price', readonly=True)
    price_average = fields.Float('Average Price', readonly=True, group_operator="avg")
    negociation = fields.Float('Purchase-Standard Price', readonly=True, group_operator="avg")
    price_standard = fields.Float('Products Value', readonly=True, group_operator="sum")
    nbr_lines = fields.Integer('# of Lines', readonly=True, oldname='nbr')
    category_id = fields.Many2one('product.category', 'Product Category', readonly=True)
    product_tmpl_id = fields.Many2one('product.template', 'Product Template', readonly=True)
    country_id = fields.Many2one('res.country', 'Partner Country', readonly=True)
    fiscal_position_id = fields.Many2one('account.fiscal.position', string='Fiscal Position', oldname='fiscal_position', readonly=True)
    account_analytic_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True)
    commercial_partner_id = fields.Many2one('res.partner', 'Commercial Entity', readonly=True)
    weight = fields.Float('Gross Weight', readonly=True)
    volume = fields.Float('Volume', readonly=True)

    @api.model_cr
    def init(self):
        self._cr.execute("""
            create or replace view purchase_report as (
                WITH currency_rate as (%s)
                select
                    min(l.id) as id,
                    s.date_order as date_order,
                    s.state,
                    s.date_approve,
                    s.dest_address_id,
                    spt.warehouse_id as picking_type_id,
                    s.partner_id as partner_id,
                    s.create_uid as user_id,
                    s.company_id as company_id,
                    s.fiscal_position_id as fiscal_position_id,
                    l.product_id,
                    p.product_tmpl_id,
                    t.categ_id as category_id,
                    s.currency_id,
                    t.uom_id as product_uom,
                    sum(l.product_qty/u.factor*u2.factor) as unit_quantity,
                    extract(epoch from age(s.date_approve,s.date_order))/(24*60*60)::decimal(16,2) as delay,
                    extract(epoch from age(l.date_planned,s.date_order))/(24*60*60)::decimal(16,2) as delay_pass,
                    count(*) as nbr_lines,
                    sum(l.price_unit / COALESCE(cr.rate, 1.0) * l.product_qty)::decimal(16,2) as price_total,
                    avg(100.0 * (l.price_unit / COALESCE(cr.rate,1.0) * l.product_qty) / NULLIF(ip.value_float*l.product_qty/u.factor*u2.factor, 0.0))::decimal(16,2) as negociation,
                    sum(ip.value_float*l.product_qty/u.factor*u2.factor)::decimal(16,2) as price_standard,
                    (sum(l.product_qty * l.price_unit / COALESCE(cr.rate, 1.0))/NULLIF(sum(l.product_qty/u.factor*u2.factor),0.0))::decimal(16,2) as price_average,
                    partner.country_id as country_id,
                    partner.commercial_partner_id as commercial_partner_id,
                    analytic_account.id as account_analytic_id,
                    sum(p.weight * l.product_qty/u.factor*u2.factor) as weight,
                    sum(p.volume * l.product_qty/u.factor*u2.factor) as volume
                from purchase_order_line l
                    join purchase_order s on (l.order_id=s.id)
                    join res_partner partner on s.partner_id = partner.id
                        left join product_product p on (l.product_id=p.id)
                            left join product_template t on (p.product_tmpl_id=t.id)
                            LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.template,',t.id) AND ip.company_id=s.company_id)
                    left join product_uom u on (u.id=l.product_uom)
                    left join product_uom u2 on (u2.id=t.uom_id)
                    left join stock_picking_type spt on (spt.id=s.picking_type_id)
                    left join account_analytic_account analytic_account on (l.account_analytic_id = analytic_account.id)
                    left join currency_rate cr on (cr.currency_id = s.currency_id and
                        cr.company_id = s.company_id and
                        cr.date_start <= coalesce(s.date_order, now()) and
                        (cr.date_end is null or cr.date_end > coalesce(s.date_order, now())))
                group by
                    s.company_id,
                    s.create_uid,
                    s.partner_id,
                    u.factor,
                    s.currency_id,
                    l.price_unit,
                    s.date_approve,
                    l.date_planned,
                    l.product_uom,
                    s.dest_address_id,
                    s.fiscal_position_id,
                    l.product_id,
                    p.product_tmpl_id,
                    t.categ_id,
                    s.date_order,
                    s.state,
                    spt.warehouse_id,
                    u.uom_type,
                    u.category_id,
                    t.uom_id,
                    u.id,
                    u2.factor,
                    partner.country_id,
                    partner.commercial_partner_id,
                    analytic_account.id
            )
        """ % self.env['res.currency']._select_companies_rates())
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from osv import fields, osv
from service import web_services
from tools.translate import _
import netsvc
import pooler
import time

class stock_partial_move(osv.osv_memory):
    _name = "stock.partial.move"
    _description = "Partial Move"
    _columns = {
        'date': fields.datetime('Date', required=True),
        'partner_id': fields.many2one('res.partner',string="Partner"),
        'type': fields.char("Type", size=3),
        'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered"),
     }

    def view_init(self, cr, uid, fields_list, context=None):
        res = super(stock_partial_move, self).view_init(cr, uid, fields_list, context=context)
        move_obj = self.pool.get('stock.move')
        if not context:
            context={}
        moveids = []
        for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
            if m.state in ('done', 'cancel'):
                continue
            if 'move%s_product_id'%(m.id) not in self._columns:
                self._columns['move%s_product_id'%(m.id)] = fields.many2one('product.product',string="Product")
            if 'move%s_product_qty'%(m.id) not in self._columns:
                self._columns['move%s_product_qty'%(m.id)] = fields.float("Quantity")
            if 'move%s_product_uom'%(m.id) not in self._columns:
                self._columns['move%s_product_uom'%(m.id)] = fields.many2one('product.uom',string="Product UOM")

            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                if 'move%s_product_price'%(m.id) not in self._columns:
                    self._columns['move%s_product_price'%(m.id)] = fields.float("Price")
                if 'move%s_product_currency'%(m.id) not in self._columns:
                    self._columns['move%s_product_currency'%(m.id)] = fields.many2one('res.currency',string="Currency")
        return res

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
        result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
        move_obj = self.pool.get('stock.move')
        move_ids = context.get('active_ids', False)
        move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
        _moves_arch_lst = """<form string="Deliver Products">
                        <separator colspan="4" string="Delivery Information"/>
                    	<field name="date"  />
                    	<separator colspan="4"/>
                     <group colspan="4" attrs="{'invisible':[('type','=','in')]}">
                    	<field name="partner_id"  attrs="{'required':[('type','!=','in')]}" />
                    	<field name="address_id"  attrs="{'required':[('type','!=','in')]}"/>
                    	<field name="type" invisible="1"/>
                    	<newline/>
                        </group>
                        <separator colspan="4" string="Move Detail"/>
                    	"""
        _moves_fields = result['fields']
        if move_ids and view_type in ['form']:
            for m in move_obj.browse(cr, uid, move_ids, context):
                if m.state in ('done', 'cancel'):
                    continue
                _moves_fields.update({
                    'move%s_product_id'%(m.id)  : {
                                'string': _('Product'),
                                'type' : 'many2one',
                                'relation': 'product.product',
                                'required' : True,
                                'readonly' : True,
                                },
                    'move%s_product_qty'%(m.id) : {
                                'string': _('Quantity'),
                                'type' : 'float',
                                'required': True,
                                },
                    'move%s_product_uom'%(m.id) : {
                                'string': _('Product UOM'),
                                'type' : 'many2one',
                                'relation': 'product.uom',
                                'required' : True,
                                'readonly' : True,
                                }
                })

                _moves_arch_lst += """
                    <group colspan="4" col="10">
                    <field name="move%s_product_id" nolabel="1"/>
                    <field name="move%s_product_qty" string="Qty" />
                    <field name="move%s_product_uom" nolabel="1" />
                """%(m.id, m.id, m.id)
                if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                    _moves_fields.update({
                        'move%s_product_price'%(m.id) : {
                                'string': _('Price'),
                                'type' : 'float',
                                },
                        'move%s_product_currency'%(m.id): {
                                'string': _('Currency'),
                                'type' : 'float',
                                'type' : 'many2one',
                                'relation': 'res.currency',
                                }
                    })
                    _moves_arch_lst += """
                        <field name="move%s_product_price" />
                        <field name="move%s_product_currency" nolabel="1"/>
                    """%(m.id, m.id)
                _moves_arch_lst += """
                    </group>
                    """
        _moves_arch_lst += """
                <separator string="" colspan="4" />
                <label string="" colspan="2"/>
                <group col="2" colspan="2">
        		<button icon='gtk-cancel' special="cancel"
        			string="_Cancel" />
        		<button name="do_partial" string="_Deliver"
        			colspan="1" type="object" icon="gtk-apply" />
        	</group>
        </form>"""
        result['arch'] = _moves_arch_lst
        result['fields'] = _moves_fields
        return result

    def default_get(self, cr, uid, fields, context=None):
        """ To get default values for the object.
        @param self: The object pointer.
        @param cr: A database cursor
        @param uid: ID of the user currently logged in
        @param fields: List of fields for which we want default values
        @param context: A standard dictionary
        @return: A dictionary which of fields with values.
        """

        res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
        move_obj = self.pool.get('stock.move')
        if not context:
            context={}
        moveids = address_delivery = address_default = []
        if 'date' in fields:
            res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
        move_ids = context.get('active_ids', [])
        move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
        for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
            if m.state in ('done', 'cancel'):
                continue
            res['type'] = m.picking_id and m.picking_id.type or ''
            address_ids = list(set([(pick.address_id and pick.address_id.id, pick.address_id and pick.address_id.partner_id and  pick.address_id.partner_id.id) for pick in move_obj.browse(cr, uid, move_ids)]))
            address_ids1 = list(set([(pick.address_id and pick.address_id.id, pick.address_id and pick.address_id.partner_id and  pick.address_id.partner_id.id) for pick in move_obj.browse(cr, uid, move_ids) if pick.address_id]))
            if len(address_ids1) == 1:
                if m.picking_id and m.picking_id.type=='out':
                    res['address_id'] = address_ids[0][0] or False
                    res['partner_id'] = address_ids[0][1] or False
            if  m.picking_id and m.picking_id.type=='in':
                    res['partner_id'] = m.company_id.partner_id.id or False
                    if  m.company_id.partner_id:
                        address_default = [add.id for add in  m.company_id.partner_id.address if add.type=='default']
                        address_delivery = [add.id for add in  m.company_id.partner_id.address if add.type=='delivery']
                    if len(address_delivery):
                        res['address_id'] =  address_delivery and address_delivery[0] or False
                    else:
                        res['address_id'] =  address_default and address_default[0] or False

            if 'move%s_product_id'%(m.id) in fields:
                res['move%s_product_id'%(m.id)] = m.product_id.id
            if 'move%s_product_qty'%(m.id) in fields:
                res['move%s_product_qty'%(m.id)] = m.product_qty
            if 'move%s_product_uom'%(m.id) in fields:
                res['move%s_product_uom'%(m.id)] = m.product_uom.id

            if (m.picking_id.type == 'out') and (m.product_id.cost_method == 'average'):
                price = 0
                if hasattr(m, 'sale_line_id') and m.sale_line_id:
                    price = m.sale_line_id.price_unit

                currency = False
                if hasattr(m.picking_id, 'sale_id') and m.picking_id.sale_id:
                    currency = m.picking_id.sale_id.pricelist_id.currency_id.id

                if 'move%s_product_price'%(m.id) in fields:
                    res['move%s_product_price'%(m.id)] = price
                if 'move%s_product_currency'%(m.id) in fields:
                    res['move%s_product_currency'%(m.id)] = currency

            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                price = 0
                if hasattr(m, 'purchase_line_id') and m.purchase_line_id:
                    price = m.purchase_line_id.price_unit

                currency = False
                if hasattr(m.picking_id, 'purchase_id') and m.picking_id.purchase_id:
                    currency = m.picking_id.purchase_id.pricelist_id.currency_id.id

                if 'move%s_product_price'%(m.id) in fields:
                    res['move%s_product_price'%(m.id)] = price
                if 'move%s_product_currency'%(m.id) in fields:
                    res['move%s_product_currency'%(m.id)] = currency
        return res

    def do_partial(self, cr, uid, ids, context):
        """ Makes partial moves and pickings done.
        @param self: The object pointer.
        @param cr: A database cursor
        @param uid: ID of the user currently logged in
        @param fields: List of fields for which we want default values
        @param context: A standard dictionary
        @return: A dictionary which of fields with values.
        """

        rec_id = context and context.get('active_id', False)
        tracking_lot = context.get('tracking_lot', False)
        if tracking_lot:
            tracking = self.pool.get('stock.tracking')
            tracking_lot = tracking.get_create_tracking_lot(cr, uid,[rec_id], tracking_lot)
            context ['tracking_lot'] = tracking_lot
        move_obj = self.pool.get('stock.move')
        move_ids = context.get('active_ids', False)
        partial = self.browse(cr, uid, ids[0], context)
        partial_datas = {
            'partner_id' : partial.partner_id and partial.partner_id.id or False,
            'address_id' : partial.address_id and partial.address_id.id or False,
            'delivery_date' : partial.date
        }
        for m in move_obj.browse(cr, uid, move_ids):
            if m.state in ('done', 'cancel'):
                continue
            partial_datas['move%s'%(m.id)] = {
                'product_id' : getattr(partial, 'move%s_product_id'%(m.id)).id,
                'product_qty' : getattr(partial, 'move%s_product_qty'%(m.id)),
                'product_uom' : getattr(partial, 'move%s_product_uom'%(m.id)).id
            }

            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                partial_datas['move%s'%(m.id)].update({
                    'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
                    'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
                })
        res = move_obj.do_partial(cr, uid, move_ids, partial_datas, context=context)
        return {}

stock_partial_move()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<commit_msg>[IMP] Stock: Give warning in stock_move if state is done/cancle<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from osv import fields, osv
from service import web_services
from tools.translate import _
import netsvc
import pooler
import time

class stock_partial_move(osv.osv_memory):
    _name = "stock.partial.move"
    _description = "Partial Move"
    _columns = {
        'date': fields.datetime('Date', required=True),
        'partner_id': fields.many2one('res.partner',string="Partner"),
        'type': fields.char("Type", size=3),
        'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered"),
     }

    def view_init(self, cr, uid, fields_list, context=None):
        res = super(stock_partial_move, self).view_init(cr, uid, fields_list, context=context)
        move_obj = self.pool.get('stock.move')
        if not context:
            context={}
        moveids = []
        for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
            if m.state in ('done', 'cancel'):
                raise osv.except_osv(_('Invalid action !'), _('Cannot delivery products  which are already delivered !'))

            if 'move%s_product_id'%(m.id) not in self._columns:
                self._columns['move%s_product_id'%(m.id)] = fields.many2one('product.product',string="Product")
            if 'move%s_product_qty'%(m.id) not in self._columns:
                self._columns['move%s_product_qty'%(m.id)] = fields.float("Quantity")
            if 'move%s_product_uom'%(m.id) not in self._columns:
                self._columns['move%s_product_uom'%(m.id)] = fields.many2one('product.uom',string="Product UOM")

            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                if 'move%s_product_price'%(m.id) not in self._columns:
                    self._columns['move%s_product_price'%(m.id)] = fields.float("Price")
                if 'move%s_product_currency'%(m.id) not in self._columns:
                    self._columns['move%s_product_currency'%(m.id)] = fields.many2one('res.currency',string="Currency")
        return res

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
        result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
        move_obj = self.pool.get('stock.move')
        move_ids = context.get('active_ids', False)
        move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
        _moves_arch_lst = """<form string="Deliver Products">
                        <separator colspan="4" string="Delivery Information"/>
                    	<field name="date"  />
                    	<separator colspan="4"/>
                     <group colspan="4" attrs="{'invisible':[('type','=','in')]}">
                    	<field name="partner_id"  attrs="{'required':[('type','!=','in')]}" />
                    	<field name="address_id"  attrs="{'required':[('type','!=','in')]}"/>
                    	<field name="type" invisible="1"/>
                    	<newline/>
                        </group>
                        <separator colspan="4" string="Move Detail"/>
                    	"""
        _moves_fields = result['fields']
        if move_ids and view_type in ['form']:
            for m in move_obj.browse(cr, uid, move_ids, context):
                if m.state in ('done', 'cancel'):
                    continue
                _moves_fields.update({
                    'move%s_product_id'%(m.id)  : {
                                'string': _('Product'),
                                'type' : 'many2one',
                                'relation': 'product.product',
                                'required' : True,
                                'readonly' : True,
                                },
                    'move%s_product_qty'%(m.id) : {
                                'string': _('Quantity'),
                                'type' : 'float',
                                'required': True,
                                },
                    'move%s_product_uom'%(m.id) : {
                                'string': _('Product UOM'),
                                'type' : 'many2one',
                                'relation': 'product.uom',
                                'required' : True,
                                'readonly' : True,
                                }
                })

                _moves_arch_lst += """
                    <group colspan="4" col="10">
                    <field name="move%s_product_id" nolabel="1"/>
                    <field name="move%s_product_qty" string="Qty" />
                    <field name="move%s_product_uom" nolabel="1" />
                """%(m.id, m.id, m.id)
                if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                    _moves_fields.update({
                        'move%s_product_price'%(m.id) : {
                                'string': _('Price'),
                                'type' : 'float',
                                },
                        'move%s_product_currency'%(m.id): {
                                'string': _('Currency'),
                                'type' : 'float',
                                'type' : 'many2one',
                                'relation': 'res.currency',
                                }
                    })
                    _moves_arch_lst += """
                        <field name="move%s_product_price" />
                        <field name="move%s_product_currency" nolabel="1"/>
                    """%(m.id, m.id)
                _moves_arch_lst += """
                    </group>
                    """
        _moves_arch_lst += """
                <separator string="" colspan="4" />
                <label string="" colspan="2"/>
                <group col="2" colspan="2">
        		<button icon='gtk-cancel' special="cancel"
        			string="_Cancel" />
        		<button name="do_partial" string="_Deliver"
        			colspan="1" type="object" icon="gtk-apply" />
        	</group>
        </form>"""
        result['arch'] = _moves_arch_lst
        result['fields'] = _moves_fields
        return result

    def default_get(self, cr, uid, fields, context=None):
        """ To get default values for the object.
        @param self: The object pointer.
        @param cr: A database cursor
        @param uid: ID of the user currently logged in
        @param fields: List of fields for which we want default values
        @param context: A standard dictionary
        @return: A dictionary which of fields with values.
        """

        res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
        move_obj = self.pool.get('stock.move')
        if not context:
            context={}
        moveids = address_delivery = address_default = []
        if 'date' in fields:
            res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
        move_ids = context.get('active_ids', [])
        move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
        for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
            if m.state in ('done', 'cancel'):
                continue
            res['type'] = m.picking_id and m.picking_id.type or ''
            address_ids = list(set([(pick.address_id and pick.address_id.id, pick.address_id and pick.address_id.partner_id and  pick.address_id.partner_id.id) for pick in move_obj.browse(cr, uid, move_ids)]))
            address_ids1 = list(set([(pick.address_id and pick.address_id.id, pick.address_id and pick.address_id.partner_id and  pick.address_id.partner_id.id) for pick in move_obj.browse(cr, uid, move_ids) if pick.address_id]))
            if len(address_ids1) == 1:
                if m.picking_id and m.picking_id.type=='out':
                    res['address_id'] = address_ids[0][0] or False
                    res['partner_id'] = address_ids[0][1] or False
            if  m.picking_id and m.picking_id.type=='in':
                    res['partner_id'] = m.company_id.partner_id.id or False
                    if  m.company_id.partner_id:
                        address_default = [add.id for add in  m.company_id.partner_id.address if add.type=='default']
                        address_delivery = [add.id for add in  m.company_id.partner_id.address if add.type=='delivery']
                    if len(address_delivery):
                        res['address_id'] =  address_delivery and address_delivery[0] or False
                    else:
                        res['address_id'] =  address_default and address_default[0] or False

            if 'move%s_product_id'%(m.id) in fields:
                res['move%s_product_id'%(m.id)] = m.product_id.id
            if 'move%s_product_qty'%(m.id) in fields:
                res['move%s_product_qty'%(m.id)] = m.product_qty
            if 'move%s_product_uom'%(m.id) in fields:
                res['move%s_product_uom'%(m.id)] = m.product_uom.id

            if (m.picking_id.type == 'out') and (m.product_id.cost_method == 'average'):
                price = 0
                if hasattr(m, 'sale_line_id') and m.sale_line_id:
                    price = m.sale_line_id.price_unit

                currency = False
                if hasattr(m.picking_id, 'sale_id') and m.picking_id.sale_id:
                    currency = m.picking_id.sale_id.pricelist_id.currency_id.id

                if 'move%s_product_price'%(m.id) in fields:
                    res['move%s_product_price'%(m.id)] = price
                if 'move%s_product_currency'%(m.id) in fields:
                    res['move%s_product_currency'%(m.id)] = currency

            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                price = 0
                if hasattr(m, 'purchase_line_id') and m.purchase_line_id:
                    price = m.purchase_line_id.price_unit

                currency = False
                if hasattr(m.picking_id, 'purchase_id') and m.picking_id.purchase_id:
                    currency = m.picking_id.purchase_id.pricelist_id.currency_id.id

                if 'move%s_product_price'%(m.id) in fields:
                    res['move%s_product_price'%(m.id)] = price
                if 'move%s_product_currency'%(m.id) in fields:
                    res['move%s_product_currency'%(m.id)] = currency
        return res

    def do_partial(self, cr, uid, ids, context):
        """ Makes partial moves and pickings done.
        @param self: The object pointer.
        @param cr: A database cursor
        @param uid: ID of the user currently logged in
        @param fields: List of fields for which we want default values
        @param context: A standard dictionary
        @return: A dictionary which of fields with values.
        """

        rec_id = context and context.get('active_id', False)
        tracking_lot = context.get('tracking_lot', False)
        if tracking_lot:
            tracking = self.pool.get('stock.tracking')
            tracking_lot = tracking.get_create_tracking_lot(cr, uid,[rec_id], tracking_lot)
            context ['tracking_lot'] = tracking_lot
        move_obj = self.pool.get('stock.move')
        move_ids = context.get('active_ids', False)
        partial = self.browse(cr, uid, ids[0], context)
        partial_datas = {
            'partner_id' : partial.partner_id and partial.partner_id.id or False,
            'address_id' : partial.address_id and partial.address_id.id or False,
            'delivery_date' : partial.date
        }
        for m in move_obj.browse(cr, uid, move_ids):
            if m.state in ('done', 'cancel'):
                continue
            partial_datas['move%s'%(m.id)] = {
                'product_id' : getattr(partial, 'move%s_product_id'%(m.id)).id,
                'product_qty' : getattr(partial, 'move%s_product_qty'%(m.id)),
                'product_uom' : getattr(partial, 'move%s_product_uom'%(m.id)).id
            }

            if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
                partial_datas['move%s'%(m.id)].update({
                    'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
                    'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
                })
        res = move_obj.do_partial(cr, uid, move_ids, partial_datas, context=context)
        return {}

stock_partial_move()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<|endoftext|>


<commit_before>#!/usr/bin/env python
# This file is a Datablox-specific wrapper on top of the Engage bootrapper and installer.
import os
import os.path
import sys
from optparse import OptionParser
import traceback
import subprocess
import tempfile
import random
import string

import bootstrap

def main(argv):
    usage = "usage: %prog [options] deployment_home"
    parser = OptionParser(usage=usage)
    (options, args) = parser.parse_args(args=argv)
    if len(args) != 1:
        parser.error("Expecting exactly one argument, the directory to install datablox (a.k.a. the deployment home)")
    dh = os.path.abspath(os.path.expanduser(args[0]))
    if os.path.exists(dh):
        parser.error("Installation directory %s already exists - delete it if you want to install to that directory." % dh)

    print "Deploying datablox to %s" % dh
    print "  Running Engage bootstrap"
    bt_log = os.path.join(dh, "log/bootstrap.log")
    try:
        rc = bootstrap.main(["-c", dh])
    except:
        traceback.print_exc()
        print "Error running Engage bootstrap, check logfile %s for details" % \
              bt_log
        return 1
    if rc != 0:
        print "Engage bootstrap failed, return code was %d. Check logfile %s for details." %\
              (rc, bt_log)
        return 1
    print "  Running install of datablox"
    install_exe = os.path.join(dh, "engage/bin/install")
    if not os.path.exists(install_exe):
        raise Exception("Could not find Engage installer script at %s" %
                        install_exe)
    di_log = os.path.join(dh, "log/install.log")
    with tempfile.NamedTemporaryFile(delete=False) as f:
        f.write(''.join([random.choice(string.letters+string.digits) for i in range(10)]))
        fname = f.name
    try:
        rc = subprocess.call([install_exe, "-p", fname, "-g", "datablox"])
    except:
        traceback.print_exc()
        print "Error running datablox install, check logfile %s for details" % \
              di_log
        return 1
    finally:
        os.remove(fname)
    if rc != 0:
        print "Engage install of Datablox caretaker failed, return code was %d. Check logfile %s for details." % \
              (rc, di_log)
        return 1
    print "Datablox deployment successful"
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
<commit_msg>Added link for svccctl<commit_after>#!/usr/bin/env python
# This file is a Datablox-specific wrapper on top of the Engage bootrapper and installer.
import os
import os.path
import sys
from optparse import OptionParser
import traceback
import subprocess
import tempfile
import random
import string

import bootstrap

def main(argv):
    usage = "usage: %prog [options] deployment_home"
    parser = OptionParser(usage=usage)
    (options, args) = parser.parse_args(args=argv)
    if len(args) != 1:
        parser.error("Expecting exactly one argument, the directory to install datablox (a.k.a. the deployment home)")
    dh = os.path.abspath(os.path.expanduser(args[0]))
    if os.path.exists(dh):
        parser.error("Installation directory %s already exists - delete it if you want to install to that directory." % dh)

    print "Deploying datablox to %s" % dh
    print "  Running Engage bootstrap"
    bt_log = os.path.join(dh, "log/bootstrap.log")
    try:
        rc = bootstrap.main(["-c", dh])
    except:
        traceback.print_exc()
        print "Error running Engage bootstrap, check logfile %s for details" % \
              bt_log
        return 1
    if rc != 0:
        print "Engage bootstrap failed, return code was %d. Check logfile %s for details." %\
              (rc, bt_log)
        return 1
    print "  Running install of datablox"
    install_exe = os.path.join(dh, "engage/bin/install")
    if not os.path.exists(install_exe):
        raise Exception("Could not find Engage installer script at %s" %
                        install_exe)
    di_log = os.path.join(dh, "log/install.log")
    with tempfile.NamedTemporaryFile(delete=False) as f:
        f.write(''.join([random.choice(string.letters+string.digits) for i in range(10)]))
        fname = f.name
    try:
        rc = subprocess.call([install_exe, "-p", fname, "-g", "datablox"])
    except:
        traceback.print_exc()
        print "Error running datablox install, check logfile %s for details" % \
              di_log
        return 1
    finally:
        os.remove(fname)
    if rc != 0:
        print "Engage install of Datablox caretaker failed, return code was %d. Check logfile %s for details." % \
              (rc, di_log)
        return 1
    svcctl_exe = os.path.join(dh, "engage/bin/svcctl")
    assert os.path.exists(svcctl_exe), "Missing svcctl script at %s" % svccctl_exe
    svcctl_link = os.path.join(dh, "python/bin/svcctl")
    rc = subprocess.call(["/bin/ln", "-s", svcctl_exe, svcctl_link])
    if rc != 0:
        print "Unable to setup svcctl link at %s" % svccctl_link
        return 1
    print "Datablox deployment successful"
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
<|endoftext|>