2
0
account-financial-tools/account_fiscal_year/models/account_fiscal_year.py
2022-10-10 14:36:00 +02:00

110 lines
3.6 KiB
Python

# Copyright 2020 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.osv import expression
class AccountFiscalYear(models.Model):
_name = "account.fiscal.year"
_description = "Fiscal Year"
name = fields.Char(
required=True,
)
date_from = fields.Date(
string="Start Date",
required=True,
help="Start Date, included in the fiscal year.",
)
date_to = fields.Date(
string="End Date",
required=True,
help="Ending Date, included in the fiscal year.",
)
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
required=True,
default=lambda self: self.env.company,
)
@api.constrains("date_from", "date_to", "company_id")
def _check_dates(self):
"""Check intersection with existing fiscal years."""
for fy in self:
# Starting date must be prior to the ending date
date_from = fy.date_from
date_to = fy.date_to
if date_to < date_from:
raise ValidationError(
_("The ending date must not be prior to the starting date.")
)
domain = fy._get_overlapping_domain()
overlapping_fy = self.search(domain, limit=1)
if overlapping_fy:
raise ValidationError(
_(
"This fiscal year '{fy}' "
"overlaps with '{overlapping_fy}'.\n"
"Please correct the start and/or end dates "
"of your fiscal years."
).format(
fy=fy.display_name,
overlapping_fy=overlapping_fy.display_name,
)
)
def _get_overlapping_domain(self):
"""Get domain for finding fiscal years overlapping with self.
The domain will search only among fiscal years of this company.
"""
self.ensure_one()
# Compare with other fiscal years defined for this company
company_domain = [
("id", "!=", self.id),
("company_id", "=", self.company_id.id),
]
date_from = self.date_from
date_to = self.date_to
# Search fiscal years intersecting with current fiscal year.
# This fiscal year's `from` is contained in another fiscal year
# other.from <= fy.from <= other.to
intersection_domain_from = [
"&",
("date_from", "<=", date_from),
("date_to", ">=", date_from),
]
# This fiscal year's `to` is contained in another fiscal year
# other.from <= fy.to <= other.to
intersection_domain_to = [
"&",
("date_from", "<=", date_to),
("date_to", ">=", date_to),
]
# This fiscal year completely contains another fiscal year
# fy.from <= other.from (or other.to) <= fy.to
intersection_domain_contain = [
"&",
("date_from", ">=", date_from),
("date_from", "<=", date_to),
]
intersection_domain = expression.OR(
[
intersection_domain_from,
intersection_domain_to,
intersection_domain_contain,
]
)
return expression.AND(
[
company_domain,
intersection_domain,
]
)