From c39007743c78fb775e7e50bb2971ff9053f642ff Mon Sep 17 00:00:00 2001 From: ps-tubtim Date: Thu, 12 Mar 2020 13:54:55 +0700 Subject: [PATCH] [IMP] mrp_unbuild_tracked_raw_material,: black, isort --- .../__manifest__.py | 6 +- .../models/product.py | 5 +- .../models/unbuild.py | 111 ++++++++++-------- .../readme/DESCRIPTION.rst | 2 +- .../readme/ROADMAP.rst | 1 - .../readme/USAGE.rst | 2 +- .../tests/test_unbuild.py | 93 ++++++++------- 7 files changed, 117 insertions(+), 103 deletions(-) diff --git a/mrp_unbuild_tracked_raw_material/__manifest__.py b/mrp_unbuild_tracked_raw_material/__manifest__.py index 930bb35c3..10895f517 100644 --- a/mrp_unbuild_tracked_raw_material/__manifest__.py +++ b/mrp_unbuild_tracked_raw_material/__manifest__.py @@ -8,12 +8,10 @@ "author": "Akretion, Odoo Community Association (OCA)", "website": "https://github.com/OCA/manufacture", "category": "Manufacturing", - "version": "12.0.1.0.0", + "version": "13.0.1.0.0", "license": "AGPL-3", "depends": ["mrp"], "maintainers": ["bealdav"], - "data": [ - "views/product_view.xml", - ], + "data": ["views/product_view.xml"], "installable": True, } diff --git a/mrp_unbuild_tracked_raw_material/models/product.py b/mrp_unbuild_tracked_raw_material/models/product.py index 6d8f102cd..f6238f996 100644 --- a/mrp_unbuild_tracked_raw_material/models/product.py +++ b/mrp_unbuild_tracked_raw_material/models/product.py @@ -10,5 +10,6 @@ class ProductTemplate(models.Model): allow_unbuild_purchased = fields.Boolean( help="If checked, unbuild orders doesn't assume a previous " - "manufacturing order have built this product.\n" - "In this case it's a purchased product and you want unbuild it") + "manufacturing order have built this product.\n" + "In this case it's a purchased product and you want unbuild it" + ) diff --git a/mrp_unbuild_tracked_raw_material/models/unbuild.py b/mrp_unbuild_tracked_raw_material/models/unbuild.py index 65116232f..4bce46332 100644 --- a/mrp_unbuild_tracked_raw_material/models/unbuild.py +++ b/mrp_unbuild_tracked_raw_material/models/unbuild.py @@ -4,18 +4,23 @@ import logging from datetime import datetime + from odoo import _, models from odoo.exceptions import UserError from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FORMAT logger = logging.getLogger(__name__) -MESSAGE = "Some of your components are tracked, you have to specify " \ - "a manufacturing order in order to retrieve " \ - "the correct components." -ALTER_MESSAGE = "Alternatively, you may unbuild '%s' tracked product " \ - "if you set it as '%s'.\n" \ - "In this case lots'll be automatically created for you." +MESSAGE = ( + "Some of your components are tracked, you have to specify " + "a manufacturing order in order to retrieve " + "the correct components." +) +ALTER_MESSAGE = ( + "Alternatively, you may unbuild '%s' tracked product " + "if you set it as '%s'.\n" + "In this case lots'll be automatically created for you." +) class MrpUnbuild(models.Model): @@ -34,13 +39,15 @@ class MrpUnbuild(models.Model): # original condition of this raise is : # any(produce_move.has_tracking != 'none' # and not self.mo_id for produce_move in produce_moves) - if hasattr(err, 'name') and err.name == _(MESSAGE): + if hasattr(err, "name") and err.name == _(MESSAGE): if self.product_id.allow_unbuild_purchased: # In this case it becomes possible to unbuild return self._bypass_tracked_product_without_mo() # Here other option to resolve unbuild conditions new_message = _(ALTER_MESSAGE) % ( - self.product_id.name, _("Unbuild Purchased")) + self.product_id.name, + _("Unbuild Purchased"), + ) # We teach user the 2 conditions that make unbuild possible raise UserError(_("%s \n\n%s") % (err.name, new_message)) # Here is the Odoo native raise @@ -51,23 +58,25 @@ class MrpUnbuild(models.Model): # These moves are already generated with call to # super().action_unbuild(). We catch them consume_move = self.env["stock.move"].search( - [("consume_unbuild_id", "=", self.id)]) - produce_moves = self.env["stock.move"].search( - [("unbuild_id", "=", self.id)]) + [("consume_unbuild_id", "=", self.id)] + ) + produce_moves = self.env["stock.move"].search([("unbuild_id", "=", self.id)]) # Comes from # https://github.com/OCA/ocb/blob/12.0/addons/mrp/models/... # mrp_unbuild.py#L117 - if consume_move.has_tracking != 'none': - self.env['stock.move.line'].create({ - 'move_id': consume_move.id, - 'lot_id': self.lot_id.id, - 'qty_done': consume_move.product_uom_qty, - 'product_id': consume_move.product_id.id, - 'product_uom_id': consume_move.product_uom.id, - 'location_id': consume_move.location_id.id, - 'location_dest_id': consume_move.location_dest_id.id, - }) + if consume_move.has_tracking != "none": + self.env["stock.move.line"].create( + { + "move_id": consume_move.id, + "lot_id": self.lot_id.id, + "qty_done": consume_move.product_uom_qty, + "product_id": consume_move.product_id.id, + "product_uom_id": consume_move.product_uom.id, + "location_id": consume_move.location_id.id, + "location_dest_id": consume_move.location_dest_id.id, + } + ) else: consume_move.quantity_done = consume_move.product_uom_qty consume_move._action_done() @@ -76,42 +85,46 @@ class MrpUnbuild(models.Model): # TODO: Will fail if user do more than one unbuild with lot # on the same MO. Need to check what other unbuild has aready took for produce_move in produce_moves: - if produce_move.has_tracking != 'none': + if produce_move.has_tracking != "none": if produce_move.product_id.tracking == "serial": # TODO - raise UserError(_( - "Unbuild of component of tracked as serial " - "is not supported for now: contact maintainers of " - "'mrp_unbuild_tracked_raw_material' module " - "if you want this feature")) - lot = self.env['stock.production.lot'].create( - self._prepare_lots_for_purchased_unbuild( - produce_move.product_id)) - self.env['stock.move.line'].create({ - 'move_id': produce_move.id, - 'lot_id': lot.id, - 'qty_done': produce_move.product_uom_qty, - 'product_id': produce_move.product_id.id, - 'product_uom_id': produce_move.product_uom.id, - 'location_id': produce_move.location_id.id, - 'location_dest_id': produce_move.location_dest_id.id, - }) + raise UserError( + _( + "Unbuild of component of tracked as serial " + "is not supported for now: contact maintainers of " + "'mrp_unbuild_tracked_raw_material' module " + "if you want this feature" + ) + ) + lot = self.env["stock.production.lot"].create( + self._prepare_lots_for_purchased_unbuild(produce_move.product_id) + ) + self.env["stock.move.line"].create( + { + "move_id": produce_move.id, + "lot_id": lot.id, + "qty_done": produce_move.product_uom_qty, + "product_id": produce_move.product_id.id, + "product_uom_id": produce_move.product_uom.id, + "location_id": produce_move.location_id.id, + "location_dest_id": produce_move.location_dest_id.id, + } + ) else: produce_move.quantity_done = produce_move.product_uom_qty # comes from native code produce_moves._action_done() - produced_move_line_ids = produce_moves.mapped( - 'move_line_ids').filtered(lambda ml: ml.qty_done > 0) + produced_move_line_ids = produce_moves.mapped("move_line_ids").filtered( + lambda ml: ml.qty_done > 0 + ) consume_move.move_line_ids.write( - {'produce_line_ids': [(6, 0, produced_move_line_ids.ids)]}) + {"produce_line_ids": [(6, 0, produced_move_line_ids.ids)]} + ) self.message_post( - body=_("Product has been unbuilt without previous " - "manufacturing order")) - return self.write({'state': 'done'}) + body=_("Product has been unbuilt without previous " "manufacturing order") + ) + return self.write({"state": "done"}) def _prepare_lots_for_purchased_unbuild(self, product): # Customize your data lot with your own code - return { - "name": datetime.now().strftime(DT_FORMAT), - "product_id": product.id, - } + return {"name": datetime.now().strftime(DT_FORMAT), "product_id": product.id} diff --git a/mrp_unbuild_tracked_raw_material/readme/DESCRIPTION.rst b/mrp_unbuild_tracked_raw_material/readme/DESCRIPTION.rst index 3b73611b1..f340cd97a 100644 --- a/mrp_unbuild_tracked_raw_material/readme/DESCRIPTION.rst +++ b/mrp_unbuild_tracked_raw_material/readme/DESCRIPTION.rst @@ -3,7 +3,7 @@ which are not manufactured in the ERP. When you try to do it, you get this warning: -Some of your components are tracked, you have to specify a manufacturing order in order to retrieve the correct components. +Some of your components are tracked, you have to specify a manufacturing order in order to retrieve the correct components. Unfortunately, it doesn't cover all the use cases. diff --git a/mrp_unbuild_tracked_raw_material/readme/ROADMAP.rst b/mrp_unbuild_tracked_raw_material/readme/ROADMAP.rst index 14e25ae53..00031023f 100644 --- a/mrp_unbuild_tracked_raw_material/readme/ROADMAP.rst +++ b/mrp_unbuild_tracked_raw_material/readme/ROADMAP.rst @@ -1,3 +1,2 @@ This module doesn't take account product `allow_unbuild_purchased` checked which use `serial` tracking - diff --git a/mrp_unbuild_tracked_raw_material/readme/USAGE.rst b/mrp_unbuild_tracked_raw_material/readme/USAGE.rst index bbb3ed384..015ace3d8 100644 --- a/mrp_unbuild_tracked_raw_material/readme/USAGE.rst +++ b/mrp_unbuild_tracked_raw_material/readme/USAGE.rst @@ -1,4 +1,4 @@ -# Check 'Allow Unbuild Purchased' field in Inventory tab on product form +# Check 'Allow Unbuild Purchased' field in Inventory tab on product form for any product with a bom you didn't manufactured but you want unbuild. # Go to Manufacturing > Operations > Unbuild Orders diff --git a/mrp_unbuild_tracked_raw_material/tests/test_unbuild.py b/mrp_unbuild_tracked_raw_material/tests/test_unbuild.py index 2fd15850d..fdbb3f2d6 100644 --- a/mrp_unbuild_tracked_raw_material/tests/test_unbuild.py +++ b/mrp_unbuild_tracked_raw_material/tests/test_unbuild.py @@ -2,70 +2,73 @@ # @author David BEAL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from datetime import datetime + # from odoo.tests.common import TransactionCase from odoo.addons.mrp.tests.common import TestMrpCommon -from datetime import datetime class TestUnbuildUnmanufacturedProduct(TestMrpCommon): - def setUp(self, *args, **kwargs): self.loc = self.env.ref("stock.stock_location_stock") super().setUp(*args, **kwargs) def create_data(self): - prd_to_build = self.env["product.product"].create({ - "name": "To unbuild", - "type": "product", - "allow_unbuild_purchased": True, - "tracking": "lot", - }) - prd_to_use1 = self.env["product.product"].create({ - "name": "component 1", - "type": "product", - "tracking": "lot", - }) - prd_to_use2 = self.env["product.product"].create({ - "name": "component 2", - "type": "product", - "tracking": "none", - }) - bom = self.env["mrp.bom"].create({ - "product_id": prd_to_build.id, - "product_tmpl_id": prd_to_build.product_tmpl_id.id, - "product_uom_id": self.uom_unit.id, - "product_qty": 1.0, - "type": "normal", - "bom_line_ids": [ - (0, 0, {"product_id": prd_to_use2.id, - "product_qty": 1}), - (0, 0, {"product_id": prd_to_use1.id, - "product_qty": 2}) - ]}) + prd_to_build = self.env["product.product"].create( + { + "name": "To unbuild", + "type": "product", + "allow_unbuild_purchased": True, + "tracking": "lot", + } + ) + prd_to_use1 = self.env["product.product"].create( + {"name": "component 1", "type": "product", "tracking": "lot"} + ) + prd_to_use2 = self.env["product.product"].create( + {"name": "component 2", "type": "product", "tracking": "none"} + ) + bom = self.env["mrp.bom"].create( + { + "product_id": prd_to_build.id, + "product_tmpl_id": prd_to_build.product_tmpl_id.id, + "product_uom_id": self.uom_unit.id, + "product_qty": 1.0, + "type": "normal", + "bom_line_ids": [ + (0, 0, {"product_id": prd_to_use2.id, "product_qty": 1}), + (0, 0, {"product_id": prd_to_use1.id, "product_qty": 2}), + ], + } + ) return (bom, prd_to_build, prd_to_use1, prd_to_use2) def test_unbuild(self): """ """ bom, prd_to_build, prd_to_use1, prd_to_use2 = self.create_data() - lot = self.env['stock.production.lot'].create( - {"name": "%s" % datetime.now(), - "product_id": prd_to_build.id}) + lot = self.env["stock.production.lot"].create( + {"name": "%s" % datetime.now(), "product_id": prd_to_build.id} + ) self.env["stock.quant"]._update_available_quantity( - prd_to_build, self.loc, 10, lot_id=lot) - unbuild = self.env["mrp.unbuild"].create({ - "product_id": prd_to_build.id, - "bom_id": bom.id, - "product_qty": 1.0, - "lot_id": lot.id, - "product_uom_id": self.uom_unit.id, - }) + prd_to_build, self.loc, 10, lot_id=lot + ) + unbuild = self.env["mrp.unbuild"].create( + { + "product_id": prd_to_build.id, + "bom_id": bom.id, + "product_qty": 1.0, + "lot_id": lot.id, + "product_uom_id": self.uom_unit.id, + } + ) unbuild.action_validate() self._check_qty(9, prd_to_build) self._check_qty(2, prd_to_use1) self._check_qty(1, prd_to_use2) def _check_qty(self, qty, product): - self.assertEqual(self.env["stock.quant"]._get_available_quantity( - product, self.loc), qty, - "You should have the %s product '%s' in stock" % ( - qty, product.name)) + self.assertEqual( + self.env["stock.quant"]._get_available_quantity(product, self.loc), + qty, + "You should have the {} product '{}' in stock".format(qty, product.name), + )