Merge lp:~openerp-dev/openobject-addons/trunk-wms-mrpclean-jco into lp:~openerp-dev/openobject-addons/trunk-wms
- trunk-wms-mrpclean-jco
- Merge into trunk-wms
Proposed by
Josse Colpaert (OpenERP)
Status: | Merged |
---|---|
Merged at revision: | 9695 |
Proposed branch: | lp:~openerp-dev/openobject-addons/trunk-wms-mrpclean-jco |
Merge into: | lp:~openerp-dev/openobject-addons/trunk-wms |
Diff against target: |
296 lines (+46/-50) 10 files modified
mrp/mrp.py (+12/-32) mrp/mrp_view.xml (+5/-7) mrp/stock.py (+1/-1) mrp_operations/mrp_operations.py (+1/-1) purchase/stock.py (+1/-1) sale_mrp/test/cancellation_propagated.yml (+7/-2) sale_mrp/test/sale_mrp.yml (+3/-3) stock/procurement.py (+1/-2) stock/stock.py (+9/-0) stock_dropshipping/test/cancellation_propagated.yml (+6/-1) |
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/trunk-wms-mrpclean-jco |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
qdp (OpenERP) | Approve | ||
Review via email: mp+217020@code.launchpad.net |
Commit message
Description of the change
Propagation of stock move cancelling (forward), cancels procurements in between when possible. The cancelling mrp/purchase order does not cancel entire chain. Backward cancelling of procurements should not check propagate on rule, but should depend on move cancellation only. (if move is propagate and cancelled, cancel procurement before)
To post a comment you must log in.
Revision history for this message
qdp (OpenERP) (qdp) wrote : | # |
Revision history for this message
qdp (OpenERP) (qdp) wrote : | # |
otherwise, i just need to adapt the code first to create procurement if a service product has been set on a bom before removing entirely the function _make_productio
Revision history for this message
qdp (OpenERP) (qdp) wrote : | # |
sorry, my bad: it was correct. :-)
review:
Approve
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 2014-04-23 15:05:03 +0000 |
3 | +++ mrp/mrp.py 2014-04-24 10:15:52 +0000 |
4 | @@ -493,7 +493,7 @@ |
5 | 'workcenter_lines': fields.one2many('mrp.production.workcenter.line', 'production_id', 'Work Centers Utilisation', |
6 | readonly=True, states={'draft': [('readonly', False)]}), |
7 | 'state': fields.selection( |
8 | - [('draft', 'New'), ('cancel', 'Cancelled'), ('picking_except', 'Picking Exception'), ('confirmed', 'Awaiting Raw Materials'), |
9 | + [('draft', 'New'), ('cancel', 'Cancelled'), ('confirmed', 'Awaiting Raw Materials'), |
10 | ('ready', 'Ready to Produce'), ('in_production', 'Production Started'), ('done', 'Done')], |
11 | string='Status', readonly=True, |
12 | track_visibility='onchange', |
13 | @@ -614,12 +614,6 @@ |
14 | } |
15 | return {'value': result} |
16 | |
17 | - def action_picking_except(self, cr, uid, ids): |
18 | - """ Changes the state to Exception. |
19 | - @return: True |
20 | - """ |
21 | - self.write(cr, uid, ids, {'state': 'picking_except'}) |
22 | - return True |
23 | |
24 | def _action_compute_lines(self, cr, uid, ids, properties=None, context=None): |
25 | """ Compute product_lines and workcenter_lines from BoM structure |
26 | @@ -685,6 +679,11 @@ |
27 | move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids]) |
28 | move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines]) |
29 | self.write(cr, uid, ids, {'state': 'cancel'}) |
30 | + # Put related procurements in exception |
31 | + proc_obj = self.pool.get("procurement.order") |
32 | + procs = proc_obj.search(cr, uid, [('production_id', 'in', ids)], context=context) |
33 | + if procs: |
34 | + proc_obj.write(cr, uid, procs, {'state': 'exception'}, context=context) |
35 | return True |
36 | |
37 | def action_ready(self, cr, uid, ids, context=None): |
38 | @@ -697,8 +696,6 @@ |
39 | for production in self.browse(cr, uid, ids, context=context): |
40 | if not production.move_created_ids: |
41 | self._make_production_produce_line(cr, uid, production, context=context) |
42 | - for scheduled in production.product_lines: |
43 | - self._make_production_line_procurement(cr, uid, scheduled, False, context=context) |
44 | |
45 | if production.move_prod_id and production.move_prod_id.location_id.id != production.location_dest_id.id: |
46 | move_obj.write(cr, uid, [production.move_prod_id.id], |
47 | @@ -712,6 +709,10 @@ |
48 | for production in self.browse(cr, uid, ids): |
49 | self._costs_generate(cr, uid, production) |
50 | write_res = self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')}) |
51 | + # Check related procurements |
52 | + proc_obj = self.pool.get("procurement.order") |
53 | + procs = proc_obj.search(cr, uid, [('production_id', 'in', ids)], context=context) |
54 | + proc_obj.check(cr, uid, procs, context=context) |
55 | return write_res |
56 | |
57 | def test_production_done(self, cr, uid, ids): |
58 | @@ -965,29 +966,8 @@ |
59 | if production.ready_production: |
60 | res = True |
61 | return res |
62 | - |
63 | - def _make_production_line_procurement(self, cr, uid, production_line, shipment_move_id, context=None): |
64 | - procurement_order = self.pool.get('procurement.order') |
65 | - production = production_line.production_id |
66 | - location_id = production.location_src_id.id |
67 | - date_planned = production.date_planned |
68 | - procurement_name = (production.origin or '').split(':')[0] + ':' + production.name |
69 | - procurement_id = procurement_order.create(cr, uid, { |
70 | - 'name': procurement_name, |
71 | - 'origin': procurement_name, |
72 | - 'date_planned': date_planned, |
73 | - 'product_id': production_line.product_id.id, |
74 | - 'product_qty': production_line.product_qty, |
75 | - 'product_uom': production_line.product_uom.id, |
76 | - 'product_uos_qty': production_line.product_uos and production_line.product_qty or False, |
77 | - 'product_uos': production_line.product_uos and production_line.product_uos.id or False, |
78 | - 'location_id': location_id, |
79 | - 'move_id': shipment_move_id, |
80 | - 'company_id': production.company_id.id, |
81 | - }) |
82 | - procurement_order.signal_button_confirm(cr, uid, [procurement_id]) |
83 | - return procurement_id |
84 | - |
85 | + |
86 | + |
87 | def _make_production_produce_line(self, cr, uid, production, context=None): |
88 | stock_move = self.pool.get('stock.move') |
89 | source_location_id = production.product_id.property_stock_production.id |
90 | |
91 | === modified file 'mrp/mrp_view.xml' |
92 | --- mrp/mrp_view.xml 2014-04-22 09:28:15 +0000 |
93 | +++ mrp/mrp_view.xml 2014-04-24 10:15:52 +0000 |
94 | @@ -674,12 +674,10 @@ |
95 | <button name="button_confirm" states="draft" string="Confirm Production" class="oe_highlight"/> |
96 | <button name="%(act_mrp_product_produce)d" states="ready,in_production" string="Produce" type="action" class="oe_highlight"/> |
97 | <button name="force_production" states="confirmed" string="Force Reservation" type="object"/> |
98 | - <button name="force_production" states="picking_except" string="Force Reservation" type="object"/> |
99 | <button name="button_produce" states="ready" string="Mark as Started"/> |
100 | - <button name="button_recreate" states="picking_except" string="Recreate Picking"/> |
101 | - <button name="button_cancel" states="draft,ready,in_production,picking_except" string="Cancel Production"/> |
102 | + <button name="button_cancel" states="draft,ready,in_production" string="Cancel Production"/> |
103 | <button name="action_cancel" type="object" states="confirmed" string="Cancel Production"/> |
104 | - <field name="state" widget="statusbar" statusbar_visible="draft,ready,in_production,done" statusbar_colors='{"picking_except":"red","confirmed":"blue"}'/> |
105 | + <field name="state" widget="statusbar" statusbar_visible="draft,ready,in_production,done" statusbar_colors='{"confirmed":"blue"}'/> |
106 | </header> |
107 | <sheet> |
108 | <div class="oe_title"> |
109 | @@ -720,7 +718,7 @@ |
110 | <group> |
111 | <group string="Products to Consume"> |
112 | <field name="move_lines" nolabel="1" options="{'reload_on_button': true}"> |
113 | - <tree colors="blue:state == 'draft';black:state in ('ready','assigned','in_production');gray:state in ('cancel','done');red:state in ('confirmed','picking_except','waiting')" string="Products to Consume"> |
114 | + <tree colors="blue:state == 'draft';black:state in ('ready','assigned','in_production');gray:state in ('cancel','done');red:state in ('confirmed','waiting')" string="Products to Consume"> |
115 | <field name="product_id"/> |
116 | <field name="product_qty" string="Quantity"/> |
117 | <field name="product_uom" string="Unit of Measure" groups="product.group_uom"/> |
118 | @@ -739,7 +737,7 @@ |
119 | </group> |
120 | <group string="Consumed Products"> |
121 | <field name="move_lines2" nolabel="1" options="{'reload_on_button': true}"> |
122 | - <tree colors="red:scrapped==True;blue:state == 'draft';black:state in('picking_except','confirmed','ready','in_production');gray:state == 'cancel' " string="Consumed Products" editable="bottom"> |
123 | + <tree colors="red:scrapped==True;blue:state == 'draft';black:state in ('confirmed','ready','in_production');gray:state == 'cancel' " string="Consumed Products" editable="bottom"> |
124 | <field name="product_id" readonly="1"/> |
125 | <field name="restrict_lot_id" context="{'product_id': product_id}" groups="stock.group_tracking_lot"/> |
126 | <field name="product_qty" readonly="1"/> |
127 | @@ -766,7 +764,7 @@ |
128 | </group> |
129 | <group string="Produced Products"> |
130 | <field name="move_created_ids2" nolabel="1" options="{'reload_on_button': true}"> |
131 | - <tree colors="red:scrapped==True;blue:state == 'draft';black:state in('picking_except','confirmed','ready','in_production');gray:state in('cancel','done') " string="Finished Products"> |
132 | + <tree colors="red:scrapped==True;blue:state == 'draft';black:state in('confirmed','ready','in_production');gray:state in('cancel','done') " string="Finished Products"> |
133 | <field name="product_id" readonly="1"/> |
134 | <field name="product_qty" readonly="1"/> |
135 | <field name="restrict_lot_id" groups="stock.group_tracking_lot"/> |
136 | |
137 | === modified file 'mrp/stock.py' |
138 | --- mrp/stock.py 2014-02-14 15:03:30 +0000 |
139 | +++ mrp/stock.py 2014-04-24 10:15:52 +0000 |
140 | @@ -227,7 +227,7 @@ |
141 | 'route_id': manufacture_route_id, |
142 | 'action': 'manufacture', |
143 | 'picking_type_id': warehouse.int_type_id.id, |
144 | - 'procure_method': 'make_to_order', |
145 | + 'propagate': False, |
146 | 'warehouse_id': warehouse.id, |
147 | } |
148 | |
149 | |
150 | === modified file 'mrp_operations/mrp_operations.py' |
151 | --- mrp_operations/mrp_operations.py 2014-04-03 09:38:33 +0000 |
152 | +++ mrp_operations/mrp_operations.py 2014-04-24 10:15:52 +0000 |
153 | @@ -97,7 +97,7 @@ |
154 | 'delay': fields.float('Working Hours',help="The elapsed time between operation start and stop in this Work Center",readonly=True), |
155 | 'production_state':fields.related('production_id','state', |
156 | type='selection', |
157 | - selection=[('draft','Draft'),('picking_except', 'Picking Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')], |
158 | + selection=[('draft','Draft'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')], |
159 | string='Production Status', readonly=True), |
160 | 'product':fields.related('production_id','product_id',type='many2one',relation='product.product',string='Product', |
161 | readonly=True), |
162 | |
163 | === modified file 'purchase/stock.py' |
164 | --- purchase/stock.py 2014-04-16 15:05:51 +0000 |
165 | +++ purchase/stock.py 2014-04-24 10:15:52 +0000 |
166 | @@ -116,7 +116,7 @@ |
167 | 'route_id': buy_route_id, |
168 | 'action': 'buy', |
169 | 'picking_type_id': warehouse.in_type_id.id, |
170 | - 'procure_method': 'make_to_order', |
171 | + 'propagate': False, |
172 | 'warehouse_id': warehouse.id, |
173 | } |
174 | |
175 | |
176 | === modified file 'sale_mrp/test/cancellation_propagated.yml' |
177 | --- sale_mrp/test/cancellation_propagated.yml 2013-10-29 19:27:02 +0000 |
178 | +++ sale_mrp/test/cancellation_propagated.yml 2014-04-24 10:15:52 +0000 |
179 | @@ -51,12 +51,17 @@ |
180 | Confirm sales order |
181 | - |
182 | !workflow {model: sale.order, action: order_confirm, ref: sale_order_product_manu} |
183 | +- |
184 | + I run scheduler. |
185 | +- |
186 | + !python {model: procurement.order}: | |
187 | + self.run_scheduler(cr, uid) |
188 | - |
189 | Check the propagation when we cancel the main procurement |
190 | * Retrieve related procurements and check that there are all running |
191 | * Check that the purchase order has been well created |
192 | * Cancel the main procurement |
193 | - * Check that all procurements related and the purchase order has been well cancelled |
194 | + * Check that all procurements related and the purchase order has been well cancelled |
195 | - |
196 | !python {model: procurement.order}: | |
197 | # Retrieve related procu |
198 | @@ -65,7 +70,7 @@ |
199 | assert len(procu_ids)>0, 'No procurements are found for sale order "%s" (with id : %d)' %(so.name, so.id) |
200 | |
201 | # Check that all procurements are running |
202 | - for procu in self.browse(cr, uid, procu_ids, context=context): |
203 | + for procu in self.browse(cr, uid, procu_ids, context=context): |
204 | assert procu.state == u'running', 'Procurement with id %d should be "running" but is with a state : %s!' %(procu.id, procu.state) |
205 | |
206 | # Check that one production order exist |
207 | |
208 | === modified file 'sale_mrp/test/sale_mrp.yml' |
209 | --- sale_mrp/test/sale_mrp.yml 2014-02-11 09:44:44 +0000 |
210 | +++ sale_mrp/test/sale_mrp.yml 2014-04-24 10:15:52 +0000 |
211 | @@ -100,7 +100,7 @@ |
212 | !python {model: procurement.order}: | |
213 | sale_order_obj = self.pool.get('sale.order') |
214 | so = sale_order_obj.browse(cr, uid, ref("sale_order_so0")) |
215 | - proc_ids = self.search(cr, uid, [('origin','=',so.name)]) |
216 | + proc_ids = self.search(cr, uid, [('origin','like',so.name)]) |
217 | self.run(cr, uid, proc_ids) |
218 | - |
219 | I verify that a procurement state is "running" |
220 | @@ -108,8 +108,8 @@ |
221 | !python {model: procurement.order}: | |
222 | sale_order_obj = self.pool.get('sale.order') |
223 | so = sale_order_obj.browse(cr, uid, ref("sale_order_so0")) |
224 | - proc_ids = self.search(cr, uid, [('origin','like',so.name), ('state','=','running')]) |
225 | - # Check that all procurement are running |
226 | + proc_ids = self.search(cr, uid, [('origin','like',so.name)]) |
227 | + # Check that all procurement are running |
228 | for procu in self.browse(cr,uid,proc_ids,context=context): |
229 | assert procu.state == u'running', 'Procurement with id %d should be with a state "running" but is with a state : %s!' %(procu.id,procu.state) |
230 | - |
231 | |
232 | === modified file 'stock/procurement.py' |
233 | --- stock/procurement.py 2014-04-23 15:55:57 +0000 |
234 | +++ stock/procurement.py 2014-04-24 10:15:52 +0000 |
235 | @@ -99,8 +99,7 @@ |
236 | #set the context for the propagation of the procurement cancelation |
237 | ctx['cancel_procurement'] = True |
238 | for procurement in self.browse(cr, uid, to_cancel_ids, context=ctx): |
239 | - if procurement.rule_id and procurement.rule_id.propagate: |
240 | - self.propagate_cancel(cr, uid, procurement, context=ctx) |
241 | + self.propagate_cancel(cr, uid, procurement, context=ctx) |
242 | return super(procurement_order, self).cancel(cr, uid, to_cancel_ids, context=ctx) |
243 | |
244 | def _find_parent_locations(self, cr, uid, procurement, context=None): |
245 | |
246 | === modified file 'stock/stock.py' |
247 | --- stock/stock.py 2014-04-23 15:55:57 +0000 |
248 | +++ stock/stock.py 2014-04-24 10:15:52 +0000 |
249 | @@ -2144,6 +2144,14 @@ |
250 | #cancel chained moves |
251 | if move.propagate: |
252 | self.action_cancel(cr, uid, [move.move_dest_id.id], context=context) |
253 | + # If we have a long chain of moves to be cancelled, it is easier for the user to handle |
254 | + # only the last procurement which will go into exception, instead of all procurements |
255 | + # along the chain going into exception. We need to check if there are no split moves not cancelled however |
256 | + if move.procurement_id: |
257 | + proc = move.procurement_id |
258 | + if all([x.state == 'cancel' for x in proc.move_ids if x.id != move.id]): |
259 | + procurement_obj.write(cr, uid, [proc.id], {'state': 'cancel'}) |
260 | + |
261 | elif move.move_dest_id.state == 'waiting': |
262 | self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'}, context=context) |
263 | return self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False}, context=context) |
264 | @@ -2360,6 +2368,7 @@ |
265 | 'restrict_lot_id': restrict_lot_id, |
266 | 'restrict_partner_id': restrict_partner_id, |
267 | 'split_from': move.id, |
268 | + 'move_dest_id': move.move_dest_id.id, |
269 | } |
270 | if context.get('source_location_id'): |
271 | defaults['location_id'] = context['source_location_id'] |
272 | |
273 | === modified file 'stock_dropshipping/test/cancellation_propagated.yml' |
274 | --- stock_dropshipping/test/cancellation_propagated.yml 2013-10-29 19:27:02 +0000 |
275 | +++ stock_dropshipping/test/cancellation_propagated.yml 2014-04-24 10:15:52 +0000 |
276 | @@ -40,6 +40,11 @@ |
277 | Confirm the sale order |
278 | - |
279 | !workflow {model: sale.order, action: order_confirm, ref: sale_order_product_mto} |
280 | +- |
281 | + I run scheduler. |
282 | +- |
283 | + !python {model: procurement.order}: | |
284 | + self.run_scheduler(cr, uid) |
285 | - |
286 | Check the propagation when we cancel the main procurement |
287 | * Retrieve related procurements and check that there are all running |
288 | @@ -64,7 +69,7 @@ |
289 | # Cancel the main procurement |
290 | main_procu_id = self.search(cr, uid, [('origin', '=', so.name)]) |
291 | assert len(main_procu_id) == 1, 'Main procurement not identified !' |
292 | - self.cancel(cr, uid, main_procu_id, context=context) |
293 | + self.cancel(cr, uid, main_procu_id, context=context) |
294 | assert self.browse(cr, uid, main_procu_id[0]).state == u'cancel', 'Main procurement should be cancelled !' |
295 | |
296 | # Check that all procurements related are cancelled |
line 246 === modified file 'stock/stock.py'
i don't think it's gonna work, i need to test more: it seems that if i cancel the move stock -> customer in a MTO it will also set the procurement in customer in cancelled instead of exception because move.procurement_id link to the procurement that _created_ the move, not the one _created by_ the move.