from odoo import api, fields, models class CommBuildingType(models.Model): _name = 'comm.btype' _description = 'Тип объекта аренды' name = fields.Char(string='Название типа объекта', required=True) class CommBuilding(models.Model): _name = 'comm.building' _description = 'Объект аренды' name = fields.Char(string='Номер офиса или машиноместа', required=True) type = fields.Many2one('comm.btype', string='Тип') busy_until = fields.Date(string='Занято до', compute='_compute_busy_until') is_free = fields.Boolean( string='Сейчас свободно', compute='_compute_is_free', search='_search_is_free', ) price_analysis = fields.Html(string='История цен', compute='_compute_price_analysis') @api.depends('name', 'type') def _compute_display_name(self): for rec in self: if rec.type and rec.name: rec.display_name = '%s %s' % (rec.type.name, rec.name) else: rec.display_name = rec.name or '' def _compute_price_analysis(self): ContractLine = self.env['comm.contractline'] for rec in self: lines = ContractLine.search([ ('counter_id', '=', False), ('contract_id.building_id', '=', rec.id), ]) if lines: sorted_lines = lines.sorted( key=lambda line: line.contract_id.date_end or fields.Date.today(), reverse=True, ) rows = sorted_lines.mapped( lambda line: '%s %s %sр. ' % ( line.contract_id.date_end or '', line.product_id.name or '', line.price, ) ) rec.price_analysis = '

%s

' % '
'.join(rows) else: rec.price_analysis = '' def _compute_busy_until(self): Contract = self.env['comm.contract'] for rec in self: contracts = Contract.search([ ('state', '=', 'open'), ('building_id', '=', rec.id), ]) if contracts: rec.busy_until = contracts.sorted( key=lambda c: c.date_end or fields.Date.today(), reverse=True, )[0].date_end else: rec.busy_until = False @api.depends('busy_until') def _compute_is_free(self): for rec in self: rec.is_free = not rec.busy_until def _search_is_free(self, operator, value): busy_building_ids = self.env['comm.contract'].search([ ('state', '=', 'open'), ]).mapped('building_id').ids # Нормализуем леф вида (is_free, op, value) к «ищем свободные?». if operator in ('=', '=='): searching_free = bool(value) elif operator == '!=': searching_free = not bool(value) else: searching_free = bool(value) # Свободные объекты — те, что не заняты действующим договором. if searching_free: return [('id', 'not in', busy_building_ids)] return [('id', 'in', busy_building_ids)]