oca-technical/odoo-bringout-oca-ddmrp-ddmrp_sale/ddmrp_sale/models/stock_buffer.py
2025-08-29 15:43:03 +02:00

99 lines
3.7 KiB
Python

# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo import api, fields, models
class StockBuffer(models.Model):
_inherit = "stock.buffer"
can_serve_sales = fields.Boolean(
compute="_compute_can_serve_sales",
store=True,
)
qualified_demand_sale_order_line_ids = fields.Many2many(
comodel_name="sale.order.line",
)
def _get_sale_source_location(self):
self.ensure_one()
proc_loc = self.env.ref("stock.stock_location_customers")
values = {
"warehouse_id": self.warehouse_id,
"company_id": self.company_id,
}
rule = self.env["procurement.group"]._get_rule(
self.product_id, proc_loc, values
)
return rule and rule.location_src_id
@api.depends("warehouse_id", "location_id")
def _compute_can_serve_sales(self):
for rec in self:
loc = rec._get_sale_source_location()
rec.can_serve_sales = loc.is_sublocation_of(rec.location_id)
def _search_sales_qualified_demand_domain(self):
self.ensure_one()
horizon = self.order_spike_horizon
date_to = self.warehouse_id.wh_plan_days(fields.Datetime.now(), horizon)
return [
("product_id", "=", self.product_id.id),
(
"state",
"in",
["draft", "sent"],
),
("commitment_date", "<=", date_to),
("order_id.warehouse_id", "=", self.warehouse_id.id),
("move_ids", "=", False),
]
def _search_sales_qualified_demand(self):
domain = self._search_sales_qualified_demand_domain()
so_lines = self.env["sale.order.line"].search(domain)
return so_lines
def _get_so_lines_by_days(self, so_lines):
so_lines_by_days = {}
sol_dates = [dt.date() for dt in so_lines.mapped("commitment_date")]
for d in sol_dates:
if not so_lines_by_days.get(d):
so_lines_by_days[d] = 0.0
for sol in so_lines:
date = sol.commitment_date.date()
so_lines_by_days[date] += sol.product_uom._compute_quantity(
sol.product_uom_qty, sol.product_id.uom_id
)
return so_lines_by_days
def _calc_qualified_demand(self, current_date=False):
res = super()._calc_qualified_demand(current_date)
today = current_date or fields.date.today()
for rec in self:
if rec.can_serve_sales:
qualified_demand = 0.0
lines = rec._search_sales_qualified_demand()
so_lines_by_days = rec._get_so_lines_by_days(lines)
dates = list(set(so_lines_by_days.keys()))
for date in dates:
if (
so_lines_by_days.get(date, 0.0) >= rec.order_spike_threshold
or date <= today
):
qualified_demand += so_lines_by_days.get(date, 0.0)
else:
lines = lines.filtered(
lambda x: x.commitment_date.date() != date
)
rec.qualified_demand += qualified_demand
rec.qualified_demand_sale_order_line_ids = lines
return res
def action_view_qualified_demand_so_lines(self):
lines = self.qualified_demand_sale_order_line_ids
action = self.env.ref("sale.action_quotations")
result = action.read()[0]
result["context"] = {}
result["domain"] = [("id", "in", lines.mapped("order_id.id"))]
return result