[14.0][MIG] mrp_production_grouped_by_product

This commit is contained in:
Lois Rilo
2021-11-16 09:49:50 +01:00
parent 4f4760bdbb
commit f2181bb7d0
5 changed files with 52 additions and 15 deletions

View File

@@ -5,7 +5,7 @@
{ {
"name": "Production Grouped By Product", "name": "Production Grouped By Product",
"version": "13.0.1.0.2", "version": "14.0.1.0.0",
"category": "MRP", "category": "MRP",
"author": "Tecnativa, " "Odoo Community Association (OCA)", "author": "Tecnativa, " "Odoo Community Association (OCA)",
"website": "https://github.com/OCA/manufacture", "website": "https://github.com/OCA/manufacture",

View File

@@ -25,6 +25,18 @@ class MrpProduction(models.Model):
self.move_finished_ids.move_dest_ids = vals["move_dest_ids"] self.move_finished_ids.move_dest_ids = vals["move_dest_ids"]
self.write(new_vals) self.write(new_vals)
def _get_grouping_target_vals(self):
return {
"product_id": self.product_id.id,
"picking_type_id": self.picking_type_id.id,
"bom_id": self.bom_id.id,
"company_id": self.company_id.id,
"state": self.state,
"date_deadline": self.date_deadline,
}
# NOTE: when extending this logic, remember to also adapt
# `_get_grouping_target_vals` accordingly.
def _get_grouping_target_domain(self, vals): def _get_grouping_target_domain(self, vals):
"""Get the domain for searching manufacturing orders that can match """Get the domain for searching manufacturing orders that can match
with the criteria we want to use. with the criteria we want to use.
@@ -33,20 +45,21 @@ class MrpProduction(models.Model):
:return: Odoo domain. :return: Odoo domain.
""" """
if "routing_id" not in vals and "bom_id" in vals: bom_has_routing = bool(self.env["mrp.bom"].browse(vals["bom_id"]).operation_ids)
bom = self.env["mrp.bom"].browse(vals["bom_id"])
vals["routing_id"] = bom.routing_id.id
domain = [ domain = [
("product_id", "=", vals["product_id"]), ("product_id", "=", vals["product_id"]),
("picking_type_id", "=", vals["picking_type_id"]), ("picking_type_id", "=", vals["picking_type_id"]),
("bom_id", "=", vals.get("bom_id", False)), ("bom_id", "=", vals.get("bom_id", False)),
("routing_id", "=", vals.get("routing_id", False)),
("company_id", "=", vals.get("company_id", False)), ("company_id", "=", vals.get("company_id", False)),
("state", "in", ["draft", "confirmed"]), ("state", "in", ["draft", "confirmed"]),
] ]
if not vals.get("date_planned_finished"): if bom_has_routing:
domain.append(("workorder_ids", "!=", False))
else:
domain.append(("workorder_ids", "=", False))
if not vals.get("date_deadline"):
return domain return domain
date = fields.Datetime.from_string(vals["date_planned_finished"]) date = fields.Datetime.from_string(vals["date_deadline"])
pt = self.env["stock.picking.type"].browse(vals["picking_type_id"]) pt = self.env["stock.picking.type"].browse(vals["picking_type_id"])
if date.hour < pt.mo_grouping_max_hour: if date.hour < pt.mo_grouping_max_hour:
date_end = date.replace(hour=pt.mo_grouping_max_hour, minute=0, second=0) date_end = date.replace(hour=pt.mo_grouping_max_hour, minute=0, second=0)
@@ -56,8 +69,8 @@ class MrpProduction(models.Model):
) )
date_start = date_end - relativedelta(days=pt.mo_grouping_interval) date_start = date_end - relativedelta(days=pt.mo_grouping_interval)
domain += [ domain += [
("date_planned_finished", ">", fields.Datetime.to_string(date_start)), ("date_deadline", ">", fields.Datetime.to_string(date_start)),
("date_planned_finished", "<=", fields.Datetime.to_string(date_end)), ("date_deadline", "<=", fields.Datetime.to_string(date_end)),
] ]
return domain return domain
@@ -89,3 +102,20 @@ class MrpProduction(models.Model):
mo._post_mo_merging_adjustments(vals) mo._post_mo_merging_adjustments(vals)
return mo return mo
return super(MrpProduction, self).create(vals) return super(MrpProduction, self).create(vals)
def _create_workorder(self):
# We need to skip the creation of workorders during `_run_manufacture`.
# It is not possible to pass a context from the `_post_mo_merging_adjustments`
# because the create is called with sudo in `_run_manufacture` and that
# creates a new context that does not reach `_create_workorder` call.
context = self.env.context
to_create_wos = self
if context.get("group_mo_by_product") and (
not config["test_enable"] or context.get("test_group_mo")
):
for rec in self:
vals = self._get_grouping_target_vals()
mo = self._find_grouping_target(vals)
if mo:
to_create_wos -= rec
return super(MrpProduction, to_create_wos)._create_workorder()

View File

@@ -1,4 +1,4 @@
* Tecnativa <https://www.tecnativa.com>__ * `Tecnativa <https://www.tecnativa.com>`__
* David Vidal * David Vidal
* Pedro M. Baeza * Pedro M. Baeza
@@ -6,3 +6,7 @@
* `Ecosoft <https://ecosoft.co.th/>`__: * `Ecosoft <https://ecosoft.co.th/>`__:
* Pimolnat Suntian <pimolnats@ecosoft.co.th> * Pimolnat Suntian <pimolnats@ecosoft.co.th>
* `ForgeFlow <https://www.forgeflow.com/>`__:
* Lois Rilo <lois.rilo@forgeflow.com>

View File

@@ -1,3 +1,8 @@
14.0.1.0.0 (2021-11-16)
~~~~~~~~~~~~~~~~~~~~~~~
* [MIG] Migration to v14.
13.0.1.0.0 (2020-01-09) 13.0.1.0.0 (2020-01-09)
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -1,6 +1,7 @@
# Copyright 2018 Tecnativa - David Vidal # Copyright 2018 Tecnativa - David Vidal
# Copyright 2018 Tecnativa - Pedro M. Baeza # Copyright 2018 Tecnativa - Pedro M. Baeza
# Copyright 2019 Rubén Bravo <rubenred18@gmail.com> # Copyright 2019 Rubén Bravo <rubenred18@gmail.com>
# Copyright 2021 ForgeFlow S.L. (http://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import exceptions from odoo import exceptions
@@ -60,7 +61,7 @@ class TestProductionGroupedByProduct(common.SavepointCase):
"product_id": cls.product1.id, "product_id": cls.product1.id,
"product_qty": 2, "product_qty": 2,
"product_uom_id": cls.product1.uom_id.id, "product_uom_id": cls.product1.uom_id.id,
"date_planned_finished": "2018-06-01 15:00:00", "date_deadline": "2018-06-01 15:00:00",
"date_planned_start": "2018-06-01 15:00:00", "date_planned_start": "2018-06-01 15:00:00",
} }
) )
@@ -79,7 +80,6 @@ class TestProductionGroupedByProduct(common.SavepointCase):
"procure_method": "make_to_order", "procure_method": "make_to_order",
"warehouse_id": cls.warehouse.id, "warehouse_id": cls.warehouse.id,
"date": "2018-06-01 18:00:00", "date": "2018-06-01 18:00:00",
"date_expected": "2018-06-01 18:00:00",
} }
) )
@@ -99,9 +99,7 @@ class TestProductionGroupedByProduct(common.SavepointCase):
self.assertEqual(mo.product_qty, 12) self.assertEqual(mo.product_qty, 12)
def test_mo_other_date(self): def test_mo_other_date(self):
self.move.write( self.move.write({"date": "2018-06-01 20:01:00"})
{"date_expected": "2018-06-01 20:01:00", "date": "2018-06-01 20:01:00"}
)
self.move.with_context(test_group_mo=True)._action_confirm(merge=False) self.move.with_context(test_group_mo=True)._action_confirm(merge=False)
self.ProcurementGroup.with_context(test_group_mo=True).run_scheduler() self.ProcurementGroup.with_context(test_group_mo=True).run_scheduler()
mo = self.MrpProduction.search([("product_id", "=", self.product1.id)]) mo = self.MrpProduction.search([("product_id", "=", self.product1.id)])