From 2c101e9432d8bce744265569d38fb76f16cf5f20 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 5 Feb 2014 10:34:11 +0100 Subject: [PATCH] [REF] mrp: code refactoring + removal of a useless and confusing part of a yaml test bzr revid: qdp-launchpad@openerp.com-20140205093411-2xqnn5l3gyw6hmw5 --- addons/mrp/stock.py | 47 +++++++------ .../test/bom_with_service_type_product.yml | 67 ------------------- addons/mrp/wizard/mrp_product_produce.py | 15 ++--- addons/mrp/wizard/stock_move.py | 4 +- 4 files changed, 30 insertions(+), 103 deletions(-) diff --git a/addons/mrp/stock.py b/addons/mrp/stock.py index 712b650c490..dd516707e7b 100644 --- a/addons/mrp/stock.py +++ b/addons/mrp/stock.py @@ -30,7 +30,7 @@ class StockMove(osv.osv): _columns = { 'production_id': fields.many2one('mrp.production', 'Production Order for Produced Products', select=True), 'raw_material_production_id': fields.many2one('mrp.production', 'Production Order for Raw Materials', select=True), - 'consumed_for': fields.many2one('stock.move', 'Consumed for'), + 'consumed_for': fields.many2one('stock.move', 'Consumed for', help='Technical field used to make the traceability of produced products'), } def check_tracking(self, cr, uid, move, lot_id, context=None): @@ -38,8 +38,8 @@ class StockMove(osv.osv): if move.product_id.track_production and (move.location_id.usage == 'production' or move.location_dest_id.usage == 'production') and not lot_id: raise osv.except_osv(_('Warning!'), _('You must assign a serial number for the product %s') % (move.product_id.name)) if move.raw_material_production_id and move.location_dest_id.usage == 'production' and move.raw_material_production_id.product_id.track_production and not move.consumed_for: - raise osv.except_osv(_('Warning!'), _('You should not process it like this as both your raw materials and finished product require to track manufacturing. In that case, you should be able to make the link between the raw materials and the finished products and this is not possible with this method. ')) - + raise osv.except_osv(_('Warning!'), _("Because the product %s requires it, you must assign a serial number to your raw material %s to proceed further in your production. Please use the 'Produce' button to do so.") % (move.raw_material_production_id.product_id.name, move.product_id.name)) + def _action_explode(self, cr, uid, move, context=None): """ Explodes pickings. @param move: Stock moves @@ -50,11 +50,11 @@ class StockMove(osv.osv): procurement_obj = self.pool.get('procurement.order') product_obj = self.pool.get('product.product') processed_ids = [move.id] - + bis = bom_obj.search(cr, uid, [ - ('product_id','=',move.product_id.id), - ('bom_id','=',False), - ('type','=','phantom')]) + ('product_id', '=', move.product_id.id), + ('bom_id', '=', False), + ('type', '=', 'phantom')]) if bis: factor = move.product_qty bom_point = bom_obj.browse(cr, uid, bis[0], context=context) @@ -62,7 +62,7 @@ class StockMove(osv.osv): state = 'confirmed' if move.state == 'assigned': state = 'assigned' - for line in res[0]: + for line in res[0]: valdef = { 'picking_id': move.picking_id.id, 'product_id': line['product_id'], @@ -86,7 +86,7 @@ class StockMove(osv.osv): 'product_qty': line['product_qty'], 'product_uom': line['product_uom'], 'product_uos_qty': line['product_uos'] and line['product_uos_qty'] or False, - 'product_uos': line['product_uos'], + 'product_uos': line['product_uos'], 'location_id': move.location_id.id, 'procure_method': prodobj.procure_method, 'move_id': mid, @@ -103,19 +103,20 @@ class StockMove(osv.osv): procurement_obj.signal_button_wait_done(cr, uid, procurement_ids) return processed_ids - - - def action_consume(self, cr, uid, ids, product_qty, location_id=False, restrict_lot_id = False, restrict_partner_id = False, - consumed_for = False, context=None): + def action_consume(self, cr, uid, ids, product_qty, location_id=False, restrict_lot_id=False, restrict_partner_id=False, + consumed_for=False, context=None): """ Consumed product with specific quantity from specific source location. @param product_qty: Consumed product quantity @param location_id: Source location + @param restrict_lot_id: optionnal parameter that allows to restrict the choice of quants on this specific lot + @param restrict_partner_id: optionnal parameter that allows to restrict the choice of quants to this specific partner + @param consumed_for: optionnal parameter given to this function to make the link between raw material consumed and produced product, for a better traceability @return: Consumed lines """ res = [] production_obj = self.pool.get('mrp.production') uom_obj = self.pool.get('product.uom') - + if product_qty <= 0: raise osv.except_osv(_('Warning!'), _('Please provide proper quantity.')) for move in self.browse(cr, uid, ids, context=context): @@ -130,15 +131,14 @@ class StockMove(osv.osv): ctx = context.copy() if location_id: ctx['source_location_id'] = location_id - new_mov = self.split(cr, uid, move, move_qty - quantity_rest, restrict_lot_id=restrict_lot_id, - restrict_partner_id=restrict_partner_id, context=ctx) - self.write(cr, uid, new_mov, {'consumed_for': consumed_for},context=context) + new_mov = self.split(cr, uid, move, move_qty - quantity_rest, restrict_lot_id=restrict_lot_id, restrict_partner_id=restrict_partner_id, context=ctx) + self.write(cr, uid, new_mov, {'consumed_for': consumed_for}, context=context) res.append(new_mov) else: res.append(move.id) if location_id: - self.write(cr, uid, [move.id], {'location_id': location_id, 'restrict_lot_id': restrict_lot_id, - 'restrict_partner_id': restrict_partner_id, + self.write(cr, uid, [move.id], {'location_id': location_id, 'restrict_lot_id': restrict_lot_id, + 'restrict_partner_id': restrict_partner_id, 'consumed_for': consumed_for}, context=context) self.action_done(cr, uid, res, context=context) production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])]) @@ -149,7 +149,6 @@ class StockMove(osv.osv): production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]}) return res - def action_scrap(self, cr, uid, ids, product_qty, location_id, restrict_lot_id=False, restrict_partner_id=False, context=None): """ Move the scrap/damaged product into scrap location @param product_qty: Scraped product quantity @@ -159,9 +158,9 @@ class StockMove(osv.osv): res = [] production_obj = self.pool.get('mrp.production') for move in self.browse(cr, uid, ids, context=context): - new_moves = super(StockMove, self).action_scrap(cr, uid, [move.id], product_qty, location_id, - restrict_lot_id = restrict_lot_id, - restrict_partner_id = restrict_partner_id, context=context) + new_moves = super(StockMove, self).action_scrap(cr, uid, [move.id], product_qty, location_id, + restrict_lot_id=restrict_lot_id, + restrict_partner_id=restrict_partner_id, context=context) #If we are not scrapping our whole move, tracking and lot references must not be removed production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])]) for prod_id in production_ids: @@ -181,6 +180,7 @@ class StockMove(osv.osv): workflow.trg_trigger(uid, 'stock.move', move.id, cr) return res + class StockPicking(osv.osv): _inherit = 'stock.picking' @@ -196,7 +196,6 @@ class StockPicking(osv.osv): return list(set(todo)) - class stock_warehouse(osv.osv): _inherit = 'stock.warehouse' _columns = { diff --git a/addons/mrp/test/bom_with_service_type_product.yml b/addons/mrp/test/bom_with_service_type_product.yml index d0125bcade3..d06a2489b02 100644 --- a/addons/mrp/test/bom_with_service_type_product.yml +++ b/addons/mrp/test/bom_with_service_type_product.yml @@ -62,70 +62,3 @@ !python {model: mrp.production}: | order = self.browse(cr, uid, ref("mrp_production_servicetype_mo1")) assert order.state == 'done', "Production order should be closed." -- - I create Bill of Materials with two service type products. -- - !record {model: mrp.bom, id: mrp_bom_test_2}: - company_id: base.main_company - name: PC Assemble SC234 - product_id: product.product_product_3 - product_qty: 1.0 - type: normal - bom_lines: - - company_id: base.main_company - name: On Site Monitoring - product_id: product.product_product_1 - product_qty: 1.0 - - company_id: base.main_company - name: On Site Assistance - product_id: product.product_product_2 - product_qty: 1.0 -- - I make the production order using BoM having two service type products. -- - !record {model: mrp.production, id: mrp_production_servicetype_2}: - product_id: product.product_product_3 - product_qty: 1.0 - bom_id: mrp_bom_test_2 - date_planned: !eval time.strftime('%Y-%m-%d %H:%M:%S') -- - I compute the data of production order. -- - !python {model: mrp.production}: | - self.action_compute(cr, uid, [ref("mrp_production_servicetype_2")], {"lang": "en_US", "tz": False, "search_default_Current": 1, - "active_model": "ir.ui.menu", "active_ids": [ref("mrp.menu_mrp_production_action")], - "active_id": ref("mrp.menu_mrp_production_action"), }) -- - I confirm the production order. -- - !workflow {model: mrp.production, action: button_confirm, ref: mrp_production_servicetype_2} -- - Now I start production. -- - !workflow {model: mrp.production, action: button_produce, ref: mrp_production_servicetype_2} -- - I check that production order in production state after start production. -- - !python {model: mrp.production}: | - order = self.browse(cr, uid, ref("mrp_production_servicetype_2")) - #assert order.state == 'in_production', 'Production order should be in production State.' -- - I produce product. -- - !python {model: mrp.product.produce}: | - context.update({'active_id': ref('mrp_production_servicetype_2')}) -- - !record {model: mrp.product.produce, id: mrp_product_produce_2}: - mode: 'consume_produce' -- - !python {model: mrp.product.produce}: | - qty = self.browse(cr, uid, ref('mrp_product_produce_2')).product_qty - lines = self.on_change_qty(cr, uid, [ref('mrp_product_produce_2')], qty, [], context=context) - self.write(cr, uid, [ref('mrp_product_produce_2')], lines['value'], context=context) - self.do_produce(cr, uid, [ref('mrp_product_produce_2')], context=context) -- - I check production order after produced. -- - !python {model: mrp.production}: | - order = self.browse(cr, uid, ref("mrp_production_servicetype_2")) - #assert order.state == 'done', "Production order should be closed." diff --git a/addons/mrp/wizard/mrp_product_produce.py b/addons/mrp/wizard/mrp_product_produce.py index fd1ab7e72d4..958425eb369 100644 --- a/addons/mrp/wizard/mrp_product_produce.py +++ b/addons/mrp/wizard/mrp_product_produce.py @@ -51,8 +51,7 @@ class mrp_product_produce(osv.osv_memory): 'consume_lines': fields.one2many('mrp.product.produce.line', 'produce_id', 'Products Consumed'), 'track_production': fields.boolean('Track production'), } - - + def on_change_qty(self, cr, uid, ids, product_qty, consume_lines, context=None): """ When changing the quantity of products to be produced it will @@ -63,12 +62,11 @@ class mrp_product_produce(osv.osv_memory): """ prod_obj = self.pool.get("mrp.production") production = prod_obj.browse(cr, uid, context['active_id'], context=context) - if product_qty > 0.0: - consume_lines = prod_obj._calculate_qty(cr, uid, production, product_qty = product_qty, context=None) - else: - consume_lines = [] - + consume_lines = [] new_consume_lines = [] + if product_qty > 0.0: + consume_lines = prod_obj._calculate_qty(cr, uid, production, product_qty=product_qty, context=context) + for consume in consume_lines: new_consume_lines.append([0, False, consume]) return {'value': {'consume_lines': new_consume_lines}} @@ -115,9 +113,6 @@ class mrp_product_produce(osv.osv_memory): 'track_production': _get_track, } - - - def do_produce(self, cr, uid, ids, context=None): production_id = context.get('active_id', False) assert production_id, "Production Id should be specified in context as a Active ID." diff --git a/addons/mrp/wizard/stock_move.py b/addons/mrp/wizard/stock_move.py index f9cf703110e..f779916ae87 100644 --- a/addons/mrp/wizard/stock_move.py +++ b/addons/mrp/wizard/stock_move.py @@ -35,7 +35,7 @@ class stock_move_consume(osv.osv_memory): 'restrict_lot_id': fields.many2one('stock.production.lot', 'Lot'), } - #TOFIX: product_uom should not have differemt category of default UOM of product. Qty should be convert into UOM of original move line before going in consume and scrap + #TOFIX: product_uom should not have different category of default UOM of product. Qty should be convert into UOM of original move line before going in consume and scrap def default_get(self, cr, uid, fields, context=None): """ Get default values @param self: The object pointer. @@ -76,7 +76,7 @@ class stock_move_consume(osv.osv_memory): move_ids = context['active_ids'] for data in self.browse(cr, uid, ids, context=context): move_obj.action_consume(cr, uid, move_ids, - data.product_qty, data.location_id.id, restrict_lot_id=data.restrict_lot_id and data.restrict_lot_id.id or False, + data.product_qty, data.location_id.id, restrict_lot_id=data.restrict_lot_id.id, context=context) return {'type': 'ir.actions.act_window_close'}