mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
[IMP] mrp_multi_level_estimate: black, isort
This commit is contained in:
committed by
JasminSForgeFlow
parent
b0cc1125fe
commit
8e6e52daf8
@@ -3,7 +3,7 @@
|
||||
|
||||
{
|
||||
"name": "MRP Multi Level Estimate",
|
||||
"version": "12.0.1.1.0",
|
||||
"version": "13.0.1.0.0",
|
||||
"development_status": "Beta",
|
||||
"license": "AGPL-3",
|
||||
"author": "ForgeFlow, Odoo Community Association (OCA)",
|
||||
@@ -11,13 +11,8 @@
|
||||
"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_matrix",
|
||||
],
|
||||
"data": [
|
||||
"views/product_mrp_area_views.xml",
|
||||
],
|
||||
"depends": ["mrp_multi_level", "stock_demand_estimate_matrix"],
|
||||
"data": ["views/product_mrp_area_views.xml"],
|
||||
"installable": True,
|
||||
"application": False,
|
||||
"auto_install": True,
|
||||
|
||||
@@ -12,11 +12,14 @@ class ProductMRPArea(models.Model):
|
||||
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.",
|
||||
"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."),
|
||||
(
|
||||
"group_estimate_days_check",
|
||||
"CHECK( group_estimate_days >= 0 )",
|
||||
"Group Days of Estimates must be greater than or equal to zero.",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -4,82 +4,93 @@
|
||||
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,
|
||||
})
|
||||
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,
|
||||
})
|
||||
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 = 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)])
|
||||
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._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,
|
||||
})
|
||||
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)])
|
||||
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),
|
||||
])
|
||||
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)
|
||||
@@ -87,32 +98,42 @@ class TestMrpMultiLevelEstimate(TestMrpMultiLevelCommon):
|
||||
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),
|
||||
])
|
||||
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)])
|
||||
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)])
|
||||
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),
|
||||
])
|
||||
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)
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml version="1.0" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_mrp_area_form" model="ir.ui.view">
|
||||
<field name="name">product.mrp.area.form - estimates</field>
|
||||
<field name="model">product.mrp.area</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="mrp_multi_level.product_mrp_area_form"/>
|
||||
<field name="inherit_id" ref="mrp_multi_level.product_mrp_area_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="mrp_nbr_days" position="after">
|
||||
<field name="group_estimate_days"/>
|
||||
<field name="group_estimate_days" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools.float_utils import float_round
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -13,14 +15,14 @@ class MultiLevelMrp(models.TransientModel):
|
||||
_inherit = "mrp.multi.level"
|
||||
|
||||
@api.model
|
||||
def _prepare_mrp_move_data_from_estimate(
|
||||
self, estimate, product_mrp_area, date):
|
||||
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")
|
||||
rounding_method="HALF-UP",
|
||||
)
|
||||
return {
|
||||
"mrp_area_id": product_mrp_area.mrp_area_id.id,
|
||||
"product_id": product_mrp_area.product_id.id,
|
||||
@@ -52,8 +54,7 @@ class MultiLevelMrp(models.TransientModel):
|
||||
|
||||
@api.model
|
||||
def _init_mrp_move_from_forecast(self, product_mrp_area):
|
||||
res = super(MultiLevelMrp, self)._init_mrp_move_from_forecast(
|
||||
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()
|
||||
@@ -67,9 +68,9 @@ class MultiLevelMrp(models.TransientModel):
|
||||
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)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user