mis-builder/mis_builder_budget/models/mis_budget_item_abstract.py

93 lines
3.3 KiB
Python
Raw Normal View History

2021-03-23 19:12:57 +00:00
# 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)
)