[MERGE]: Merge with lp:openobject-trunk-dev-addons2
authorksa (Open ERP) <ksa@tinyerp.co.in>
Mon, 15 Nov 2010 04:55:10 +0000 (10:25 +0530)
committerksa (Open ERP) <ksa@tinyerp.co.in>
Mon, 15 Nov 2010 04:55:10 +0000 (10:25 +0530)
bzr revid: ksa@tinyerp.co.in-20101115045510-0qmgqiz8n20fmtnm

1  2 
addons/product/product.py
addons/stock/stock.py
addons/stock/stock_view.xml

@@@ -24,7 -24,7 +24,7 @@@ import decimal_precision as d
  
  import math
  from _common import rounding
 -import re  
 +import re
  from tools.translate import _
  
  def is_pair(x):
@@@ -69,7 -69,7 +69,7 @@@ class product_uom(osv.osv)
          'name': fields.char('Name', size=64, required=True, translate=True),
          'category_id': fields.many2one('product.uom.categ', 'UoM Category', required=True, ondelete='cascade',
              help="Quantity conversions may happen automatically between Units of Measure in the same category, according to their respective ratios."),
-         'factor': fields.float('Ratio', required=True,digits=(12, 6),
+         'factor': fields.float('Ratio', required=True,digits=(12, 12),
              help='How many times this UoM is smaller than the reference UoM in this category:\n'\
                      '1 * (reference unit) = ratio * (this unit)'),
          'factor_inv': fields.function(_factor_inv, digits_compute=dp.get_precision('Product UoM'),
              from_unit, to_unit = uoms[-1], uoms[0]
          return self._compute_qty_obj(cr, uid, from_unit, qty, to_unit)
  
 -    def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context={}):
 +    def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context=None):
 +        if context is None:
 +            context = {}
          if from_unit.category_id.id <> to_unit.category_id.id:
 -            return qty
 +            if context.get('raise-exception', True):
 +                raise osv.except_osv(_('Error !'), _('Conversion from Product UoM m to Default UoM PCE is not possible as they both belong to different Category!.'))
 +            else:
 +                return qty
          amount = qty / from_unit.factor
          if to_unit:
              amount = rounding(amount * to_unit.factor, to_unit.rounding)
@@@ -347,7 -342,7 +347,7 @@@ class product_product(osv.osv)
  
      def _product_price(self, cr, uid, ids, name, arg, context={}):
          res = {}
-         quantity = context.get('quantity', 1)
+         quantity = context.get('quantity') or 1.0
          pricelist = context.get('pricelist', False)
          if pricelist:
              for id in ids:
diff --combined addons/stock/stock.py
@@@ -930,6 -930,25 +930,25 @@@ class stock_picking(osv.osv)
          '''Call after the creation of the invoice'''
          return
  
+     def _get_invoice_type(self, pick):
+         src_usage = dest_usage = None
+         inv_type = None
+         if pick.invoice_state == '2binvoiced':
+             if pick.move_lines:
+                 src_usage = pick.move_lines[0].location_id.usage
+                 dest_usage = pick.move_lines[0].location_dest_id.usage
+             if pick.type == 'out' and dest_usage == 'supplier':
+                 inv_type = 'in_refund'
+             elif pick.type == 'out' and dest_usage == 'customer':
+                 inv_type = 'out_invoice'
+             elif pick.type == 'in' and src_usage == 'supplier':
+                 inv_type = 'in_invoice'
+             elif pick.type == 'in' and src_usage == 'customer':
+                 inv_type = 'out_refund'
+             else:
+                 inv_type = 'out_invoice'
+         return inv_type
      def action_invoice_create(self, cr, uid, ids, journal_id=False,
              group=False, type='out_invoice', context=None):
          """ Creates invoice based on the invoice state selected for picking.
          invoice_line_obj = self.pool.get('account.invoice.line')
          invoices_group = {}
          res = {}
+         inv_type = type
          for picking in self.browse(cr, uid, ids, context=context):
              if picking.invoice_state != '2binvoiced':
                  continue
              if not partner:
                  raise osv.except_osv(_('Error, no partner !'),
                      _('Please put a partner on the picking list if you want to generate invoice.'))
+             
+             if not inv_type:
+                 inv_type = self._get_invoice_type(picking)
  
-             if type in ('out_invoice', 'out_refund'):
+             if inv_type in ('out_invoice', 'out_refund'):
                  account_id = partner.property_account_receivable.id
                  payment_term_id = self._get_payment_term(cr, uid, picking)
              else:
                  invoice_vals = {
                      'name': picking.name,
                      'origin': (picking.name or '') + (picking.origin and (':' + picking.origin) or ''),
-                     'type': type,
+                     'type': inv_type,
                      'account_id': account_id,
                      'partner_id': partner.id,
                      'address_invoice_id': address_invoice_id,
                  else:
                      name = move_line.name
  
-                 if type in ('out_invoice', 'out_refund'):
+                 if inv_type in ('out_invoice', 'out_refund'):
                      account_id = move_line.product_id.product_tmpl_id.\
                              property_account_income.id
                      if not account_id:
                                  property_account_expense_categ.id
  
                  price_unit = self._get_price_unit_invoice(cr, uid,
-                         move_line, type)
+                         move_line, inv_type)
                  discount = self._get_discount_invoice(cr, uid, move_line)
-                 tax_ids = self._get_taxes_invoice(cr, uid, move_line, type)
+                 tax_ids = self._get_taxes_invoice(cr, uid, move_line, inv_type)
                  account_analytic_id = self._get_account_analytic_invoice(cr, uid, picking, move_line)
  
                  #set UoS if it's a sale and the picking doesn't have one
                  uos_id = move_line.product_uos and move_line.product_uos.id or False
-                 if not uos_id and type in ('out_invoice', 'out_refund'):
+                 if not uos_id and inv_type in ('out_invoice', 'out_refund'):
                      uos_id = move_line.product_uom.id
  
                  account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, partner.property_account_position, account_id)
                  self._invoice_line_hook(cr, uid, move_line, invoice_line_id)
  
              invoice_obj.button_compute(cr, uid, [invoice_id], context=context,
-                     set_total=(type in ('in_invoice', 'in_refund')))
+                     set_total=(inv_type in ('in_invoice', 'in_refund')))
              self.write(cr, uid, [picking.id], {
                  'invoice_state': 'invoiced',
                  }, context=context)
@@@ -1353,7 -1375,7 +1375,7 @@@ class stock_production_lot(osv.osv)
          'name': fields.char('Serial Number', size=64, required=True, help="Unique serial number, will be displayed as: PREFIX/SERIAL [INT_REF]"),
          'ref': fields.char('Internal Reference', size=256, help="Internal reference number in case it differs from the manufacturer's serial number"),
          'prefix': fields.char('Prefix', size=64, help="Optional prefix to prepend when displaying this serial number: PREFIX/SERIAL [INT_REF]"),
-         'product_id': fields.many2one('product.product', 'Product', required=True),
+         'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type', '<>', 'service')]),
          'date': fields.datetime('Creation Date', required=True),
          'stock_available': fields.function(_get_stock, fnct_search=_stock_search, method=True, type="float", string="Available", select=True,
              help="Current quantity of products with this Production Lot Number available in company warehouses",
@@@ -1480,7 -1502,7 +1502,7 @@@ class stock_move(osv.osv)
          'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Optional: next stock move when chaining them", select=True),
          'move_history_ids': fields.many2many('stock.move', 'stock_move_history_ids', 'parent_id', 'child_id', 'Move History (child moves)'),
          'move_history_ids2': fields.many2many('stock.move', 'stock_move_history_ids', 'child_id', 'parent_id', 'Move History (parent moves)'),
-         'picking_id': fields.many2one('stock.picking', 'Picking List', select=True,states={'done': [('readonly', True)]}),
+         'picking_id': fields.many2one('stock.picking', 'Reference', select=True,states={'done': [('readonly', True)]}),
          'note': fields.text('Notes'),
          'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, select=True,
                                    help='When the stock move is created it is in the \'Draft\' state.\n After that it is set to \'Confirmed\' state.\n If stock is available state is set to \'Available\'.\n When the picking is done the state is \'Done\'.\
                  quantity_rest = quantity
                  uos_qty_rest =  uos_qty
                  if move.product_id.track_production and location_id:
-                     res += self.split_lines(cr, uid, [move.id], quantity_rest, split_by_qty=1, context=context)
+                     res += self.action_split(cr, uid, [move.id], quantity_rest, split_by_qty=1, context=context)
                  else:
                      res += [move.id]
                      update_val = {
@@@ -2376,7 -2398,7 +2398,7 @@@ class stock_inventory(osv.osv)
          'date_done': fields.datetime('Date done'),
          'inventory_line_id': fields.one2many('stock.inventory.line', 'inventory_id', 'Inventories', states={'done': [('readonly', True)]}),
          'move_ids': fields.many2many('stock.move', 'stock_inventory_move_rel', 'inventory_id', 'move_id', 'Created Moves'),
 -        'state': fields.selection( (('draft', 'Draft'), ('done', 'Done'), ('cancel','Cancelled')), 'State', readonly=True, select=True),
 +        'state': fields.selection( (('draft', 'Draft'), ('done', 'Done'), ('confirm','Confirmed'),('cancel','Cancelled')), 'State', readonly=True, select=True),
          'company_id': fields.many2one('res.company','Company',required=True,select=True),
      }
      _defaults = {
          return self.pool.get('stock.move').create(cr, uid, move_vals)
  
      def action_done(self, cr, uid, ids, context=None):
 +        self.write(cr, uid, ids, {'state':'done'} ,context=context)
 +        return True
 +
 +    def action_confirm(self, cr, uid, ids, context=None):
          """ Finishes the inventory and writes its finished date
          @return: True
          """
                      move_ids.append(self._inventory_line_hook(cr, uid, line, value))
              message = _('Inventory') + " '" + inv.name + "' "+ _("is done.")
              self.log(cr, uid, inv.id, message)
 -            self.write(cr, uid, [inv.id], {'state': 'done', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S'), 'move_ids': [(6, 0, move_ids)]})
 +            self.write(cr, uid, [inv.id], {'state': 'confirm', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S'), 'move_ids': [(6, 0, move_ids)]})
          return True
  
      def action_cancel(self, cr, uid, ids, context=None):
                              </form>
                          </field>
                      </page><page string="Posted Inventory" groups="base.group_extended">
 -                             <field colspan="2" name="move_ids" nolabel="1"  readonly="1" widget="one2many_list">
 +                             <field colspan="2" name="move_ids" nolabel="1" widget="one2many_list">
                                  <tree string="Stock Moves">
                                      <field name="product_id"/>
                                      <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
                                      <field name="product_uom" string="UoM"/>
                                      <field name="prodlot_id" groups="base.group_extended"/>
 +                                     <button name="%(track_line)d" string="Split in production lots" type="action"
 +                                        icon="terp-stock_effects-object-colorize"
 +                                        attrs="{'invisible': [('prodlot_id','&lt;&gt;',False)]}"
 +                                        context="{'default_use_exist': picking_id.type=='in'}"
 +                                        states="draft,done,cancel"
 +                                        groups="base.group_extended"/>
 +                                    <field groups="base.group_extended" name="tracking_id"/>
 +                                    <button name="setlast_tracking" string="Put in current pack" type="object"
 +                                        groups="base.group_extended"
 +                                        icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
 +                                        states="draft,done,cancel"/>
 +                                     <button name="%(split_into)d" string="Put in a new pack" type="action"
 +                                        groups="base.group_extended"
 +                                        icon="terp-stock_effects-object-colorize"
 +                                        states="draft,done,cancel"/>
                                      <field name="location_id"/>
                                      <field name="location_dest_id"/>
                                      <field name="date" string="Date"/>
                      <field name="state"/>
                      <group col="4" colspan="2">
                          <button name="action_cancel_inventary" states="draft" string="Cancel Inventory" type="object" icon="gtk-cancel"/>
 -                        <button name="action_done" states="draft" string="Confirm Inventory" type="object" icon="gtk-apply"/>
 +                        <button name="action_confirm" states="draft" string="Confirm Inventory" type="object" icon="gtk-apply"/>
 +                        <button name="action_done" states="confirm" string="Done" type="object" icon="gtk-jump-to"/>
                          <button name="action_cancel" states="cancel" string="Set to Draft" type="object" icon="gtk-convert"/>
                      </group>
  
                      <group col="2" colspan="2" groups="base.group_extended">
                          <separator string="Chained Locations" colspan="2"/>
                          <field name="chained_location_type"/>
-                         <field name="chained_location_id"/>
+                         <field name="chained_location_id"  attrs="{'required':[('chained_location_type','=','fixed')]}"/>
                          <field name="chained_auto_packing"/>
                          <field name="chained_delay"/>
                          <field name="chained_journal_id"/>
                                          groups="base.group_extended"
                                          icon="terp-stock_effects-object-colorize"
                                          states="draft,assigned,confirmed,done"/>
 +                                    <button name="%(split_into)d" string="Put in a new pack" type="action"
 +                                        groups="base.group_extended"
 +                                        icon="terp-stock_effects-object-colorize"
 +                                        states="draft,assigned,confirmed,done"/>
                                      <field name="location_id"/>
                                      <field name="location_dest_id"/>
                                      <field name="date_expected" string="Date Expected"/>
                                  <button name="action_assign" states="confirmed" string="Check Availability" type="object" icon="gtk-find"/>
                                  <button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
                                  <button name="action_process" states="assigned" string="Process" type="object" icon="gtk-go-forward"/>
-                                 <button states="done" name="%(action_stock_invoice_onshipping)d"  string="Create Invoice" type="action" icon="terp-gtk-go-back-rtl" attrs="{'invisible':[('invoice_state','!=','2binvoiced')]}"/>
+                                 <button states="done" name="%(action_stock_invoice_onshipping)d"  string="Create Invoice" type="action" icon="terp-gtk-go-back-rtl" />
                              </group>
                          </page>
                          <page string="Additional info" groups="base.group_extended,base.group_multi_company">
                                  <button name="action_assign" states="confirmed" string="Check Availability" type="object" groups="base.group_extended" icon="gtk-find"/>
                                  <button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
                                  <button name="action_process" states="assigned" string="Process" type="object" icon="gtk-go-forward"/>
-                                 <button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" states="done" type="action" icon="terp-gtk-go-back-rtl" attrs="{'invisible':[('invoice_state','!=','2binvoiced')]}"/>
+                                 <button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" states="done" type="action" icon="terp-gtk-go-back-rtl"/>
                              </group>
                          </page>
                          <page string="Additional info" groups="base.group_extended,base.group_multi_company">
                                  <button name="force_assign" states="confirmed" string="Force Availability" type="object" groups="base.group_extended" icon="gtk-jump-to"/>
                                  <button name="action_process" states="assigned" string="Process" type="object" icon="gtk-go-forward"/>
                                  <group colspan="1" states="done">
-                                     <button name="%(action_stock_invoice_onshipping)d"  string="Create Invoice" type="action" icon="terp-gtk-go-back-rtl" attrs="{'invisible':[('invoice_state','!=','2binvoiced')]}"/>
+                                     <button name="%(action_stock_invoice_onshipping)d"  string="Create Invoice" type="action" icon="terp-gtk-go-back-rtl"/>
                                  </group>
                              </group>
                          </page>