diff --git a/mrp_bom_reference_selection/README.rst b/mrp_bom_reference_selection/README.rst new file mode 100644 index 000000000..2c106cbab --- /dev/null +++ b/mrp_bom_reference_selection/README.rst @@ -0,0 +1,55 @@ +MRP Bill of Material Reference Selection +======================================== + +This module allows to select the component in a bom when you have several bom for one product. +This is used to manage versions of a product. +Produced lot contains a reference to the bill of material used to compute the lot. + +Installation +============ + +To install this module, you just need to select the module and insure yourself dependancies are available. + +Configuration +============= + +No particular configuration to use this module. + + +Usage +===== + +To use this module, you need to : +- create a product +- create a bom from this product (ie : AA), give a reference to this bom (ie : A1) +- create an other bom for the same product, give a reference to this bom (ie : A2) +- now, you can create an other bom for an other product (ie : BB) with products AA as component. You will have to choose the bom you want between A1 or A2 + + +Credits +======= + +Module developed and tested with Odoo version 8.0 +For questions, please contact our support services + +Contributors +------------ + +* David DUFRESNE +* Jordi RIERA +* Bruno JOLIVEAU + +Icon +---- +* http://en.wikipedia.org/wiki/File:People%27s_Action_Party_of_Singapore_logo.svg + +Maintainer +---------- + +Odoo Community Association + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/mrp_bom_reference_selection/__init__.py b/mrp_bom_reference_selection/__init__.py new file mode 100644 index 000000000..0083786b3 --- /dev/null +++ b/mrp_bom_reference_selection/__init__.py @@ -0,0 +1,39 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import models +from . import wizards +from openerp import SUPERUSER_ID + + +def set_bill_of_material_references(cr, registry): + """ + This function adds a reference record to each existing boms when the + module is installed. This ensures that each bom has a reference + so that the module works properly. + """ + bom_obj = registry['mrp.bom'] + ref_obj = registry['mrp.bom.reference'] + bom_ids = bom_obj.search(cr, SUPERUSER_ID, []) + for bom in bom_obj.browse(cr, SUPERUSER_ID, bom_ids): + if not bom.reference_id: + ref_obj.create(cr, SUPERUSER_ID, {'bom_id': bom.id}) diff --git a/mrp_bom_reference_selection/__openerp__.py b/mrp_bom_reference_selection/__openerp__.py new file mode 100644 index 000000000..d2b272cf7 --- /dev/null +++ b/mrp_bom_reference_selection/__openerp__.py @@ -0,0 +1,45 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': 'Bill of Material Selection Reference', + 'version': '1.1', + 'author': 'Savoir-faire Linux', + 'license': 'AGPL-3', + 'category': 'Others', + 'summary': 'Bill of Material Selection Reference', + 'depends': [ + 'mrp', + ], + 'external_dependencies': { + 'python': [], + }, + 'data': [ + 'security/ir.model.access.csv', + 'views/mrp_bom_view.xml', + 'views/mrp_product_produce_view.xml', + 'views/stock_production_lot_view.xml', + ], + 'post_init_hook': 'set_bill_of_material_references', + 'installable': True, + 'application': True, +} diff --git a/mrp_bom_reference_selection/i18n/fr.po b/mrp_bom_reference_selection/i18n/fr.po new file mode 100644 index 000000000..ac4a25004 --- /dev/null +++ b/mrp_bom_reference_selection/i18n/fr.po @@ -0,0 +1,68 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mrp_bom_reference_selection +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-02-25 13:19+0000\n" +"PO-Revision-Date: 2015-02-25 08:24-0500\n" +"Last-Translator: David Dufresne \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 1.5.4\n" + +#. module: mrp_bom_reference_selection +#: model:ir.model,name:mrp_bom_reference_selection.model_mrp_bom +#: field:mrp.bom.reference,bom_id:0 +msgid "Bill of Material" +msgstr "Nomenclature" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom,reference_id:0 +msgid "BoM Reference" +msgstr "Référence de nomenclature" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,create_uid:0 +msgid "Created by" +msgstr "Créé par" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,create_date:0 +msgid "Created on" +msgstr "Créé le" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,id:0 +msgid "ID" +msgstr "ID" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,write_uid:0 +msgid "Last Updated by" +msgstr "Dernière mise-à-jour par" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,write_date:0 +msgid "Last Updated on" +msgstr "Dernière mise-à-jour le" + +#. module: mrp_bom_reference_selection +#: model:ir.model,name:mrp_bom_reference_selection.model_mrp_bom_reference +msgid "MRP Bill of Material Reference" +msgstr "Référence de nomenclature" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.line,product_tmpl_id:0 +msgid "Product Template" +msgstr "Modèle d'article" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,name:0 +msgid "Reference" +msgstr "Référence" diff --git a/mrp_bom_reference_selection/i18n/mrp_bom_reference_selection.pot b/mrp_bom_reference_selection/i18n/mrp_bom_reference_selection.pot new file mode 100644 index 000000000..ff58455bf --- /dev/null +++ b/mrp_bom_reference_selection/i18n/mrp_bom_reference_selection.pot @@ -0,0 +1,68 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mrp_bom_reference_selection +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-02-25 13:19+0000\n" +"PO-Revision-Date: 2015-02-25 13:19+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: mrp_bom_reference_selection +#: model:ir.model,name:mrp_bom_reference_selection.model_mrp_bom +#: field:mrp.bom.reference,bom_id:0 +msgid "Bill of Material" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom,reference_id:0 +msgid "BoM Reference" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,create_uid:0 +msgid "Created by" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,create_date:0 +msgid "Created on" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,id:0 +msgid "ID" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,write_uid:0 +msgid "Last Updated by" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,write_date:0 +msgid "Last Updated on" +msgstr "" + +#. module: mrp_bom_reference_selection +#: model:ir.model,name:mrp_bom_reference_selection.model_mrp_bom_reference +msgid "MRP Bill of Material Reference" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.line,product_tmpl_id:0 +msgid "Product Template" +msgstr "" + +#. module: mrp_bom_reference_selection +#: field:mrp.bom.reference,name:0 +msgid "Reference" +msgstr "" + diff --git a/mrp_bom_reference_selection/models/__init__.py b/mrp_bom_reference_selection/models/__init__.py new file mode 100644 index 000000000..472d7c654 --- /dev/null +++ b/mrp_bom_reference_selection/models/__init__.py @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import ( + mrp_bom, + mrp_bom_line, + mrp_bom_reference, + mrp_production, + stock_production_lot, +) diff --git a/mrp_bom_reference_selection/models/mrp_bom.py b/mrp_bom_reference_selection/models/mrp_bom.py new file mode 100644 index 000000000..550fa197a --- /dev/null +++ b/mrp_bom_reference_selection/models/mrp_bom.py @@ -0,0 +1,37 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, fields, api + + +class MrpBillOfMaterial(models.Model): + _inherit = 'mrp.bom' + + @api.model + def create(self, vals): + res = super(MrpBillOfMaterial, self).create(vals) + if not res.reference_id: + self.env['mrp.bom.reference'].create({'bom_id': res.id}) + return res + + reference_id = fields.One2many( + 'mrp.bom.reference', 'bom_id', string="BoM Reference") diff --git a/mrp_bom_reference_selection/models/mrp_bom_line.py b/mrp_bom_reference_selection/models/mrp_bom_line.py new file mode 100644 index 000000000..5f2c73a35 --- /dev/null +++ b/mrp_bom_reference_selection/models/mrp_bom_line.py @@ -0,0 +1,71 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, fields, api + + +class MrpBillOfMaterialLine(models.Model): + _inherit = 'mrp.bom.line' + + reference_id = fields.Many2one('mrp.bom.reference', 'Ref') + product_tmpl_id = fields.Many2one( + 'product.template', 'Product Template', + related='product_id.product_tmpl_id', store=True) + + product_id = fields.Many2one( + 'product.product', required=True, string='Product') + + @api.multi + def onchange_product_id(self, product_id): + product = self.env['product.product'].browse(product_id) + + res = {'value': {}} + + if not product: + res['value']['reference_id'] = False + else: + refs = self.env['mrp.bom.reference'].search( + [('bom_id.product_tmpl_id', '=', product.product_tmpl_id.id)]) + res['value']['reference_id'] = refs and refs[0] + + return res + + @api.one + @api.depends('product_id') + def _get_child_bom_lines(self): + if self.reference_id: + self.child_line_ids = self.reference_id.bom_id.bom_line_ids.ids + else: + bom_obj = self.env['mrp.bom'] + bom_id = bom_obj._bom_find( + product_tmpl_id=self.product_id.product_tmpl_id.id, + product_id=self.product_id.id) + self.child_line_ids = bom_id and [ + (6, 0, child_id) for child_id in + bom_obj.browse(bom_id).bom_line_ids.ids + ] or False + + child_line_ids = fields.One2many( + relation='mrp.bom.line', + compute='_get_child_bom_lines', + string="BOM lines of the referred bom", + ) diff --git a/mrp_bom_reference_selection/models/mrp_bom_reference.py b/mrp_bom_reference_selection/models/mrp_bom_reference.py new file mode 100644 index 000000000..8059c25f9 --- /dev/null +++ b/mrp_bom_reference_selection/models/mrp_bom_reference.py @@ -0,0 +1,34 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, fields + + +class MrpBillOfMaterialReference(models.Model): + + _name = 'mrp.bom.reference' + _description = 'MRP Bill of Material Reference' + + bom_id = fields.Many2one( + 'mrp.bom', required=True, ondelete='cascade', + string='Bill of Material') + name = fields.Char(related='bom_id.code', store=True) diff --git a/mrp_bom_reference_selection/models/mrp_production.py b/mrp_bom_reference_selection/models/mrp_production.py new file mode 100644 index 000000000..931a7cd73 --- /dev/null +++ b/mrp_bom_reference_selection/models/mrp_production.py @@ -0,0 +1,47 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import logging +from openerp import models, api + +_logger = logging.getLogger(__name__) + + +class MrpProduction(models.Model): + _inherit = 'mrp.production' + + @api.model + def action_produce(self, production_id, production_qty, + production_mode, wiz=False): + """Affect the Bill of Material to each serial number related to + the produced stocks + """ + res = super(MrpProduction, self).action_produce( + production_id, production_qty, production_mode, wiz) + + production = self.browse(production_id) + + for move in production.move_created_ids2: + prod_lots = move.lot_ids + prod_lots.write({'bom_id': production.bom_id.id}) + + return res diff --git a/mrp_bom_reference_selection/models/stock_production_lot.py b/mrp_bom_reference_selection/models/stock_production_lot.py new file mode 100644 index 000000000..a1c38988e --- /dev/null +++ b/mrp_bom_reference_selection/models/stock_production_lot.py @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, fields + + +class StockProductionLot(models.Model): + _inherit = 'stock.production.lot' + + bom_id = fields.Many2one('mrp.bom', 'Bill of Material') diff --git a/mrp_bom_reference_selection/security/ir.model.access.csv b/mrp_bom_reference_selection/security/ir.model.access.csv new file mode 100644 index 000000000..2ccaa9f4a --- /dev/null +++ b/mrp_bom_reference_selection/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_mrp_bom_reference_user,mrp.bom.reference,model_mrp_bom_reference,mrp.group_mrp_user,1,1,1,1 diff --git a/mrp_bom_reference_selection/tests/__init__.py b/mrp_bom_reference_selection/tests/__init__.py new file mode 100644 index 000000000..bf6ddd1bb --- /dev/null +++ b/mrp_bom_reference_selection/tests/__init__.py @@ -0,0 +1,27 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import test_mrp_bom + +checks = [ + test_mrp_bom, +] diff --git a/mrp_bom_reference_selection/tests/test_mrp_bom.py b/mrp_bom_reference_selection/tests/test_mrp_bom.py new file mode 100644 index 000000000..1cee04866 --- /dev/null +++ b/mrp_bom_reference_selection/tests/test_mrp_bom.py @@ -0,0 +1,276 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.tests import common + + +class test_mrp_bom(common.TransactionCase): + + def get_bom_ref(self, code, product): + return self.ref_model.search([ + ('bom_id.product_tmpl_id', '=', product.product_tmpl_id.id), + ('name', '=', code), + ])[0] + + def setUp(self): + super(test_mrp_bom, self).setUp() + + self.ref_model = self.env['mrp.bom.reference'] + self.product_model = self.env['product.product'] + self.bom_model = self.env['mrp.bom'] + self.route = self.env.ref('mrp.route_warehouse0_manufacture') + self.production_model = self.env['mrp.production'] + self.lot_model = self.env['stock.production.lot'] + self.wizard_model = self.env['mrp.product.produce'] + + self.product_a = self.product_model.create({ + 'name': 'Product A', + 'route_ids': [(4, self.route.id)], + 'standard_price': 10, + }) + + self.product_b = self.product_model.create({ + 'name': 'Product B', + 'route_ids': [(4, self.route.id)], + 'standard_price': 20, + }) + + self.product_c = self.product_model.create({ + 'name': 'Product C', + 'route_ids': [(4, self.route.id)], + 'standard_price': 30, + }) + + self.product_d = self.product_model.create({ + 'name': 'Product C', + 'route_ids': [(4, self.route.id)], + 'standard_price': 30, + }) + + self.bom_a1 = self.bom_model.create({ + 'product_tmpl_id': self.product_a.product_tmpl_id.id, + 'product_qty': 1, + 'code': 'A-1', + }) + + self.bom_a2 = self.bom_model.create({ + 'product_tmpl_id': self.product_a.product_tmpl_id.id, + 'product_qty': 1, + 'code': 'A-2', + }) + + self.bom_b1 = self.bom_model.create({ + 'product_tmpl_id': self.product_b.product_tmpl_id.id, + 'product_qty': 1, + 'code': 'B-1', + 'bom_line_ids': [(0, 0, { + 'product_id': self.product_a.id, + 'reference_id': self.get_bom_ref('A-1', self.product_a).id, + 'product_qty': 1, + })], + }) + + self.bom_b2 = self.bom_model.create({ + 'product_tmpl_id': self.product_b.product_tmpl_id.id, + 'product_qty': 1, + 'code': 'B-2', + 'bom_line_ids': [(0, 0, { + 'product_id': self.product_a.id, + 'reference_id': self.get_bom_ref('A-2', self.product_a).id, + 'product_qty': 1, + })], + }) + + self.bom_c1 = self.bom_model.create({ + 'product_tmpl_id': self.product_c.product_tmpl_id.id, + 'product_qty': 1, + 'code': 'C-1', + 'bom_line_ids': [ + (0, 0, { + 'product_id': self.product_a.id, + 'reference_id': self.get_bom_ref('A-1', self.product_a).id, + 'product_qty': 2, + 'sequence': 1, + }), + (0, 0, { + 'product_id': self.product_b.id, + 'reference_id': self.get_bom_ref('B-2', self.product_b).id, + 'product_qty': 1, + 'sequence': 2, + }) + ], + }) + + self.bom_c2 = self.bom_model.create({ + 'product_tmpl_id': self.product_c.product_tmpl_id.id, + 'product_qty': 1, + 'code': 'C-2', + 'bom_line_ids': [ + (0, 0, { + 'product_id': self.product_a.id, + 'reference_id': self.get_bom_ref('A-2', self.product_a).id, + 'product_qty': 2, + 'sequence': 1, + }), + (0, 0, { + 'product_id': self.product_b.id, + 'reference_id': self.get_bom_ref('B-1', self.product_b).id, + 'product_qty': 1, + 'sequence': 2, + }) + ], + }) + + self.bom_d1 = self.bom_model.create({ + 'product_tmpl_id': self.product_d.product_tmpl_id.id, + 'product_qty': 1, + 'code': 'D-1', + 'bom_line_ids': [ + (0, 0, { + 'product_id': self.product_b.id, + 'reference_id': self.get_bom_ref('B-1', self.product_b).id, + 'product_qty': 2, + 'sequence': 1, + }), + (0, 0, { + 'product_id': self.product_c.id, + 'reference_id': self.get_bom_ref('C-2', self.product_c).id, + 'product_qty': 2, + 'sequence': 2, + }), + (0, 0, { + 'product_id': self.product_a.id, + 'reference_id': self.get_bom_ref('A-2', self.product_a).id, + 'product_qty': 3, + 'sequence': 3, + }), + ], + }) + + def get_bom_line(self, bom, ref): + for line in bom.bom_line_ids: + if line.reference_id == ref: + return line + return False + + def test_bom_child_line_ids(self): + """ + Test the child_line_ids field when the child bom has one bom lines + """ + line_d1_b1 = self.get_bom_line( + self.bom_d1, self.get_bom_ref('B-1', self.product_b)) + + line_b1_a1 = self.get_bom_line( + self.bom_b1, self.get_bom_ref('A-1', self.product_a)) + + self.assertEqual(len(line_d1_b1.child_line_ids), 1) + + self.assertEqual(line_d1_b1.child_line_ids[0], line_b1_a1) + + def test_bom_child_line_ids_with_2_childs(self): + """ + Test the child_line_ids field when the child bom has 2 bom lines + """ + line_d1_c2 = self.get_bom_line( + self.bom_d1, self.get_bom_ref('C-2', self.product_c)) + + line_c2_a2 = self.get_bom_line( + self.bom_c2, self.get_bom_ref('A-2', self.product_a)) + + line_c2_b1 = self.get_bom_line( + self.bom_c2, self.get_bom_ref('B-1', self.product_b)) + + self.assertEqual(len(line_d1_c2.child_line_ids), 2) + + self.assertEqual(line_d1_c2.child_line_ids[0], line_c2_a2) + self.assertEqual(line_d1_c2.child_line_ids[1], line_c2_b1) + + def test_bom_child_ids_change_child(self): + """ + Test the child_line_ids field when a child is changed + """ + line_d1_c2 = self.get_bom_line( + self.bom_d1, self.get_bom_ref('C-2', self.product_c)) + + self.bom_c2.bom_line_ids[0].unlink() + + self.bom_c2.write({ + 'bom_line_ids': [ + (0, 0, { + 'product_id': self.product_a.id, + 'reference_id': self.get_bom_ref('A-1', self.product_a).id, + 'product_qty': 1, + 'sequence': 3, + }), + ]}) + + line_c2_b1 = self.get_bom_line( + self.bom_c2, self.get_bom_ref('B-1', self.product_b)) + + line_c2_a1 = self.get_bom_line( + self.bom_c2, self.get_bom_ref('A-1', self.product_a)) + + self.assertEqual(len(line_d1_c2.child_line_ids), 2) + self.assertEqual(line_d1_c2.child_line_ids[0], line_c2_b1) + self.assertEqual(line_d1_c2.child_line_ids[1], line_c2_a1) + + def prepare_production(self): + self.production = self.production_model.create({ + 'product_id': self.product_d.id, + 'product_qty': 1, + 'bom_id': self.bom_d1.id, + 'product_uom': self.product_d.uom_id.id + }) + + self.lot = self.lot_model.create({ + 'product_id': self.product_d.id, + }) + + self.wizard = self.wizard_model.create({ + 'product_id': self.product_d.id, + 'product_qty': 1, + 'lot_id': self.lot.id, + }) + + def produce(self): + self.production.action_confirm() + self.production_model.action_produce( + self.production.id, 1, 'consume_produce', self.wizard) + self.production.refresh() + + self.assertEqual( + len(self.production.move_created_ids2), 1) + + self.move_produced = self.production.move_created_ids2[0] + + self.assertEqual( + len(self.move_produced.lot_ids), 1) + + self.lot_produced = self.move_produced.lot_ids + + def test_action_produce(self): + """ + Test that the bom_id field is computed in a lot produced + """ + self.prepare_production() + self.produce() + self.assertEqual(self.lot_produced.bom_id, self.bom_d1) diff --git a/mrp_bom_reference_selection/views/mrp_bom_view.xml b/mrp_bom_reference_selection/views/mrp_bom_view.xml new file mode 100644 index 000000000..04ed63a7e --- /dev/null +++ b/mrp_bom_reference_selection/views/mrp_bom_view.xml @@ -0,0 +1,36 @@ + + + + + + mrp.bom.tree + mrp.bom + + + + + + + + + + + mrp.bom.form + mrp.bom + + + + + + + + + + + + \ No newline at end of file diff --git a/mrp_bom_reference_selection/views/mrp_product_produce_view.xml b/mrp_bom_reference_selection/views/mrp_product_produce_view.xml new file mode 100644 index 000000000..7a6e25e87 --- /dev/null +++ b/mrp_bom_reference_selection/views/mrp_product_produce_view.xml @@ -0,0 +1,24 @@ + + + + + + mrp.product.produce.form + mrp.product.produce + + + + + + + + [ + ('bom_id', 'in', [False, bom_id]), + ('product_id', '=', product_id), + ] + + + + + + \ No newline at end of file diff --git a/mrp_bom_reference_selection/views/stock_production_lot_view.xml b/mrp_bom_reference_selection/views/stock_production_lot_view.xml new file mode 100644 index 000000000..fe82aff0b --- /dev/null +++ b/mrp_bom_reference_selection/views/stock_production_lot_view.xml @@ -0,0 +1,42 @@ + + + + + + stock.production.lot.form + stock.production.lot + + + + + + + + + + stock.production.lot.tree + stock.production.lot + + + + + + + + + + stock.production.lot.filter + stock.production.lot + + + + + + + + + + + + + \ No newline at end of file diff --git a/mrp_bom_reference_selection/wizards/__init__.py b/mrp_bom_reference_selection/wizards/__init__.py new file mode 100644 index 000000000..5e6fc6b8a --- /dev/null +++ b/mrp_bom_reference_selection/wizards/__init__.py @@ -0,0 +1,23 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import mrp_product_produce diff --git a/mrp_bom_reference_selection/wizards/mrp_product_produce.py b/mrp_bom_reference_selection/wizards/mrp_product_produce.py new file mode 100644 index 000000000..b7ee4ad90 --- /dev/null +++ b/mrp_bom_reference_selection/wizards/mrp_product_produce.py @@ -0,0 +1,41 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2015 Savoir-faire Linux +# (). +# +# This program is free software: you can redistribute it and/or modify +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, fields, api + + +class MrpProductProduce(models.TransientModel): + _inherit = 'mrp.product.produce' + + @api.model + def _get_default_bom_id(self): + active_id = self.env.context.get("active_id") + if active_id: + prod = self.env['mrp.production'].browse(active_id) + if prod.bom_id: + return prod.bom_id.id + return False + + bom_id = fields.Many2one( + 'mrp.bom', 'Bill of Material', default=_get_default_bom_id, + readonly=True, + )