From 5e6367cdeb2b47c2f92cce3282c34dbafe00a6b6 Mon Sep 17 00:00:00 2001 From: dufresnedavid Date: Wed, 25 Feb 2015 09:57:20 -0500 Subject: [PATCH 1/5] [Add] mrp_bom_reference_selection --- mrp_bom_reference_selection/README.rst | 56 +++++++++++++++ mrp_bom_reference_selection/__init__.py | 33 +++++++++ mrp_bom_reference_selection/__openerp__.py | 43 +++++++++++ mrp_bom_reference_selection/i18n/fr.po | 68 ++++++++++++++++++ .../i18n/mrp_bom_reference_selection.pot | 68 ++++++++++++++++++ .../models/__init__.py | 27 +++++++ mrp_bom_reference_selection/models/mrp_bom.py | 37 ++++++++++ .../models/mrp_bom_line.py | 71 +++++++++++++++++++ .../models/mrp_bom_reference.py | 34 +++++++++ .../security/ir.model.access.csv | 2 + .../views/mrp_bom_view.xml | 36 ++++++++++ 11 files changed, 475 insertions(+) create mode 100644 mrp_bom_reference_selection/README.rst create mode 100644 mrp_bom_reference_selection/__init__.py create mode 100644 mrp_bom_reference_selection/__openerp__.py create mode 100644 mrp_bom_reference_selection/i18n/fr.po create mode 100644 mrp_bom_reference_selection/i18n/mrp_bom_reference_selection.pot create mode 100644 mrp_bom_reference_selection/models/__init__.py create mode 100644 mrp_bom_reference_selection/models/mrp_bom.py create mode 100644 mrp_bom_reference_selection/models/mrp_bom_line.py create mode 100644 mrp_bom_reference_selection/models/mrp_bom_reference.py create mode 100644 mrp_bom_reference_selection/security/ir.model.access.csv create mode 100644 mrp_bom_reference_selection/views/mrp_bom_view.xml diff --git a/mrp_bom_reference_selection/README.rst b/mrp_bom_reference_selection/README.rst new file mode 100644 index 000000000..88410ab57 --- /dev/null +++ b/mrp_bom_reference_selection/README.rst @@ -0,0 +1,56 @@ +MRP Bill of Material Reference Selection +======================================== + +This module was written to extend mrp features. +It delivers new feature to select the component in a bom when you have several bom for one product. + +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 + +Known issues / Roadmap +====================== + +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..7f4f3afdc --- /dev/null +++ b/mrp_bom_reference_selection/__init__.py @@ -0,0 +1,33 @@ +# -*- 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 openerp import SUPERUSER_ID + + +def set_bill_of_material_references(cr, registry): + 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..1c665c779 --- /dev/null +++ b/mrp_bom_reference_selection/__openerp__.py @@ -0,0 +1,43 @@ +# -*- 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.0', + 'author': 'Savoir-faire Linux', + 'license': 'AGPL-3', + 'category': 'Others', + 'summary': 'Bill of Material Selection Reference', + 'depends': [ + 'mrp', + ], + 'external_dependencies': { + 'python': [], + }, + 'data': [ + 'views/mrp_bom_view.xml', + 'security/ir.model.access.csv', + ], + '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..7143231a8 --- /dev/null +++ b/mrp_bom_reference_selection/models/__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 ( + mrp_bom, + mrp_bom_line, + mrp_bom_reference, +) 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..555dd0bb9 --- /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 BillOfMaterial(models.Model): + _inherit = 'mrp.bom' + + @api.model + def create(self, vals): + res = super(BillOfMaterial, 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..7737fd469 --- /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 BillOfMaterialLine(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..9d7cdee2c --- /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 BillOfMaterialReference(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/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/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 From 05b50b237af78127041bfd4eef8089b9c227ccc8 Mon Sep 17 00:00:00 2001 From: dufresnedavid Date: Fri, 27 Feb 2015 13:31:26 -0500 Subject: [PATCH 2/5] Remove redondant parts in readme.rst --- mrp_bom_reference_selection/README.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mrp_bom_reference_selection/README.rst b/mrp_bom_reference_selection/README.rst index 88410ab57..99ddd7441 100644 --- a/mrp_bom_reference_selection/README.rst +++ b/mrp_bom_reference_selection/README.rst @@ -1,19 +1,13 @@ MRP Bill of Material Reference Selection ======================================== -This module was written to extend mrp features. -It delivers new feature to select the component in a bom when you have several bom for one product. +This module delivers new feature to select the component in a bom when you have several bom for one product. 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 ===== From 1e8f38dd82550c1ccfd165218f87acef85606f41 Mon Sep 17 00:00:00 2001 From: dufresnedavid Date: Thu, 19 Mar 2015 11:15:09 -0400 Subject: [PATCH 3/5] Add unit tests and add reference to the bom on production lots --- mrp_bom_reference_selection/README.rst | 11 +- mrp_bom_reference_selection/__init__.py | 1 + mrp_bom_reference_selection/__openerp__.py | 4 +- .../models/__init__.py | 2 + mrp_bom_reference_selection/models/mrp_bom.py | 4 +- .../models/mrp_bom_line.py | 2 +- .../models/mrp_bom_reference.py | 2 +- .../models/mrp_production.py | 45 +++ .../models/stock_production_lot.py | 29 ++ mrp_bom_reference_selection/tests/__init__.py | 27 ++ .../tests/test_mrp_bom.py | 276 ++++++++++++++++++ .../views/mrp_product_produce_view.xml | 24 ++ .../views/stock_production_lot_view.xml | 42 +++ .../wizards/__init__.py | 23 ++ .../wizards/mrp_product_produce.py | 41 +++ 15 files changed, 525 insertions(+), 8 deletions(-) create mode 100644 mrp_bom_reference_selection/models/mrp_production.py create mode 100644 mrp_bom_reference_selection/models/stock_production_lot.py create mode 100644 mrp_bom_reference_selection/tests/__init__.py create mode 100644 mrp_bom_reference_selection/tests/test_mrp_bom.py create mode 100644 mrp_bom_reference_selection/views/mrp_product_produce_view.xml create mode 100644 mrp_bom_reference_selection/views/stock_production_lot_view.xml create mode 100644 mrp_bom_reference_selection/wizards/__init__.py create mode 100644 mrp_bom_reference_selection/wizards/mrp_product_produce.py diff --git a/mrp_bom_reference_selection/README.rst b/mrp_bom_reference_selection/README.rst index 99ddd7441..bcabe5a10 100644 --- a/mrp_bom_reference_selection/README.rst +++ b/mrp_bom_reference_selection/README.rst @@ -1,13 +1,20 @@ MRP Bill of Material Reference Selection ======================================== -This module delivers new feature to select the component in a bom when you have several bom for one product. +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 contain 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 ===== @@ -18,8 +25,6 @@ To use this module, you need to : - 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 -Known issues / Roadmap -====================== Credits ======= diff --git a/mrp_bom_reference_selection/__init__.py b/mrp_bom_reference_selection/__init__.py index 7f4f3afdc..fd3ec9075 100644 --- a/mrp_bom_reference_selection/__init__.py +++ b/mrp_bom_reference_selection/__init__.py @@ -21,6 +21,7 @@ ############################################################################## from . import models +from . import wizards from openerp import SUPERUSER_ID diff --git a/mrp_bom_reference_selection/__openerp__.py b/mrp_bom_reference_selection/__openerp__.py index 1c665c779..f28afd5f4 100644 --- a/mrp_bom_reference_selection/__openerp__.py +++ b/mrp_bom_reference_selection/__openerp__.py @@ -34,8 +34,10 @@ 'python': [], }, 'data': [ - 'views/mrp_bom_view.xml', '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, diff --git a/mrp_bom_reference_selection/models/__init__.py b/mrp_bom_reference_selection/models/__init__.py index 7143231a8..472d7c654 100644 --- a/mrp_bom_reference_selection/models/__init__.py +++ b/mrp_bom_reference_selection/models/__init__.py @@ -24,4 +24,6 @@ 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 index 555dd0bb9..550fa197a 100644 --- a/mrp_bom_reference_selection/models/mrp_bom.py +++ b/mrp_bom_reference_selection/models/mrp_bom.py @@ -23,12 +23,12 @@ from openerp import models, fields, api -class BillOfMaterial(models.Model): +class MrpBillOfMaterial(models.Model): _inherit = 'mrp.bom' @api.model def create(self, vals): - res = super(BillOfMaterial, self).create(vals) + res = super(MrpBillOfMaterial, self).create(vals) if not res.reference_id: self.env['mrp.bom.reference'].create({'bom_id': res.id}) return res diff --git a/mrp_bom_reference_selection/models/mrp_bom_line.py b/mrp_bom_reference_selection/models/mrp_bom_line.py index 7737fd469..5f2c73a35 100644 --- a/mrp_bom_reference_selection/models/mrp_bom_line.py +++ b/mrp_bom_reference_selection/models/mrp_bom_line.py @@ -23,7 +23,7 @@ from openerp import models, fields, api -class BillOfMaterialLine(models.Model): +class MrpBillOfMaterialLine(models.Model): _inherit = 'mrp.bom.line' reference_id = fields.Many2one('mrp.bom.reference', 'Ref') diff --git a/mrp_bom_reference_selection/models/mrp_bom_reference.py b/mrp_bom_reference_selection/models/mrp_bom_reference.py index 9d7cdee2c..8059c25f9 100644 --- a/mrp_bom_reference_selection/models/mrp_bom_reference.py +++ b/mrp_bom_reference_selection/models/mrp_bom_reference.py @@ -23,7 +23,7 @@ from openerp import models, fields -class BillOfMaterialReference(models.Model): +class MrpBillOfMaterialReference(models.Model): _name = 'mrp.bom.reference' _description = 'MRP Bill of Material Reference' 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..8fad0c9ec --- /dev/null +++ b/mrp_bom_reference_selection/models/mrp_production.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 . +# +############################################################################## + +from openerp import models, api + + +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) + + prod_lots = production.move_created_ids2.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/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_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, + ) From de4f9d69b2090744716b6e9b70b7b9605f2be858 Mon Sep 17 00:00:00 2001 From: dufresnedavid Date: Tue, 31 Mar 2015 13:37:20 -0400 Subject: [PATCH 4/5] Add docstring to post_init_hook --- mrp_bom_reference_selection/README.rst | 2 +- mrp_bom_reference_selection/__init__.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mrp_bom_reference_selection/README.rst b/mrp_bom_reference_selection/README.rst index bcabe5a10..2c106cbab 100644 --- a/mrp_bom_reference_selection/README.rst +++ b/mrp_bom_reference_selection/README.rst @@ -3,7 +3,7 @@ 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 contain a reference to the bill of material used to compute the lot. +Produced lot contains a reference to the bill of material used to compute the lot. Installation ============ diff --git a/mrp_bom_reference_selection/__init__.py b/mrp_bom_reference_selection/__init__.py index fd3ec9075..0083786b3 100644 --- a/mrp_bom_reference_selection/__init__.py +++ b/mrp_bom_reference_selection/__init__.py @@ -26,6 +26,11 @@ 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, []) From 342e0f567b701c14d462a3a4da7bf3944d76afd7 Mon Sep 17 00:00:00 2001 From: Jordi Riera Date: Wed, 1 Apr 2015 13:12:39 -0400 Subject: [PATCH 5/5] [FIX] error raise if the manufacturing order produce in more than 1 move. --- mrp_bom_reference_selection/__openerp__.py | 2 +- .../models/mrp_production.py | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mrp_bom_reference_selection/__openerp__.py b/mrp_bom_reference_selection/__openerp__.py index f28afd5f4..d2b272cf7 100644 --- a/mrp_bom_reference_selection/__openerp__.py +++ b/mrp_bom_reference_selection/__openerp__.py @@ -22,7 +22,7 @@ { 'name': 'Bill of Material Selection Reference', - 'version': '1.0', + 'version': '1.1', 'author': 'Savoir-faire Linux', 'license': 'AGPL-3', 'category': 'Others', diff --git a/mrp_bom_reference_selection/models/mrp_production.py b/mrp_bom_reference_selection/models/mrp_production.py index 8fad0c9ec..931a7cd73 100644 --- a/mrp_bom_reference_selection/models/mrp_production.py +++ b/mrp_bom_reference_selection/models/mrp_production.py @@ -20,18 +20,19 @@ # ############################################################################## +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 + 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( @@ -39,7 +40,8 @@ class MrpProduction(models.Model): production = self.browse(production_id) - prod_lots = production.move_created_ids2.lot_ids - prod_lots.write({'bom_id': production.bom_id.id}) + for move in production.move_created_ids2: + prod_lots = move.lot_ids + prod_lots.write({'bom_id': production.bom_id.id}) return res