diff --git a/addons/auction/__openerp__.py b/addons/auction/__openerp__.py index cd27c60fdb7..0959d6a4dd9 100644 --- a/addons/auction/__openerp__.py +++ b/addons/auction/__openerp__.py @@ -60,6 +60,7 @@ 'auction_wizard.xml' ], 'demo_xml': ['auction_demo.xml'], +# 'test' : ['test/auction.yml','test/auction_wizard.yml'], 'installable': True, 'active': False, 'certificate': '0039333102717', diff --git a/addons/auction/test/auction.yml b/addons/auction/test/auction.yml new file mode 100644 index 00000000000..968bb5f6bbf --- /dev/null +++ b/addons/auction/test/auction.yml @@ -0,0 +1,204 @@ +- + In order to test the auction module in the Open-ERP I start the process by creating a product. +- + I create a new product furniture. +- + !record {model: product.product, id: product_product_furniture0}: + categ_id: product.cat1 + cost_method: standard + mes_type: fixed + name: Furniture + procure_method: make_to_stock + 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 +- + I create a new artist for an object. +- + !record {model: auction.artists, id: auction_artists_vincentvangogh0}: + birth_death_dates: 1853-1900 + name: Vincent van Gogh +- + Now I want to associate an object with the auction so for that I create an auction "Antique furniture exhibition" +- + !record {model: auction.dates, id: auction_dates_antiquefurnitureexhibition0}: + acc_expense: account.a_pay + acc_income: account.a_recv + account_analytic_id: account.analytic_root + auction1: '2010-05-20' + auction2: '2010-05-21' + expo1: '2010-05-18' + expo2: '2010-05-19' + journal_id: account.expenses_journal + journal_seller_id: account.sales_journal + name: Antique furniture exhibition +- + An object is being deposited for an auction,I create a seller's deposit record. +- + !record {model: auction.deposit, id: auction_deposit_ad0}: + date_dep: '2010-05-18' + method: keep + name: AD/006 + partner_id: base.res_partner_4 +- + I create a new object wooden-chair which is to be auctioned. +- + !record {model: auction.lots, id: auction_lots_woodenchair0}: + ach_uid: base.res_partner_2 + artist_id: auction_artists_vincentvangogh0 + auction_id: auction_dates_antiquefurnitureexhibition0 + bord_vnd_id: auction_deposit_ad0 + lot_est1: 3000.0 + lot_est2: 5000.0 + lot_num: 1 + name: wooden-chair + name2: antique wooden chair + obj_num: 1 + obj_price: 4000.0 + obj_ret: 5000.0 + product_id: 'product_product_furniture0' + state: draft + vnd_lim: 5000.0 +- + I create a bid for an object "wooden-chair" which is to be auctioned in Antique furniture exhibition. +- + !record {model: auction.bid, id: auction_bid_bid0}: + auction_id: auction_dates_antiquefurnitureexhibition0 + contact_tel: (+32)2 211 34 83 + name: bid/001 + partner_id: auction.partner_record1 +- + I create a bid line. +- + !record {model: auction.bid_line, id: auction_bid_line_0}: + auction: Antique furniture exhibition + bid_id: auction_bid_bid0 + lot_id: auction.auction_lots_woodenchair0 + price: 3500.0 +- + I create another bid for an object "wooden-chair" bided by a different partner +- + !record {model: auction.bid, id: auction_bid_bid1}: + auction_id: auction_dates_antiquefurnitureexhibition0 + name: bid/002 + partner_id: base.res_partner_2 +- + I create a bid line. +- + !record {model: auction.bid_line, id: auction_bid_line_1}: + auction: Antique furniture exhibition + bid_id: 'auction_bid_bid1' + call: 1 + lot_id: auction.auction_lots_woodenchair0 + price: 4000.0 +- + I check that buyer price and seller price gets bind with the value +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + assert(auc_id.buyer_price,auc_id.seller_price), _('Buyer price and seller price are not available!') +- + I check that a record gets created in the Seller's Summary. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + auc_deposit_obj=self.pool.get('auction.deposit') + rep_sell_obj = self.pool.get('report.seller.auction') + ids =rep_sell_obj.search(cr, uid, [('auction', '=', auc_id.auction_id.id),('seller', '=',auc_id.bord_vnd_id.partner_id.id)]) + assert ids, _('No record found!') +- + I check that a record gets created in the Seller's Revenues. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + auc_deposit_obj=self.pool.get('auction.deposit') + rep_sell_obj = self.pool.get('report.seller.auction2') + ids =rep_sell_obj.search(cr, uid, [('auction', '=', auc_id.auction_id.id),('seller', '=',auc_id.bord_vnd_id.partner_id.id)]) + assert ids, _('No record found!') +- + I check that a record gets created in the Buyer's Summary. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id1=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + rep_buy_obj1 = self.pool.get('report.buyer.auction') + ids1=rep_buy_obj1.search(cr, uid, [('auction', '=', auc_id1.auction_id.id),('buyer', '=',auc_id1.ach_uid.id)]) + assert ids1, _('No record found!') +- + I check that a record gets created in the Buyer's Revenue. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id1=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + rep_buy_obj1 = self.pool.get('report.buyer.auction2') + ids1=rep_buy_obj1.search(cr, uid, [('auction', '=', auc_id1.auction_id.id),('buyer', '=',auc_id1.ach_uid.id)]) + assert ids1, _('No record found!') +- + I check that a record gets created in the Auction's Summary. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id2=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + rep_auc_obj1 = self.pool.get('report.auction.view') + ids2=rep_auc_obj1.search(cr, uid, [('auction_id', '=', auc_id2.auction_id.id)]) + assert ids2, _('No record found!') +- + I check that a record gets created in the Auction's Revenues. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id3=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + rep_auc_obj1 = self.pool.get('report.auction.view2') + ids3=rep_auc_obj1.search(cr, uid, [('auction', '=', auc_id3.auction_id.id)]) + assert ids3, _('No record found!') +- + An object has been sold,so I click on the "Sold" button. +- + !python {model: auction.lots}: | + self.button_bought(cr, uid, [ref("auction_lots_woodenchair0")], {"lang": "en_US", "tz": + False, "active_model": "ir.ui.menu", "active_ids": [ref("auction.auction_lots_woodenchair0")], + "active_id": ref("auction.auction_lots_woodenchair0")}) +- + I check that the order which was initially in the draft state has transit to sold state. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + assert(auc_id.state == 'sold'), _('State not changed!') +- + Then I click on the Taken Away button. +- + !python {model: auction.lots}: | + self.button_taken_away(cr, uid, [ref("auction_lots_woodenchair0")], {"lang": + "en_US", "tz": False, "active_model": "ir.ui.menu", "active_ids": [ref("auction.auction_all_objects_menu")], + "active_id": ref("auction.auction_all_objects_menu")}) +- + I check that the order which was initially in the sold state has transit to taken away state. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + assert(auc_id.state == 'taken_away'), _('State not changed!') +- + I click on the "Close + Create all invoices" button +- + !python {model: auction.dates}: | + self.close(cr, uid, [ref("auction.auction_dates_antiquefurnitureexhibition0")], + {"lang": "en_US", "tz": False, "active_model": "ir.ui.menu", "active_ids": + [ref("auction.menu_auction_dates_next1")], "active_id": ref("auction.menu_auction_dates_next1")}) +- + I check that a record gets created in the "Supplier Invoices". +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_woodenchair0")) + assert(auc_id.sel_inv_id), _('Seller Invoice has not been created!') diff --git a/addons/auction/test/auction_wizard.yml b/addons/auction/test/auction_wizard.yml new file mode 100644 index 00000000000..0998e7a03a5 --- /dev/null +++ b/addons/auction/test/auction_wizard.yml @@ -0,0 +1,248 @@ +- + In order to test the wizards of auction module I create a new record. +- + I start the process by creating a new product Paintings. +- + !record {model: product.product, id: product_product_paintings0}: + categ_id: product.cat1 + cost_method: standard + mes_type: fixed + name: Paintings + procure_method: make_to_stock + 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 +- + I create a new artist-Picasso's record. +- + !record {model: auction.artists, id: auction_artists_picasso0}: + birth_death_dates: 1881-1973 + name: Picasso +- + Now I want to associate an object with the auction so for that I create an auction "Picasso's painting exhibition" +- + !record {model: auction.dates, id: auction_dates_picassospaintingexhibition0}: + acc_expense: account.a_pay + acc_income: account.a_recv + account_analytic_id: account.analytic_root + auction1: '2010-05-24' + auction2: '2010-05-25' + expo1: '2010-05-21' + expo2: '2010-05-22' + journal_id: account.expenses_journal + journal_seller_id: account.sales_journal + name: Picasso's painting exhibition +- + An object is being deposited for an auction,I create a seller's deposit record. +- + !record {model: auction.deposit, id: auction_deposit_ad1}: + date_dep: '2010-05-18' + method: keep + name: AD/007 + partner_id: base.res_partner_9 +- + I create a new object painting which is to be auctioned. +- + !record {model: auction.lots, id: auction_lots_painting0}: + ach_login: 'Mr.Chang' + artist_id: auction.auction_artists_picasso0 + auction_id: auction_dates_picassospaintingexhibition0 + bord_vnd_id: auction_deposit_ad1 + lot_est1: 2000.0 + lot_est2: 4000.0 + lot_num: 2 + name: painting + name2: picasso_painting + obj_num: 2 + obj_price: 3500.0 + obj_ret: 4000.0 + product_id: auction.product_product_paintings0 + state: draft + vnd_lim: 4000.0 +- + I assign the buyer through "Map buyer user name to Partners" wizard. +- + !record {model: auction.lots.buyer_map, id: auction_lots_buyer_map_0}: + ach_login: 'Mr.Chang' + ach_uid: base.res_partner_3 +- + I click on the "Update" button. +- + !python {model: auction.lots.buyer_map}: | + auc_obj=self.pool.get('auction.lots') + ids=self.browse(cr, uid, ref("auction_lots_painting0")) + self.buyer_map_set(cr, uid, [ref("auction_lots_buyer_map_0")], {"lang": "en_US", + "tz": False, "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], + "active_id": ref("auction_lots_painting0")}) +- + I check that the buyer field gets bind with the value. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_painting0")) + assert(auc_id.ach_uid), _('Buyer not assigned!') +- + I mark that a seller has been paid by using the "Mark as paid for seller" wizard. +- + !record {model: auction.payer.sel, id: auction_payer_sel_0}: + {} +- + I click on the "Pay" button. +- + !python {model: auction.payer.sel}: | + self.payer_sel(cr, uid, [ref("auction_payer_sel_0")], {"lang": "en_US", "tz": + False, "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], "active_id": ref("auction_lots_painting0")}) +- + I check that the Seller paid field is set to True. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_painting0")) + assert(auc_id.paid_vnd == True), _('Seller paid is not marked!') +- + I use the "Mark as taken away" wizard to indicate that an object is taken away. +- + !record {model: auction.lots.able, id: auction_lots_able_0}: + {} +- + Then I click on the "Able Taken away" wizard. +- + !python {model: auction.lots.able}: | + self.confirm_able(cr, uid, [ref("auction_lots_able_0")], {"lang":"en_US", "tz": + False, "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], + "active_id": ref("auction_lots_painting0")}) +- + I check that Taken away field is set to True. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_painting0")) + assert(auc_id.ach_emp == True), _('Taken away is not marked!') +- + I use the "Unmark as taken away" wizard to unmark the Taken Away field. +- + !record {model: auction.lots.enable, id: auction_lots_enable_0}: + confirm_en: 0.0 +- + Then I click on the "Enable Taken away" button. +- + !python {model: auction.lots.enable}: | + self.confirm_enable(cr, uid, [ref("auction_lots_enable_0")], {"lang": "en_US", + "tz": False, "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], + "active_id": ref("auction_lots_painting0"),}) +- + I check that Taken away field is set to False. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_painting0")) + assert(auc_id.ach_emp == False), _('Taken away is marked!') +- + I create statement lines for an object's payment by using the "Pay objects of the buyer" wizard +- + I create a bank statement. +- + !record {model: account.bank.statement, id: account_bank_statement_st0}: + balance_end_real: 0.0 + date: '2010-05-19' + journal_id: account.bank_journal + name: St. 05/19 + period_id: account.period_5 + state: draft +- + I create auction payment record. +- + !record {model: auction.pay.buy, id: auction_pay_buy_0}: + amount: 2000.0 + amount2: 1000.0 + amount3: 1000.0 + buyer_id: base.res_partner_2 + statement_id1: account_bank_statement_st0 + statement_id2: account_bank_statement_st0 + statement_id3: account_bank_statement_st0 + total: 4000.0 +- + Then I click "Pay" button. +- + !python {model: auction.pay.buy}: | + self.pay_and_reconcile(cr, uid, [ref("auction_pay_buy_0")], {"lang": "en_US", "tz": + False, "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], + "active_id": ref("auction_lots_painting0"),}) +- + I check that a record gets created in the 'auction_statement_line_rel' table +- + !python {model: auction.lots}: | + from tools.translate import _ + cr.execute("select statement from auction_statement_line_rel,auction_lots where auction_lots.id=auction_statement_line_rel.auction_id AND auction_lots.name='painting'") + ans=cr.fetchall() + assert ans, _('statement_id not found!') +- + I create the seller's invoice by using the "Invoice Seller objects" wizard. +- + !record {model: auction.lots.make.invoice, id: auction_lots_make_invoice_0}: + amount: 3500.0 + number: 2010/002 + objects: 1 +- + Then I click on the "Create Invoices" button. +- + !python {model: auction.lots.make.invoice}: | + self.makeInvoices(cr, uid, [ref("auction_lots_make_invoice_0")], {"lang": "en_US", + "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], + "tz": False, "active_id": ref("auction_lots_painting0"),}) +- + I check that a "Seller Invoice" field gets bind with the value. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_painting0")) + assert(auc_id.sel_inv_id), _('Seller Invoice has not been created!') +- + I create a buyer's invoice by using the "Invoice Buyer objects" wizard. +- + !record {model: auction.lots.make.invoice.buyer, id: auction_lots_make_invoice_buyer_0}: + amount: 3500.0 + buyer_id: base.res_partner_3 + number: 2010/003 + objects: 1 +- + Then I click on the "Create Invoices" button. +- + !python {model: auction.lots.make.invoice.buyer}: | + self.makeInvoices(cr, uid, [ref("auction_lots_make_invoice_buyer_0")], {"lang": + "en_US", "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], + "tz": False, "active_id": ref("auction_lots_painting0"), }) +- + I check that a "Buyer Invoice" field gets bind with the value. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_painting0")) + assert(auc_id.ach_inv_id), _('Seller Invoice has not been created!') +- + In order to change the auction for an object I use the "Change auction date" wizard. +- + !record {model: auction.lots.auction.move, id: auction_lots_auction_move_0}: + auction_id: auction.auction_date_2 +- + Then I click on the "Move to Auction date" button. +- + !python {model: auction.lots.auction.move}: | + self.auction_move_set(cr, uid, [ref("auction_lots_auction_move_0")], {"lang": + "en_US", "tz": False, "active_model": "auction.lots", "active_ids": [ref("auction_lots_painting0")], + "active_id": ref("auction_lots_painting0"), }) +- + I check that a record gets created in the lot history. +- + !python {model: auction.lots}: | + from tools.translate import _ + auc_id=self.browse(cr, uid, ref("auction_lots_painting0")) + auc_lot_his=self.pool.get('auction.lot.history') + ids=auc_lot_his.search(cr, uid, [('lot_id', '=', auc_id.id)]) + assert ids, _('Auction history does not exists!') diff --git a/addons/board_manufacturing/board_manufacturing_view.xml b/addons/board_manufacturing/board_manufacturing_view.xml index 191f1818612..37624d6e025 100644 --- a/addons/board_manufacturing/board_manufacturing_view.xml +++ b/addons/board_manufacturing/board_manufacturing_view.xml @@ -14,8 +14,8 @@ - - + + diff --git a/addons/board_warehouse/board_warehouse_view.xml b/addons/board_warehouse/board_warehouse_view.xml index af797401935..08ece3f821d 100644 --- a/addons/board_warehouse/board_warehouse_view.xml +++ b/addons/board_warehouse/board_warehouse_view.xml @@ -23,7 +23,7 @@
- + diff --git a/addons/mrp/__init__.py b/addons/mrp/__init__.py index d23cee8d565..30367ec35f8 100644 --- a/addons/mrp/__init__.py +++ b/addons/mrp/__init__.py @@ -26,6 +26,6 @@ import installer import wizard import report import company -import mrp_procurement +import procurement # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py index 97e23f3488d..58320ebfdf7 100644 --- a/addons/mrp/__openerp__.py +++ b/addons/mrp/__openerp__.py @@ -26,7 +26,7 @@ "author" : "Tiny", "website" : "http://www.openerp.com", "category" : "Generic Modules/Production", - "depends" : ["mrp_procurement", "stock", "resource", "purchase", "product","process"], + "depends" : ["procurement", "stock", "resource", "purchase", "product","process"], "description": """ This is the base module to manage the manufacturing process in Open ERP. @@ -76,7 +76,7 @@ 'report/mrp_report_view.xml', 'report/mrp_production_order_view.xml', ], - 'demo_xml': ['mrp_demo.xml', 'mrp_order_point.xml'], + 'demo_xml': ['mrp_demo.xml'], 'test': [ 'test/mrp_phantom_bom.yml', 'test/mrp_production_order.yml', diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 685d289a194..b4c575bf2b0 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -247,7 +247,7 @@ class mrp_bom(osv.osv): v['name'] = prod.name return {'value': v} return {} - + def _bom_find(self, cr, uid, product_id, product_uom, properties=[]): """ Finds BoM for particular product and product uom. @param product_id: Selected product. @@ -460,18 +460,6 @@ class mrp_production(osv.osv): result[prod.id] = prod.date_planned[:10] return result - def _ref_calc(self, cr, uid, ids, field_names=None, arg=False, context={}): - """ Finds reference sale order for production order. - @param field_names: Names of fields. - @param arg: User defined arguments - @return: Dictionary of values. - """ - res = {} - for f in field_names: - for order_id in ids: - res[order_id] = {f:False} - return res - _columns = { 'name': fields.char('Reference', size=64, required=True), 'origin': fields.char('Source Document', size=64, help="Reference of the document that generated this production order request."), @@ -512,8 +500,6 @@ class mrp_production(osv.osv): 'hour_total': fields.function(_production_calc, method=True, type='float', string='Total Hours', multi='workorder'), 'cycle_total': fields.function(_production_calc, method=True, type='float', string='Total Cycles', multi='workorder'), - 'sale_name': fields.function(_ref_calc, method=True, multi='sale_name', type='char', string='Sale Name', help='Indicate the name of sale order.'), - 'sale_ref': fields.function(_ref_calc, method=True, multi='sale_ref', type='char', string='Sale Reference', help='Indicate the Customer Reference from sale order.'), 'company_id': fields.many2one('res.company','Company',required=True), } _defaults = { @@ -823,7 +809,7 @@ class mrp_production(osv.osv): seq_obj = self.pool.get('ir.sequence') pick_obj = self.pool.get('stock.picking') move_obj = self.pool.get('stock.move') - proc_obj = self.pool.get('mrp.procurement') + proc_obj = self.pool.get('procurement.order') wf_service = netsvc.LocalService("workflow") for production in self.browse(cr, uid, ids): if not production.product_lines: @@ -917,7 +903,7 @@ class mrp_production(osv.osv): 'move_id': move_id, 'company_id': production.company_id.id, }) - wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr) + wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr) proc_ids.append(proc_id) wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr) self.write(cr, uid, [production.id], {'picking_id': picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'}) diff --git a/addons/mrp/mrp_data.xml b/addons/mrp/mrp_data.xml index a7db7109e55..64dd9f2c9e5 100644 --- a/addons/mrp/mrp_data.xml +++ b/addons/mrp/mrp_data.xml @@ -16,20 +16,5 @@ 1 - - - Stock orderpoint - mrp.warehouse.orderpoint - - - - Stock orderpoint - mrp.warehouse.orderpoint - OP/ - 5 - 1 - 1 - - diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index 0e044d3a347..293c8d58aa9 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -255,12 +255,12 @@ - + - + @@ -406,18 +406,18 @@ Procurement --> - - + - + - + - mrp.procurement.form.inherit - mrp.procurement - + procurement.order.form.inherit + procurement.order + form diff --git a/addons/mrp/mrp_workflow.xml b/addons/mrp/mrp_workflow.xml index a9c83b23b7e..0a55ccdd610 100644 --- a/addons/mrp/mrp_workflow.xml +++ b/addons/mrp/mrp_workflow.xml @@ -117,7 +117,7 @@ - + produce subflow @@ -125,20 +125,20 @@ - + check_product() - + subflow.cancel - + subflow.done diff --git a/addons/mrp/process/procurement_process.xml b/addons/mrp/process/procurement_process.xml index 08d66570b1f..16369eef298 100644 --- a/addons/mrp/process/procurement_process.xml +++ b/addons/mrp/process/procurement_process.xml @@ -4,11 +4,11 @@ - + - + @@ -19,94 +19,94 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/addons/mrp/process/service_product_process.xml b/addons/mrp/process/service_product_process.xml index 60bf3b562b9..a96a7a7bd4d 100644 --- a/addons/mrp/process/service_product_process.xml +++ b/addons/mrp/process/service_product_process.xml @@ -8,7 +8,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/addons/mrp/process/stockable_product_process.xml b/addons/mrp/process/stockable_product_process.xml index c053103f476..bb5c36a015a 100644 --- a/addons/mrp/process/stockable_product_process.xml +++ b/addons/mrp/process/stockable_product_process.xml @@ -8,7 +8,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/addons/mrp/mrp_procurement.py b/addons/mrp/procurement.py similarity index 90% rename from addons/mrp/mrp_procurement.py rename to addons/mrp/procurement.py index 84392b329ea..d704afa46d6 100644 --- a/addons/mrp/mrp_procurement.py +++ b/addons/mrp/procurement.py @@ -27,17 +27,20 @@ import ir import netsvc import time -class mrp_procurement(osv.osv): - _inherit = 'mrp.procurement' +class procurement_order(osv.osv): + _inherit = 'procurement.order' _columns = { 'bom_id': fields.many2one('mrp.bom', 'BoM', ondelete='cascade', select=True), } def check_produce_product(self, cr, uid, procurement, context=[]): + """ Finds the bill of material for the product from procurement order. + @return: True or False + """ properties = [x.id for x in procurement.property_ids] bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, procurement.product_id.id, procurement.product_uom.id, properties) if not bom_id: - cr.execute('update mrp_procurement set message=%s where id=%s', (_('No BoM defined for this product !'), procurement.id)) + cr.execute('update procurement_order set message=%s where id=%s', (_('No BoM defined for this product !'), procurement.id)) return False return True @@ -45,7 +48,7 @@ class mrp_procurement(osv.osv): """ This is action which call from workflow to assign production order to procurements @return: True """ - procurement_obj = self.pool.get('mrp.procurement') + procurement_obj = self.pool.get('procurement.order') res = procurement_obj.make_mo(cr, uid, ids, context=context) res = res.values() return len(res) and res[0] or 0 #TO CHECK: why workflow is generated error if return not integer value @@ -59,7 +62,7 @@ class mrp_procurement(osv.osv): production_obj = self.pool.get('mrp.production') move_obj = self.pool.get('stock.move') wf_service = netsvc.LocalService("workflow") - procurement_obj = self.pool.get('mrp.procurement') + procurement_obj = self.pool.get('procurement.order') for procurement in procurement_obj.browse(cr, uid, ids): res_id = procurement.move_id.id loc_id = procurement.location_id.id @@ -88,6 +91,6 @@ class mrp_procurement(osv.osv): {'location_id': procurement.location_id.id}) return res -mrp_procurement() +procurement_order() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/product.py b/addons/mrp/product.py index 6a73063e591..ea717bd546c 100644 --- a/addons/mrp/product.py +++ b/addons/mrp/product.py @@ -26,30 +26,6 @@ from tools.translate import _ class product_product(osv.osv): _inherit = "product.product" - def get_product_accounts(self, cr, uid, product_id, context={}): - """ To get the stock input account, stock output account and stock journal related to product. - @param product_id: product id - @return: dictionary which contains information regarding stock input account, stock output account and stock journal - """ - product_obj = self.pool.get('product.product').browse(cr, uid, product_id, False) - - stock_input_acc = product_obj.property_stock_account_input and product_obj.property_stock_account_input.id or False - if not stock_input_acc: - stock_input_acc = product_obj.categ_id.property_stock_account_input_categ and product_obj.categ_id.property_stock_account_input_categ.id or False - - stock_output_acc = product_obj.property_stock_account_output and product_obj.property_stock_account_output.id or False - if not stock_output_acc: - stock_output_acc = product_obj.categ_id.property_stock_account_output_categ and product_obj.categ_id.property_stock_account_output_categ.id or False - - journal_id = product_obj.categ_id.property_stock_journal and product_obj.categ_id.property_stock_journal.id or False - - res = {} - res.update({'stock_account_input': stock_input_acc}) - res.update({'stock_account_output': stock_output_acc}) - res.update({'stock_journal': journal_id}) - - return res - def do_change_standard_price(self, cr, uid, ids, datas, context={}): """ Changes the Standard Price of Product and parent products and creates an account move accordingly. @param datas: dict. contain default datas like new_price, stock_output_account, stock_input_account, stock_journal diff --git a/addons/mrp/report/order.rml b/addons/mrp/report/order.rml index af55afce91b..200ca5bb76e 100644 --- a/addons/mrp/report/order.rml +++ b/addons/mrp/report/order.rml @@ -265,10 +265,10 @@ [[ formatLang(o.date_planned, date_time = True) ]] - [[ o.sale_ref or ' ' ]] + [[ o.sale_ref or removeParentNode('para')]] - [[ o.sale_name or '' ]] + [[ o.sale_name or removeParentNode('para') ]] diff --git a/addons/mrp/security/ir.model.access.csv b/addons/mrp/security/ir.model.access.csv index d5e00b9cbda..8f58f7179ad 100644 --- a/addons/mrp/security/ir.model.access.csv +++ b/addons/mrp/security/ir.model.access.csv @@ -7,7 +7,7 @@ "access_mrp_production","mrp.production","model_mrp_production","mrp.group_mrp_user",1,1,1,1 "access_mrp_production_workcenter_line","mrp.production.workcenter.line","model_mrp_production_workcenter_line","mrp.group_mrp_user",1,1,1,1 "access_mrp_production_product_line","mrp.production.product.line","model_mrp_production_product_line","mrp.group_mrp_user",1,1,1,1 -"access_mrp_procurement","mrp.procurement","model_mrp_procurement","mrp.group_mrp_user",1,1,1,1 +"access_procurement","procurement.order","model_procurement_order","mrp.group_mrp_user",1,1,1,1 "access_mrp_workcenter_manager","mrp.workcenter.manager","model_mrp_workcenter","mrp.group_mrp_user",1,1,1,1 "access_mrp_routing_manager","mrp.routing.manager","model_mrp_routing","mrp.group_mrp_manager",1,1,1,1 "access_mrp_routing_workcenter_manager","mrp.routing.workcenter.manager","model_mrp_routing_workcenter","mrp.group_mrp_manager",1,1,1,1 @@ -22,7 +22,7 @@ "access_purchase_order_mrp_worker","purchase.order mrp_worker","purchase.model_purchase_order","mrp.group_mrp_user",1,0,0,0 "access_purchase_order_line_mrp_worker","purchase.order.line mrp_worker","purchase.model_purchase_order_line","mrp.group_mrp_user",1,0,0,0 "access_hr_timesheet_group_mrp_worker","resource.calendar mrp_worker","resource.model_resource_calendar","mrp.group_mrp_user",1,0,0,0 -"access_mrp_procurement_stock_worker","mrp.procurement stock_worker","model_mrp_procurement","stock.group_stock_user",1,1,1,1 +"access_procurement_stock_worker","procurement.order stock_worker","model_procurement_order","stock.group_stock_user",1,1,1,1 "access_mrp_production_stock_worker","mrp.production stock_worker","model_mrp_production","stock.group_stock_user",1,0,0,0 "access_mrp_installer","mrp.installer","model_mrp_installer","mrp.group_mrp_user",1,0,0,0 "access_mrp_product_produce","mrp.product.produce","model_mrp_product_produce","mrp.group_mrp_user",1,0,0,0 diff --git a/addons/mrp/stock.py b/addons/mrp/stock.py index 9bcc92e5c81..67efd0d2753 100644 --- a/addons/mrp/stock.py +++ b/addons/mrp/stock.py @@ -28,82 +28,12 @@ import netsvc import time -class stock_warehouse_orderpoint(osv.osv): - """ - Defines Minimum stock rules. - """ - _name = "stock.warehouse.orderpoint" - _description = "Minimum Inventory Rule" - - _columns = { - 'name': fields.char('Name', size=32, required=True), - 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the orderpoint without removing it."), - 'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True), - 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"), - 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"), - 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','=','product')]), - 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True), - 'product_min_qty': fields.float('Min Quantity', required=True, - help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\ - "a procurement to bring the virtual stock to the Max Quantity."), - 'product_max_qty': fields.float('Max Quantity', required=True, - help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\ - "a procurement to bring the virtual stock to the Max Quantity."), - 'qty_multiple': fields.integer('Qty Multiple', required=True, - help="The procurement quantity will by rounded up to this multiple."), - 'procurement_id': fields.many2one('mrp.procurement', 'Latest procurement', ondelete="set null"), - 'company_id': fields.many2one('res.company','Company',required=True), - } - _defaults = { - 'active': lambda *a: 1, - 'logic': lambda *a: 'max', - 'qty_multiple': lambda *a: 1, - 'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.warehouse.orderpoint') or '', - 'product_uom': lambda sel, cr, uid, context: context.get('product_uom', False), - 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c) - } - _sql_constraints = [ - ('qty_multiple_check', 'CHECK( qty_multiple > 0 )', _('Qty Multiple must be greater than zero.')), - ] - - def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}): - """ Finds location id for changed warehouse. - @param warehouse_id: Changed id of warehouse. - @return: Dictionary of values. - """ - if warehouse_id: - w = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context) - v = {'location_id': w.lot_stock_id.id} - return {'value': v} - return {} - - def onchange_product_id(self, cr, uid, ids, product_id, context={}): - """ Finds UoM for changed product. - @param product_id: Changed id of product. - @return: Dictionary of values. - """ - if product_id: - prod = self.pool.get('product.product').browse(cr,uid,product_id) - v = {'product_uom': prod.uom_id.id} - return {'value': v} - return {} - - def copy(self, cr, uid, id, default=None,context={}): - if not default: - default = {} - default.update({ - 'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.warehouse.orderpoint') or '', - }) - return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context) - -stock_warehouse_orderpoint() - class StockMove(osv.osv): _inherit = 'stock.move' _columns = { 'production_id': fields.many2one('mrp.production', 'Production', select=True), - 'procurements': fields.one2many('mrp.procurement', 'move_id', 'Procurements'), + 'procurements': fields.one2many('procurement.order', 'move_id', 'Procurements'), } def copy(self, cr, uid, id, default=None, context=None): @@ -118,7 +48,7 @@ class StockMove(osv.osv): """ bom_obj = self.pool.get('mrp.bom') move_obj = self.pool.get('stock.move') - procurement_obj = self.pool.get('mrp.procurement') + procurement_obj = self.pool.get('procurement.order') product_obj = self.pool.get('product.product') wf_service = netsvc.LocalService("workflow") if move.product_id.supply_method == 'produce' and move.product_id.procure_method == 'make_to_order': @@ -166,7 +96,7 @@ class StockMove(osv.osv): 'move_id': mid, 'company_id': line['company_id'], }) - wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr) + wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr) move_obj.write(cr, uid, [move.id], { 'location_id': move.location_dest_id.id, 'auto_validate': True, @@ -175,7 +105,7 @@ class StockMove(osv.osv): 'state': 'waiting' }) for m in procurement_obj.search(cr, uid, [('move_id','=',move.id)], context): - wf_service.trg_validate(uid, 'mrp.procurement', m, 'button_wait_done', cr) + wf_service.trg_validate(uid, 'procurement.order', m, 'button_wait_done', cr) return True def action_consume(self, cr, uid, ids, product_qty, location_id=False, context=None): @@ -231,7 +161,7 @@ class StockPicking(osv.osv): for move in picking.move_lines: if move.state == 'done' and move.procurements: for procurement in move.procurements: - wf_service.trg_validate(user, 'mrp.procurement', + wf_service.trg_validate(user, 'procurement.order', procurement.id, 'button_check', cursor) return res diff --git a/addons/mrp/test/mrp_phantom_bom.yml b/addons/mrp/test/mrp_phantom_bom.yml index 5475d54ffd4..4a3e2e3e1da 100644 --- a/addons/mrp/test/mrp_phantom_bom.yml +++ b/addons/mrp/test/mrp_phantom_bom.yml @@ -9,6 +9,8 @@ factor: 1.0 name: Litre rounding: 0.01 +- + I create record for product Orange Juice. - !record {model: product.product, id: product_product_orangejuice0}: categ_id: product.cat1 @@ -18,6 +20,8 @@ type: product uom_id: product_uom_litre0 uom_po_id: product_uom_litre0 +- + I create record for product Orange. - !record {model: product.product, id: product_product_orange0}: categ_id: product.cat1 @@ -31,6 +35,8 @@ type: product uom_id: product.product_uom_kgm uom_po_id: product.product_uom_kgm +- + I create record for product Sugar. - !record {model: product.product, id: product_product_sugar0}: categ_id: product.cat1 @@ -44,6 +50,8 @@ type: product uom_id: product.product_uom_kgm uom_po_id: product.product_uom_kgm +- + I create record for product Water. - !record {model: product.product, id: product_product_water0}: categ_id: product.cat1 @@ -54,7 +62,7 @@ uom_id: product_uom_litre0 uom_po_id: product_uom_litre0 - - I define the BoM to produce an orange juice + I define the BoM to produce an orange juice. - !record {model: mrp.bom, id: mrp_bom_orangejuice0}: company_id: base.main_company @@ -64,6 +72,8 @@ product_qty: 1.0 product_uom: product_uom_litre0 type: phantom +- + I create bom lines for BoM for Orange Juice. - !record {model: mrp.bom, id: mrp_bom_orangejuice0}: bom_lines: @@ -92,7 +102,7 @@ product_uom: product_uom_litre0 type: normal - - I define Minimum stock rules for my stockable products orange and sugar + I define Minimum stock rules for my stockable product "Orange". - !record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op0}: company_id: base.main_company @@ -105,6 +115,8 @@ product_uom: product.product_uom_kgm qty_multiple: 1 warehouse_id: stock.warehouse0 +- + I define Minimum stock rules for my stockable product "Sugar". - !record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op1}: company_id: base.main_company @@ -168,23 +180,23 @@ - I am checking Procurement orders. There are 3 orders generated for Oranges, Sugar and Water. - - !python {model: mrp.procurement}: | + !python {model: procurement.order}: | from tools.translate import _ proc_ids = self.search(cr, uid, [('state','!=','cofirmed')]) assert proc_ids, _('No Procurements!') - The scheduler runs. - - !function {model: mrp.procurement, name: run_scheduler}: - - model: mrp.procurement - search: "[('origin','=',':MO/00002')]" + !function {model: procurement.order, name: run_scheduler}: + - model: procurement.order + search: "[('state','!=','cofirmed')]" - I am checking Internal picking. I see one picking for Orange juice and its stock moves for Oranges, Sugar and Water made correctly. - !python {model: stock.picking}: | from tools.translate import _ - pick_ids = self.search(cr, uid, [('origin','=',':MO/00002'),('type','=','internal')]) + pick_ids = self.search(cr, uid, [('type','=','internal')]) assert pick_ids, _('No Internal Pickings!') - According to minimum stock rules. I have 2 purchase orders for @@ -220,11 +232,15 @@ assert pick_ids, _('No Incoming Shipments found!') - I receive both the products. My incoming pickings are done. +- + I create record for the incoming picking wizard. - !record {model: stock.partial.picking, id: stock_partial_picking0}: date: '2010-04-30 16:53:36' partner_id: base.res_partner_asus address_id: base.res_partner_address_tang +- + I make my pickings done. - !python {model: stock.partial.picking}: | pick_obj = self.pool.get('stock.picking') diff --git a/addons/mrp/test/mrp_procurement.yml b/addons/mrp/test/mrp_procurement.yml index 37d0de5c5a9..1fe0f74fa6a 100644 --- a/addons/mrp/test/mrp_procurement.yml +++ b/addons/mrp/test/mrp_procurement.yml @@ -4,7 +4,7 @@ - I am creating products. - - Creating a product.product record + I create record for product Shirt. - !record {model: product.product, id: product_product_shirt0}: categ_id: product.cat1 @@ -27,7 +27,7 @@ weight: 0.0 weight_net: 0.0 - - Creating a product.product record + I create record for product Cloth. - !record {model: product.product, id: product_product_cloth0}: categ_id: product.cat1 @@ -53,7 +53,7 @@ weight: 0.0 weight_net: 0.0 - - Creating a product.product record + I create record for product Buttons. - !record {model: product.product, id: product_product_buttons0}: categ_id: product.cat1 @@ -81,7 +81,7 @@ - I am creating bills of material for 'Shirt'. - - Creating a mrp.bom record + I create bills of material for Shirt. - !record {model: mrp.bom, id: mrp_bom_shirt0}: bom_lines: @@ -129,7 +129,7 @@ - I create a procurement order for product Shirt. - - !record {model: mrp.procurement, id: mrp_procurement_shirt0}: + !record {model: procurement.order, id: procurement_order_shirt0}: name: 'PROC: Shirt' product_id: product_product_shirt0 product_qty: 5.00 @@ -138,11 +138,11 @@ - I confirm the procurement order. - - !workflow {model: mrp.procurement, action: button_confirm, ref: mrp_procurement_shirt0} + !workflow {model: procurement.order, action: button_confirm, ref: procurement_order_shirt0} - I run the procurement. - - !workflow {model: mrp.procurement, action: button_check, ref: mrp_procurement_shirt0} + !workflow {model: procurement.order, action: button_check, ref: procurement_order_shirt0} - I see that there is a manufacturing order for Shirt. - @@ -153,15 +153,15 @@ - I also check that there are two more procurement orders for sub products Cloth and Buttons. - - !python {model: mrp.procurement}: | + !python {model: procurement.order}: | 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 + !function {model: procurement.order, name: run_scheduler}: + - model: procurement.order search: "[]" - I check that there is one purchase order for Cloth. @@ -216,11 +216,15 @@ from tools.translate import _ pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')]) assert pick_ids, _('No Incoming Shipments found!') +- + I create record for partial picking. - !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 +- + I make my picking done. - !python {model: stock.partial.picking}: | pick_obj = self.pool.get('stock.picking') @@ -245,17 +249,21 @@ }) pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context) - - I Check incoming shipments for buttons. And receive products. + 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!') +- + I create record for partial picking. - !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 +- + I make my picking done. - !python {model: stock.partial.picking}: | pick_obj = self.pool.get('stock.picking') @@ -282,8 +290,8 @@ - Run scheduler again. - - !function {model: mrp.procurement, name: run_scheduler}: - - model: mrp.procurement + !function {model: procurement.order, name: run_scheduler}: + - model: procurement.order search: "[]" - Check state of manufacturing order for Shirt. @@ -303,22 +311,30 @@ wf_service = netsvc.LocalService("workflow") for p_id in prod_ids: wf_service.trg_validate(uid, 'mrp.production', p_id, 'button_produce', cr) +- + I create record for producing products with quantity 5.00. - !record {model: mrp.product.produce, id: mrp_product_produce0}: product_qty: 5.00 mode: 'consume_produce' +- + I produce 2 products with 5.00 quantities each. - !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}) +- + I create record for remaining products with quantity 35.00. - !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 +- + I produce remaining product Buttons with 35.00 quantity. - !python {model: stock.move.consume}: | from tools.translate import _ diff --git a/addons/mrp/test/mrp_production_order.yml b/addons/mrp/test/mrp_production_order.yml index 5de26180723..0ceebfab107 100644 --- a/addons/mrp/test/mrp_production_order.yml +++ b/addons/mrp/test/mrp_production_order.yml @@ -18,7 +18,7 @@ product_uom: product.product_uom_unit product_uos_qty: 0.0 - - Creating a mrp.production.workcenter.line record + I create a record for Workcenter line. - !record {model: mrp.production.workcenter.line, id: mrp_production_workcenter_line_assemblyline0}: cycle: 5.0 @@ -28,7 +28,7 @@ sequence: 0.0 workcenter_id: mrp.mrp_workcenter_0 - - Creating a mrp.production.product.line record + I create second record for Workcenter line. - !record {model: mrp.production.product.line, id: mrp_production_product_line_regularprocessorconfig0}: name: Regular processor config @@ -38,7 +38,7 @@ product_uos_qty: 0.0 production_id: mrp_production_mo0 - - Creating a mrp.production.product.line record + I create third record for Workcenter line. - !record {model: mrp.production.product.line, id: mrp_production_product_line_hddseagategb0}: name: HDD Seagate 7200.8 80GB @@ -48,7 +48,7 @@ product_uos_qty: 0.0 production_id: mrp_production_mo0 - - Creating a mrp.production.product.line record + I create fourth record for Workcenter line. - !record {model: mrp.production.product.line, id: mrp_production_product_line_atxmidsizetower0}: name: ATX Mid-size Tower @@ -58,7 +58,7 @@ product_uos_qty: 0.0 production_id: mrp_production_mo0 - - Creating a mrp.production.product.line record + I create a record for production line. - !record {model: mrp.production.product.line, id: mrp_production_product_line_mouse0}: name: Mouse @@ -68,7 +68,7 @@ product_uos_qty: 0.0 production_id: mrp_production_mo0 - - Creating a mrp.production.product.line record + I create second record for production line. - !record {model: mrp.production.product.line, id: mrp_production_product_line_keyboard0}: name: Keyboard @@ -84,15 +84,15 @@ - I am checking Procurement orders. - - !python {model: mrp.procurement}: | + !python {model: procurement.order}: | from tools.translate import _ 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 + !function {model: procurement.order, name: run_scheduler}: + - model: procurement.order search: "[('state','=','confirmed')]" - I am checking Internal picking. @@ -102,7 +102,7 @@ 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. + I see that there is a manufacturing order for the sub product of PC1 with ready state. - !python {model: mrp.production}: | from tools.translate import _ @@ -110,17 +110,21 @@ assert order_ids, _('No manufacturing order!') - I start producing that product first. So I marked it as started. +- + I create record for producing products with quantity 5.00. - !record {model: mrp.product.produce, id: mrp_product_produce0}: product_qty: 5.00 mode: 'consume_produce' +- + I produce the product. - !python {model: mrp.product.produce}: | prod_obj = self.pool.get('mrp.production') 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 + Now the manufacturing order for subproduct CPU_GEN is done and manufacturing order for PC1 is in ready state. - !python {model: mrp.production}: | @@ -131,6 +135,8 @@ I start producing the product PC1. - !workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0} +- + Finally my production order is done. - !python {model: mrp.product.produce}: | from tools.translate import _ diff --git a/addons/mrp_jit/__openerp__.py b/addons/mrp_jit/__openerp__.py index d9a862f5ddd..497a81352f3 100644 --- a/addons/mrp_jit/__openerp__.py +++ b/addons/mrp_jit/__openerp__.py @@ -40,7 +40,7 @@ """, 'author': 'Tiny', - 'depends': ['mrp_procurement'], + 'depends': ['procurement'], 'update_xml': ['mrp_jit.xml'], 'demo_xml': [], 'installable': True, diff --git a/addons/mrp_jit/mrp_jit.xml b/addons/mrp_jit/mrp_jit.xml index bab0d62b495..99f74a19517 100644 --- a/addons/mrp_jit/mrp_jit.xml +++ b/addons/mrp_jit/mrp_jit.xml @@ -2,7 +2,7 @@ - + diff --git a/addons/mrp_operations/__openerp__.py b/addons/mrp_operations/__openerp__.py index 9c0a2bb4f33..0ce116535c1 100644 --- a/addons/mrp_operations/__openerp__.py +++ b/addons/mrp_operations/__openerp__.py @@ -61,6 +61,7 @@ 'process/mrp_operation_process.xml' ], 'demo_xml': ['mrp_operation_data.xml'], + 'test': ['test/mrp_operations.yml'], 'installable': True, 'active': False, 'certificate': '0056233813133', diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index e8a97a47d9d..d1e66c92889 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -47,6 +47,9 @@ stock_move() class mrp_production_workcenter_line(osv.osv): def _get_date_date(self, cr, uid, ids, field_name, arg, context): + """ Finds starting date. + @return: Dictionary of values. + """ res={} for op in self.browse(cr, uid, ids, context=context): if op.date_start: @@ -54,7 +57,11 @@ class mrp_production_workcenter_line(osv.osv): else: res[op.id]=False return res + def _get_date_end(self, cr, uid, ids, field_name, arg, context): + """ Finds ending date. + @return: Dictionary of values. + """ res = {} for op in self.browse(cr, uid, ids, context=context): res[op.id]= False @@ -66,8 +73,10 @@ class mrp_production_workcenter_line(osv.osv): else: res[op.id] = op.date_planned return res + _inherit = 'mrp.production.workcenter.line' _order = "sequence, date_planned" + _columns = { 'state': fields.selection([('draft','Draft'),('startworking', 'In Progress'),('pause','Pause'),('cancel','Canceled'),('done','Finished')],'State', readonly=True, help="* When a work order is created it is set in 'Draft' state.\n" \ @@ -90,16 +99,21 @@ class mrp_production_workcenter_line(osv.osv): 'qty':fields.related('production_id','product_qty',type='float',string='Qty',readonly=True), 'uom':fields.related('production_id','product_uom',type='many2one',relation='product.uom',string='UOM',readonly=True), } + _defaults = { 'state': lambda *a: 'draft', 'delay': lambda *a: 0.0 } - def modify_production_order_state(self,cr,uid,ids,action): + def modify_production_order_state(self, cr, uid, ids, action): + """ Modifies production order state if work order state is changed. + @param action: Action to perform. + @return: Nothing + """ wf_service = netsvc.LocalService("workflow") - oper_obj=self.browse(cr,uid,ids)[0] - prod_obj=oper_obj.production_id - if action=='start': + oper_obj = self.browse(cr, uid, ids)[0] + prod_obj = oper_obj.production_id + if action == 'start': if prod_obj.state =='confirmed': self.pool.get('mrp.production').force_production(cr, uid, [prod_obj.id]) wf_service.trg_validate(uid, 'mrp.production', prod_obj.id, 'button_produce', cr) @@ -110,12 +124,12 @@ class mrp_production_workcenter_line(osv.osv): else: raise osv.except_osv(_('Error!'),_('Production Order Cannot start in [%s] state') % (prod_obj.state,)) else: - oper_ids=self.search(cr,uid,[('production_id','=',prod_obj.id)]) - obj=self.browse(cr,uid,oper_ids) - flag=True + oper_ids = self.search(cr,uid,[('production_id','=',prod_obj.id)]) + obj = self.browse(cr,uid,oper_ids) + flag = True for line in obj: - if line.state!='done': - flag=False + if line.state != 'done': + flag = False if flag: wf_service.trg_validate(uid, 'mrp.production', oper_obj.production_id.id, 'button_produce_done', cr) return @@ -132,15 +146,24 @@ class mrp_production_workcenter_line(osv.osv): return result def action_draft(self, cr, uid, ids): + """ Sets state to draft. + @return: True + """ self.write(cr, uid, ids, {'state':'draft'}) return True def action_start_working(self, cr, uid, ids): - self.modify_production_order_state(cr,uid,ids,'start') + """ Sets state to start working and writes starting date. + @return: True + """ + self.modify_production_order_state(cr, uid, ids, 'start') self.write(cr, uid, ids, {'state':'startworking', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')}) return True def action_done(self, cr, uid, ids): + """ Sets state to done, writes finish date and calculates delay. + @return: True + """ delay = 0.0 date_now = time.strftime('%Y-%m-%d %H:%M:%S') obj_line = self.browse(cr, uid, ids[0]) @@ -155,14 +178,23 @@ class mrp_production_workcenter_line(osv.osv): return True def action_cancel(self, cr, uid, ids): + """ Sets state to cancel. + @return: True + """ self.write(cr, uid, ids, {'state':'cancel'}) return True def action_pause(self, cr, uid, ids): + """ Sets state to pause. + @return: True + """ self.write(cr, uid, ids, {'state':'pause'}) return True def action_resume(self, cr, uid, ids): + """ Sets state to startworking. + @return: True + """ self.write(cr, uid, ids, {'state':'startworking'}) return True @@ -175,6 +207,9 @@ class mrp_production(osv.osv): } def _production_date_end(self, cr, uid, ids, prop, unknow_none, context={}): + """ Calculates planned end date of production order. + @return: Dictionary of values + """ result = {} for prod in self.browse(cr, uid, ids, context=context): result[prod.id] = prod.date_planned @@ -183,10 +218,13 @@ class mrp_production(osv.osv): return result def action_production_end(self, cr, uid, ids): - obj=self.browse(cr,uid,ids)[0] + """ Finishes work order if production order is done. + @return: Super method + """ + obj = self.browse(cr, uid, ids)[0] for workcenter_line in obj.workcenter_lines: - tmp = self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,[workcenter_line.id]) - return super(mrp_production,self).action_production_end(cr,uid,ids) + tmp = self.pool.get('mrp.production.workcenter.line').action_done(cr, uid, [workcenter_line.id]) + return super(mrp_production,self).action_production_end(cr, uid, ids) def action_in_production(self, cr, uid, ids): """ Changes state to In Production and writes starting date. @@ -199,12 +237,18 @@ class mrp_production(osv.osv): return super(mrp_production,self).action_in_production(cr, uid, ids) def action_cancel(self, cr, uid, ids): - obj=self.browse(cr,uid,ids)[0] + """ Cancels work order if production order is canceled. + @return: Super method + """ + obj = self.browse(cr, uid, ids)[0] for workcenter_line in obj.workcenter_lines: - tmp=self.pool.get('mrp.production.workcenter.line').action_cancel(cr,uid,[workcenter_line.id]) + tmp = self.pool.get('mrp.production.workcenter.line').action_cancel(cr, uid, [workcenter_line.id]) return super(mrp_production,self).action_cancel(cr,uid,ids) def _compute_planned_workcenter(self, cr, uid, ids, context={}, mini=False): + """ Computes planned and finished dates for work order. + @return: Calculated date + """ dt_end = DateTime.now() for po in self.browse(cr, uid, ids, context=context): dt_end = DateTime.strptime(po.date_start or po.date_planned, '%Y-%m-%d %H:%M:%S') @@ -241,6 +285,9 @@ class mrp_production(osv.osv): return dt_end def _move_pass(self, cr, uid, ids, context={}): + """ Calculates start date for stock moves finding interval from resource calendar. + @return: True + """ for po in self.browse(cr, uid, ids, context): if po.allow_reorder: continue @@ -251,7 +298,7 @@ class mrp_production(osv.osv): if l.state in ('done','cancel','draft'): continue todo += l.move_dest_id_lines - if l.production_id and (l.production_id.date_finnished>dt): + if l.production_id and (l.production_id.date_finnished > dt): if l.production_id.state not in ('done','cancel'): for wc in l.production_id.workcenter_lines: i = self.pool.get('resource.calendar').interval_min_get( @@ -261,11 +308,14 @@ class mrp_production(osv.osv): dt, wc.hour or 0.0 ) dt = i[0][0] - if l.production_id.date_start>dt.strftime('%Y-%m-%d %H:%M:%S'): + if l.production_id.date_start > dt.strftime('%Y-%m-%d %H:%M:%S'): self.write(cr, uid, [l.production_id.id], {'date_start':dt.strftime('%Y-%m-%d %H:%M:%S')}, mini=True) return True def _move_futur(self, cr, uid, ids, context={}): + """ Calculates start date for stock moves. + @return: True + """ for po in self.browse(cr, uid, ids, context): if po.allow_reorder: continue @@ -277,8 +327,8 @@ class mrp_production(osv.osv): break if l.production_id.state in ('done','cancel'): break - if l.production_id and (l.production_id.date_start