diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 4f33b0c1558..d2079df4503 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -34,15 +34,12 @@ import time # capacity_hour : capacity per hour. default: 1.0. # Eg: If 5 concurrent operations at one time: capacity = 5 (because 5 employees) # unit_per_cycle : how many units are produced for one cycle -# -# TODO: Work Center may be recursive ? -# + class mrp_workcenter(osv.osv): _name = 'mrp.workcenter' _description = 'Work Center' _inherits = {'resource.resource':"resource_id"} _columns = { -# 'name': fields.char('Work Center Name', size=64, required=True), 'note': fields.text('Description', help="Description of the workcenter. Explain here what's a cycle according to this workcenter."), 'capacity_per_cycle': fields.float('Capacity per Cycle', help="Number of operations this workcenter can do in parallel. If this workcenter represents a team of 5 workers, the capacity per cycle is 5."), 'time_cycle': fields.float('Time for 1 cycle (hour)', help="Time in hours for doing one cycle."), @@ -56,7 +53,6 @@ class mrp_workcenter(osv.osv): help="Complete this only if you want automatic analytic accounting entries on production orders."), 'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'), 'costs_general_account_id': fields.many2one('account.account', 'General Account', domain=[('type','<>','view')]), -# 'company_id': fields.many2one('res.company','Company',required=True), 'resource_id': fields.many2one('resource.resource','Resource',ondelete='cascade'), } _defaults = { @@ -255,7 +251,6 @@ class mrp_bom(osv.osv): @return: False or BoM id. """ bom_result = False - # Why searching on BoM without parent ? cr.execute('select id from mrp_bom where product_id=%s and bom_id is null order by sequence', (product_id,)) ids = map(lambda x: x[0], cr.fetchall()) max_prop = 0 @@ -607,9 +602,6 @@ class mrp_production(osv.osv): if not bom_id: raise osv.except_osv(_('Error'), _("Couldn't find bill of material for product")) - #if bom_point.routing_id and bom_point.routing_id.location_id: - # self.write(cr, uid, [production.id], {'location_src_id': bom_point.routing_id.location_id.id}) - factor = production.product_qty * production.product_uom.factor / bom_point.product_uom.factor res = bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties) results = res[0] @@ -631,11 +623,9 @@ class mrp_production(osv.osv): if production.move_created_ids: move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids]) move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines]) - self.write(cr, uid, ids, {'state': 'cancel'}) #,'move_lines':[(6,0,[])]}) + self.write(cr, uid, ids, {'state': 'cancel'}) return True - #XXX: may be a bug here; lot_lines are unreserved for a few seconds; - # between the end of the picking list and the call to this function def action_ready(self, cr, uid, ids): """ Changes the production state to Ready and location id of stock move. @return: True @@ -981,3 +971,4 @@ class mrp_production_product_line(osv.osv): } mrp_production_product_line() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/procurement.py b/addons/mrp/procurement.py index 50a976c741a..6425f6e84ac 100644 --- a/addons/mrp/procurement.py +++ b/addons/mrp/procurement.py @@ -55,7 +55,7 @@ class procurement_order(osv.osv): 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 + return len(res) and res[0] or 0 def make_mo(self, cr, uid, ids, context={}): """ Make Manufacturing(production) order from procurement diff --git a/addons/mrp/report/bom_structure.py b/addons/mrp/report/bom_structure.py index 25d179b6901..fa2f5835ae4 100644 --- a/addons/mrp/report/bom_structure.py +++ b/addons/mrp/report/bom_structure.py @@ -1,22 +1,21 @@ -# -*- encoding: utf-8 -*- +## -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved -# $Id$ +# Copyright (C) 2004-2010 Tiny SPRL (). # # This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# GNU Affero General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . # ############################################################################## diff --git a/addons/mrp/report/mrp_production_order.py b/addons/mrp/report/mrp_production_order.py index 4fffbdf1689..9aeae1781cd 100644 --- a/addons/mrp/report/mrp_production_order.py +++ b/addons/mrp/report/mrp_production_order.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # ############################################################################## + from osv import fields,osv import tools diff --git a/addons/mrp/report/order.py b/addons/mrp/report/order.py index 7acf6029392..4481c2c121b 100644 --- a/addons/mrp/report/order.py +++ b/addons/mrp/report/order.py @@ -21,8 +21,6 @@ import time from report import report_sxw -from osv import osv -import pooler class order(report_sxw.rml_parse): def __init__(self, cr, uid, name, context): @@ -31,9 +29,6 @@ class order(report_sxw.rml_parse): 'time': time, }) - - report_sxw.report_sxw('report.mrp.production.order','mrp.production','addons/mrp/report/order.rml',parser=order,header=1) - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/report/workcenter_load.py b/addons/mrp/report/workcenter_load.py index 8e5b9bff7ba..9c31e343043 100644 --- a/addons/mrp/report/workcenter_load.py +++ b/addons/mrp/report/workcenter_load.py @@ -173,7 +173,6 @@ class report_custom(report_int): ar.add_plot(bar_plot.T(label=workcenter['name'], data=data, fill_style=f, hcol=workcenter_num+1, cluster=(workcenter_num, len(res)))) workcenter_num += 1 - #plot = bar_plot.T(label=workcenter['name'], data=data, hcol=1, fill_style=fill_style.white, cluster=(color_index,len(ids))) if (not data) or (len(data[0]) <= 1): ar = self._empty_graph(time.strftime('%Y-%m-%d')) ar.draw(can) diff --git a/addons/mrp/test/mrp_phantom_bom.yml b/addons/mrp/test/mrp_phantom_bom.yml index 97778408b05..1cb7aa9b631 100644 --- a/addons/mrp/test/mrp_phantom_bom.yml +++ b/addons/mrp/test/mrp_phantom_bom.yml @@ -203,7 +203,7 @@ - !function {model: procurement.order, name: run_scheduler}: - model: procurement.order - search: "[('state','!=','confirmed')]" + search: "[('state','=','confirmed')]" - I am checking Internal picking. I see one picking for Orange juice and its stock moves for Oranges, Sugar and Water made correctly. diff --git a/addons/mrp/wizard/mrp_change_standard_price.py b/addons/mrp/wizard/mrp_change_standard_price.py index 21492bda4f8..3fc63bcc421 100644 --- a/addons/mrp/wizard/mrp_change_standard_price.py +++ b/addons/mrp/wizard/mrp_change_standard_price.py @@ -47,3 +47,5 @@ class change_standard_price(osv.osv_memory): return super(change_standard_price, self).change_price(cr, uid, ids, context=context) change_standard_price() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp/wizard/mrp_product_produce.py b/addons/mrp/wizard/mrp_product_produce.py index 180c0831577..a554a829428 100644 --- a/addons/mrp/wizard/mrp_product_produce.py +++ b/addons/mrp/wizard/mrp_product_produce.py @@ -74,3 +74,4 @@ class mrp_product_produce(osv.osv_memory): mrp_product_produce() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/mrp_jit/__openerp__.py b/addons/mrp_jit/__openerp__.py index aa06715d986..0cf11110ef2 100644 --- a/addons/mrp_jit/__openerp__.py +++ b/addons/mrp_jit/__openerp__.py @@ -43,6 +43,7 @@ 'depends': ['procurement'], 'update_xml': ['mrp_jit.xml'], 'demo_xml': [], + 'test': ['test/mrp_jit.yml'], 'installable': True, 'active': False, 'certificate': '0086634760061', diff --git a/addons/mrp_jit/test/mrp_jit.yml b/addons/mrp_jit/test/mrp_jit.yml new file mode 100644 index 00000000000..edafb8ca5a5 --- /dev/null +++ b/addons/mrp_jit/test/mrp_jit.yml @@ -0,0 +1,35 @@ +- + In order to test mrp_jit module with OpenERP, I will create manufacturing order + and check whether the procurement orders run without scheduler or not. +- + !record {model: mrp.production, id: mrp_production_mo0}: + bom_id: mrp.mrp_bom_1 + company_id: base.main_company + date_planned: '2010-08-05 17:59:49' + location_dest_id: stock.stock_location_stock + location_src_id: stock.stock_location_stock + name: MO/00017 + product_id: product.product_product_pc2 + product_qty: 10.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 + routing_id: mrp.mrp_routing_0 +- + | + I confirm production order. +- + !workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo0} +- + | + I check the procurement orders generated from the production order. +- + | + It runs without using schedulers. +- + !python {model: procurement.order}: | + prod_obj = self.pool.get('mrp.production') + production = prod_obj.browse(cr, uid, ref('mrp_production_mo0')) + products = map(lambda x:x.product_id.id, production.move_lines) + procurement_ids = self.search(cr, uid, [('product_id','in',products)]) + procurements = self.browse(cr, uid, procurement_ids) + assert all(proc.state != 'confirmed' for proc in procurements), 'Procurement not scheduled!' diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index 5fbbc5ea18a..d0a669590e2 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -34,9 +34,6 @@ from tools.translate import _ # capacity_hour : capacity per hour. default: 1.0. # Eg: If 5 concurrent operations at one time: capacity = 5 (because 5 employees) # unit_per_cycle : how many units are produced for one cycle -# -# TODO: Work Center may be recursive ? -# class stock_move(osv.osv): _inherit = 'stock.move' diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index 819acffd4ae..248234d8952 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -411,7 +411,6 @@ class mrp_repair(osv.osv): }) repair_fee_obj.write(cr, uid, [fee.id], {'invoiced': True, 'invoice_line_id': invoice_fee_id}) res[repair.id] = inv_id - #self.action_invoice_end(cr, uid, ids) return res def action_repair_ready(self, cr, uid, ids, context=None): @@ -444,7 +443,6 @@ class mrp_repair(osv.osv): if (order.invoice_method == 'b4repair'): val['state'] = 'ready' else: - #val['state'] = 'done' pass self.write(cr, uid, [order.id], val) return True @@ -462,7 +460,6 @@ class mrp_repair(osv.osv): elif (not order.invoiced and order.invoice_method=='b4repair'): val['state'] = 'ready' else: - #val['state'] = 'done' pass self.write(cr, uid, [order.id], val) return True @@ -496,7 +493,6 @@ class mrp_repair(osv.osv): 'state': 'done', }) repair_line_obj.write(cr, uid, [move.id], {'move_id': move_id}) - if repair.deliver_bool: pick_name = seq_obj.get(cr, uid, 'stock.picking.out') picking = pick_obj.create(cr, uid, { @@ -509,23 +505,20 @@ class mrp_repair(osv.osv): 'invoice_state': 'none', 'type': 'out', }) - wf_service.trg_validate(uid, 'stock.picking', picking, 'button_confirm', cr) - move_id = move_obj.create(cr, uid, { 'name': repair.name, 'picking_id': picking, 'product_id': repair.product_id.id, 'product_qty': 1.0, 'product_uom': repair.product_id.uom_id.id, - #'product_uos_qty': line.product_uom_qty, - #'product_uos': line.product_uom.id, 'prodlot_id': repair.prodlot_id and repair.prodlot_id.id or False, 'address_id': repair.address_id and repair.address_id.id or False, 'location_id': repair.location_id.id, 'location_dest_id': repair.location_dest_id.id, 'tracking_id': False, - 'state': 'assigned', # FIXME done ? + 'state': 'assigned', }) + wf_service.trg_validate(uid, 'stock.picking', picking, 'button_confirm', cr) self.write(cr, uid, [repair.id], {'state': 'done', 'picking_id': picking}) res[repair.id] = picking else: diff --git a/addons/mrp_repair/mrp_repair_view.xml b/addons/mrp_repair/mrp_repair_view.xml index 4e59a7d6a15..cf58fdefe4a 100644 --- a/addons/mrp_repair/mrp_repair_view.xml +++ b/addons/mrp_repair/mrp_repair_view.xml @@ -180,7 +180,7 @@ - + diff --git a/addons/mrp_repair/test/test_mrp_repair.yml b/addons/mrp_repair/test/test_mrp_repair.yml index a3fe8ef28f4..961ebdf2496 100644 --- a/addons/mrp_repair/test/test_mrp_repair.yml +++ b/addons/mrp_repair/test/test_mrp_repair.yml @@ -1,5 +1,5 @@ - | - In order to test "mrp_repair" module, I start with creating repairt order, confirm it, and start repair. + In order to test "mrp_repair" module, I start with creating repair order, confirm it, and start repair. - | Given that I have already stock move line created. diff --git a/addons/mrp_subproduct/__openerp__.py b/addons/mrp_subproduct/__openerp__.py index f208e0b1a76..b1c9db1ccf9 100644 --- a/addons/mrp_subproduct/__openerp__.py +++ b/addons/mrp_subproduct/__openerp__.py @@ -38,6 +38,7 @@ With this module: 'init_xml': [], 'update_xml': ['security/ir.model.access.csv', 'mrp_subproduct_view.xml'], 'demo_xml': [], + 'test': ['test/mrp_subproduct.yml'], 'installable': True, 'active': False, 'certificate': '0050060616733', diff --git a/addons/mrp_subproduct/test/mrp_subproduct.yml b/addons/mrp_subproduct/test/mrp_subproduct.yml new file mode 100644 index 00000000000..520a4e98163 --- /dev/null +++ b/addons/mrp_subproduct/test/mrp_subproduct.yml @@ -0,0 +1,169 @@ +- + In order to test mrp_subproduct with OpenERP, I create a bill of material with subproducts. + I make a production order, confirm it so stock moves for subproducts are generated. +- + I create a record for the product Chair. +- + !record {model: product.product, id: product_product_woodenchair0}: + categ_id: product.cat1 + name: Wooden Chair + procure_method: make_to_stock + supply_method: produce + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit + property_stock_inventory: stock.location_inventory + property_stock_procurement: stock.location_procurement + property_stock_production: stock.location_production +- + I create a record for the product Wood. +- + !record {model: product.product, id: product_product_wood0}: + categ_id: product.cat1 + name: Wood + procure_method: make_to_order + supply_method: buy + property_stock_inventory: stock.location_inventory + property_stock_procurement: stock.location_procurement + property_stock_production: stock.location_production + seller_ids: + - delay: 1 + name: base.res_partner_maxtor + min_qty: 300.0 + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit +- + I create a record for the product Nails. +- + !record {model: product.product, id: product_product_nails0}: + categ_id: product.cat1 + name: Nails + procure_method: make_to_order + supply_method: buy + property_stock_inventory: stock.location_inventory + property_stock_procurement: stock.location_procurement + property_stock_production: stock.location_production + seller_ids: + - delay: 1 + name: base.res_partner_asus + min_qty: 500.0 + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit +- + I create a record for the product Table. +- + !record {model: product.product, id: product_product_woodentable0}: + categ_id: product.cat1 + name: Wooden Table + procure_method: make_to_stock + supply_method: produce + type: product + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit + property_stock_inventory: stock.location_inventory + property_stock_procurement: stock.location_procurement + property_stock_production: stock.location_production +- + Now I create a bill of material for the product Wooden Chair. +- + !record {model: mrp.bom, id: mrp_bom_woodenchair0}: + company_id: base.main_company + name: Wooden Chair + product_efficiency: 1.0 + product_id: product_product_woodenchair0 + product_qty: 1.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 + type: normal + bom_lines: + - company_id: base.main_company + name: Wood + product_efficiency: 1.0 + product_id: product_product_wood0 + product_qty: 10.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 + sequence: 0.0 + type: normal + - company_id: base.main_company + name: Nails + product_efficiency: 1.0 + product_id: product_product_nails0 + product_qty: 35.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 + sequence: 0.0 + type: normal + sub_products: + - product_id: product_product_woodentable0 + product_uom: product.product_uom_unit + product_qty: 1.0 + subproduct_type: fixed +- + I create a production order for Wooden Chair. +- + !record {model: mrp.production, id: mrp_production_mo0}: + bom_id: mrp_bom_woodenchair0 + company_id: base.main_company + date_planned: '2010-08-06 14:55:52' + location_dest_id: stock.stock_location_stock + location_src_id: stock.stock_location_stock + name: MO/00004 + product_id: product_product_woodenchair0 + product_qty: 10.0 + product_uom: product.product_uom_unit + product_uos_qty: 0.0 +- + I compute the data of production order. +- + !python {model: mrp.production}: | + self.action_compute(cr, uid, [ref("mrp_production_mo0")], {"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_mo0} +- + Now I check the stock moves for the subproduct I created in the bill of material. + This move is created automatically when I confirmed the production order. +- + !python {model: stock.move}: | + move_id = self.search(cr, uid, [('product_id','=',ref('product_product_woodentable0'))]) + assert move_id, 'No moves are created !' +- + I want to start the production so I force the reservation of products. +- + !python {model: mrp.production}: | + self.force_production(cr, uid, [ref("mrp_production_mo0")], {"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 start the production. +- + !workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0} +- + I consume and produce the Production of products. +- + I create record for selecting mode and quantity of products to produce. +- + !record {model: mrp.product.produce, id: mrp_product_produce0}: + product_qty: 10.00 + mode: 'consume_produce' +- + I finish the production order. +- + !python {model: mrp.product.produce}: | + self.do_produce(cr, uid, [ref("mrp_product_produce0")], {"lang": "en_US", "tz": + False, "search_default_Current": 1, "active_model": "mrp.production", "active_ids": + [ref("mrp_production_mo0")], "active_id": ref("mrp_production_mo0"), }) +- + I see that stock moves of Wood and Nails including Wooden Table are done now. +- + !python {model: stock.move}: | + move_ids = self.search(cr, uid, [('product_id','in',[ref("product_product_woodenchair0"),ref("product_product_woodentable0"),ref("product_product_wood0"),ref("product_product_nails0")])]) + moves = self.browse(cr, uid, move_ids) + assert all(move.state == 'done' for move in moves), 'Moves are not done!' diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml index bb5976c9761..155e759a549 100644 --- a/addons/product/product_demo.xml +++ b/addons/product/product_demo.xml @@ -744,6 +744,7 @@ Returning customers (0.00) : 0.99'" name="pricelist_sale"/> 10 1 + 5 10 @@ -751,6 +752,7 @@ Returning customers (0.00) : 0.99'" name="pricelist_sale"/> 10 1 + 5 10 @@ -758,6 +760,7 @@ Returning customers (0.00) : 0.99'" name="pricelist_sale"/> 10 1 + 5 10