112 lines
4.7 KiB
Python
112 lines
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
||
|
||
from odoo import models, fields, api
|
||
from datetime import timedelta, datetime
|
||
|
||
|
||
class DiscountMaster(models.TransientModel):
|
||
_name = 'mklab.discountmaster'
|
||
|
||
is_net_check = fields.Boolean(string='Учитывать скидку на полке')
|
||
date_from = fields.Date(string='Дата начала', required=True)
|
||
date_to = fields.Date(string='Дата окончания', required=True)
|
||
line_ids = fields.One2many(
|
||
comodel_name='mklab.discountmaster.line',
|
||
inverse_name='master_id',
|
||
string='Продукты и скидки',
|
||
required=True,
|
||
)
|
||
accuracy = fields.Float(string='Точность', default=5)
|
||
|
||
def _reopen_form(self):
|
||
self.ensure_one()
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': self._name,
|
||
'res_id': self.id,
|
||
'view_type': 'form',
|
||
'view_mode': 'form',
|
||
'target': 'new',
|
||
}
|
||
|
||
|
||
class DiscountMasterLine(models.TransientModel):
|
||
_name = 'mklab.discountmaster.line'
|
||
|
||
product_id = fields.Many2one(
|
||
comodel_name='product.product',
|
||
string='Продукт',
|
||
)
|
||
our_disc = fields.Float(string='Наша скидка')
|
||
net_disc = fields.Float(string='Скидка на полке')
|
||
master_id = fields.Many2one(
|
||
comodel_name='mklab.discountmaster',
|
||
string='Мастер',
|
||
)
|
||
sale_growth = fields.Float(string='Ожидаемый рост продаж, %')
|
||
note = fields.Char(string='Пояснения')
|
||
|
||
def calc_sale_growth(self):
|
||
for s in self:
|
||
orderlines = self.env['sale.order.line'].search([
|
||
('order_id.date_order', '>=', s.master_id.date_from),
|
||
('order_id.date_order', '<=', s.master_id.date_to),
|
||
('product_id', '=', s.product_id.id),
|
||
])
|
||
action_days = 0
|
||
non_action_days = 0
|
||
summ_action = 0.0
|
||
summ_non_action = 0.0
|
||
tmp_date = datetime.combine(s.master_id.date_from, datetime.min.time())
|
||
end_date = datetime.combine(s.master_id.date_to, datetime.min.time())
|
||
action_days_list = []
|
||
|
||
while tmp_date < end_date:
|
||
tmp_date_only = tmp_date.date()
|
||
marketline = self.env['mklab.productline'].search([
|
||
('product_id', '=', s.product_id.id),
|
||
('action_id.start_date', '<=', tmp_date_only),
|
||
('action_id.end_date', '>=', tmp_date_only),
|
||
])
|
||
if marketline:
|
||
action_days_list.append(tmp_date_only)
|
||
action_days += 1
|
||
else:
|
||
non_action_days += 1
|
||
tmp_date += timedelta(days=1)
|
||
|
||
for line in orderlines:
|
||
order_dt = line.order_id.date_order
|
||
order_date = order_dt.date() if isinstance(order_dt, datetime) else order_dt
|
||
if order_date in action_days_list:
|
||
discount = line.discount
|
||
if s.our_disc - s.master_id.accuracy <= discount <= s.our_disc + s.master_id.accuracy:
|
||
summ_action += line.price_unit * line.product_uom_qty
|
||
else:
|
||
summ_non_action += line.price_unit * line.product_uom_qty
|
||
|
||
if action_days > 0 and non_action_days > 0 and summ_non_action > 0:
|
||
s.sale_growth = (
|
||
(summ_action / action_days - summ_non_action / non_action_days)
|
||
/ summ_non_action * 100
|
||
)
|
||
s.note = (
|
||
'Сумма по акции: ' + str(summ_action) +
|
||
', сумма без акции: ' + str(summ_non_action) +
|
||
', дней с акцией: ' + str(action_days) +
|
||
', дней без акции: ' + str(non_action_days)
|
||
)
|
||
else:
|
||
if action_days == 0:
|
||
s.note = 'Невозможно сделать расчет! Не было дней с акцией.'
|
||
elif non_action_days == 0:
|
||
s.note = 'Невозможно сделать расчет! Не было дней без акции.'
|
||
elif summ_non_action == 0:
|
||
s.note = 'Невозможно сделать расчет! Сумма без акции равна 0.'
|
||
|
||
if s.sale_growth <= 0:
|
||
s.note = 'Для указанной пары скидок не найдено подходящей статистики продаж'
|
||
s.sale_growth = 0
|
||
|
||
return s.master_id._reopen_form()
|