From edf42894039e41e8af69024034574c1653415042 Mon Sep 17 00:00:00 2001 From: Quentin De Paoli Date: Thu, 20 May 2010 11:34:53 +0200 Subject: [PATCH] [FIX] mrp/mrp_procurement: commited work of team1 bzr revid: qdp@cyan-20100520093453-suu4n8d0305gb19j --- addons/mrp/__openerp__.py | 6 +- addons/mrp/mrp_view.xml | 23 +- addons/mrp/mrp_workflow.xml | 34 +- .../mrp/report/mrp_production_order_view.xml | 6 +- addons/mrp/report/order.rml | 95 ++++- addons/mrp/test/mrp_phantom_bom.yml | 16 +- addons/mrp/test/mrp_procurement.yml | 336 ++++++++++++++++++ addons/mrp/test/mrp_production_order.yml | 12 +- .../mrp_procurement/mrp_procurement_view.xml | 21 +- .../mrp_procurement_workflow.xml | 58 +-- addons/project_mrp/project_mrp_workflow.xml | 4 +- 11 files changed, 494 insertions(+), 117 deletions(-) create mode 100644 addons/mrp/test/mrp_procurement.yml diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py index 0fa66ac7bd1..97e23f3488d 100644 --- a/addons/mrp/__openerp__.py +++ b/addons/mrp/__openerp__.py @@ -77,7 +77,11 @@ 'report/mrp_production_order_view.xml', ], 'demo_xml': ['mrp_demo.xml', 'mrp_order_point.xml'], -# 'test': ['test/mrp_phantom_bom.yml','test/mrp_production_order.yml'], + 'test': [ + 'test/mrp_phantom_bom.yml', + 'test/mrp_production_order.yml', + 'test/mrp_procurement.yml' + ], 'installable': True, 'active': False, 'certificate': '0032052481373', diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index dcea7ac4f9e..1c7dce6e30b 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -249,7 +249,7 @@ - + @@ -471,10 +471,10 @@
- - - - + + + + @@ -493,7 +493,7 @@ - + @@ -592,8 +592,8 @@ - - + + @@ -611,7 +611,7 @@ - + @@ -636,8 +636,7 @@ - mrp.production form tree,form,calendar,graph,gantt + {'search_default_current':1} @@ -799,6 +799,7 @@ + action_produce_assign_product() - - - produce_check - - - - produce_service - function - action_produce_assign_service() - - - - - - check_produce() - - - - - not check_product() - - - - - - subflow.cancel - - - - - - - + check_product() diff --git a/addons/mrp/report/mrp_production_order_view.xml b/addons/mrp/report/mrp_production_order_view.xml index a97abe846de..1ae2e6b32bb 100644 --- a/addons/mrp/report/mrp_production_order_view.xml +++ b/addons/mrp/report/mrp_production_order_view.xml @@ -48,8 +48,8 @@ - - + + @@ -101,7 +101,7 @@ tree,graph - {'search_default_Product': 1} + {'search_default_Product': 1,'search_default_this_year':1,'search_default_this_month':1} diff --git a/addons/mrp/report/order.rml b/addons/mrp/report/order.rml index 7bc2e7e7ee5..af55afce91b 100644 --- a/addons/mrp/report/order.rml +++ b/addons/mrp/report/order.rml @@ -135,19 +135,36 @@ + + + + + + + + + + + + + + + + + - - + + - - - - - - - + + + + + + + @@ -172,6 +189,7 @@ +
[[ repeatIn(objects,'o') ]] @@ -313,7 +331,10 @@ +
+ Products to Consume + [[ o.move_lines ==[] and removeParentNode('section')]] Product @@ -329,9 +350,10 @@ +
- [[ repeatIn(o.move_lines,'line') ]] + [[ repeatIn(o.move_lines,'line') ]] [[ line.product_id.code ]] [[ line.product_id.name ]] @@ -350,9 +372,54 @@ - - - +
+ + + +
+ Consumed Products + + + [[ o.move_lines2 ==[] and removeParentNode('section')]] + + + Product + + + Quantity + + + Source Location + + + Destination Location + + + +
+
+ + [[ repeatIn(o.move_lines2,'line2') ]] + + + [[ line2.product_id.code ]] [[ line2.product_id.name ]] + + + [[ formatLang( line2.product_qty) ]] + + + [[line2.product_uom.name]] + + + [[ line2.location_id.name ]] + + + [[ line2.location_dest_id.name ]] + + + +
+
- + \ No newline at end of file diff --git a/addons/mrp/test/mrp_phantom_bom.yml b/addons/mrp/test/mrp_phantom_bom.yml index df4ade1cb6e..5475d54ffd4 100644 --- a/addons/mrp/test/mrp_phantom_bom.yml +++ b/addons/mrp/test/mrp_phantom_bom.yml @@ -2,7 +2,7 @@ In order to test the mrp phantom bom type in OpenERP, I will create products and then I will create Phantom bom structure for those products. - - I create the products required to produce some orange juices: Oranges, Sugar and Water. + I create the products required to produce some orange juices with Oranges, Sugar and Water. - !record {model: product.uom, id: product_uom_litre0}: category_id: product.product_uom_categ_kgm @@ -129,7 +129,6 @@ date_planned: '2010-04-16 15:53:36' location_dest_id: stock.stock_location_output location_src_id: stock.stock_location_stock - name: MO/00002 product_id: product_product_orangejuice0 product_qty: 100.0 product_uom: product_uom_litre0 @@ -171,7 +170,7 @@ - !python {model: mrp.procurement}: | from tools.translate import _ - proc_ids = self.search(cr, uid, [('origin','=',':MO/00002')]) + proc_ids = self.search(cr, uid, [('state','!=','cofirmed')]) assert proc_ids, _('No Procurements!') - The scheduler runs. @@ -196,7 +195,7 @@ !python {model: purchase.order}: | from tools.translate import _ import netsvc - purch_ids = self.search(cr, uid, [('origin','in',['SCHEDULER','OP/00002','OP/00003'])]) + purch_ids = self.search(cr, uid, [('state','=','draft')]) assert purch_ids, _('No Purchase Orders were made!') wf_service = netsvc.LocalService("workflow") for p_id in purch_ids: @@ -207,7 +206,7 @@ !python {model: purchase.order}: | from tools.translate import _ import netsvc - purch_ids = self.search(cr, uid, [('origin','in',['SCHEDULER','OP/00002','OP/00003']),('state','=','confirmed')]) + purch_ids = self.search(cr, uid, [('state','=','confirmed')]) assert purch_ids, _('No Confirmed Purchase Orders found!') wf_service = netsvc.LocalService("workflow") for p_id in purch_ids: @@ -217,7 +216,7 @@ - !python {model: stock.picking}: | from tools.translate import _ - pick_ids = self.search(cr, uid, [('origin','in',['PO00001:SCHEDULER','PO00002:SCHEDULER','PO00003:OP/00002','PO00004:OP/00003']),('type','=','in')]) + pick_ids = self.search(cr, uid, [('type','=','in')]) assert pick_ids, _('No Incoming Shipments found!') - I receive both the products. My incoming pickings are done. @@ -229,6 +228,7 @@ - !python {model: stock.partial.picking}: | pick_obj = self.pool.get('stock.picking') - picking_ids = pick_obj.search(cr, uid, [('origin','in',['PO00001:SCHEDULER','PO00002:SCHEDULER','PO00003:OP/00002','PO00004:OP/00003']),('type','=','in')]) - self.do_partial(cr, uid, [1],context={'active_ids': picking_ids}) + picking_ids = pick_obj.search(cr, uid, [('type','=','in')]) + self.view_init(cr, uid, ['date','partner_id','address_id'],context={'active_ids': picking_ids}) + self.do_partial(cr, uid, [1], context={'active_ids': picking_ids}) \ No newline at end of file diff --git a/addons/mrp/test/mrp_procurement.yml b/addons/mrp/test/mrp_procurement.yml new file mode 100644 index 00000000000..37d0de5c5a9 --- /dev/null +++ b/addons/mrp/test/mrp_procurement.yml @@ -0,0 +1,336 @@ +- + In order to test the flow of procurement orders. I will put some orders with + different procurement methods. I have installed sale, mrp and purchase modules. +- + I am creating products. +- + Creating a product.product record +- + !record {model: product.product, id: product_product_shirt0}: + categ_id: product.cat1 + cost_method: standard + list_price: 350.0 + mes_type: fixed + name: Shirt + procure_method: make_to_stock + property_stock_inventory: stock.location_inventory + property_stock_procurement: stock.location_procurement + property_stock_production: stock.location_production + seller_delay: '1' + standard_price: 300.0 + supply_method: produce + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit + volume: 0.0 + warranty: 0.0 + weight: 0.0 + weight_net: 0.0 +- + Creating a product.product record +- + !record {model: product.product, id: product_product_cloth0}: + categ_id: product.cat1 + cost_method: standard + mes_type: fixed + name: Cloth + procure_method: make_to_order + property_stock_inventory: stock.location_inventory + property_stock_procurement: stock.location_procurement + property_stock_production: stock.location_production + seller_delay: '1' + seller_ids: + - delay: 1 + name: base.res_partner_maxtor + qty: 300.0 + standard_price: 1.0 + supply_method: buy + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit + volume: 0.0 + warranty: 0.0 + weight: 0.0 + weight_net: 0.0 +- + Creating a product.product record +- + !record {model: product.product, id: product_product_buttons0}: + categ_id: product.cat1 + cost_method: standard + mes_type: fixed + name: Buttons + procure_method: make_to_stock + property_stock_inventory: stock.location_inventory + property_stock_procurement: stock.location_procurement + property_stock_production: stock.location_production + seller_delay: '1' + seller_ids: + - delay: 1 + name: base.res_partner_asus + qty: 100.0 + standard_price: 1.0 + supply_method: buy + type: product + uom_id: product.product_uom_kgm + uom_po_id: product.product_uom_kgm + volume: 0.0 + warranty: 0.0 + weight: 0.0 + weight_net: 0.0 +- + I am creating bills of material for 'Shirt'. +- + Creating a mrp.bom record +- + !record {model: mrp.bom, id: mrp_bom_shirt0}: + bom_lines: + - company_id: base.main_company + name: Cloth + product_efficiency: 1.0 + product_id: product_product_cloth0 + product_qty: 1.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 + sequence: 0.0 + type: normal + - company_id: base.main_company + name: Buttons + product_efficiency: 1.0 + product_id: product_product_buttons0 + product_qty: 8.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 + sequence: 0.0 + type: normal + company_id: base.main_company + name: Shirt + product_efficiency: 1.0 + product_id: product_product_shirt0 + product_qty: 1.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 + sequence: 0.0 + type: normal +- + I create minimum stock rule for product Buttons +- + !record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op0}: + company_id: base.main_company + location_id: stock.stock_location_stock + logic: max + name: OP/00007 + product_id: mrp.product_product_buttons0 + product_max_qty: 50.0 + product_min_qty: 10.0 + product_uom: product.product_uom_unit + qty_multiple: 1 + warehouse_id: stock.warehouse0 +- + I create a procurement order for product Shirt. +- + !record {model: mrp.procurement, id: mrp_procurement_shirt0}: + name: 'PROC: Shirt' + product_id: product_product_shirt0 + product_qty: 5.00 + location_id: stock.stock_location_stock + product_uom: product.product_uom_unit +- + I confirm the procurement order. +- + !workflow {model: mrp.procurement, action: button_confirm, ref: mrp_procurement_shirt0} +- + I run the procurement. +- + !workflow {model: mrp.procurement, action: button_check, ref: mrp_procurement_shirt0} +- + I see that there is a manufacturing order for Shirt. +- + !python {model: mrp.production}: | + from tools.translate import _ + order_ids = self.search(cr, uid, [('product_id','=',ref('product_product_shirt0'))]) + assert order_ids, 'No Manufacturing Order.' +- + I also check that there are two more procurement orders for sub products Cloth and Buttons. +- + !python {model: mrp.procurement}: | + from tools.translate import _ + proc_ids = self.search(cr, uid, [('product_id','in',[ref('product_product_cloth0'),ref('product_product_buttons0')])]) + assert proc_ids, 'No Procurements.' +- + The scheduler runs. +- + !function {model: mrp.procurement, name: run_scheduler}: + - model: mrp.procurement + search: "[]" +- + I check that there is one purchase order for Cloth. +- + !python {model: purchase.order}: | + purch_ids = self.search(cr, uid, [('partner_id.name','=','Maxtor')]) + assert purch_ids, 'No Purchase Orders.' +- + I confirm purchase order for Cloth. +- + !python {model: purchase.order}: | + import netsvc + purch_ids = self.search(cr, uid, [('partner_id.name','=','Maxtor')]) + wf_service = netsvc.LocalService("workflow") + for p_id in purch_ids: + wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr) +- + I get the approval from the supplier. So I approve my purchase orders. +- + !python {model: purchase.order}: | + from tools.translate import _ + import netsvc + purch_ids = self.search(cr, uid, [('state','=','confirmed')]) + assert purch_ids, _('No Confirmed Purchase Orders found!') + wf_service = netsvc.LocalService("workflow") + for p_id in purch_ids: + wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_approve', cr) +- + I confirm purchase order for Buttons. +- + !python {model: purchase.order}: | + import netsvc + purch_ids = self.search(cr, uid, [('partner_id.name','=','ASUStek')]) + wf_service = netsvc.LocalService("workflow") + for p_id in purch_ids: + wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr) +- + I get the approval from the supplier. So I approve my purchase orders. +- + !python {model: purchase.order}: | + from tools.translate import _ + import netsvc + purch_ids = self.search(cr, uid, [('state','=','confirmed')]) + assert purch_ids, _('No Confirmed Purchase Orders found!') + wf_service = netsvc.LocalService("workflow") + for p_id in purch_ids: + wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_approve', cr) +- + I Check incoming shipments for cloth. And receive products. +- + !python {model: stock.picking}: | + from tools.translate import _ + pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')]) + assert pick_ids, _('No Incoming Shipments found!') +- + !record {model: stock.partial.picking, id: stock_partial_picking0}: + date: '2010-04-30 16:53:36' + partner_id: base.res_partner_maxtor + address_id: base.res_partner_address_wong +- + !python {model: stock.partial.picking}: | + pick_obj = self.pool.get('stock.picking') + picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')]) + partial = self.browse(cr, uid, 1, context) + partial_datas = { + 'partner_id' : partial.partner_id and partial.partner_id.id or False, + 'address_id' : partial.address_id and partial.address_id.id or False, + 'delivery_date' : partial.date + } + for pick in pick_obj.browse(cr, uid, picking_ids): + for m in pick.move_lines: + partial_datas['move%s'%(m.id)] = { + 'product_id' : m.product_id.id, + 'product_qty' : m.product_qty, + 'product_uom' : m.product_uom.id + } + if (pick.type == 'in') and (m.product_id.cost_method == 'average'): + partial_datas['move%s'%(m.id)].update({ + 'product_price' : m.product_price, + 'product_currency': m.product_currency + }) + pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context) +- + I Check incoming shipments for buttons. And receive products. +- + !python {model: stock.picking}: | + from tools.translate import _ + pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')]) + assert pick_ids, _('No Incoming Shipments found!') +- + !record {model: stock.partial.picking, id: stock_partial_picking0}: + date: '2010-04-30 16:53:36' + partner_id: base.res_partner_maxtor + address_id: base.res_partner_address_wong +- + !python {model: stock.partial.picking}: | + pick_obj = self.pool.get('stock.picking') + picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')]) + partial = self.browse(cr, uid, 1, context) + partial_datas = { + 'partner_id': partial.partner_id and partial.partner_id.id or False, + 'address_id': partial.address_id and partial.address_id.id or False, + 'delivery_date': partial.date + } + for pick in pick_obj.browse(cr, uid, picking_ids): + for m in pick.move_lines: + partial_datas['move%s'%(m.id)] = { + 'product_id': m.product_id.id, + 'product_qty': m.product_qty, + 'product_uom': m.product_uom.id + } + if (pick.type == 'in') and (m.product_id.cost_method == 'average'): + partial_datas['move%s'%(m.id)].update({ + 'product_price': m.product_price, + 'product_currency': m.product_currency + }) + pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context) +- + Run scheduler again. +- + !function {model: mrp.procurement, name: run_scheduler}: + - model: mrp.procurement + search: "[]" +- + Check state of manufacturing order for Shirt. +- + !python {model: mrp.production}: | + from tools.translate import _ + order_ids = self.search(cr, uid, [('product_id','=',ref('product_product_shirt0')),('state','=','ready')]) + assert order_ids, 'No Manufacturing Order in Ready state.' +- + I start production order for Shirt. +- + !python {model: mrp.production}: | + from tools.translate import _ + import netsvc + prod_ids = self.search(cr, uid, [('state','=','ready')]) + assert prod_ids, _('No Ready Manufacturing Orders found!') + wf_service = netsvc.LocalService("workflow") + for p_id in prod_ids: + wf_service.trg_validate(uid, 'mrp.production', p_id, 'button_produce', cr) +- + !record {model: mrp.product.produce, id: mrp_product_produce0}: + product_qty: 5.00 + mode: 'consume_produce' +- + !python {model: mrp.product.produce}: | + from tools.translate import _ + prod_obj = self.pool.get('mrp.production') + prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')]) + self.do_produce(cr, uid, [1], context={'active_ids': prod_ids}) +- + !record {model: stock.move.consume, id: stock_move_consume0}: + product_id: product_product_buttons0 + product_qty: 35.00 + product_uom: product.product_uom_unit + location_id: stock.stock_location_stock +- + !python {model: stock.move.consume}: | + from tools.translate import _ + stock_obj = self.pool.get('stock.move') + stock_ids = stock_obj.search(cr, uid, [('product_id.name','=','Buttons')]) + self.do_move_consume(cr, uid, [1], context={'active_ids': stock_ids}) +- + And finally production order is done. +- + !python {model: mrp.product.produce}: | + from tools.translate import _ + prod_obj = self.pool.get('mrp.production') + prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')]) + self.do_produce(cr, uid, [1], context={'active_ids': prod_ids}) + \ No newline at end of file diff --git a/addons/mrp/test/mrp_production_order.yml b/addons/mrp/test/mrp_production_order.yml index 023a9f22f31..5de26180723 100644 --- a/addons/mrp/test/mrp_production_order.yml +++ b/addons/mrp/test/mrp_production_order.yml @@ -86,27 +86,27 @@ - !python {model: mrp.procurement}: | from tools.translate import _ - proc_ids = self.search(cr, uid, [('origin','=',':MO/00004')]) + proc_ids = self.search(cr, uid, [('state','!=','confirmed')]) assert proc_ids, _('No Procurements!') - The scheduler runs. - !function {model: mrp.procurement, name: run_scheduler}: - model: mrp.procurement - search: "[('origin','=',':MO/00004')]" + search: "[('state','=','confirmed')]" - I am checking Internal picking. - !python {model: stock.picking}: | from tools.translate import _ - pick_ids = self.search(cr, uid, [('origin','=',':MO/00004'),('type','=','internal')]) + pick_ids = self.search(cr, uid, [('state','!=','done'),('type','=','internal')]) assert pick_ids, _('No Internal Pickings!') - I see that there is a manufacturing order for the subproduct of PC1 with ready state. - !python {model: mrp.production}: | from tools.translate import _ - order_ids = self.search(cr, uid, [('origin','=',':MO/00004'),('state','=','ready')]) + order_ids = self.search(cr, uid, [('state','=','confirmed')]) assert order_ids, _('No manufacturing order!') - I start producing that product first. So I marked it as started. @@ -117,7 +117,7 @@ - !python {model: mrp.product.produce}: | prod_obj = self.pool.get('mrp.production') - prod_ids = prod_obj.search(cr, uid, [('origin','=',':MO/00004')]) + prod_ids = prod_obj.search(cr, uid, [('state','=','confirmed')]) self.do_produce(cr, uid, [1], context={'active_ids': prod_ids}) - Now the manufacturing order for subproduct CPU_GEN is done. And manufacturing @@ -125,7 +125,7 @@ - !python {model: mrp.production}: | from tools.translate import _ - prod_ids = self.search(cr, uid, [('origin','=',':MO/00004'),('state','=','done')]) + prod_ids = self.search(cr, uid, [('state','!=','done')]) assert prod_ids, _('Manufacturing order is yet not done!') - I start producing the product PC1. diff --git a/addons/mrp_procurement/mrp_procurement_view.xml b/addons/mrp_procurement/mrp_procurement_view.xml index 84b47ee516d..94ee009d7df 100644 --- a/addons/mrp_procurement/mrp_procurement_view.xml +++ b/addons/mrp_procurement/mrp_procurement_view.xml @@ -29,20 +29,20 @@ - + - + - + - + @@ -85,7 +85,7 @@ - + mrp.procurement form + {'search_default_current':1} @@ -179,11 +180,11 @@ - - - - - + + + + + diff --git a/addons/mrp_procurement/mrp_procurement_workflow.xml b/addons/mrp_procurement/mrp_procurement_workflow.xml index 46c4a10fffc..5ab36dd4cb8 100644 --- a/addons/mrp_procurement/mrp_procurement_workflow.xml +++ b/addons/mrp_procurement/mrp_procurement_workflow.xml @@ -48,16 +48,16 @@ function action_move_assigned() - - - - - - - - - - + + + produce_check + + + + produce_service + function + action_produce_assign_service() + ready @@ -155,16 +155,16 @@ check_make_to_stock() - - - - - - - - - - + + + + check_produce() + + + + + not check_product() + @@ -172,15 +172,15 @@ - - - - - - - - - + + + + subflow.cancel + + + + + diff --git a/addons/project_mrp/project_mrp_workflow.xml b/addons/project_mrp/project_mrp_workflow.xml index a4f038f4ad2..43217d69f83 100644 --- a/addons/project_mrp/project_mrp_workflow.xml +++ b/addons/project_mrp/project_mrp_workflow.xml @@ -1,8 +1,8 @@ - - + + subflow.done