Initial commit: Odoo 18.0-20251222 extra-addons
This commit is contained in:
4
sale_procurement_group_by_line/model/__init__.py
Executable file
4
sale_procurement_group_by_line/model/__init__.py
Executable file
@@ -0,0 +1,4 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import sale
|
||||
from . import stock_move
|
||||
118
sale_procurement_group_by_line/model/sale.py
Executable file
118
sale_procurement_group_by_line/model/sale.py
Executable file
@@ -0,0 +1,118 @@
|
||||
# Copyright 2013-2014 Camptocamp SA - Guewen Baconnier
|
||||
# © 2016-20 ForgeFlow S.L. (https://www.forgeflow.com)
|
||||
# © 2016 Serpent Consulting Services Pvt. Ltd.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import fields, models
|
||||
from odoo.tools.float_utils import float_compare
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
procurement_group_id = fields.Many2one(
|
||||
"procurement.group", "Procurement group", copy=False
|
||||
)
|
||||
|
||||
def _get_procurement_group(self):
|
||||
super()._get_procurement_group()
|
||||
return self.procurement_group_id or False
|
||||
|
||||
def _get_procurement_group_key(self):
|
||||
"""Return a key with priority to be used to regroup lines in multiple
|
||||
procurement groups
|
||||
|
||||
"""
|
||||
return 8, self.order_id.id
|
||||
|
||||
def _action_launch_stock_rule(self, previous_product_uom_qty=False):
|
||||
"""
|
||||
Launch procurement group run method.
|
||||
"""
|
||||
if self._context.get("skip_procurement"):
|
||||
return True
|
||||
precision = self.env["decimal.precision"].precision_get(
|
||||
"Product Unit of Measure"
|
||||
)
|
||||
procurements = []
|
||||
groups = {}
|
||||
if not previous_product_uom_qty:
|
||||
previous_product_uom_qty = {}
|
||||
for line in self:
|
||||
line = line.with_company(line.company_id)
|
||||
if (
|
||||
line.state != "sale"
|
||||
or line.order_id.locked
|
||||
or line.product_id.type != "consu"
|
||||
):
|
||||
continue
|
||||
qty = line._get_qty_procurement(previous_product_uom_qty) or 0.0
|
||||
if (
|
||||
float_compare(qty, line.product_uom_qty, precision_digits=precision)
|
||||
== 0
|
||||
):
|
||||
continue
|
||||
|
||||
group_id = line._get_procurement_group()
|
||||
|
||||
# Group the sales order lines with same procurement group
|
||||
# according to the group key
|
||||
for order_line in line.order_id.order_line:
|
||||
g_id = order_line.procurement_group_id or False
|
||||
if g_id:
|
||||
groups[order_line._get_procurement_group_key()] = g_id
|
||||
if not group_id:
|
||||
group_id = groups.get(line._get_procurement_group_key())
|
||||
|
||||
if not group_id:
|
||||
vals = line._prepare_procurement_group_vals()
|
||||
group_id = self.env["procurement.group"].create(vals)
|
||||
else:
|
||||
# In case the procurement group is already created and the
|
||||
# order was cancelled, we need to update certain values
|
||||
# of the group.
|
||||
updated_vals = {}
|
||||
if group_id.partner_id != line.order_id.partner_shipping_id:
|
||||
updated_vals.update(
|
||||
{"partner_id": line.order_id.partner_shipping_id.id}
|
||||
)
|
||||
if group_id.move_type != line.order_id.picking_policy:
|
||||
updated_vals.update({"move_type": line.order_id.picking_policy})
|
||||
if updated_vals:
|
||||
group_id.write(updated_vals)
|
||||
line.procurement_group_id = group_id
|
||||
|
||||
values = line._prepare_procurement_values(group_id=group_id)
|
||||
product_qty = line.product_uom_qty - qty
|
||||
|
||||
line_uom = line.product_uom
|
||||
quant_uom = line.product_id.uom_id
|
||||
origin = (
|
||||
f"{line.order_id.name} - {line.order_id.client_order_ref}"
|
||||
if line.order_id.client_order_ref
|
||||
else line.order_id.name
|
||||
)
|
||||
product_qty, procurement_uom = line_uom._adjust_uom_quantities(
|
||||
product_qty, quant_uom
|
||||
)
|
||||
procurements += line._create_procurements(
|
||||
product_qty, procurement_uom, origin, values
|
||||
)
|
||||
# We store the procured quantity in the UoM of the line to avoid
|
||||
# duplicated procurements, specially for dropshipping and kits.
|
||||
previous_product_uom_qty[line.id] = line.product_uom_qty
|
||||
if procurements:
|
||||
self.env["procurement.group"].run(procurements)
|
||||
# This next block is currently needed only because the scheduler trigger is done
|
||||
# by picking confirmation rather than stock.move confirmation
|
||||
orders = self.mapped("order_id")
|
||||
for order in orders:
|
||||
pickings_to_confirm = order.picking_ids.filtered(
|
||||
lambda p: p.state not in ["cancel", "done"]
|
||||
)
|
||||
if pickings_to_confirm:
|
||||
# Trigger the Scheduler for Pickings
|
||||
pickings_to_confirm.action_confirm()
|
||||
return super(
|
||||
SaleOrderLine, self.with_context(sale_group_by_line=True)
|
||||
)._action_launch_stock_rule(previous_product_uom_qty=previous_product_uom_qty)
|
||||
19
sale_procurement_group_by_line/model/stock_move.py
Executable file
19
sale_procurement_group_by_line/model/stock_move.py
Executable file
@@ -0,0 +1,19 @@
|
||||
# Copyright 2022 ForgeFlow S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class StockMove(models.Model):
|
||||
_inherit = "stock.move"
|
||||
|
||||
def _update_candidate_moves_list(self, candidate_moves_set):
|
||||
"""
|
||||
We want to merge stock moves within the procurement group only
|
||||
"""
|
||||
res = super()._update_candidate_moves_list(candidate_moves_set)
|
||||
if self.env.context.get("sale_group_by_line"):
|
||||
candidate_moves_set.add(
|
||||
self.sale_line_id.procurement_group_id.stock_move_ids
|
||||
)
|
||||
return res
|
||||
Reference in New Issue
Block a user