mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-20 07:31:59 +02:00
Initial commit: OCA Technical packages (595 packages)
This commit is contained in:
commit
2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions
|
|
@ -0,0 +1,3 @@
|
|||
from . import ddmrp_adjustment
|
||||
from . import stock_buffer
|
||||
from . import ddmrp_adjustment_demand
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# Copyright 2017-24 ForgeFlow S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
DAF_string = "DAF"
|
||||
LTAF_string = "LTAF"
|
||||
|
||||
|
||||
class DdmrpAdjustment(models.Model):
|
||||
_name = "ddmrp.adjustment"
|
||||
_description = "DDMRP Adjustment"
|
||||
|
||||
buffer_id = fields.Many2one(
|
||||
comodel_name="stock.buffer",
|
||||
string="Buffer",
|
||||
required=True,
|
||||
)
|
||||
product_id = fields.Many2one(
|
||||
comodel_name="product.product",
|
||||
related="buffer_id.product_id",
|
||||
readonly=True,
|
||||
)
|
||||
location_id = fields.Many2one(
|
||||
comodel_name="stock.location",
|
||||
related="buffer_id.location_id",
|
||||
readonly=True,
|
||||
)
|
||||
date_range_id = fields.Many2one(
|
||||
comodel_name="date.range",
|
||||
string="Date Range",
|
||||
required=True,
|
||||
)
|
||||
adjustment_type = fields.Selection(
|
||||
selection=[
|
||||
(DAF_string, "Demand Adjustment Factor"),
|
||||
(LTAF_string, "Lead Time Adjustment Factor"),
|
||||
],
|
||||
)
|
||||
value = fields.Float(group_operator="avg")
|
||||
company_id = fields.Many2one(
|
||||
comodel_name="res.company",
|
||||
related="buffer_id.company_id",
|
||||
)
|
||||
date_start = fields.Date(related="date_range_id.date_start")
|
||||
date_end = fields.Date(related="date_range_id.date_end")
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright 2017-20 ForgeFlow S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class DdmrpAdjustmentDemand(models.Model):
|
||||
_name = "ddmrp.adjustment.demand"
|
||||
_description = "DDMRP Adjustment Demand"
|
||||
|
||||
buffer_id = fields.Many2one(
|
||||
comodel_name="stock.buffer",
|
||||
string="Apply to",
|
||||
)
|
||||
product_id = fields.Many2one(related="buffer_id.product_id")
|
||||
buffer_origin_id = fields.Many2one(
|
||||
comodel_name="stock.buffer",
|
||||
string="Originated from",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
)
|
||||
product_origin_id = fields.Many2one(
|
||||
related="buffer_origin_id.product_id",
|
||||
string="Origin Product",
|
||||
)
|
||||
extra_demand = fields.Float()
|
||||
product_uom_id = fields.Many2one(
|
||||
comodel_name="uom.uom",
|
||||
string="Unit of Measure",
|
||||
related="buffer_id.product_uom",
|
||||
)
|
||||
date_start = fields.Date(
|
||||
string="Start date",
|
||||
)
|
||||
date_end = fields.Date(
|
||||
string="End date",
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
comodel_name="res.company",
|
||||
related="buffer_id.company_id",
|
||||
)
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
# Copyright 2017-24 ForgeFlow S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import logging
|
||||
from datetime import timedelta as td
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
from ..models.ddmrp_adjustment import DAF_string, LTAF_string
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class StockBuffer(models.Model):
|
||||
_inherit = "stock.buffer"
|
||||
|
||||
extra_demand_ids = fields.One2many(
|
||||
comodel_name="ddmrp.adjustment.demand",
|
||||
string="Extra Demand",
|
||||
inverse_name="buffer_id",
|
||||
help="Demand associated to Demand Adjustment Factors applied to "
|
||||
"parent buffers.",
|
||||
)
|
||||
daf_text = fields.Char(compute="_compute_daf_text")
|
||||
parent_daf_text = fields.Char(compute="_compute_daf_text")
|
||||
pre_daf_adu = fields.Float(readonly=True)
|
||||
daf_applied = fields.Float(default=-1, readonly=True)
|
||||
parent_daf_applied = fields.Float(default=-1, readonly=True)
|
||||
count_ddmrp_adjustment_demand = fields.Integer(
|
||||
compute="_compute_count_ddmrp_adjustment_demand"
|
||||
)
|
||||
|
||||
def _compute_count_ddmrp_adjustment_demand(self):
|
||||
for rec in self:
|
||||
rec.count_ddmrp_adjustment_demand = len(
|
||||
self.env["ddmrp.adjustment.demand"].search(
|
||||
[("buffer_origin_id", "=", rec.id)]
|
||||
)
|
||||
)
|
||||
|
||||
@api.depends("daf_applied", "parent_daf_applied")
|
||||
def _compute_daf_text(self):
|
||||
for rec in self:
|
||||
rec.daf_text = "DAF: *" + str(round(rec.daf_applied, 2))
|
||||
rec.parent_daf_text = "P. DAF: +" + str(round(rec.parent_daf_applied, 2))
|
||||
|
||||
def _daf_to_apply_domain(self, current=True):
|
||||
self.ensure_one()
|
||||
today = fields.Date.today()
|
||||
domain = [
|
||||
("buffer_id", "=", self.id),
|
||||
("adjustment_type", "=", DAF_string),
|
||||
("date_range_id.date_end", ">=", today),
|
||||
]
|
||||
if current:
|
||||
domain.append(("date_range_id.date_start", "<=", today))
|
||||
return domain
|
||||
|
||||
def _calc_adu(self):
|
||||
# Apply DAFs if existing for the buffer.
|
||||
res = super()._calc_adu()
|
||||
for rec in self:
|
||||
self.env["ddmrp.adjustment.demand"].search(
|
||||
[("buffer_origin_id", "=", rec.id)]
|
||||
).unlink()
|
||||
dafs_to_apply = self.env["ddmrp.adjustment"].search(
|
||||
rec._daf_to_apply_domain()
|
||||
)
|
||||
rec.daf_applied = -1
|
||||
if dafs_to_apply:
|
||||
rec.daf_applied = 1
|
||||
values = dafs_to_apply.mapped("value")
|
||||
for val in values:
|
||||
rec.daf_applied *= val
|
||||
rec.pre_daf_adu = rec.adu
|
||||
rec.adu *= rec.daf_applied
|
||||
_logger.debug(
|
||||
"DAF={} applied to {}. ADU: {} -> {}".format(
|
||||
rec.daf_applied, rec.name, rec.pre_daf_adu, rec.adu
|
||||
)
|
||||
)
|
||||
# Compute generated demand to be applied to components:
|
||||
dafs_to_explode = self.env["ddmrp.adjustment"].search(
|
||||
rec._daf_to_apply_domain(False)
|
||||
)
|
||||
for daf in dafs_to_explode:
|
||||
prev = rec.adu
|
||||
increased_demand = prev * daf.value - prev
|
||||
rec.explode_demand_to_components(daf, increased_demand, rec.product_uom)
|
||||
return res
|
||||
|
||||
def explode_demand_to_components(self, daf, demand, uom_id):
|
||||
demand_obj = self.env["ddmrp.adjustment.demand"]
|
||||
init_bom = self._get_manufactured_bom()
|
||||
if not init_bom:
|
||||
return
|
||||
|
||||
def _get_extra_demand(bom, line, buffer_id, factor):
|
||||
qty = factor * line.product_qty / bom.product_qty
|
||||
extra = line.product_uom_id._compute_quantity(qty, buffer_id.product_uom)
|
||||
return extra
|
||||
|
||||
def _create_demand(bom, factor=1, level=0, clt=0):
|
||||
level += 1
|
||||
produce_delay = (
|
||||
bom[0].product_id.produce_delay or bom[0].product_tmpl_id.produce_delay
|
||||
)
|
||||
clt += produce_delay
|
||||
for line in bom.bom_line_ids:
|
||||
if line.is_buffered:
|
||||
buffer_id = line.buffer_id
|
||||
extra_demand = _get_extra_demand(bom, line, buffer_id, factor)
|
||||
date_start = daf.date_range_id.date_start - td(days=clt)
|
||||
date_end = daf.date_range_id.date_end - td(days=clt)
|
||||
demand_obj.sudo().create(
|
||||
{
|
||||
"buffer_id": buffer_id.id,
|
||||
"buffer_origin_id": self.id,
|
||||
"extra_demand": extra_demand,
|
||||
"date_start": date_start,
|
||||
"date_end": date_end,
|
||||
}
|
||||
)
|
||||
location = line.location_id
|
||||
line_boms = line.product_id.bom_ids
|
||||
child_bom = line_boms.filtered(
|
||||
lambda bom: bom.location_id == location
|
||||
) or line_boms.filtered(lambda b: not b.location_id)
|
||||
if child_bom:
|
||||
line_qty = line.product_uom_id._compute_quantity(
|
||||
line.product_qty, child_bom.product_uom_id
|
||||
)
|
||||
new_factor = factor * line_qty / bom.product_qty
|
||||
_create_demand(child_bom[0], new_factor, level, clt)
|
||||
|
||||
initial_factor = uom_id._compute_quantity(demand, init_bom.product_uom_id)
|
||||
_create_demand(init_bom, factor=initial_factor)
|
||||
return True
|
||||
|
||||
@api.model
|
||||
def cron_ddmrp_adu(self, automatic=False):
|
||||
"""Apply extra demand originated by Demand Adjustment Factors to
|
||||
components after the cron update of all the buffers."""
|
||||
res = super().cron_ddmrp_adu(automatic)
|
||||
today = fields.Date.today()
|
||||
self.search(
|
||||
[("parent_daf_applied", "!=", -1), ("extra_demand_ids", "=", False)]
|
||||
).write({"parent_daf_applied": -1})
|
||||
for op in self.search([("extra_demand_ids", "!=", False)]):
|
||||
op.parent_daf_applied = -1
|
||||
daf_parent = sum(
|
||||
op.extra_demand_ids.filtered(
|
||||
lambda r: r.date_start <= today <= r.date_end
|
||||
).mapped("extra_demand")
|
||||
)
|
||||
if daf_parent:
|
||||
op.parent_daf_applied = daf_parent
|
||||
op.adu += op.parent_daf_applied
|
||||
_logger.debug(
|
||||
"DAFs-originated demand applied. {}: ADU += {}".format(
|
||||
op.name, op.parent_daf_applied
|
||||
)
|
||||
)
|
||||
return res
|
||||
|
||||
def _ltaf_to_apply_domain(self):
|
||||
self.ensure_one()
|
||||
today = fields.Date.today()
|
||||
return [
|
||||
("buffer_id", "=", self.id),
|
||||
("adjustment_type", "=", LTAF_string),
|
||||
("date_range_id.date_start", "<=", today),
|
||||
("date_range_id.date_end", ">=", today),
|
||||
]
|
||||
|
||||
def _compute_dlt(self):
|
||||
"""Apply Lead Time Adj Factor if existing"""
|
||||
res = super()._compute_dlt()
|
||||
for rec in self:
|
||||
ltaf_to_apply = self.env["ddmrp.adjustment"].search(
|
||||
rec._ltaf_to_apply_domain()
|
||||
)
|
||||
if ltaf_to_apply:
|
||||
ltaf = 1
|
||||
values = ltaf_to_apply.mapped("value")
|
||||
for val in values:
|
||||
ltaf *= val
|
||||
prev = rec.dlt
|
||||
rec.dlt *= ltaf
|
||||
_logger.debug(
|
||||
"LTAF=%s applied to %s. DLT: %s -> %s"
|
||||
% (ltaf, rec.name, prev, rec.dlt)
|
||||
)
|
||||
return res
|
||||
|
||||
def action_archive(self):
|
||||
self.env["ddmrp.adjustment.demand"].search(
|
||||
[("buffer_origin_id", "in", self.ids)]
|
||||
).unlink()
|
||||
return super().action_archive()
|
||||
|
||||
def action_view_demand_to_components(self):
|
||||
demand_ids = (
|
||||
self.env["ddmrp.adjustment.demand"]
|
||||
.search([("buffer_origin_id", "=", self.id)])
|
||||
.ids
|
||||
)
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"ddmrp_adjustment.ddmrp_adjustment_demand_action"
|
||||
)
|
||||
action["domain"] = [("id", "in", demand_ids)]
|
||||
return action
|
||||
|
||||
def action_view_affecting_adu(self):
|
||||
demand_ids = (
|
||||
self.env["ddmrp.adjustment"]
|
||||
.search(self._daf_to_apply_domain(current=False))
|
||||
.ids
|
||||
)
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"ddmrp_adjustment.ddmrp_adjustment_action"
|
||||
)
|
||||
action["domain"] = [("id", "in", demand_ids)]
|
||||
action["context"] = {"search_default_current": 1}
|
||||
return action
|
||||
|
||||
def action_view_parent_affecting_adu(self):
|
||||
demand_ids = self.extra_demand_ids.ids
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"ddmrp_adjustment.ddmrp_adjustment_demand_action"
|
||||
)
|
||||
action["domain"] = [("id", "in", demand_ids)]
|
||||
return action
|
||||
Loading…
Add table
Add a link
Reference in a new issue