From 68348b724e2db9bf947f9a4170bc5854b3bc8652 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Mon, 5 Aug 2019 16:14:36 +0200 Subject: [PATCH 01/34] [12.0][ADD] mrp_multi_level_estimate --- mrp_multi_level_estimate/README.rst | 90 ++++ mrp_multi_level_estimate/__init__.py | 2 + mrp_multi_level_estimate/__manifest__.py | 25 + mrp_multi_level_estimate/models/__init__.py | 1 + .../models/product_mrp_area.py | 22 + mrp_multi_level_estimate/readme/CONFIGURE.rst | 5 + .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 1 + .../static/description/icon.png | Bin 0 -> 7222 bytes .../static/description/index.html | 430 ++++++++++++++++++ mrp_multi_level_estimate/tests/__init__.py | 1 + .../tests/test_mrp_multi_level_estimate.py | 128 ++++++ .../views/product_mrp_area_views.xml | 16 + mrp_multi_level_estimate/wizards/__init__.py | 1 + .../wizards/mrp_multi_level.py | 75 +++ 15 files changed, 798 insertions(+) create mode 100644 mrp_multi_level_estimate/README.rst create mode 100644 mrp_multi_level_estimate/__init__.py create mode 100644 mrp_multi_level_estimate/__manifest__.py create mode 100644 mrp_multi_level_estimate/models/__init__.py create mode 100644 mrp_multi_level_estimate/models/product_mrp_area.py create mode 100644 mrp_multi_level_estimate/readme/CONFIGURE.rst create mode 100644 mrp_multi_level_estimate/readme/CONTRIBUTORS.rst create mode 100644 mrp_multi_level_estimate/readme/DESCRIPTION.rst create mode 100644 mrp_multi_level_estimate/static/description/icon.png create mode 100644 mrp_multi_level_estimate/static/description/index.html create mode 100644 mrp_multi_level_estimate/tests/__init__.py create mode 100644 mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py create mode 100644 mrp_multi_level_estimate/views/product_mrp_area_views.xml create mode 100644 mrp_multi_level_estimate/wizards/__init__.py create mode 100644 mrp_multi_level_estimate/wizards/mrp_multi_level.py diff --git a/mrp_multi_level_estimate/README.rst b/mrp_multi_level_estimate/README.rst new file mode 100644 index 000000000..2406e8d02 --- /dev/null +++ b/mrp_multi_level_estimate/README.rst @@ -0,0 +1,90 @@ +======================== +MRP Multi Level Estimate +======================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! 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/mrp_multi_level_estimate + :alt: OCA/manufacture +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/manufacture-12-0/manufacture-12-0-mrp_multi_level_estimate + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/129/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Integration for MRP Multi Level and `Stock Demand Estimates `_ system. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +You can edit how to consolidate your estimates as demand at product MRP area +level using the field *Group Days of Estimates*. This number represents the +days to group your estimates as demand for the MRP, e.g: if set to 7, you will +have your estimates (regardless of the date range used) grouped in weekly +demand. + +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 +~~~~~~~ + +* Eficent + +Contributors +~~~~~~~~~~~~ + +* Lois Rilo + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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-lreficent| image:: https://github.com/lreficent.png?size=40px + :target: https://github.com/lreficent + :alt: lreficent + +Current `maintainer `__: + +|maintainer-lreficent| + +This module is part of the `OCA/manufacture `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mrp_multi_level_estimate/__init__.py b/mrp_multi_level_estimate/__init__.py new file mode 100644 index 000000000..aee8895e7 --- /dev/null +++ b/mrp_multi_level_estimate/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/mrp_multi_level_estimate/__manifest__.py b/mrp_multi_level_estimate/__manifest__.py new file mode 100644 index 000000000..a57ff4203 --- /dev/null +++ b/mrp_multi_level_estimate/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright 2019 Eficent Business and IT Consulting Services S.L. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/Agpl.html). + +{ + "name": "MRP Multi Level Estimate", + "version": "12.0.1.0.0", + "development_status": "Beta", + "license": "AGPL-3", + "author": "Eficent, " + "Odoo Community Association (OCA)", + "maintainers": ["lreficent"], + "summary": "Allows to consider demand estimates using MRP multi level.", + "website": "https://github.com/OCA/manufacture", + "category": "Manufacturing", + "depends": [ + "mrp_multi_level", + "stock_demand_estimate", + ], + "data": [ + "views/product_mrp_area_views.xml", + ], + "installable": True, + "application": False, + "auto_install": True, +} diff --git a/mrp_multi_level_estimate/models/__init__.py b/mrp_multi_level_estimate/models/__init__.py new file mode 100644 index 000000000..3bf74fdf9 --- /dev/null +++ b/mrp_multi_level_estimate/models/__init__.py @@ -0,0 +1 @@ +from . import product_mrp_area diff --git a/mrp_multi_level_estimate/models/product_mrp_area.py b/mrp_multi_level_estimate/models/product_mrp_area.py new file mode 100644 index 000000000..f76b8d0d8 --- /dev/null +++ b/mrp_multi_level_estimate/models/product_mrp_area.py @@ -0,0 +1,22 @@ +# Copyright 2019 Eficent Business and IT Consulting Services S.L. +# - Lois Rilo Antelo +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ProductMRPArea(models.Model): + _inherit = "product.mrp.area" + + group_estimate_days = fields.Integer( + string="Group Days of Estimates", + default=1, + help="The days to group your estimates as demand for the MRP." + "It can be different from the lenght of the date ranges you " + "use in the estimates.", + ) + + _sql_constraints = [ + ("group_estimate_days_check", "CHECK( group_estimate_days >= 0 )", + "Group Days of Estimates must be greater than or equal to zero."), + ] diff --git a/mrp_multi_level_estimate/readme/CONFIGURE.rst b/mrp_multi_level_estimate/readme/CONFIGURE.rst new file mode 100644 index 000000000..1b720c2e6 --- /dev/null +++ b/mrp_multi_level_estimate/readme/CONFIGURE.rst @@ -0,0 +1,5 @@ +You can edit how to consolidate your estimates as demand at product MRP area +level using the field *Group Days of Estimates*. This number represents the +days to group your estimates as demand for the MRP, e.g: if set to 7, you will +have your estimates (regardless of the date range used) grouped in weekly +demand. diff --git a/mrp_multi_level_estimate/readme/CONTRIBUTORS.rst b/mrp_multi_level_estimate/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..4b574636c --- /dev/null +++ b/mrp_multi_level_estimate/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Lois Rilo diff --git a/mrp_multi_level_estimate/readme/DESCRIPTION.rst b/mrp_multi_level_estimate/readme/DESCRIPTION.rst new file mode 100644 index 000000000..e7f56f84a --- /dev/null +++ b/mrp_multi_level_estimate/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Integration for MRP Multi Level and `Stock Demand Estimates `_ system. diff --git a/mrp_multi_level_estimate/static/description/icon.png b/mrp_multi_level_estimate/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b1cef6c4cc410514ad582e091cdab458d691cb9e GIT binary patch literal 7222 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 literal 0 HcmV?d00001 diff --git a/mrp_multi_level_estimate/static/description/index.html b/mrp_multi_level_estimate/static/description/index.html new file mode 100644 index 000000000..eb249d824 --- /dev/null +++ b/mrp_multi_level_estimate/static/description/index.html @@ -0,0 +1,430 @@ + + + + + + +MRP Multi Level Estimate + + + +
+

MRP Multi Level Estimate

+ + +

Beta License: AGPL-3 OCA/manufacture Translate me on Weblate Try me on Runbot

+

Integration for MRP Multi Level and Stock Demand Estimates system.

+

Table of contents

+ +
+

Configuration

+

You can edit how to consolidate your estimates as demand at product MRP area +level using the field Group Days of Estimates. This number represents the +days to group your estimates as demand for the MRP, e.g: if set to 7, you will +have your estimates (regardless of the date range used) grouped in weekly +demand.

+
+
+

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

+
    +
  • Eficent
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

Current maintainer:

+

lreficent

+

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

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/mrp_multi_level_estimate/tests/__init__.py b/mrp_multi_level_estimate/tests/__init__.py new file mode 100644 index 000000000..f26efbd60 --- /dev/null +++ b/mrp_multi_level_estimate/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mrp_multi_level_estimate diff --git a/mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py b/mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py new file mode 100644 index 000000000..66161a18e --- /dev/null +++ b/mrp_multi_level_estimate/tests/test_mrp_multi_level_estimate.py @@ -0,0 +1,128 @@ +# Copyright 2018-19 Eficent Business and IT Consulting Services S.L. +# (http://www.eficent.com) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from datetime import datetime, timedelta + +from dateutil.rrule import WEEKLY +from odoo.addons.mrp_multi_level.tests.common import TestMrpMultiLevelCommon + + +class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.estimate_obj = cls.env["stock.demand.estimate"] + + # Create new clean area: + cls.estimate_loc = cls.loc_obj.create({ + "name": "Test location for estimates", + "usage": "internal", + "location_id": cls.wh.view_location_id.id, + }) + cls.estimate_area = cls.mrp_area_obj.create({ + "name": "Test", + "warehouse_id": cls.wh.id, + "location_id": cls.estimate_loc.id, + }) + cls.product_mrp_area_obj.create({ + 'product_id': cls.prod_test.id, + 'mrp_area_id': cls.estimate_area.id, + 'mrp_nbr_days': 7, + }) + + # Create Date Ranges: + cls.dr_type = cls.env["date.range.type"].create({ + "name": "Weeks", + "company_id": False, + "allow_overlap": False, + }) + today = datetime.today().replace(hour=0) + generator = cls.env["date.range.generator"].create({ + "date_start": today - timedelta(days=3), + "name_prefix": "W-", + "type_id": cls.dr_type.id, + "duration_count": 1, + "unit_of_time": WEEKLY, + "count": 3}) + generator.action_apply() + + # Create Demand Estimates: + ranges = cls.env["date.range"].search( + [("type_id", "=", cls.dr_type.id)]) + qty = 140.0 + for dr in ranges: + qty += 70.0 + cls._create_demand_estimate( + cls.prod_test, cls.stock_location, dr, qty) + cls._create_demand_estimate( + cls.prod_test, cls.estimate_loc, dr, qty) + + cls.mrp_multi_level_wiz.create({}).run_mrp_multi_level() + + @classmethod + def _create_demand_estimate(cls, product, location, date_range, qty): + cls.estimate_obj.create({ + "product_id": product.id, + "location_id": location.id, + "product_uom": product.uom_id.id, + "product_uom_qty": qty, + "date_range_id": date_range.id, + }) + + def test_01_demand_estimates(self): + """Tests demand estimates integration.""" + estimates = self.estimate_obj.search([ + ("product_id", "=", self.prod_test.id), + ("location_id", "=", self.stock_location.id)]) + self.assertEqual(len(estimates), 3) + moves = self.mrp_move_obj.search([ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.mrp_area.id), + ]) + # 3 weeks - 3 days in the past = 18 days of valid estimates: + moves_from_estimates = moves.filtered(lambda m: m.mrp_type == "d") + self.assertEqual(len(moves_from_estimates), 18) + quantities = moves_from_estimates.mapped("mrp_qty") + self.assertIn(-30.0, quantities) # 210 a week => 30.0 dayly: + self.assertIn(-40.0, quantities) # 280 a week => 40.0 dayly: + self.assertIn(-50.0, quantities) # 350 a week => 50.0 dayly: + plans = self.planned_order_obj.search([ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.mrp_area.id), + ]) + action = list(set(plans.mapped("mrp_action"))) + self.assertEqual(len(action), 1) + self.assertEqual(action[0], "buy") + self.assertEqual(len(plans), 18) + inventories = self.mrp_inventory_obj.search([ + ("mrp_area_id", "=", self.estimate_area.id)]) + self.assertEqual(len(inventories), 18) + + def test_02_group_demand_estimates(self): + """Test demand grouping functionality, `nbr_days`.""" + estimates = self.estimate_obj.search([ + ("product_id", "=", self.prod_test.id), + ("location_id", "=", self.estimate_loc.id)]) + self.assertEqual(len(estimates), 3) + moves = self.mrp_move_obj.search([ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.estimate_area.id), + ]) + supply_plans = self.planned_order_obj.search([ + ("product_id", "=", self.prod_test.id), + ("mrp_area_id", "=", self.estimate_area.id), + ]) + # 3 weeks - 3 days in the past = 18 days of valid estimates: + moves_from_estimates = moves.filtered(lambda m: m.mrp_type == "d") + self.assertEqual(len(moves_from_estimates), 18) + # 18 days of demand / 7 nbr_days = 2.57 => 3 supply moves expected. + self.assertEqual(len(supply_plans), 3) + quantities = supply_plans.mapped("mrp_qty") + week_1_expected = sum(moves_from_estimates[0:7].mapped("mrp_qty")) + self.assertIn(abs(week_1_expected), quantities) + week_2_expected = sum(moves_from_estimates[7:14].mapped("mrp_qty")) + self.assertIn(abs(week_2_expected), quantities) + week_3_expected = sum(moves_from_estimates[14:].mapped("mrp_qty")) + self.assertIn(abs(week_3_expected), quantities) diff --git a/mrp_multi_level_estimate/views/product_mrp_area_views.xml b/mrp_multi_level_estimate/views/product_mrp_area_views.xml new file mode 100644 index 000000000..cf1f382b1 --- /dev/null +++ b/mrp_multi_level_estimate/views/product_mrp_area_views.xml @@ -0,0 +1,16 @@ + + + + + product.mrp.area.form - estimates + product.mrp.area + form + + + + + + + + + diff --git a/mrp_multi_level_estimate/wizards/__init__.py b/mrp_multi_level_estimate/wizards/__init__.py new file mode 100644 index 000000000..869fb19c7 --- /dev/null +++ b/mrp_multi_level_estimate/wizards/__init__.py @@ -0,0 +1 @@ +from . import mrp_multi_level diff --git a/mrp_multi_level_estimate/wizards/mrp_multi_level.py b/mrp_multi_level_estimate/wizards/mrp_multi_level.py new file mode 100644 index 000000000..70c47285e --- /dev/null +++ b/mrp_multi_level_estimate/wizards/mrp_multi_level.py @@ -0,0 +1,75 @@ +# Copyright 2019 Eficent Business and IT Consulting Services S.L. +# - Lois Rilo +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import logging +from datetime import timedelta +from odoo import api, fields, models +from odoo.tools.float_utils import float_round +logger = logging.getLogger(__name__) + + +class MultiLevelMrp(models.TransientModel): + _inherit = "mrp.multi.level" + + @api.model + def _prepare_mrp_move_data_from_estimate( + self, estimate, product_mrp_area, date): + mrp_type = "d" + origin = "fc" + daily_qty = float_round( + estimate.daily_qty, + precision_rounding=product_mrp_area.product_id.uom_id.rounding, + rounding_method="HALF-UP") + return { + "mrp_area_id": product_mrp_area.mrp_area_id.id, + "product_id": product_mrp_area.product_id.id, + "product_mrp_area_id": product_mrp_area.id, + "production_id": None, + "purchase_order_id": None, + "purchase_line_id": None, + "stock_move_id": None, + "mrp_qty": -daily_qty * product_mrp_area.group_estimate_days, + "current_qty": -daily_qty, + "mrp_date": date, + "current_date": date, + "mrp_type": mrp_type, + "mrp_origin": origin, + "mrp_order_number": None, + "parent_product_id": None, + "name": "Forecast", + "state": "confirmed", + } + + @api.model + def _estimates_domain(self, product_mrp_area): + locations = product_mrp_area.mrp_area_id._get_locations() + return [ + ("product_id", "=", product_mrp_area.product_id.id), + ("location_id", "in", locations.ids), + ("date_range_id.date_end", ">=", fields.Date.today()), + ] + + @api.model + def _init_mrp_move_from_forecast(self, product_mrp_area): + res = super(MultiLevelMrp, self)._init_mrp_move_from_forecast( + product_mrp_area) + if not product_mrp_area.group_estimate_days: + return False + today = fields.Date.today() + domain = self._estimates_domain(product_mrp_area) + estimates = self.env["stock.demand.estimate"].search(domain) + for rec in estimates: + start = rec.date_range_id.date_start + if start < today: + start = today + mrp_date = fields.Date.from_string(start) + date_end = fields.Date.from_string(rec.date_range_id.date_end) + delta = timedelta(days=product_mrp_area.group_estimate_days) + while mrp_date <= date_end: + mrp_move_data = \ + self._prepare_mrp_move_data_from_estimate( + rec, product_mrp_area, mrp_date) + self.env["mrp.move"].create(mrp_move_data) + mrp_date += delta + return res From 0e7deebdddcc27e4d9715fdbbb2690f0201916b5 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Mon, 30 Sep 2019 11:57:17 +0000 Subject: [PATCH 02/34] [UPD] Update mrp_multi_level_estimate.pot --- .../i18n/mrp_multi_level_estimate.pot | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 mrp_multi_level_estimate/i18n/mrp_multi_level_estimate.pot diff --git a/mrp_multi_level_estimate/i18n/mrp_multi_level_estimate.pot b/mrp_multi_level_estimate/i18n/mrp_multi_level_estimate.pot new file mode 100644 index 000000000..cb6ff2527 --- /dev/null +++ b/mrp_multi_level_estimate/i18n/mrp_multi_level_estimate.pot @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mrp_multi_level_estimate +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \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_multi_level_estimate +#: model:ir.model.fields,field_description:mrp_multi_level_estimate.field_product_mrp_area__group_estimate_days +msgid "Group Days of Estimates" +msgstr "" + +#. module: mrp_multi_level_estimate +#: sql_constraint:product.mrp.area:0 +msgid "Group Days of Estimates must be greater than or equal to zero." +msgstr "" + +#. module: mrp_multi_level_estimate +#: model:ir.model,name:mrp_multi_level_estimate.model_mrp_multi_level +msgid "Multi Level MRP" +msgstr "" + +#. module: mrp_multi_level_estimate +#: model:ir.model,name:mrp_multi_level_estimate.model_product_mrp_area +msgid "Product MRP Area" +msgstr "" + +#. module: mrp_multi_level_estimate +#: model:ir.model.fields,help:mrp_multi_level_estimate.field_product_mrp_area__group_estimate_days +msgid "The days to group your estimates as demand for the MRP.It can be different from the lenght of the date ranges you use in the estimates." +msgstr "" + From dc6f318c8e1597d5e9baa5b64eab885970d88410 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Thu, 2 Jan 2020 11:02:36 +0100 Subject: [PATCH 03/34] [12.0][FIX] mrp_multi_level_estimate: adapt to latest split of stock_demand_estimate module. --- mrp_multi_level_estimate/__manifest__.py | 2 +- mrp_multi_level_estimate/wizards/mrp_multi_level.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mrp_multi_level_estimate/__manifest__.py b/mrp_multi_level_estimate/__manifest__.py index a57ff4203..db095777b 100644 --- a/mrp_multi_level_estimate/__manifest__.py +++ b/mrp_multi_level_estimate/__manifest__.py @@ -14,7 +14,7 @@ "category": "Manufacturing", "depends": [ "mrp_multi_level", - "stock_demand_estimate", + "stock_demand_estimate_matrix", ], "data": [ "views/product_mrp_area_views.xml", diff --git a/mrp_multi_level_estimate/wizards/mrp_multi_level.py b/mrp_multi_level_estimate/wizards/mrp_multi_level.py index 70c47285e..d3bfc1e13 100644 --- a/mrp_multi_level_estimate/wizards/mrp_multi_level.py +++ b/mrp_multi_level_estimate/wizards/mrp_multi_level.py @@ -47,7 +47,7 @@ class MultiLevelMrp(models.TransientModel): return [ ("product_id", "=", product_mrp_area.product_id.id), ("location_id", "in", locations.ids), - ("date_range_id.date_end", ">=", fields.Date.today()), + ("date_to", ">=", fields.Date.today()), ] @api.model From c56658cc3c314d9de6be09b1af1bc52bf75653e4 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Thu, 2 Jan 2020 11:05:58 +0100 Subject: [PATCH 04/34] [12.0][UPD] mrp_multi_level_estimate: eficent rebranded to forgeflow. --- mrp_multi_level_estimate/README.rst | 12 ++++++------ mrp_multi_level_estimate/__manifest__.py | 7 +++---- mrp_multi_level_estimate/models/product_mrp_area.py | 4 ++-- mrp_multi_level_estimate/readme/CONTRIBUTORS.rst | 2 +- .../static/description/index.html | 8 ++++---- .../tests/test_mrp_multi_level_estimate.py | 3 +-- mrp_multi_level_estimate/wizards/mrp_multi_level.py | 4 ++-- 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/mrp_multi_level_estimate/README.rst b/mrp_multi_level_estimate/README.rst index 2406e8d02..fac6e09dd 100644 --- a/mrp_multi_level_estimate/README.rst +++ b/mrp_multi_level_estimate/README.rst @@ -57,12 +57,12 @@ Credits Authors ~~~~~~~ -* Eficent +* ForgeFlow Contributors ~~~~~~~~~~~~ -* Lois Rilo +* Lois Rilo Maintainers ~~~~~~~~~~~ @@ -77,13 +77,13 @@ 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-lreficent| image:: https://github.com/lreficent.png?size=40px - :target: https://github.com/lreficent - :alt: lreficent +.. |maintainer-LoisRForgeFlow| image:: https://github.com/LoisRForgeFlow.png?size=40px + :target: https://github.com/LoisRForgeFlow + :alt: LoisRForgeFlow Current `maintainer `__: -|maintainer-lreficent| +|maintainer-LoisRForgeFlow| This module is part of the `OCA/manufacture `_ project on GitHub. diff --git a/mrp_multi_level_estimate/__manifest__.py b/mrp_multi_level_estimate/__manifest__.py index db095777b..55dc92b52 100644 --- a/mrp_multi_level_estimate/__manifest__.py +++ b/mrp_multi_level_estimate/__manifest__.py @@ -1,4 +1,4 @@ -# Copyright 2019 Eficent Business and IT Consulting Services S.L. +# Copyright 2019-20 ForgeFlow S.L. (http://www.forgeflow.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/Agpl.html). { @@ -6,9 +6,8 @@ "version": "12.0.1.0.0", "development_status": "Beta", "license": "AGPL-3", - "author": "Eficent, " - "Odoo Community Association (OCA)", - "maintainers": ["lreficent"], + "author": "ForgeFlow, Odoo Community Association (OCA)", + "maintainers": ["LoisRForgeFlow"], "summary": "Allows to consider demand estimates using MRP multi level.", "website": "https://github.com/OCA/manufacture", "category": "Manufacturing", diff --git a/mrp_multi_level_estimate/models/product_mrp_area.py b/mrp_multi_level_estimate/models/product_mrp_area.py index f76b8d0d8..b8091d210 100644 --- a/mrp_multi_level_estimate/models/product_mrp_area.py +++ b/mrp_multi_level_estimate/models/product_mrp_area.py @@ -1,5 +1,5 @@ -# Copyright 2019 Eficent Business and IT Consulting Services S.L. -# - Lois Rilo Antelo +# Copyright 2019-20 ForgeFlow S.L. (http://www.forgeflow.com) +# - Lois Rilo Antelo # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import fields, models diff --git a/mrp_multi_level_estimate/readme/CONTRIBUTORS.rst b/mrp_multi_level_estimate/readme/CONTRIBUTORS.rst index 4b574636c..77dfbe89e 100644 --- a/mrp_multi_level_estimate/readme/CONTRIBUTORS.rst +++ b/mrp_multi_level_estimate/readme/CONTRIBUTORS.rst @@ -1 +1 @@ -* Lois Rilo +* Lois Rilo diff --git a/mrp_multi_level_estimate/static/description/index.html b/mrp_multi_level_estimate/static/description/index.html index eb249d824..01cf37e93 100644 --- a/mrp_multi_level_estimate/static/description/index.html +++ b/mrp_multi_level_estimate/static/description/index.html @@ -3,7 +3,7 @@ - + MRP Multi Level Estimate