from datetime import datetime from odoo import api, fields, models, exceptions class CommSaveValuesWizard(models.TransientModel): _name = 'comm.savevalues' _description = 'Мастер ввода показаний счётчиков' year = fields.Integer( string='Год', required=True, default=lambda self: datetime.today().year, ) month = fields.Integer( string='Месяц', required=True, default=lambda self: datetime.today().month, ) line_ids = fields.Many2many('comm.save_line', string='Счётчики и показания') message = fields.Char(string='Сообщение') type_ids = fields.Many2many('comm.countertype', string='Типы счётчиков') def _active_counters(self): return self.env['comm.contractline'].search([ ('contract_id.state', '=', 'open'), ('counter_id', '!=', False), ]).mapped('counter_id') def _build_lines(self, counters): self.line_ids = False SaveLine = self.env['comm.save_line'] for counter in counters.sorted( key=lambda c: (c.type.id, c.contract_id.id, c.id) ): if counter.type in self.type_ids or not self.type_ids: self.line_ids |= SaveLine.create({'counter_id': counter.id}) return self._reopen_form() def fill_values(self): """Счётчики без показаний за выбранный период.""" self.ensure_one() active = self._active_counters() with_values = self.env['comm.counterval'].search([ ('year', '=', self.year), ('month', '=', self.month), ]).mapped('counter_id') return self._build_lines(active - with_values) def fill_all_values(self): """Все счётчики по действующим договорам.""" self.ensure_one() return self._build_lines(self._active_counters()) def do_save(self): self.ensure_one() CounterVal = self.env['comm.counterval'] for line in self.line_ids: CounterVal.create({ 'name': line.current_value, 'year': self.year, 'month': self.month, 'counter_id': line.counter_id.id, }) self.message = 'Показания записаны' self.fill_values() return self._reopen_form() def _reopen_form(self): self.ensure_one() return { 'type': 'ir.actions.act_window', 'res_model': self._name, 'res_id': self.id, 'view_mode': 'form', 'target': 'new', } class CommSaveValuesWizardLine(models.TransientModel): _name = 'comm.save_line' _description = 'Строка мастера ввода показаний' counter_id = fields.Many2one('comm.counter', string='Счётчик') type = fields.Many2one( 'comm.countertype', string='Тип', related='counter_id.type', ) contract_id = fields.Many2one( 'comm.contract', string='Договор', related='counter_id.contract_id', ) partner_id = fields.Many2one( 'res.partner', string='Партнёр', related='counter_id.contract_id.partner_id', ) last_value = fields.Float( string='Последнее показание', related='counter_id.last_value_val', ) current_value = fields.Float(string='Текущее показание') values_ids = fields.Many2many( 'comm.counterval', string='Показания', related='counter_id.values_ids', ) last_period = fields.Char( string='Последний период', related='counter_id.last_period', ) @api.onchange('current_value') def _onchange_current_value(self): if self.current_value and self.current_value <= self.last_value: raise exceptions.ValidationError( 'Текущее значение не может быть меньше предыдущего.' )