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

Proposed by Vincent Vinet on 2014-07-03
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 2014-07-03 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 on 2014-07-03

fix merge conflict

9050. By Vincent Vinet on 2014-07-03

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

9049. By Alexandre Fayolle - camptocamp on 2013-07-11

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

9048. By Alexandre Fayolle - camptocamp on 2013-07-11

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

9047. By Alexandre Fayolle - camptocamp on 2013-07-11

[TEST] added test for bug lp:1168398

9046. By SnippetBucket.com on 2013-04-22

[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
1=== modified file 'mrp/__openerp__.py'
2--- mrp/__openerp__.py 2014-04-04 12:30:03 +0000
3+++ mrp/__openerp__.py 2014-07-03 17:47:44 +0000
4@@ -75,11 +75,19 @@
5 ],
6 'demo': ['mrp_demo.xml'],
7 'test': [
8+<<<<<<< TREE
9 'test/bom_with_service_type_product.yml',
10 'test/mrp_users.yml',
11 'test/order_demo.yml',
12 'test/order_process.yml',
13 'test/cancel_order.yml',
14+=======
15+ 'test/order_demo.yml',
16+ 'test/order_process.yml',
17+ 'test/cancel_order.yml',
18+ 'test/order_process_prodlot_split.yml',
19+ 'test/order_process_prodlot_partial_consume.yml',
20+>>>>>>> MERGE-SOURCE
21 ],
22 'installable': True,
23 'application': True,
24
25=== modified file 'mrp/mrp.py'
26--- mrp/mrp.py 2014-03-06 09:45:04 +0000
27+++ mrp/mrp.py 2014-07-03 17:47:44 +0000
28@@ -780,8 +780,17 @@
29 if float_compare(qty, 0, precision_rounding=scheduled.product_id.uom_id.rounding) <= 0:
30 # we already have more qtys consumed than we need
31 continue
32-
33- raw_product[0].action_consume(qty, raw_product[0].location_id.id, context=context)
34+ splitqty = qty
35+ moves = sorted(raw_product, key=lambda k: (k.product_qty))
36+ for move in moves:
37+ if splitqty <= 0:
38+ break
39+ elif move.product_qty >= splitqty:
40+ move.action_consume(splitqty, move.location_id.id, context=context)
41+ splitqty = 0
42+ else:
43+ move.action_consume(move.product_qty, move.location_id.id, context=context)
44+ splitqty = splitqty - move.product_qty
45
46 if production_mode == 'consume_produce':
47 # To produce remaining qty of final product
48
49=== added file 'mrp/test/order_process_prodlot_partial_consume.yml'
50--- mrp/test/order_process_prodlot_partial_consume.yml 1970-01-01 00:00:00 +0000
51+++ mrp/test/order_process_prodlot_partial_consume.yml 2014-07-03 17:47:44 +0000
52@@ -0,0 +1,66 @@
53+-
54+ I create a MO for 10 PCSC349
55+-
56+ !record {model: mrp.production, id: test_mo_pcsc349_2}:
57+ product_id: product.product_product_4
58+ product_qty: 10
59+ product_uom: product.product_uom_unit
60+ location_src_id: stock.stock_location_stock
61+ location_dest_id: stock.stock_location_stock
62+ bom_id: mrp_bom_24
63+-
64+ I confirm the MO
65+-
66+ !workflow {model: mrp.production, action: button_confirm, ref: test_mo_pcsc349_2}
67+-
68+ I split the 20 RAM SR3 in 2 production lots of 5, 15 units
69+-
70+ !python {model: stock.move.split}: |
71+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
72+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
73+ assert len(ram_lines) == 1, 'no RAM-SR3 lines found'
74+ ctxt = context.copy()
75+ ctxt['active_id'] = ram_lines[0].id
76+ ctxt['active_ids'] = [ram_lines[0].id]
77+ ctxt['active_model'] = 'stock.move'
78+ values = self.default_get(cr, uid,
79+ ['product_id', 'product_uom', 'qty', 'use_exist', 'location_id'],
80+ ctxt)
81+ wizard_id = self.create(cr, uid, values, context=ctxt)
82+ prodlot_obj = self.pool.get('stock.production.lot')
83+ split_line_obj = self.pool.get('stock.move.split.lines')
84+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
85+ 'name': 'ram_sn_3',
86+ 'quantity': 5,}, context=ctxt)
87+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
88+ 'name': 'ram_sn_4',
89+ 'quantity': 15,}, context=ctxt)
90+ self.split_lot(cr, uid, [wizard_id], context=ctxt)
91+ order.refresh()
92+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
93+ assert len(ram_lines) == 2, 'RAM-SR3 line not split'
94+
95+
96+-
97+ I click on the "Produce" button of the Manufacturing Order and in the wizard select "Consume and Produce" mode.
98+ I produce 5 units, which should consume 10 RAM-SR3
99+-
100+ !python {model: mrp.product.produce}: |
101+ ctxt = context.copy()
102+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
103+ ctxt['active_id'] = order.id
104+ ctxt['active_model'] = 'mrp.production'
105+ wizard_id = self.create(cr, uid,
106+ {'product_qty': 5,
107+ 'mode': 'consume_produce'}, ctxt)
108+ self.do_produce(cr, uid, [wizard_id], ctxt)
109+-
110+ I expect 10 RAM-SR3 to be consumed, takling 5 ram_sn3 and 5 ram_sn4
111+-
112+ !python {model: mrp.production}: |
113+ order = self.browse(cr, uid, ref('test_mo_pcsc349_2'), context=context)
114+ ram_lines = [line for line in order.move_lines2 if line.product_id.default_code == 'RAM-SR3']
115+ ram_sn_3 = [line for line in ram_lines if line.prodlot_id.name == 'ram_sn_3']
116+ ram_sn_4 = [line for line in ram_lines if line.prodlot_id.name == 'ram_sn_4']
117+ 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
118+ 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
119
120=== added file 'mrp/test/order_process_prodlot_split.yml'
121--- mrp/test/order_process_prodlot_split.yml 1970-01-01 00:00:00 +0000
122+++ mrp/test/order_process_prodlot_split.yml 2014-07-03 17:47:44 +0000
123@@ -0,0 +1,67 @@
124+-
125+ I create a MO for 1 PCSC349
126+-
127+ !record {model: mrp.production, id: test_mo_pcsc349}:
128+ product_id: product.product_product_4
129+ product_qty: 1
130+ product_uom: product.product_uom_unit
131+ location_src_id: stock.stock_location_stock
132+ location_dest_id: stock.stock_location_stock
133+ bom_id: mrp_bom_24
134+-
135+ I confirm the MO
136+-
137+ !workflow {model: mrp.production, action: button_confirm, ref: test_mo_pcsc349}
138+-
139+ I split the RAM SR3 in 2 production lots
140+-
141+ !python {model: stock.move.split}: |
142+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349'), context=context)
143+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
144+ assert len(ram_lines) == 1, 'no RAM-SR3 lines found'
145+ ctxt = context.copy()
146+ ctxt['active_id'] = ram_lines[0].id
147+ ctxt['active_ids'] = [ram_lines[0].id]
148+ ctxt['active_model'] = 'stock.move'
149+ values = self.default_get(cr, uid,
150+ ['product_id', 'product_uom', 'qty', 'use_exist', 'location_id'],
151+ ctxt)
152+ wizard_id = self.create(cr, uid, values, context=ctxt)
153+ prodlot_obj = self.pool.get('stock.production.lot')
154+ split_line_obj = self.pool.get('stock.move.split.lines')
155+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
156+ 'name': 'ram_sn_1',
157+ 'quantity': 1,}, context=ctxt)
158+ split_line_obj.create(cr, uid, {'wizard_id': wizard_id,
159+ 'name': 'ram_sn_2',
160+ 'quantity': 1,}, context=ctxt)
161+ self.split_lot(cr, uid, [wizard_id], context=ctxt)
162+ order.refresh()
163+ ram_lines = [line for line in order.move_lines if line.product_id.default_code == 'RAM-SR3']
164+ assert len(ram_lines) == 2, 'RAM-SR3 line not split'
165+
166+
167+-
168+ I click on the "Produce" button of the Manufacturing Order and in the wizard select "Consume and Produce" mode
169+-
170+ !python {model: mrp.product.produce}: |
171+ ctxt = context.copy()
172+ order = self.pool.get('mrp.production').browse(cr, uid, ref('test_mo_pcsc349'), context=context)
173+ ctxt['active_id'] = order.id
174+ ctxt['active_model'] = 'mrp.production'
175+ wizard_id = self.create(cr, uid,
176+ {'product_qty': 1,
177+ 'mode': 'consume_produce'}, ctxt)
178+ self.do_produce(cr, uid, [wizard_id], ctxt)
179+-
180+ I expect
181+ all the Products in the "Products to consume" lists to be consumed
182+ and moved to the "consumed products" list,
183+ and the manufacturing order to be in state "Done"
184+-
185+ !python {model: mrp.production}: |
186+ order = self.browse(cr, uid, ref('test_mo_pcsc349'), context=context)
187+ assert order.state == 'done', "wrong state for the production order (%r, expected: 'done')" % order.state
188+ assert len(order.move_lines) == 0, "%d leftover move lines in 'products to consume'" % len(order.move_lines)
189+ ram_lines = [line for line in order.move_lines2 if line.product_id.default_code == 'RAM-SR3']
190+ assert len(ram_lines) == 2, 'not all RAM-SR3 were consumed'