Public release from ruodoo-project: 19.0 - 2026-11-01 22:52:25 UTC
This commit is contained in:
195
ruodoo_commservice/models/counter.py
Normal file
195
ruodoo_commservice/models/counter.py
Normal file
@@ -0,0 +1,195 @@
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from odoo import api, fields, models, exceptions
|
||||
|
||||
|
||||
class CommCounterType(models.Model):
|
||||
_name = 'comm.countertype'
|
||||
_description = 'Тип счётчика'
|
||||
|
||||
name = fields.Char(string='Название типа счётчика', required=True)
|
||||
uom = fields.Many2one('uom.uom', string='Единица измерения')
|
||||
|
||||
|
||||
class CommCounter(models.Model):
|
||||
_name = 'comm.counter'
|
||||
_description = 'Прибор учёта (счётчик)'
|
||||
_order = 'contract_name,type,name'
|
||||
|
||||
name = fields.Char(string='Номер счётчика', required=True)
|
||||
type = fields.Many2one('comm.countertype', string='Тип счётчика')
|
||||
contract_id = fields.Many2one('comm.contract', string='Договор')
|
||||
contract_name = fields.Char(
|
||||
string='Номер договора',
|
||||
related='contract_id.name',
|
||||
store=True,
|
||||
readonly=True,
|
||||
)
|
||||
price = fields.Float(
|
||||
string='Цена',
|
||||
compute='_compute_price',
|
||||
store=True,
|
||||
readonly=True,
|
||||
)
|
||||
last_value_val = fields.Float(
|
||||
string='Последнее показание',
|
||||
compute='_compute_last_value',
|
||||
store=True,
|
||||
)
|
||||
last_period = fields.Char(
|
||||
string='Последний период',
|
||||
compute='_compute_last_period',
|
||||
store=True,
|
||||
)
|
||||
values_ids = fields.Many2many('comm.counterval', string='Показания')
|
||||
|
||||
@api.depends('name', 'type', 'last_period', 'last_value_val')
|
||||
def _compute_display_name(self):
|
||||
for rec in self:
|
||||
if rec.last_period:
|
||||
suffix = ' (%s: %s, %s)' % (
|
||||
rec.last_period, rec.last_value_val, rec.type.name,
|
||||
)
|
||||
elif rec.type:
|
||||
suffix = ' (%s)' % rec.type.name
|
||||
else:
|
||||
suffix = ''
|
||||
rec.display_name = '%s%s' % (rec.name or '', suffix)
|
||||
|
||||
@api.depends('values_ids', 'contract_id')
|
||||
def _compute_last_value(self):
|
||||
for rec in self:
|
||||
rec.last_value_val = rec._last_value()
|
||||
|
||||
def _last_value(self):
|
||||
self.ensure_one()
|
||||
value = self.env['comm.counterval'].search(
|
||||
[('counter_id', '=', self.id)],
|
||||
order='year desc, month desc',
|
||||
limit=1,
|
||||
)
|
||||
return value.name if value else 0.0
|
||||
|
||||
@api.depends('contract_id', 'contract_id.line_ids.price')
|
||||
def _compute_price(self):
|
||||
for rec in self:
|
||||
line = rec.contract_id.line_ids.filtered(
|
||||
lambda ln: ln.counter_id.id == rec.id
|
||||
)
|
||||
rec.price = line[:1].price
|
||||
|
||||
@api.depends('values_ids', 'contract_id')
|
||||
def _compute_last_period(self):
|
||||
for rec in self:
|
||||
value = self.env['comm.counterval'].search(
|
||||
[('counter_id', '=', rec.id)],
|
||||
order='year desc, month desc',
|
||||
limit=1,
|
||||
)
|
||||
rec.last_period = (
|
||||
'%s-%s' % (value.year, value.month) if value else ''
|
||||
)
|
||||
|
||||
@api.onchange('contract_id')
|
||||
def _onchange_contract_id(self):
|
||||
for rec in self:
|
||||
if not rec.contract_id:
|
||||
continue
|
||||
existing = rec.contract_id.line_ids.mapped('counter_id').ids
|
||||
if rec.id and rec.id not in existing:
|
||||
rec.contract_id.line_ids.create({
|
||||
'counter_id': rec.id,
|
||||
'contract_id': rec.contract_id.id,
|
||||
})
|
||||
|
||||
def action_show_last_value(self):
|
||||
self.ensure_one()
|
||||
raise exceptions.UserError(
|
||||
'На сегодняшнее число последнее показание этого счётчика, '
|
||||
'зарегистрированное в базе: %s' % self._last_value()
|
||||
)
|
||||
|
||||
def action_add_value(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'comm.counterval',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {'default_counter_id': self.id},
|
||||
}
|
||||
|
||||
|
||||
class CommCounterValue(models.Model):
|
||||
_name = 'comm.counterval'
|
||||
_description = 'Показание счётчика'
|
||||
_order = 'year desc, month desc'
|
||||
|
||||
name = fields.Float(string='Показание', required=True)
|
||||
year = fields.Integer(
|
||||
string='Год', required=True,
|
||||
default=lambda self: datetime.today().year,
|
||||
)
|
||||
month = fields.Integer(
|
||||
string='Месяц', required=True,
|
||||
default=lambda self: datetime.today().month,
|
||||
)
|
||||
counter_id = fields.Many2one('comm.counter', string='Счётчик', required=True)
|
||||
contract_id = fields.Many2one(
|
||||
'comm.contract', string='Договор',
|
||||
related='counter_id.contract_id', store=True,
|
||||
)
|
||||
type = fields.Many2one(
|
||||
'comm.countertype', string='Тип',
|
||||
related='counter_id.type', store=True,
|
||||
)
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner', string='Партнёр',
|
||||
related='counter_id.contract_id.partner_id', store=True,
|
||||
)
|
||||
|
||||
@api.constrains('name', 'month', 'year', 'counter_id')
|
||||
def _check_value(self):
|
||||
for rec in self:
|
||||
if rec.month > 12 or rec.month < 1:
|
||||
raise exceptions.ValidationError(
|
||||
'Счётчик: %s. Месяц должен быть от 1 до 12!' % rec.counter_id.name
|
||||
)
|
||||
if rec.year < 2010 or rec.year > 2050:
|
||||
raise exceptions.ValidationError(
|
||||
'Счётчик: %s. Некорректно указан год!' % rec.counter_id.name
|
||||
)
|
||||
if rec.name == 0:
|
||||
raise exceptions.ValidationError(
|
||||
'Счётчик: %s. Значение не может быть равно 0.' % rec.counter_id.name
|
||||
)
|
||||
later = self.search([
|
||||
('year', '>=', rec.year),
|
||||
('month', '>=', rec.month),
|
||||
('counter_id', '=', rec.counter_id.id),
|
||||
('id', '!=', rec.id),
|
||||
])
|
||||
if later:
|
||||
raise exceptions.ValidationError(
|
||||
'Счётчик: %s. Уже существует показание за указанный или '
|
||||
'более поздний период.' % rec.counter_id.name
|
||||
)
|
||||
bigger = self.search([
|
||||
('name', '>', rec.name),
|
||||
('counter_id', '=', rec.counter_id.id),
|
||||
('id', '!=', rec.id),
|
||||
])
|
||||
if bigger:
|
||||
raise exceptions.ValidationError(
|
||||
'Счётчик: %s. Уже существует большее показание для этого '
|
||||
'счётчика. Например: %s.' % (rec.counter_id.name, bigger[0].name)
|
||||
)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
records = super().create(vals_list)
|
||||
for record in records:
|
||||
if record.counter_id:
|
||||
record.counter_id.values_ids |= record
|
||||
return records
|
||||
Reference in New Issue
Block a user