Merge lp:~openerp-dev/openobject-addons/7.0-opw-586594-acl into lp:openobject-addons/7.0

Proposed by Anaël Closson (openerp)
Status: Needs review
Proposed branch: lp:~openerp-dev/openobject-addons/7.0-opw-586594-acl
Merge into: lp:openobject-addons/7.0
Diff against target: 121 lines (+22/-19)
5 files modified
mrp/mrp.py (+13/-11)
mrp/procurement.py (+1/-1)
mrp/report/price.py (+1/-1)
mrp/stock.py (+6/-5)
mrp/wizard/change_production_qty.py (+1/-1)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/7.0-opw-586594-acl
Reviewer Review Type Date Requested Status
OpenERP R&D Team Pending
Review via email: mp+150551@code.launchpad.net

Description of the change

When creating a sale order with lines having phantom BoM, the first BoM for the corresponding product was always found.

It now takes care of properties to select the right BoM.

Steps to reproduce :

1. In Settings > Manufacturing, we have selected the tickbox: Allow several bill of materials per products using properties

2. In the Manufacturing module > Products > Bill of Materials there are 2 BOM’s called ‘HDD on Demand’. I have edited them both to be BOM Type: Sets / Phantoms

3. In Manufacturing > Properties, I created 2 new Properties: one called HDD1 x1 and the other called HDD2 x4

4. In the 1st ‘HDD on Demand’ I loaded Property HDD1 x1 and in the 2nd ‘HDD on Demand’ we loaded HDD2 x4

5. In each BOM ‘HDD on Demand’ I added an extra line for ease of identification

6. Then I go to the Sales module > Sales Orders to create a quotation using any Customer. When I come to add a product line, I Create Product ‘HDD on Demand’ and select a Property, look for hdd, the 1st one being: HDD1 x1. Save & Close. Confirm the Order. View the Delivery Order and I see the 2 lines on Property HDD x1

7. If I create another order and create Product ‘HDD on Demand’ and select Property, look for hdd and select the 2nd one being: HDD2 x4. Save and Close. Confirm the Order. View the Delivery Order, I see the 2 lines from HDD1 x2 displayed. In other words, the Property selection is not picking any subsequent Properties selected other than the 1st Property.

To post a comment you must log in.

Unmerged revisions

8765. By Anaël Closson (openerp)

[FIX] mrp : Phantom BoM can be chosen according sale order line properties

Before this patch, BoM was incorrectly chosen : for 2 BoM bound to properties for a single product,
the first BoM found was used each time the product was added to a sale order; the property had no impact.
Now, the right BoM is used according the property used in the sale order line.

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 2012-12-20 11:47:30 +0000
3+++ mrp/mrp.py 2013-02-26 12:54:33 +0000
4@@ -286,17 +286,19 @@
5 res['value'].update({'product_uom': product.uom_id.id})
6 return res
7
8- def _bom_find(self, cr, uid, product_id, product_uom, properties=None):
9- """ Finds BoM for particular product and product uom.
10- @param product_id: Selected product.
11- @param product_uom: Unit of measure of a product.
12+ def _bom_find(self, cr, uid, domain=None, properties=None):
13+ """ Finds the best BoM for particular domain according to the properties.
14+ @param domain: Bom domain.
15 @param properties: List of related properties.
16 @return: False or BoM id.
17 """
18- if properties is None:
19- properties = []
20- cr.execute('select id from mrp_bom where product_id=%s and bom_id is null order by sequence', (product_id,))
21- ids = map(lambda x: x[0], cr.fetchall())
22+ if not domain:
23+ domain = []
24+ if not properties:
25+ properties = []
26+ domain += [('bom_id','=',False)]
27+ ids = self.search(cr, uid, domain)
28+
29 max_prop = 0
30 result = False
31 for bom in self.pool.get('mrp.bom').browse(cr, uid, ids):
32@@ -328,7 +330,7 @@
33 result2 = []
34 phantom = False
35 if bom.type == 'phantom' and not bom.bom_lines:
36- newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties)
37+ newbom = self._bom_find(cr, uid, [('product_id','=',bom.product_id.id)], properties)
38
39 if newbom:
40 res = self._bom_explode(cr, uid, self.browse(cr, uid, [newbom])[0], factor*bom.product_qty, properties, addthis=True, level=level+10)
41@@ -545,7 +547,7 @@
42 }}
43 bom_obj = self.pool.get('mrp.bom')
44 product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
45- bom_id = bom_obj._bom_find(cr, uid, product.id, product.uom_id and product.uom_id.id, [])
46+ bom_id = bom_obj._bom_find(cr, uid, [('product_id', '=', product.id)])
47 routing_id = False
48 if bom_id:
49 bom_point = bom_obj.browse(cr, uid, bom_id, context=context)
50@@ -600,7 +602,7 @@
51 bom_point = production.bom_id
52 bom_id = production.bom_id.id
53 if not bom_point:
54- bom_id = bom_obj._bom_find(cr, uid, production.product_id.id, production.product_uom.id, properties)
55+ bom_id = bom_obj._bom_find(cr, uid, [('product_id','=',production.product_id.id)], properties)
56 if bom_id:
57 bom_point = bom_obj.browse(cr, uid, bom_id)
58 routing_id = bom_point.routing_id.id or False
59
60=== modified file 'mrp/procurement.py'
61--- mrp/procurement.py 2012-12-18 22:50:15 +0000
62+++ mrp/procurement.py 2013-02-26 12:54:33 +0000
63@@ -45,7 +45,7 @@
64 for procurement in self.browse(cr, uid, ids, context=context):
65 product = procurement.product_id
66 properties = [x.id for x in procurement.property_ids]
67- bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, procurement.product_id.id, procurement.product_uom.id, properties)
68+ bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, [('product_id', '=', procurement.product_id.id)], properties)
69 if not bom_id:
70 cr.execute('update procurement_order set message=%s where id=%s', (_('No BoM defined for this product !'), procurement.id))
71 for (id, name) in self.name_get(cr, uid, procurement.id):
72
73=== modified file 'mrp/report/price.py'
74--- mrp/report/price.py 2012-12-06 14:56:32 +0000
75+++ mrp/report/price.py 2013-02-26 12:54:33 +0000
76@@ -142,7 +142,7 @@
77
78 for product in product_pool.browse(cr, uid, ids, context=context):
79 product_uom_name = to_xml(product.uom_id.name)
80- bom_id = bom_pool._bom_find(cr, uid, product.id, product.uom_id.id)
81+ bom_id = bom_pool._bom_find(cr, uid, [('product_id', '=', product.id)])
82 title = "<title>%s</title>" %(_("Cost Structure"))
83 title += "<title>%s</title>" % (to_xml(product.name))
84 xml += "<lines style='header'>" + title + prod_header + "</lines>"
85
86=== modified file 'mrp/stock.py'
87--- mrp/stock.py 2012-12-06 14:56:32 +0000
88+++ mrp/stock.py 2013-02-26 12:54:33 +0000
89@@ -48,13 +48,14 @@
90 wf_service = netsvc.LocalService("workflow")
91 processed_ids = [move.id]
92 if move.product_id.supply_method == 'produce' and move.product_id.procure_method == 'make_to_order':
93- bis = bom_obj.search(cr, uid, [
94- ('product_id','=',move.product_id.id),
95- ('bom_id','=',False),
96- ('type','=','phantom')])
97+ property_ids = []
98+ if move.sale_line_id:
99+ property_ids = [i.id for i in move.sale_line_id.property_ids]
100+ bis = bom_obj._bom_find(cr, uid, [('product_id','=',move.product_id.id), ('type','=','phantom')], property_ids)
101+
102 if bis:
103 factor = move.product_qty
104- bom_point = bom_obj.browse(cr, uid, bis[0], context=context)
105+ bom_point = bom_obj.browse(cr, uid, bis, context=context)
106 res = bom_obj._bom_explode(cr, uid, bom_point, factor, [])
107 state = 'confirmed'
108 if move.state == 'assigned':
109
110=== modified file 'mrp/wizard/change_production_qty.py'
111--- mrp/wizard/change_production_qty.py 2012-12-17 15:23:03 +0000
112+++ mrp/wizard/change_production_qty.py 2013-02-26 12:54:33 +0000
113@@ -78,7 +78,7 @@
114 bom_point = prod.bom_id
115 bom_id = prod.bom_id.id
116 if not bom_point:
117- bom_id = bom_obj._bom_find(cr, uid, prod.product_id.id, prod.product_uom.id)
118+ bom_id = bom_obj._bom_find(cr, uid, [('product_id', '=', prod.product_id.id)])
119 if not bom_id:
120 raise osv.except_osv(_('Error!'), _("Cannot find bill of material for this product."))
121 prod_obj.write(cr, uid, [prod.id], {'bom_id': bom_id})