diff --git a/product_quick_bom/README.rst b/product_quick_bom/README.rst index 1c012bd77..06a74fa74 100644 --- a/product_quick_bom/README.rst +++ b/product_quick_bom/README.rst @@ -1,61 +1,76 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 - ================= Product Quick Bom ================= -This module was written to create quickly the bom for your product. -Indeed in the product form you now have a new tab "bom" that give you the posibility -to add the bom line directly here +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-oca%2Fmanufacture-lightgray.png?logo=github + :target: https://github.com/oca/manufacture/tree/12.0/product_quick_bom + :alt: oca/manufacture + +|badge1| |badge2| |badge3| + +This module was written to be able to quickly create the BoM for your product. There is a new "Bill of Materials" tab in the product form view that allows the user to add a BoM and its lines directly. + +Beware that this functionality is relevant only when one product template has one Bill of Materials, and works only for product templates for simplicity's sake. + +**Table of contents** + +.. contents:: + :local: Usage ===== -To use this module, you need to: - -* Go to a product form, click on edit, add a line in the bom tab and see that a bom - linked to the product have been created. - -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/129/10.0 - -.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt -.. branch is "8.0" for example - -For further information, please visit: - -* https://www.odoo.com/forum/help-1 - +Go to product form view, click on edit, use the BoM lines field. If there is no BoM for the product yet, you can quickly create one by clicking on the "Create BoM" button. Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* Akretion + Contributors ------------- +~~~~~~~~~~~~ -* Sébastien Beau +* Sébastien Beau +* Kevin Khao -Maintainer ----------- +Maintainers +~~~~~~~~~~~ -.. image:: https://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: https://odoo-community.org +.. |maintainer-sebastienbeau| image:: https://github.com/sebastienbeau.png?size=40px + :target: https://github.com/sebastienbeau + :alt: sebastienbeau +.. |maintainer-kevinkhao| image:: https://github.com/kevinkhao.png?size=40px + :target: https://github.com/kevinkhao + :alt: kevinkhao -This module is maintained by the OCA. +Current maintainers: -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. +|maintainer-sebastienbeau| |maintainer-kevinkhao| -To contribute to this module, please visit http://odoo-community.org. +This module is part of the `oca/manufacture `_ project on GitHub. + +You are welcome to contribute. diff --git a/product_quick_bom/__init__.py b/product_quick_bom/__init__.py index 8ebf94e87..1732d15e5 100644 --- a/product_quick_bom/__init__.py +++ b/product_quick_bom/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2015 Akretion (http://www.akretion.com). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/product_quick_bom/__manifest__.py b/product_quick_bom/__manifest__.py index a0f27800e..aa4c0cedb 100644 --- a/product_quick_bom/__manifest__.py +++ b/product_quick_bom/__manifest__.py @@ -1,22 +1,17 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2015 Akretion (http://www.akretion.com). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Product Quick Bom", "summary": "Create the bom directly from the product", - "version": "10.0.1.0.0", + "version": "12.0.1.0.0", "category": "mrp", - "website": "https://odoo-community.org/", + "website": "https://github.com/OCA/manufacture", "author": "Akretion, Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, "installable": True, - "depends": [ - "mrp", - ], - "data": [ - "views/product_view.xml", - ], - + "depends": ["mrp"], + "data": ["views/product_view.xml"], + "maintainers": ["sebastienbeau", "kevinkhao"], } diff --git a/product_quick_bom/models/__init__.py b/product_quick_bom/models/__init__.py index e55d597f7..c60fd5138 100644 --- a/product_quick_bom/models/__init__.py +++ b/product_quick_bom/models/__init__.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2015 Akretion (http://www.akretion.com). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import product -from . import bom diff --git a/product_quick_bom/models/bom.py b/product_quick_bom/models/bom.py deleted file mode 100644 index 9e3313ab2..000000000 --- a/product_quick_bom/models/bom.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2015 Akretion (http://www.akretion.com). -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import fields, models, _ - - -class MrpBom(models.Model): - _inherit = 'mrp.bom' - - _sql_constraint = ( - 'uniq_product_template', - 'uniq(product_tmpl_id)', - _('You can only have one Bom per product template'), - ) - - -class MrpBomLine(models.Model): - _inherit = 'mrp.bom.line' - - product_tmpl_id = fields.Many2one( - comodel_name='product.template', - related='bom_id.product_tmpl_id', - readonly=True, - store=True) diff --git a/product_quick_bom/models/product.py b/product_quick_bom/models/product.py index 4eca5dd82..e6afef532 100644 --- a/product_quick_bom/models/product.py +++ b/product_quick_bom/models/product.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2015 Akretion (http://www.akretion.com). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). @@ -6,59 +5,33 @@ from odoo import api, fields, models class ProductTemplate(models.Model): - _inherit = 'product.template' + _inherit = "product.template" - bom_line_ids = fields.One2many( - comodel_name='mrp.bom.line', - inverse_name='product_tmpl_id', - string='Bom Line', - help='If your product is manufactured you can select ' - 'here the component to produce them') - - @api.model - def _extract_bom_line(self, vals): - return vals.pop('bom_line_ids', {}) - - @api.multi - def _prepare_bom_vals(self, vals): - self.ensure_one() - return { - 'product_tmpl_id': self.id, - 'bom_line_ids': vals, - } - - @api.multi - def _process_bom_vals(self, vals): - for record in self: - if record.bom_ids: - record.bom_ids[0].write({'bom_line_ids': vals}) + @api.depends("bom_ids") + def _compute_bom_id(self): + for rec in self: + if len(rec.bom_ids.ids) == 1: + rec.bom_id = rec.bom_ids[0] else: - record.env['mrp.bom'].create(self._prepare_bom_vals(vals)) + rec.bom_id = self.env["mrp.bom"] - @api.model - def create(self, vals): - bom_vals = self._extract_bom_line(vals) - record = super(ProductTemplate, self).create(vals) - if bom_vals: - record._process_bom_vals(bom_vals) - return record + bom_id = fields.Many2one( + "mrp.bom", + string="Bill of Materials (quick access)", + compute=_compute_bom_id, + store=True, + ) - @api.multi - def write(self, vals): - """ default_type is in product and bom so _context ovewrite the default - value for bom with typ:'product' need to becarefull - """ - bom_vals = self._extract_bom_line(vals) - res = super(ProductTemplate, self).write(vals) - if bom_vals: - ctx = self._context.copy() - ctx.pop('default_type', None) - self.with_context(ctx)._process_bom_vals(bom_vals) - return res + # In case there is no bom_id yet, to simplify logic + # we just add a button to create one + def button_create_bom(self): + self.ensure_one() + vals = { + "product_tmpl_id": self.id, + "type": "normal", + } + self.env["mrp.bom"].create(vals) - @api.multi - def unlink(self): - for record in self: - if record.bom_ids: - record.bom_ids.unlink() - return super(ProductTemplate, self).unlink() + specific_bom_line_ids = fields.One2many( + related="bom_id.bom_line_ids", readonly=False + ) diff --git a/product_quick_bom/readme/CONTRIBUTORS.rst b/product_quick_bom/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..ff1ec5950 --- /dev/null +++ b/product_quick_bom/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Sébastien Beau +* Kevin Khao diff --git a/product_quick_bom/readme/DESCRIPTION.rst b/product_quick_bom/readme/DESCRIPTION.rst new file mode 100644 index 000000000..2af97755a --- /dev/null +++ b/product_quick_bom/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +This module was written to be able to quickly create the BoM for your product. There is a new "Bill of Materials" tab in the product form view that allows the user to add a BoM and its lines directly. + +Beware that this functionality is relevant only when one product template has one Bill of Materials, and works only for product templates for simplicity's sake. diff --git a/product_quick_bom/readme/USAGE.rst b/product_quick_bom/readme/USAGE.rst new file mode 100644 index 000000000..c94b325ec --- /dev/null +++ b/product_quick_bom/readme/USAGE.rst @@ -0,0 +1 @@ +Go to product form view, click on edit, use the BoM lines field. If there is no BoM for the product yet, you can quickly create one by clicking on the "Create BoM" button. diff --git a/product_quick_bom/static/description/index.html b/product_quick_bom/static/description/index.html new file mode 100644 index 000000000..70312a41f --- /dev/null +++ b/product_quick_bom/static/description/index.html @@ -0,0 +1,423 @@ + + + + + + +Product Quick Bom + + + +
+

Product Quick Bom

+ + +

Beta License: AGPL-3 oca/manufacture

+

This module was written to be able to quickly create the BoM for your product. There is a new “Bill of Materials” tab in the product form view that allows the user to add a BoM and its lines directly.

+

Beware that this functionality is relevant only when one product template has one Bill of Materials, and works only for product templates for simplicity’s sake.

+

Table of contents

+ +
+

Usage

+

Go to product form view, click on edit, use the BoM lines field. If there is no BoM for the product yet, you can quickly create one by clicking on the “Create BoM” button.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

Current maintainers:

+

sebastienbeau kevinkhao

+

This module is part of the oca/manufacture project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/product_quick_bom/tests/test_quick_bom.py b/product_quick_bom/tests/test_quick_bom.py index 4893a8bde..c2e01afba 100644 --- a/product_quick_bom/tests/test_quick_bom.py +++ b/product_quick_bom/tests/test_quick_bom.py @@ -1,57 +1,57 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2015 Akretion (http://www.akretion.com). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo.tests.common import TransactionCase import logging + _logger = logging.getLogger(__name__) class TestQuickBom(TransactionCase): - def setUp(self): - super(TestQuickBom, self).setUp() - self.computer = self.env.ref( - 'product.product_product_5_product_template') - self.ram = self.env.ref('product.product_product_13_product_template') - self.hard_drive = self.env.ref( - 'product.product_product_17_product_template') - self.cpu = self.env.ref('product.product_product_22_product_template') + # as we test new BoMs that must not already exist in demo data, + # bolt + screw + ply = lamp + super().setUp() + self.prd_1 = self.env.ref("mrp.product_product_computer_desk_bolt") + self.prd_2 = self.env.ref("mrp.product_product_computer_desk_screw") + self.prd_3 = self.env.ref("mrp.product_product_wood_ply") + self.tmpl_4 = self.env.ref( + "product.product_delivery_02_product_template" + ) def test_create_bom(self): - self.computer.write({'bom_line_ids': [ - (0, 0, {'product_id': self.ram.id, 'product_qty': 2, }), - (0, 0, {'product_id': self.hard_drive.id, 'product_qty': 2, }), - (0, 0, {'product_id': self.cpu.id, 'product_qty': 1, })]}) - bom = self.computer.bom_ids - self.assertEqual(self.computer.id, bom.product_tmpl_id.id) - self.assertEqual(bom.bom_line_ids[0].product_id.id, self.ram.id) + self.tmpl_4.button_create_bom() + self.tmpl_4.write( + { + "specific_bom_line_ids": [ + (0, 0, {"product_id": self.prd_1.id, "product_qty": 2}), + (0, 0, {"product_id": self.prd_2.id, "product_qty": 2}), + (0, 0, {"product_id": self.prd_3.id, "product_qty": 1}), + ] + } + ) + bom = self.tmpl_4.bom_id + self.assertEqual(self.tmpl_4.id, bom.product_tmpl_id.id) + self.assertEqual(bom.bom_line_ids[0].product_id.id, self.prd_1.id) self.assertEqual(bom.bom_line_ids[0].product_qty, 2) - self.assertEqual(bom.bom_line_ids[1].product_id.id, self.hard_drive.id) + self.assertEqual(bom.bom_line_ids[1].product_id.id, self.prd_2.id) self.assertEqual(bom.bom_line_ids[1].product_qty, 2) - self.assertEqual(bom.bom_line_ids[2].product_id.id, self.cpu.id) + self.assertEqual(bom.bom_line_ids[2].product_id.id, self.prd_3.id) self.assertEqual(bom.bom_line_ids[2].product_qty, 1) def test_read_bom(self): - bom = self.env['mrp.bom'].create({ - 'type': 'normal', - 'product_tmpl_id': self.computer.id}) - bomline1 = self.env['mrp.bom.line'].create({ - 'product_id': self.ram.id, - 'product_qty': 2, - 'bom_id': bom.id, - }) - bomline2 = self.env['mrp.bom.line'].create({ - 'product_id': self.hard_drive.id, - 'product_qty': 2, - 'bom_id': bom.id, - }) - bomline3 = self.env['mrp.bom.line'].create({ - 'product_id': self.cpu.id, - 'product_qty': 1, - 'bom_id': bom.id, - }) - - self.assertTrue(bomline1 in self.computer.bom_line_ids) - self.assertTrue(bomline2 in self.computer.bom_line_ids) - self.assertTrue(bomline3 in self.computer.bom_line_ids) + bom = self.env["mrp.bom"].create( + {"type": "normal", "product_tmpl_id": self.tmpl_4.id} + ) + bomline1 = self.env["mrp.bom.line"].create( + {"product_id": self.prd_1.id, "product_qty": 2, "bom_id": bom.id} + ) + bomline2 = self.env["mrp.bom.line"].create( + {"product_id": self.prd_2.id, "product_qty": 2, "bom_id": bom.id} + ) + bomline3 = self.env["mrp.bom.line"].create( + {"product_id": self.prd_3.id, "product_qty": 1, "bom_id": bom.id} + ) + self.assertTrue(bomline1 in self.tmpl_4.specific_bom_line_ids) + self.assertTrue(bomline2 in self.tmpl_4.specific_bom_line_ids) + self.assertTrue(bomline3 in self.tmpl_4.specific_bom_line_ids) diff --git a/product_quick_bom/views/product_view.xml b/product_quick_bom/views/product_view.xml index 804c1267c..4e6a6bc34 100644 --- a/product_quick_bom/views/product_view.xml +++ b/product_quick_bom/views/product_view.xml @@ -1,20 +1,31 @@ - - product.template - - - - - - - - - - - - - - - + + product.template + + + + + + + + + + + + + + + + +