Files
manufacture/mrp_multi_level/models/mrp_inventory.py
Lois Rilo 8b68f618de [IMP] mrp_multi_level: better group operators
For initial OH, final OH and planned availability grouping with sum
does not provide any value, specially when grouping by product.
And avg though can be more interesting.

For demand and supply we could have more doubts and the sum can
make sense, so we keep it as is.
2023-02-09 15:27:33 +01:00

139 lines
4.8 KiB
Python

# © 2016 Ucamco - Wim Audenaert <wim.audenaert@ucamco.com>
# Copyright 2016-21 ForgeFlow S.L. (https://www.forgeflow.com)
# - Jordi Ballester Alomar <jordi.ballester@forgeflow.com>
# - Lois Rilo Antelo <lois.rilo@forgeflow.com>
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from datetime import date, timedelta
from odoo import _, api, fields, models
class MrpInventory(models.Model):
_name = "mrp.inventory"
_order = "product_mrp_area_id, date"
_description = "MRP inventory projections"
_rec_name = "product_mrp_area_id"
# TODO: name to pass to procurements?
# TODO: compute procurement_date to pass to the wizard? not needed for
# PO at least. Check for MO and moves
mrp_area_id = fields.Many2one(
comodel_name="mrp.area",
string="MRP Area",
related="product_mrp_area_id.mrp_area_id",
store=True,
)
product_mrp_area_id = fields.Many2one(
comodel_name="product.mrp.area",
string="Product Parameters",
index=True,
required=True,
ondelete="cascade",
)
company_id = fields.Many2one(
comodel_name="res.company",
related="product_mrp_area_id.mrp_area_id.warehouse_id.company_id",
store=True,
)
product_id = fields.Many2one(
comodel_name="product.product",
related="product_mrp_area_id.product_id",
store=True,
)
uom_id = fields.Many2one(
comodel_name="uom.uom", string="Product UoM", compute="_compute_uom_id"
)
date = fields.Date(string="Date")
demand_qty = fields.Float(string="Demand")
supply_qty = fields.Float(string="Supply")
initial_on_hand_qty = fields.Float(
string="Starting Inventory", group_operator="avg"
)
final_on_hand_qty = fields.Float(
string="Forecasted Inventory", group_operator="avg"
)
to_procure = fields.Float(compute="_compute_to_procure", store=True)
running_availability = fields.Float(
string="Planned Availability",
group_operator="avg",
help="Theoretical inventory level if all planned orders were released.",
)
order_release_date = fields.Date(
string="Order Release Date", compute="_compute_order_release_date", store=True
)
planned_order_ids = fields.One2many(
comodel_name="mrp.planned.order", inverse_name="mrp_inventory_id", readonly=True
)
supply_method = fields.Selection(
string="Supply Method",
related="product_mrp_area_id.supply_method",
readonly=True,
store=True,
)
main_supplier_id = fields.Many2one(
string="Main Supplier",
related="product_mrp_area_id.main_supplier_id",
readonly=True,
store=True,
)
mrp_planner_id = fields.Many2one(
related="product_mrp_area_id.mrp_planner_id",
readonly=True,
store=True,
)
def _compute_uom_id(self):
for rec in self:
rec.uom_id = rec.product_mrp_area_id.product_id.uom_id
@api.depends("planned_order_ids", "planned_order_ids.qty_released")
def _compute_to_procure(self):
for rec in self:
rec.to_procure = sum(rec.planned_order_ids.mapped("mrp_qty")) - sum(
rec.planned_order_ids.mapped("qty_released")
)
@api.depends(
"product_mrp_area_id",
"product_mrp_area_id.main_supplierinfo_id",
"product_mrp_area_id.mrp_lead_time",
"product_mrp_area_id.mrp_area_id.calendar_id",
)
def _compute_order_release_date(self):
today = date.today()
for rec in self.filtered(lambda r: r.date):
delay = rec.product_mrp_area_id.mrp_lead_time
if delay and rec.mrp_area_id.calendar_id:
dt_date = fields.Datetime.to_datetime(rec.date)
# dt_date is at the beginning of the day (00:00),
# so we can subtract the delay straight forward.
order_release_date = rec.mrp_area_id.calendar_id.plan_days(
-delay, dt_date
).date()
elif delay:
order_release_date = fields.Date.from_string(rec.date) - timedelta(
days=delay
)
else:
order_release_date = rec.date
if order_release_date < today:
order_release_date = today
rec.order_release_date = order_release_date
def action_open_planned_orders(self):
planned_order_ids = []
for rec in self:
planned_order_ids += rec.planned_order_ids.ids
domain = [("id", "in", planned_order_ids)]
return {
"name": _("Planned Orders"),
"type": "ir.actions.act_window",
"res_model": "mrp.planned.order",
"view_mode": "tree,form",
"domain": domain,
}