# 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