Merge lp:~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv into lp:openobject-addons/7.0

Proposed by Vincent Vinet
Status: Needs review
Proposed branch: lp:~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv
Merge into: lp:openobject-addons/7.0
Diff against target: 190 lines (+152/-2) (has conflicts)
4 files modified
mrp/__openerp__.py (+8/-0)
mrp/mrp.py (+11/-2)
mrp/test/order_process_prodlot_partial_consume.yml (+66/-0)
mrp/test/order_process_prodlot_split.yml (+67/-0)
Text conflict in mrp/__openerp__.py
To merge this branch: bzr merge lp:~savoirfairelinux-openerp/openobject-addons/7.0-bug-1168398-tta+afe+vv
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+225532@code.launchpad.net

This proposal supersedes a proposal from 2014-07-03.

Description of the change

based on lp:~camptocamp/openobject-addons/7.0-bug-1168398-tta+afe with additional test
that shows wrong behavior.

To post a comment you must log in.

Unmerged revisions

9051. By Vincent Vinet

fix merge conflict

9050. By Vincent Vinet

[FIX] use the remaining quantity to split instead of original qty when splitting consume moves

9049. By Alexandre Fayolle - camptocamp

[MRG] merge back the fix on 7.0 head, and hopefully get green on runbot

9048. By Alexandre Fayolle - camptocamp

[IMP] fix typo in test, delete trailing whitespace, add an assertion

9047. By Alexandre Fayolle - camptocamp

[TEST] added test for bug lp:1168398

9046. By SnippetBucket.com

[FIX] bug:1168398/Incorrect behaviour when producing MO with component split in serial numbers.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== 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 @@
75 ],75 ],
76 'demo': ['mrp_demo.xml'],76 'demo': ['mrp_demo.xml'],
77 'test': [77 'test': [
78<<<<<<< TREE
78 'test/bom_with_service_type_product.yml',79 'test/bom_with_service_type_product.yml',
79 'test/mrp_users.yml',80 'test/mrp_users.yml',
80 'test/order_demo.yml',81 'test/order_demo.yml',
81 'test/order_process.yml',82 'test/order_process.yml',
82 'test/cancel_order.yml',83 'test/cancel_order.yml',
84=======
85 'test/order_demo.yml',
86 'test/order_process.yml',
87 'test/cancel_order.yml',
88 'test/order_process_prodlot_split.yml',
89 'test/order_process_prodlot_partial_consume.yml',
90>>>>>>> MERGE-SOURCE
83 ],91 ],
84 'installable': True,92 'installable': True,
85 'application': True,93 'application': True,
8694
=== 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 @@
780 if float_compare(qty, 0, precision_rounding=scheduled.product_id.uom_id.rounding) <= 0: 780 if float_compare(qty, 0, precision_rounding=scheduled.product_id.uom_id.rounding) <= 0:
781 # we already have more qtys consumed than we need781 # we already have more qtys consumed than we need
782 continue782 continue
783783 splitqty = qty
784 raw_product[0].action_consume(qty, raw_product[0].location_id.id, context=context)784 moves = sorted(raw_product, key=lambda k: (k.product_qty))
785 for move in moves:
786 if splitqty <= 0:
787 break
788 elif move.product_qty >= splitqty:
789 move.action_consume(splitqty, move.location_id.id, context=context)
790 splitqty = 0
791 else:
792 move.action_consume(move.product_qty, move.location_id.id, context=context)
793 splitqty = splitqty - move.product_qty
785794
786 if production_mode == 'consume_produce':795 if production_mode == 'consume_produce':
787 # To produce remaining qty of final product796 # To produce remaining qty of final product
788797
=== 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 @@
1-
2 I create a MO for 10 PCSC349
3-
4 !record {model: mrp.production, id: test_mo_pcsc349_2}:
5 product_id: product.product_product_4
6 product_qty: 10
7 product_uom: product.product_uom_unit
8 location_src_id: stock.stock_location_stock
9 location_dest_id: stock.stock_location_stock
10 bom_id: mrp_bom_24
11-
12 I confirm the MO
13-
14 !workflow {model: mrp.production, action: button_confirm, ref: test_mo_pcsc349_2}
15-
16 I split the 20 RAM SR3 in 2 production lots of 5, 15 units
17-
18 !python {model: stock.move.split}: |
19 order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
20 ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
21 assert len(ram_lines) == 1, 'no RAM-SR3 lines found'
22 ctxt = context.copy()
23 ctxt['active_id'] = ram_lines[0].id
24 ctxt['active_ids'] = [ram_lines[0].id]
25 ctxt['active_model'] = 'stock.move'
26 values = self.default_get(cr, uid,
27 ['product_id', 'product_uom', 'qty', 'use_exist', 'location_id'],
28 ctxt)
29 wizard_id = self.create(cr, uid, values, context=ctxt)
30 prodlot_obj = self.pool.get('stock.production.lot')
31 split_line_obj = self.pool.get('stock.move.split.lines')
32 split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
33 'name': 'ram_sn_3',
34 'quantity': 5,}, context=ctxt)
35 split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
36 'name': 'ram_sn_4',
37 'quantity': 15,}, context=ctxt)
38 self.split_lot(cr, uid, [wizard_id], context=ctxt)
39 order.refresh()
40 ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
41 assert len(ram_lines) == 2, 'RAM-SR3 line not split'
42
43
44-
45 I click on the "Produce" button of the Manufacturing Order and in the wizard select "Consume and Produce" mode.
46 I produce 5 units, which should consume 10 RAM-SR3
47-
48 !python {model: mrp.product.produce}: |
49 ctxt = context.copy()
50 order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
51 ctxt['active_id'] = order.id
52 ctxt['active_model'] = 'mrp.production'
53 wizard_id = self.create(cr, uid,
54 {'product_qty': 5,
55 'mode': 'consume_produce'}, ctxt)
56 self.do_produce(cr, uid, [wizard_id], ctxt)
57-
58 I expect 10 RAM-SR3 to be consumed, takling 5 ram_sn3 and 5 ram_sn4
59-
60 !python {model: mrp.production}: |
61 order = self.browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
62 ram_lines = [line for line in order.move_lines2 if line.product_id.default_code == 'RAM-SR3']
63 ram_sn_3 = [line for line in ram_lines if line.prodlot_id.name == 'ram_sn_3']
64 ram_sn_4 = [line for line in ram_lines if line.prodlot_id.name == 'ram_sn_4']
65 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
66 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
067
=== 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 @@
1-
2 I create a MO for 1 PCSC349
3-
4 !record {model: mrp.production, id: test_mo_pcsc349}:
5 product_id: product.product_product_4
6 product_qty: 1
7 product_uom: product.product_uom_unit
8 location_src_id: stock.stock_location_stock
9 location_dest_id: stock.stock_location_stock
10 bom_id: mrp_bom_24
11-
12 I confirm the MO
13-
14 !workflow {model: mrp.production, action: button_confirm, ref: test_mo_pcsc349}
15-
16 I split the RAM SR3 in 2 production lots
17-
18 !python {model: stock.move.split}: |
19 order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349'), context=context)
20 ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
21 assert len(ram_lines) == 1, 'no RAM-SR3 lines found'
22 ctxt = context.copy()
23 ctxt['active_id'] = ram_lines[0].id
24 ctxt['active_ids'] = [ram_lines[0].id]
25 ctxt['active_model'] = 'stock.move'
26 values = self.default_get(cr, uid,
27 ['product_id', 'product_uom', 'qty', 'use_exist', 'location_id'],
28 ctxt)
29 wizard_id = self.create(cr, uid, values, context=ctxt)
30 prodlot_obj = self.pool.get('stock.production.lot')
31 split_line_obj = self.pool.get('stock.move.split.lines')
32 split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
33 'name': 'ram_sn_1',
34 'quantity': 1,}, context=ctxt)
35 split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
36 'name': 'ram_sn_2',
37 'quantity': 1,}, context=ctxt)
38 self.split_lot(cr, uid, [wizard_id], context=ctxt)
39 order.refresh()
40 ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
41 assert len(ram_lines) == 2, 'RAM-SR3 line not split'
42
43
44-
45 I click on the "Produce" button of the Manufacturing Order and in the wizard select "Consume and Produce" mode
46-
47 !python {model: mrp.product.produce}: |
48 ctxt = context.copy()
49 order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349'), context=context)
50 ctxt['active_id'] = order.id
51 ctxt['active_model'] = 'mrp.production'
52 wizard_id = self.create(cr, uid,
53 {'product_qty': 1,
54 'mode': 'consume_produce'}, ctxt)
55 self.do_produce(cr, uid, [wizard_id], ctxt)
56-
57 I expect
58 all the Products in the "Products to consume" lists to be consumed
59 and moved to the "consumed products" list,
60 and the manufacturing order to be in state "Done"
61-
62 !python {model: mrp.production}: |
63 order = self.browse(cr, uid, ref('test_mo_pcsc349'), context=context)
64 assert order.state == 'done', "wrong state for the production order (%r, expected: 'done')" % order.state
65 assert len(order.move_lines) == 0, "%d leftover move lines in 'products to consume'" % len(order.move_lines)
66 ram_lines = [line for line in order.move_lines2 if line.product_id.default_code == 'RAM-SR3']
67 assert len(ram_lines) == 2, 'not all RAM-SR3 were consumed'