# -*- 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()