Merge lp:~zaber/openobject-addons/phantom-bom-moves into lp:openobject-addons/5.0

Proposed by Don Kirkby
Status: Needs review
Proposed branch: lp:~zaber/openobject-addons/phantom-bom-moves
Merge into: lp:openobject-addons/5.0
Diff against target: 381 lines (+264/-22)
5 files modified
mrp/mrp.py (+6/-7)
mrp/mrp_demo.xml (+2/-15)
mrp_jit/test/mrp_jit_test.xml (+108/-0)
product/product_demo.xml (+2/-0)
sale/test/sale_test.xml (+146/-0)
To merge this branch: bzr merge lp:~zaber/openobject-addons/phantom-bom-moves
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+45582@code.launchpad.net

Description of the change

Test and bug fix for bug lp:700154.

To post a comment you must log in.

Unmerged revisions

2881. By Don Kirkby

[FIX] Link move_dest_id to original phantom product move for bug lp:700154.

2880. By Don Kirkby

[FIX] Call action_confirm() to fix part of bug lp:700154.

2879. By Don Kirkby

[IMP] Add failing test for bug lp:700154 phantom BOM sales order

2878. By Don Kirkby

[MERGE] tweak demo data so that we can sell a product with a phantom BOM (PC0). Merged from phantom-bom-workflow branch.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'mrp/mrp.py'
2--- mrp/mrp.py 2010-12-30 06:18:22 +0000
3+++ mrp/mrp.py 2011-01-07 23:47:54 +0000
4@@ -1208,9 +1208,6 @@
5 factor = move.product_qty
6 bom_point = self.pool.get('mrp.bom').browse(cr, uid, bis[0])
7 res = self.pool.get('mrp.bom')._bom_explode(cr, uid, bom_point, factor, [])
8- state = 'confirmed'
9- if move.state=='assigned':
10- state='assigned'
11 for line in res[0]:
12 valdef = {
13 'picking_id': move.picking_id.id,
14@@ -1219,13 +1216,15 @@
15 'product_qty': line['product_qty'],
16 'product_uos': line['product_uos'],
17 'product_uos_qty': line['product_uos_qty'],
18- 'state': state,
19+ 'state': 'draft',
20 'name': line['name'],
21+ 'move_dest_id': move.id,
22 'move_history_ids': [(6,0,[move.id])],
23 'move_history_ids2': [(6,0,[])],
24 'procurements': []
25 }
26 mid = self.pool.get('stock.move').copy(cr, uid, move.id, default=valdef)
27+ self.action_confirm(cr, uid, [mid], context)
28 prodobj = self.pool.get('product.product').browse(cr, uid, line['product_id'], context=context)
29 proc_id = self.pool.get('mrp.procurement').create(cr, uid, {
30 'name': (move.picking_id.origin or ''),
31@@ -1272,10 +1271,10 @@
32 #
33 # Explode picking by replacing phantom BoMs
34 #
35- def action_explode(self, cr, uid, picks, *args):
36- for move in self.pool.get('stock.move').browse(cr, uid, picks):
37+ def action_explode(self, cr, uid, moves, *args):
38+ for move in self.pool.get('stock.move').browse(cr, uid, moves):
39 self.pool.get('stock.move')._action_explode(cr, uid, move)
40- return picks
41+ return moves
42
43 StockPicking()
44
45
46=== modified file 'mrp/mrp_demo.xml'
47--- mrp/mrp_demo.xml 2010-02-17 12:18:07 +0000
48+++ mrp/mrp_demo.xml 2011-01-07 23:47:54 +0000
49@@ -238,12 +238,6 @@
50 <field name="name">Complete PC with peripherals</field>
51 <field name="product_uom" ref="product.product_uom_unit"/>
52 <field name="product_qty">1.0</field>
53- <field model="product.product" name="product_id" ref="product.product_product_23"/>
54- </record>
55- <record id="mrp_bom_11" model="mrp.bom">
56- <field name="name">RAM on demand</field>
57- <field name="product_uom" ref="product.product_uom_unit"/>
58- <field name="product_qty">1.0</field>
59 <field name="type">phantom</field>
60 <field model="product.product" name="product_id" ref="product.product_product_23"/>
61 </record>
62@@ -260,9 +254,9 @@
63 <field name="name">Kit Mouse</field>
64 <field name="product_uom" ref="product.product_uom_unit"/>
65 <field name="product_qty">1.0</field>
66- <field name="type">normal</field>
67+ <field name="type">phantom</field>
68 <field name="bom_id" ref="mrp_bom_10"/>
69- <field model="product.product" name="product_id" ref="product.product_product_25"/>
70+ <field model="product.product" name="product_id" ref="product.product_product_26"/>
71 </record>
72 <record id="mrp_bom_clavier" model="mrp.bom">
73 <field name="name">Keyboard</field>
74@@ -306,13 +300,6 @@
75 <field name="bom_id" ref="mrp_bom_13"/>
76 <field model="product.product" name="product_id" ref="product.product_product_fan"/>
77 </record>
78- <record id="mrp_bom_23" model="mrp.bom">
79- <field name="name">DDR 256MB PC333</field>
80- <field name="product_uom" ref="product.product_uom_unit"/>
81- <field name="product_qty">1.0</field>
82- <field name="bom_id" ref="mrp_bom_11"/>
83- <field model="product.product" name="product_id" ref="product.product_product_ram"/>
84- </record>
85 <record id="mrp_bom_1901" model="mrp.bom">
86 <field name="name">DDR 512MB PC400</field>
87 <field name="product_uom" ref="product.product_uom_unit"/>
88
89=== modified file 'mrp_jit/test/mrp_jit_test.xml'
90--- mrp_jit/test/mrp_jit_test.xml 2010-03-11 13:05:02 +0000
91+++ mrp_jit/test/mrp_jit_test.xml 2011-01-07 23:47:54 +0000
92@@ -166,6 +166,114 @@
93 <assert id="smoke_test_sale_order" model="sale.order" string="the sale order is now done">
94 <test expr="state">done</test>
95 </assert>
96+
97+
98+
99+ <!-- ================================================================
100+ Test phantom bill of materials with MRP-JIT installed,
101+ based on a similar smoke test in 'sale' module
102+
103+ 0. Check that the set product is configured correctly
104+ 1. creates a simple sale order with 1 line using a set product
105+ 2. confirms the sale order
106+ 3. Check that a chained move got created for each component
107+ 4. Check that no production order is created
108+
109+ ================================================================
110+ -->
111+
112+ <!-- ==== 0. Check that the set product is configured correctly ==== -->
113+ <assert
114+ id="product.product_product_23"
115+ model="product.product"
116+ string="The PC with peripherals product is configured as a set.">
117+ <test expr="name">Complete PC With Peripherals</test>
118+ <test expr="code">PC0</test>
119+ <test expr="supply_method">produce</test>
120+ <test expr="procure_method">make_to_order</test>
121+ </assert>
122+ <assert
123+ id="mrp.mrp_bom_10"
124+ model="mrp.bom"
125+ string="The PC with peripherals product has a phantom BOM.">
126+ <test expr="type">phantom</test>
127+ <test expr="product_id.code">PC0</test>
128+ </assert>
129+ <assert
130+ id="product.product_product_26"
131+ model="product.product"
132+ string="The keyboard + mouse product is configured as a set.">
133+ <test expr="name">Kit Keyboard + Mouse</test>
134+ <test expr="code">KIT0</test>
135+ <test expr="supply_method">produce</test>
136+ <test expr="procure_method">make_to_order</test>
137+ </assert>
138+ <assert
139+ id="mrp.mrp_bom_kit"
140+ model="mrp.bom"
141+ string="The keyboard + mouse product has a phantom BOM.">
142+ <test expr="type">phantom</test>
143+ <test expr="product_id.code">KIT0</test>
144+ </assert>
145+
146+ <!-- ==== 1. creates a simple sale order with 1 line using a set product ==== -->
147+ <!-- Resource: sale.order -->
148+ <record id="phantom_sale_order" model="sale.order">
149+ <field name="shop_id" ref="sale.shop"/>
150+ <field model="product.pricelist" name="pricelist_id" search="[]"/>
151+ <field name="user_id" ref="base.user_root"/>
152+ <field model="res.partner" name="partner_id" search="[]"/>
153+ <field name="order_policy">manual</field> <!-- force manual invoicing -->
154+ <field name="picking_policy">one</field> <!-- full delivery only -->
155+ <field name="invoice_quantity">order</field> <!-- invoice based on ordered quantities -->
156+ <field model="res.partner.address" name="partner_invoice_id" search="[]"/>
157+ <field model="res.partner.address" name="partner_shipping_id" search="[]"/>
158+ <field model="res.partner.address" name="partner_order_id" search="[]"/>
159+ <field name="name">SO-PHANTOM-JIT</field>
160+ </record>
161+ <record id="phantom_sale_order_line_1" model="sale.order.line">
162+ <field name="order_id" ref="phantom_sale_order"/>
163+ <field name="name">[PC0] Complete PC With Peripherals</field>
164+ <field name="product_id" ref="product.product_product_23"/>
165+ <field name="product_uom" ref="product.product_uom_unit"/>
166+ <field name="price_unit">750</field>
167+ <field name="product_uom_qty">1</field>
168+ <field name="product_uos_qty">1</field>
169+ <field name="type">make_to_order</field>
170+ </record>
171+
172+ <!-- ==== 2. confirms the sale order ==== -->
173+ <workflow action="order_confirm" model="sale.order" ref="phantom_sale_order"/>
174+
175+ <assert
176+ id="phantom_sale_order"
177+ model="sale.order"
178+ string="the sale order is now in 'Manual in progress' state">
179+ <test expr="state">manual</test>
180+ </assert>
181+
182+ <!-- ==== 3. Check that both packing lists contain set contents ==== -->
183+ <assert
184+ model="sale.order"
185+ id="phantom_sale_order"
186+ string="stock moves for phantom product (stock to output and output to cust)">
187+ <test expr="str(len(order_line[0].move_ids)) + ' stock moves'">7 stock moves</test>
188+ <test expr="order_line[0].move_ids[0].product_id.code">PC0</test>
189+ <test expr="order_line[0].move_ids[1].product_id.code + ' - ' + order_line[0].move_ids[1].picking_id.type">KEYA - out</test>
190+ <test expr="order_line[0].move_ids[2].product_id.code + ' - ' + order_line[0].move_ids[2].picking_id.type">KEYA - delivery</test>
191+ <test expr="order_line[0].move_ids[3].product_id.code + ' - ' + order_line[0].move_ids[3].picking_id.type">MOU - out</test>
192+ <test expr="order_line[0].move_ids[4].product_id.code + ' - ' + order_line[0].move_ids[4].picking_id.type">MOU - delivery</test>
193+ <test expr="order_line[0].move_ids[5].product_id.code + ' - ' + order_line[0].move_ids[5].picking_id.type">PC1 - out</test>
194+ <test expr="order_line[0].move_ids[6].product_id.code + ' - ' + order_line[0].move_ids[6].picking_id.type">PC1 - delivery</test>
195+ </assert>
196+
197+ <!-- ==== 4. Check that no production order is created ==== -->
198+ <assert
199+ model="mrp.production"
200+ search="[('product_id', '=', ref('product.product_product_23'))]"
201+ string="There should not be any production orders for the set product">
202+ <test expr="False"/>
203+ </assert>
204 </data>
205
206 <data>
207
208=== modified file 'product/product_demo.xml'
209--- product/product_demo.xml 2010-04-23 13:26:04 +0000
210+++ product/product_demo.xml 2011-01-07 23:47:54 +0000
211@@ -349,6 +349,7 @@
212 <record id="product_product_23" model="product.product">
213 <field name="default_code">PC0</field>
214 <field name="supply_method">produce</field>
215+ <field name="procure_method">make_to_order</field>
216 <field name="list_price">750.0</field>
217 <field name="standard_price">500.0</field>
218 <field name="uom_id" ref="product_uom_unit"/>
219@@ -378,6 +379,7 @@
220 <record id="product_product_26" model="product.product">
221 <field name="default_code">KIT0</field>
222 <field name="supply_method">produce</field>
223+ <field name="procure_method">make_to_order</field>
224 <field name="list_price">7.0</field>
225 <field name="standard_price">5.0</field>
226 <field name="uom_id" ref="product_uom_unit"/>
227
228=== modified file 'sale/test/sale_test.xml'
229--- sale/test/sale_test.xml 2010-06-10 13:40:19 +0000
230+++ sale/test/sale_test.xml 2011-01-07 23:47:54 +0000
231@@ -173,6 +173,152 @@
232 <assert id="smoke_test_sale_order" model="sale.order" string="the sale order is now done">
233 <test expr="state">done</test>
234 </assert>
235+
236+
237+ <!-- ================================================================
238+ Test phantom bill of materials
239+
240+ 0. Check that the set product is configured correctly
241+ 1. creates a simple sale order with 1 line using a set product
242+ 2. confirms the sale order
243+ 3. Check that a chained move got created for each component
244+ 4. Check that no production order is created
245+ 5. Picking: check availability
246+ 6. Make the delivery
247+ 7. Verify that everything is done
248+
249+ ================================================================
250+ -->
251+
252+ <!-- ==== 0. Check that the set product is configured correctly ==== -->
253+ <assert
254+ id="product.product_product_23"
255+ model="product.product"
256+ string="The PC with peripherals product is configured as a set.">
257+ <test expr="name">Complete PC With Peripherals</test>
258+ <test expr="code">PC0</test>
259+ <test expr="supply_method">produce</test>
260+ <test expr="procure_method">make_to_order</test>
261+ </assert>
262+ <assert
263+ id="mrp.mrp_bom_10"
264+ model="mrp.bom"
265+ string="The PC with peripherals product has a phantom BOM.">
266+ <test expr="type">phantom</test>
267+ <test expr="product_id.code">PC0</test>
268+ </assert>
269+ <assert
270+ id="product.product_product_26"
271+ model="product.product"
272+ string="The keyboard + mouse product is configured as a set.">
273+ <test expr="name">Kit Keyboard + Mouse</test>
274+ <test expr="code">KIT0</test>
275+ <test expr="supply_method">produce</test>
276+ <test expr="procure_method">make_to_order</test>
277+ </assert>
278+ <assert
279+ id="mrp.mrp_bom_kit"
280+ model="mrp.bom"
281+ string="The keyboard + mouse product has a phantom BOM.">
282+ <test expr="type">phantom</test>
283+ <test expr="product_id.code">KIT0</test>
284+ </assert>
285+
286+ <!-- ==== 1. creates a simple sale order with 1 line using a set product ==== -->
287+ <!-- Resource: sale.order -->
288+ <record id="phantom_sale_order" model="sale.order">
289+ <field name="shop_id" ref="shop"/>
290+ <field model="product.pricelist" name="pricelist_id" search="[]"/>
291+ <field name="user_id" ref="base.user_root"/>
292+ <field model="res.partner" name="partner_id" search="[]"/>
293+ <field name="order_policy">manual</field> <!-- force manual invoicing -->
294+ <field name="picking_policy">one</field> <!-- full delivery only -->
295+ <field name="invoice_quantity">order</field> <!-- invoice based on ordered quantities -->
296+ <field model="res.partner.address" name="partner_invoice_id" search="[]"/>
297+ <field model="res.partner.address" name="partner_shipping_id" search="[]"/>
298+ <field model="res.partner.address" name="partner_order_id" search="[]"/>
299+ <field name="name">SO-PHANTOM</field>
300+ </record>
301+ <record id="phantom_sale_order_line_1" model="sale.order.line">
302+ <field name="order_id" ref="phantom_sale_order"/>
303+ <field name="name">[PC0] Complete PC With Peripherals</field>
304+ <field name="product_id" ref="product.product_product_23"/>
305+ <field name="product_uom" ref="product.product_uom_unit"/>
306+ <field name="price_unit">750</field>
307+ <field name="product_uom_qty">1</field>
308+ <field name="product_uos_qty">1</field>
309+ <field name="type">make_to_order</field>
310+ </record>
311+
312+ <!-- ==== 2. confirms the sale order ==== -->
313+ <workflow action="order_confirm" model="sale.order" ref="phantom_sale_order"/>
314+
315+ <assert
316+ id="phantom_sale_order"
317+ model="sale.order"
318+ string="the sale order is now in 'Manual in progress' state">
319+ <test expr="state">manual</test>
320+ </assert>
321+
322+ <!-- ==== 3. Check that a chained move got created for each component ==== -->
323+ <assert
324+ model="sale.order"
325+ id="phantom_sale_order"
326+ string="stock moves for phantom product (stock to output and output to cust)">
327+ <test expr="str(len(order_line[0].move_ids)) + ' stock moves'">7 stock moves</test>
328+ <test expr="order_line[0].move_ids[0].product_id.code">PC0</test>
329+ <test expr="order_line[0].move_ids[1].product_id.code + ' - ' + order_line[0].move_ids[1].picking_id.type">KEYA - out</test>
330+ <test expr="order_line[0].move_ids[2].product_id.code + ' - ' + order_line[0].move_ids[2].picking_id.type">KEYA - delivery</test>
331+ <test expr="order_line[0].move_ids[3].product_id.code + ' - ' + order_line[0].move_ids[3].picking_id.type">MOU - out</test>
332+ <test expr="order_line[0].move_ids[4].product_id.code + ' - ' + order_line[0].move_ids[4].picking_id.type">MOU - delivery</test>
333+ <test expr="order_line[0].move_ids[5].product_id.code + ' - ' + order_line[0].move_ids[5].picking_id.type">PC1 - out</test>
334+ <test expr="order_line[0].move_ids[6].product_id.code + ' - ' + order_line[0].move_ids[6].picking_id.type">PC1 - delivery</test>
335+ </assert>
336+
337+ <!-- ==== 4. Check that no production order is created ==== -->
338+ <assert
339+ model="mrp.production"
340+ search="[('product_id', '=', ref('product.product_product_23'))]"
341+ string="There should not be any production orders for the set product">
342+ <test expr="False"/>
343+ </assert>
344+ <!-- ==== 5. Picking: check availability ==== -->
345+ <!-- Here we need to directly call the function tag because action_assign is a method of stock_picking and not part of the workflow -->
346+ <function model="stock.picking" name="action_assign">
347+ <value eval="[obj(ref('phantom_sale_order')).picking_ids[0].id]" model="sale.order"/>
348+ </function>
349+ <assert id="phantom_sale_order" model="sale.order" severity="error" string="the sale order's picking is now assigned">
350+ <test expr="picking_ids[0].state">assigned</test>
351+ </assert>
352+
353+ <!-- The above step could also be replaced by the following call to the mrp schedulers: -->
354+ <!-- <function model="mrp.procurement" name="run_scheduler"/> -->
355+
356+ <!-- ==== 6. Make the delivery ==== -->
357+ <!-- See wizard_picking_make or wizard_partial_picking in stock module. -->
358+ <function model="stock.picking" name="action_move">
359+ <value eval="[obj(ref('phantom_sale_order')).picking_ids[0].id]" model="sale.order"/>
360+ </function>
361+ <workflow action="button_done" model="stock.picking">
362+ <value eval="obj(ref('phantom_sale_order')).picking_ids[0].id" model="sale.order"/>
363+ </workflow>
364+ <function model="stock.picking" name="action_move">
365+ <value eval="[obj(ref('phantom_sale_order')).order_line[0].move_ids[6].picking_id.id]" model="sale.order"/>
366+ </function>
367+ <workflow action="button_done" model="stock.picking">
368+ <value eval="obj(ref('phantom_sale_order')).order_line[0].move_ids[6].picking_id.id" model="sale.order"/>
369+ </workflow>
370+
371+
372+ <!-- ==== 7. Verify that everything is done ==== -->
373+ <assert id="phantom_sale_order" model="sale.order" string="the main procurement is now done">
374+ <test expr="order_line[0].procurement_id.state">done</test>
375+ </assert>
376+ <assert id="phantom_sale_order" model="sale.order" string="the sale order's picking is now done">
377+ <test expr="picking_ids[0].state">done</test>
378+ <test expr="order_line[0].move_ids[3].picking_id.state">done</test>
379+ <test expr="shipped == True"/>
380+ </assert>
381 </data>
382
383