112 lines
3.6 KiB
Python
112 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"
|
||
|
_rec_name = "name"
|
||
|
|
||
|
name = fields.Char(
|
||
|
string="Name",
|
||
|
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,
|
||
|
]
|
||
|
)
|