You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

126 lines
4.1 KiB

# -*- encoding: utf-8 -*-
from openerp import models, fields, api
import datetime as dt
class ProductTemplate(models.Model):
_inherit = "product.template"
consumption_calculation_method = fields.Selection(
selection=[("sales_history", "Sales History")],
string="Consumption Calculation Method",
default="sales_history",
)
calculation_range = fields.Integer("Calculation range (days)", default=14)
average_consumption = fields.Float(
string="Average Consumption",
compute="_compute_average_daily_consumption",
readonly=True,
digits=(100, 2),
)
total_consumption = fields.Float(
string="Total Consumption",
default=0,
compute="_compute_total_consumption",
store=True,
readonly=True,
digits=(100, 2),
)
estimated_stock_coverage = fields.Float(
string="Estimated Stock Coverage (days)",
compute="_compute_estimated_stock_coverage",
default=0,
digits=(100, 2),
readonly=True,
)
@api.multi
@api.depends("total_consumption")
def _compute_average_daily_consumption(self):
for template in self:
if template.calculation_range > 0:
avg = template.total_consumption / template.calculation_range
else:
avg = 0
template.average_consumption = avg
return True
@api.multi
@api.depends("calculation_range")
def _compute_total_consumption(self):
for template in self:
products = self.env["product.product"].search(
[("product_tmpl_id", "=", template.id)]
)
today = dt.date.today()
pol_date_limit = today - dt.timedelta(
days=template.calculation_range
)
order_lines = self.env["pos.order.line"].search(
[
("product_id", "in", products.ids),
(
"create_date",
">",
fields.Datetime.to_string(pol_date_limit),
), # noqa
]
)
if order_lines:
order_lines = order_lines.filtered(
lambda ol: ol.order_id.state
in ["done", "invoiced", "paid"]
) # noqa
template.total_consumption = sum(order_lines.mapped("qty"))
else:
template.total_consumption = 0
return True
@api.multi
@api.depends("total_consumption")
def _compute_estimated_stock_coverage(self):
for product_template in self:
qty = product_template.qty_available
avg = product_template.average_consumption
if avg > 0:
product_template.estimated_stock_coverage = qty / avg
else:
# todo what would be a good default value? (not float(inf))
product_template.estimated_stock_coverage = 9999
return True
@api.model
def _batch_compute_total_consumption(self):
products = self.env["product.template"].search([("active", "=", True)])
query = """
select
template.id as product_template_id,
sum(pol.qty) as total_consumption
from pos_order_line pol
join pos_order po ON pol.order_id = po.id
join product_product product ON pol.product_id = product.id
join product_template template ON product.product_tmpl_id = template.id
where po.state in ('done', 'invoiced', 'paid')
and template.active
and pol.create_date
BETWEEN date_trunc('day', now()) - calculation_range * interval '1 days'
and date_trunc('day', now())
group by product_template_id
""" # noqa
self.env.cr.execute(query)
results = {pid: qty for pid, qty in self.env.cr.fetchall()}
for product in products:
product.total_consumption = results.get(
product.id, product.total_consumption
)