savoirfairelinux-openerp team mailing list archive
-
savoirfairelinux-openerp team
-
Mailing list archive
-
Message #01397
[Merge] lp:~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv into lp:openobject-addons/7.0
Vincent Vinet has proposed merging lp:~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv into lp:openobject-addons/7.0.
Requested reviews:
OpenERP Core Team (openerp)
Related bugs:
Bug #1168398 in Odoo Addons: "[trunk/7.0] Incorrect behaviour when producing MO with component split in serial numbers"
https://bugs.launchpad.net/openobject-addons/+bug/1168398
For more details, see:
https://code.launchpad.net/~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv/+merge/225532
based on lp:~camptocamp/openobject-addons/7.0-bug-1168398-tta+afe with additional test
that shows wrong behavior.
--
https://code.launchpad.net/~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv/+merge/225532
Your team Savoir-faire Linux' OpenERP is subscribed to branch lp:~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv.
=== modified file 'mrp/__openerp__.py'
--- mrp/__openerp__.py 2014-04-04 12:30:03 +0000
+++ mrp/__openerp__.py 2014-07-03 17:47:44 +0000
@@ -75,11 +75,19 @@
],
'demo': ['mrp_demo.xml'],
'test': [
+<<<<<<< TREE
'test/bom_with_service_type_product.yml',
'test/mrp_users.yml',
'test/order_demo.yml',
'test/order_process.yml',
'test/cancel_order.yml',
+=======
+ 'test/order_demo.yml',
+ 'test/order_process.yml',
+ 'test/cancel_order.yml',
+ 'test/order_process_prodlot_split.yml',
+ 'test/order_process_prodlot_partial_consume.yml',
+>>>>>>> MERGE-SOURCE
],
'installable': True,
'application': True,
=== modified file 'mrp/mrp.py'
--- mrp/mrp.py 2014-03-06 09:45:04 +0000
+++ mrp/mrp.py 2014-07-03 17:47:44 +0000
@@ -780,8 +780,17 @@
if float_compare(qty, 0, precision_rounding=scheduled.product_id.uom_id.rounding) <= 0:
# we already have more qtys consumed than we need
continue
-
- raw_product[0].action_consume(qty, raw_product[0].location_id.id, context=context)
+ splitqty = qty
+ moves = sorted(raw_product, key=lambda k: (k.product_qty))
+ for move in moves:
+ if splitqty <= 0:
+ break
+ elif move.product_qty >= splitqty:
+ move.action_consume(splitqty, move.location_id.id, context=context)
+ splitqty = 0
+ else:
+ move.action_consume(move.product_qty, move.location_id.id, context=context)
+ splitqty = splitqty - move.product_qty
if production_mode == 'consume_produce':
# To produce remaining qty of final product
=== added file 'mrp/test/order_process_prodlot_partial_consume.yml'
--- mrp/test/order_process_prodlot_partial_consume.yml 1970-01-01 00:00:00 +0000
+++ mrp/test/order_process_prodlot_partial_consume.yml 2014-07-03 17:47:44 +0000
@@ -0,0 +1,66 @@
+-
+ I create a MO for 10 PCSC349
+-
+ !record {model: mrp.production, id: test_mo_pcsc349_2}:
+ product_id: product.product_product_4
+ product_qty: 10
+ product_uom: product.product_uom_unit
+ location_src_id: stock.stock_location_stock
+ location_dest_id: stock.stock_location_stock
+ bom_id: mrp_bom_24
+-
+ I confirm the MO
+-
+ !workflow {model: mrp.production, action: button_confirm, ref: test_mo_pcsc349_2}
+-
+ I split the 20 RAM SR3 in 2 production lots of 5, 15 units
+-
+ !python {model: stock.move.split}: |
+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
+ assert len(ram_lines) == 1, 'no RAM-SR3 lines found'
+ ctxt = context.copy()
+ ctxt['active_id'] = ram_lines[0].id
+ ctxt['active_ids'] = [ram_lines[0].id]
+ ctxt['active_model'] = 'stock.move'
+ values = self.default_get(cr, uid,
+ ['product_id', 'product_uom', 'qty', 'use_exist', 'location_id'],
+ ctxt)
+ wizard_id = self.create(cr, uid, values, context=ctxt)
+ prodlot_obj = self.pool.get('stock.production.lot')
+ split_line_obj = self.pool.get('stock.move.split.lines')
+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
+ 'name': 'ram_sn_3',
+ 'quantity': 5,}, context=ctxt)
+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
+ 'name': 'ram_sn_4',
+ 'quantity': 15,}, context=ctxt)
+ self.split_lot(cr, uid, [wizard_id], context=ctxt)
+ order.refresh()
+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
+ assert len(ram_lines) == 2, 'RAM-SR3 line not split'
+
+
+-
+ I click on the "Produce" button of the Manufacturing Order and in the wizard select "Consume and Produce" mode.
+ I produce 5 units, which should consume 10 RAM-SR3
+-
+ !python {model: mrp.product.produce}: |
+ ctxt = context.copy()
+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
+ ctxt['active_id'] = order.id
+ ctxt['active_model'] = 'mrp.production'
+ wizard_id = self.create(cr, uid,
+ {'product_qty': 5,
+ 'mode': 'consume_produce'}, ctxt)
+ self.do_produce(cr, uid, [wizard_id], ctxt)
+-
+ I expect 10 RAM-SR3 to be consumed, takling 5 ram_sn3 and 5 ram_sn4
+-
+ !python {model: mrp.production}: |
+ order = self.browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
+ ram_lines = [line for line in order.move_lines2 if line.product_id.default_code == 'RAM-SR3']
+ ram_sn_3 = [line for line in ram_lines if line.prodlot_id.name == 'ram_sn_3']
+ ram_sn_4 = [line for line in ram_lines if line.prodlot_id.name == 'ram_sn_4']
+ assert ram_sn_3 and ram_sn_3[0].product_qty == 5, 'should have consumed 5 ram_sn3, not %d' % ram_sn_3[0].product_qty
+ assert ram_sn_4 and ram_sn_4[0].product_qty == 5, 'should have consumed 5 ram_sn4. not %d' % ram_sn_4[0].product_qty
=== added file 'mrp/test/order_process_prodlot_split.yml'
--- mrp/test/order_process_prodlot_split.yml 1970-01-01 00:00:00 +0000
+++ mrp/test/order_process_prodlot_split.yml 2014-07-03 17:47:44 +0000
@@ -0,0 +1,67 @@
+-
+ I create a MO for 1 PCSC349
+-
+ !record {model: mrp.production, id: test_mo_pcsc349}:
+ product_id: product.product_product_4
+ product_qty: 1
+ product_uom: product.product_uom_unit
+ location_src_id: stock.stock_location_stock
+ location_dest_id: stock.stock_location_stock
+ bom_id: mrp_bom_24
+-
+ I confirm the MO
+-
+ !workflow {model: mrp.production, action: button_confirm, ref: test_mo_pcsc349}
+-
+ I split the RAM SR3 in 2 production lots
+-
+ !python {model: stock.move.split}: |
+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349'), context=context)
+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
+ assert len(ram_lines) == 1, 'no RAM-SR3 lines found'
+ ctxt = context.copy()
+ ctxt['active_id'] = ram_lines[0].id
+ ctxt['active_ids'] = [ram_lines[0].id]
+ ctxt['active_model'] = 'stock.move'
+ values = self.default_get(cr, uid,
+ ['product_id', 'product_uom', 'qty', 'use_exist', 'location_id'],
+ ctxt)
+ wizard_id = self.create(cr, uid, values, context=ctxt)
+ prodlot_obj = self.pool.get('stock.production.lot')
+ split_line_obj = self.pool.get('stock.move.split.lines')
+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
+ 'name': 'ram_sn_1',
+ 'quantity': 1,}, context=ctxt)
+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
+ 'name': 'ram_sn_2',
+ 'quantity': 1,}, context=ctxt)
+ self.split_lot(cr, uid, [wizard_id], context=ctxt)
+ order.refresh()
+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
+ assert len(ram_lines) == 2, 'RAM-SR3 line not split'
+
+
+-
+ I click on the "Produce" button of the Manufacturing Order and in the wizard select "Consume and Produce" mode
+-
+ !python {model: mrp.product.produce}: |
+ ctxt = context.copy()
+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349'), context=context)
+ ctxt['active_id'] = order.id
+ ctxt['active_model'] = 'mrp.production'
+ wizard_id = self.create(cr, uid,
+ {'product_qty': 1,
+ 'mode': 'consume_produce'}, ctxt)
+ self.do_produce(cr, uid, [wizard_id], ctxt)
+-
+ I expect
+ all the Products in the "Products to consume" lists to be consumed
+ and moved to the "consumed products" list,
+ and the manufacturing order to be in state "Done"
+-
+ !python {model: mrp.production}: |
+ order = self.browse(cr, uid, ref('test_mo_pcsc349'), context=context)
+ assert order.state == 'done', "wrong state for the production order (%r, expected: 'done')" % order.state
+ assert len(order.move_lines) == 0, "%d leftover move lines in 'products to consume'" % len(order.move_lines)
+ ram_lines = [line for line in order.move_lines2 if line.product_id.default_code == 'RAM-SR3']
+ assert len(ram_lines) == 2, 'not all RAM-SR3 were consumed'