mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
135 lines
4.9 KiB
Python
135 lines
4.9 KiB
Python
# Copyright 2016-20 ForgeFlow S.L. (https://www.forgeflow.com)
|
|
# Copyright 2016 Aleph Objects, Inc. (https://www.alephobjects.com/)
|
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
|
|
|
from datetime import date, timedelta
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class StockDemandEstimate(models.Model):
|
|
_name = "stock.demand.estimate"
|
|
_description = "Stock Demand Estimate Line"
|
|
|
|
date_from = fields.Date(
|
|
compute="_compute_dates", string="From (computed)", store=True
|
|
)
|
|
date_to = fields.Date(compute="_compute_dates", string="To (computed)", store=True)
|
|
manual_date_from = fields.Date(string="From")
|
|
manual_date_to = fields.Date(string="To")
|
|
manual_duration = fields.Integer(
|
|
string="Duration", help="Duration (in days)", default=1
|
|
)
|
|
duration = fields.Integer(
|
|
compute="_compute_dates", string="Duration (computed))", store=True
|
|
)
|
|
product_id = fields.Many2one(
|
|
comodel_name="product.product", string="Product", required=True
|
|
)
|
|
product_uom = fields.Many2one(comodel_name="uom.uom", string="Unit of measure")
|
|
location_id = fields.Many2one(
|
|
comodel_name="stock.location", string="Location", required=True
|
|
)
|
|
product_uom_qty = fields.Float(string="Quantity", digits="Product Unit of Measure")
|
|
product_qty = fields.Float(
|
|
"Real Quantity",
|
|
compute="_compute_product_quantity",
|
|
inverse="_inverse_product_quantity",
|
|
digits=0,
|
|
store=True,
|
|
help="Quantity in the default UoM of the product",
|
|
readonly=True,
|
|
)
|
|
daily_qty = fields.Float(string="Quantity / Day", compute="_compute_daily_qty")
|
|
company_id = fields.Many2one(
|
|
comodel_name="res.company",
|
|
string="Company",
|
|
required=True,
|
|
default=lambda self: self.env.company,
|
|
)
|
|
|
|
@api.depends("manual_duration", "manual_date_from", "manual_date_to")
|
|
def _compute_dates(self):
|
|
today = date.today()
|
|
for rec in self:
|
|
rec.date_from = rec.manual_date_from or today
|
|
if rec.manual_date_to:
|
|
rec.date_to = rec.manual_date_to
|
|
rec.duration = (rec.manual_date_to - rec.date_from).days + 1
|
|
elif rec.manual_duration:
|
|
rec.date_to = rec.date_from + timedelta(days=rec.manual_duration - 1)
|
|
rec.duration = rec.manual_duration
|
|
else:
|
|
rec.date_to = rec.date_from + timedelta(days=1)
|
|
rec.duration = 2
|
|
|
|
@api.depends("product_qty", "duration")
|
|
def _compute_daily_qty(self):
|
|
for rec in self:
|
|
if rec.duration:
|
|
rec.daily_qty = rec.product_qty / rec.duration
|
|
else:
|
|
rec.daily_qty = 0.0
|
|
|
|
@api.depends("product_id", "product_uom", "product_uom_qty")
|
|
def _compute_product_quantity(self):
|
|
for rec in self:
|
|
if rec.product_uom:
|
|
rec.product_qty = rec.product_uom._compute_quantity(
|
|
rec.product_uom_qty, rec.product_id.uom_id
|
|
)
|
|
else:
|
|
rec.product_qty = rec.product_uom_qty
|
|
|
|
def _inverse_product_quantity(self):
|
|
raise UserError(
|
|
_(
|
|
"The requested operation cannot be "
|
|
"processed because of a programming error "
|
|
"setting the `product_qty` field instead "
|
|
"of the `product_uom_qty`."
|
|
)
|
|
)
|
|
|
|
def name_get(self):
|
|
res = []
|
|
for rec in self:
|
|
name = "{} - {}: {} - {}".format(
|
|
rec.date_from, rec.date_to, rec.product_id.name, rec.location_id.name
|
|
)
|
|
res.append((rec.id, name))
|
|
return res
|
|
|
|
@api.onchange("manual_date_to")
|
|
def _onchange_manual_date_to(self):
|
|
for rec in self:
|
|
if rec.manual_date_from:
|
|
rec.manual_duration = (
|
|
rec.manual_date_to - rec.manual_date_from
|
|
).days + 1
|
|
|
|
@api.onchange("manual_duration")
|
|
def _onchange_manual_duration(self):
|
|
for rec in self:
|
|
if rec.manual_date_from:
|
|
rec.manual_date_to = rec.manual_date_from + timedelta(
|
|
days=rec.manual_duration - 1
|
|
)
|
|
|
|
@api.model
|
|
def get_quantity_by_date_range(self, date_start, date_end):
|
|
"""To be used in other modules"""
|
|
# Check if the dates overlap with the period
|
|
period_date_start = self.date_from
|
|
period_date_end = self.date_to
|
|
|
|
# We need only the periods that overlap
|
|
# the dates introduced by the user.
|
|
if period_date_start <= date_end and period_date_end >= date_start:
|
|
overlap_date_start = max(period_date_start, date_start)
|
|
overlap_date_end = min(period_date_end, date_end)
|
|
days = (abs(overlap_date_end - overlap_date_start)).days + 1
|
|
return days * self.daily_qty
|
|
return 0.0
|