# Copyright 2017-2020 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from flectra import _, api, fields, models from flectra.exceptions import ValidationError class MisBudgetItemAbstract(models.AbstractModel): _name = "mis.budget.item.abstract" _description = "MIS Budget Item (Abstract Base Class)" budget_id = fields.Many2one( comodel_name="mis.budget.abstract", string="Budget", required=True, ondelete="cascade", index=True, ) budget_date_from = fields.Date( related="budget_id.date_from", readonly=True, string="Budget Date From" ) budget_date_to = fields.Date( related="budget_id.date_to", readonly=True, string="Budget Date To" ) date_range_id = fields.Many2one( comodel_name="date.range", domain="[('date_start', '>=', budget_date_from)," " ('date_end', '<=', budget_date_to)]", string="Date range", ) date_from = fields.Date(required=True, string="From") date_to = fields.Date(required=True, string="To") analytic_account_id = fields.Many2one( comodel_name="account.analytic.account", string="Analytic account" ) analytic_tag_ids = fields.Many2many( comodel_name="account.analytic.tag", string="Analytic Tags" ) @api.onchange("date_range_id") def _onchange_date_range(self): for rec in self: if rec.date_range_id: rec.date_from = rec.date_range_id.date_start rec.date_to = rec.date_range_id.date_end @api.onchange("date_from", "date_to") def _onchange_dates(self): for rec in self: if rec.date_range_id: if ( rec.date_from != rec.date_range_id.date_start or rec.date_to != rec.date_range_id.date_end ): rec.date_range_id = False def _prepare_overlap_domain(self): """Prepare a domain to check for overlapping budget items.""" self.ensure_one() domain = [ ("id", "!=", self.id), ("budget_id", "=", self.budget_id.id), ("date_from", "<=", self.date_to), ("date_to", ">=", self.date_from), ("analytic_account_id", "=", self.analytic_account_id.id), ] for tag in self.analytic_tag_ids: domain.append(("analytic_tag_ids", "in", [tag.id])) return domain def _check_dates(self): for rec in self: # date_from <= date_to if rec.date_from > rec.date_to: raise ValidationError( _("%s start date must not be after end date") % (rec.display_name,) ) # within budget dates if rec.date_from < rec.budget_date_from or rec.date_to > rec.budget_date_to: raise ValidationError( _("%s is not within budget %s date range.") % (rec.display_name, rec.budget_id.display_name) ) # overlaps domain = rec._prepare_overlap_domain() res = self.search(domain, limit=1) if res: raise ValidationError( _("%s overlaps %s in budget %s") % (rec.display_name, res.display_name, rec.budget_id.display_name) )