Skip to content

Commit

Permalink
[IMP] stock_buffer_route: Do not consider other locations Buy routes
Browse files Browse the repository at this point in the history
Considering all buy routes should not be the default behaviour. If this is needed should be in a customized module.
  • Loading branch information
BernatPForgeFlow committed Apr 18, 2024
1 parent 3ce6de2 commit 96992fa
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 12 deletions.
2 changes: 2 additions & 0 deletions stock_buffer_route/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from . import mrp_production
from . import purchase_order
from . import stock_buffer
42 changes: 42 additions & 0 deletions stock_buffer_route/models/mrp_production.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2023 ForgeFlow S.L. (https://www.forgeflow.com)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from odoo import models


class MrpProduction(models.Model):
_inherit = "mrp.production"

def _get_domain_buffer_link_alternative(self, warehouse_level=False):
self.ensure_one()
if not warehouse_level:
locations = self.env["stock.location"].search(
[("id", "child_of", [self.location_dest_id.id])]
)
return [
("product_id", "=", self.product_id.id),
("company_id", "=", self.company_id.id),
("item_type_alternative", "=", "manufactured"),
("location_id", "in", locations.ids),
]
else:
return [
("product_id", "=", self.product_id.id),
("company_id", "=", self.company_id.id),
("item_type_alternative", "=", "manufactured"),
("warehouse_id", "=", self.picking_type_id.warehouse_id.id),
]

def _find_buffer_link(self):
res = super()._find_buffer_link()
buffer_model = self.env["stock.buffer"]
for rec in self.filtered(lambda r: not r.buffer_id):
domain = rec._get_domain_buffer_link_alternative()
buffer = buffer_model.search(domain, limit=1)
if not buffer:
domain = rec._get_domain_buffer_link_alternative(warehouse_level=True)
buffer = buffer_model.search(domain, limit=1)
rec.buffer_id = buffer
if buffer:
rec._calc_execution_priority()
return res
38 changes: 38 additions & 0 deletions stock_buffer_route/models/purchase_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright 2023 ForgeFlow S.L. (https://www.forgeflow.com)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from odoo import models


class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"

def _get_domain_buffer_link_alternative(self):
self.ensure_one()
if not self.product_id:
# Return impossible domain -> no buffer.
return [(0, "=", 1)]
return [
("product_id", "=", self.product_id.id),
("company_id", "=", self.order_id.company_id.id),
("item_type_alternative", "=", "purchased"),
("warehouse_id", "=", self.order_id.picking_type_id.warehouse_id.id),
]

def _find_buffer_link(self):
res = super()._find_buffer_link()
buffer_model = self.env["stock.buffer"]
move_model = self.env["stock.move"]
for rec in self.filtered(lambda r: not r.buffer_ids):
mto_move = move_model.search(
[("created_purchase_line_id", "=", rec.id)], limit=1
)
if mto_move:
# MTO lines are not accounted in MTS stock buffers.
continue
domain = rec._get_domain_buffer_link_alternative()
buffer = buffer_model.search(domain, limit=1)
if buffer:
rec.buffer_ids = buffer
rec._calc_execution_priority()
return res
29 changes: 17 additions & 12 deletions stock_buffer_route/models/stock_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class StockBuffer(models.Model):
"stock.location.route",
string="Allowed routes",
compute="_compute_route_ids",
store=True,
)
route_id = fields.Many2one(
"stock.location.route",
Expand Down Expand Up @@ -109,16 +110,21 @@ def _compute_main_supplier(self):
rec.main_supplier_id = suppliers[0].name if suppliers else False
return res

def _calc_incoming_dlt_qty(self):
res = super()._calc_incoming_dlt_qty()
for rec in self:
if rec.item_type_alternative == "purchased":
cut_date = rec._get_incoming_supply_date_limit()
pols = rec.purchase_line_ids.filtered(
lambda l: l.date_planned > fields.Datetime.to_datetime(cut_date)
def _get_rfq_dlt_qty(self, outside_dlt=False):
res = super()._get_rfq_dlt_qty(outside_dlt)
if self.item_type_alternative == "purchased":
cut_date = self._get_incoming_supply_date_limit()
if not outside_dlt:
pols = self.purchase_line_ids.filtered(
lambda l: l.date_planned <= fields.Datetime.to_datetime(cut_date)
and l.state in ("draft", "sent")
)
rec.rfq_outside_dlt_qty = sum(pols.mapped("product_qty"))
else:
pols = self.purchase_line_ids.filtered(
lambda l: l.date_planned > fields.Datetime.to_datetime(cut_date)
and l.order_id.state in ("draft", "sent")
)
res += sum(pols.mapped("product_qty"))
return res

def _get_date_planned(self, force_lt=None):
Expand All @@ -145,7 +151,6 @@ def _get_location_routes_of_parents(self, routes, parents):
)
& parents
)
or any(rule.action == "buy" for rule in route.rule_ids)
)

def get_parents(self):
Expand Down Expand Up @@ -200,11 +205,11 @@ def write(self, vals):
self._calc_distributed_source_location()
return res

def action_view_supply(self, outside_dlt=False, view_rfq=False):
res = super().action_view_supply(outside_dlt, view_rfq)
def action_view_supply(self, outside_dlt=False):
res = super().action_view_supply(outside_dlt)
# If route is set it means that there is at least two alternatively ways to
# procure the buffer. Therefore, we will show Stock Pickings.
if self.route_id and not view_rfq:
if self.route_id:
moves = self._search_stock_moves_incoming(outside_dlt)
picks = moves.mapped("picking_id")
res = self.env["ir.actions.actions"]._for_xml_id(
Expand Down

0 comments on commit 96992fa

Please sign in to comment.