server-ux/date_range/models/date_range.py
2021-03-23 20:15:27 +01:00

114 lines
3.8 KiB
Python

# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from flectra import _, api, fields, models
from flectra.exceptions import ValidationError
class DateRange(models.Model):
_name = "date.range"
_description = "Date Range"
_order = "type_name,date_start"
@api.model
def _default_company(self):
return self.env.company
name = fields.Char(required=True, translate=True)
date_start = fields.Date(string="Start date", required=True)
date_end = fields.Date(string="End date", required=True)
type_id = fields.Many2one(
comodel_name="date.range.type",
string="Type",
index=1,
required=True,
ondelete="restrict",
domain="['|', ('company_id', '=', company_id), " "('company_id', '=', False)]",
store=True,
compute="_compute_type_id",
readonly=False,
)
type_name = fields.Char(related="type_id.name", store=True, string="Type Name")
company_id = fields.Many2one(
comodel_name="res.company", string="Company", index=1, default=_default_company
)
active = fields.Boolean(
help="The active field allows you to hide the date range without "
"removing it.",
default=True,
)
_sql_constraints = [
(
"date_range_uniq",
"unique (name,type_id, company_id)",
"A date range must be unique per company !",
)
]
@api.depends("company_id", "type_id.company_id")
def _compute_type_id(self):
"""Enforce check of company consistency when changing company, here
or in the type.
"""
self._check_company_id_type_id()
@api.constrains("company_id", "type_id")
def _check_company_id_type_id(self):
for rec in self.sudo():
if (
rec.company_id
and rec.type_id.company_id
and rec.company_id != rec.type_id.company_id
):
raise ValidationError(
_(
"The Company in the Date Range and in "
"Date Range Type must be the same."
)
)
@api.constrains("type_id", "date_start", "date_end", "company_id")
def _validate_range(self):
for this in self:
if this.date_start > this.date_end:
raise ValidationError(
_("%s is not a valid range (%s > %s)")
% (this.name, this.date_start, this.date_end)
)
if this.type_id.allow_overlap:
continue
# here we use a plain SQL query to benefit of the daterange
# function available in PostgresSQL
# (http://www.postgresql.org/docs/current/static/rangetypes.html)
SQL = """
SELECT
id
FROM
date_range dt
WHERE
DATERANGE(dt.date_start, dt.date_end, '[]') &&
DATERANGE(%s::date, %s::date, '[]')
AND dt.id != %s
AND dt.active
AND dt.company_id = %s
AND dt.type_id=%s;"""
self.env.cr.execute(
SQL,
(
this.date_start,
this.date_end,
this.id,
this.company_id.id or None,
this.type_id.id,
),
)
res = self.env.cr.fetchall()
if res:
dt = self.browse(res[0][0])
raise ValidationError(_("%s overlaps %s") % (this.name, dt.name))
def get_domain(self, field_name):
self.ensure_one()
return [(field_name, ">=", self.date_start), (field_name, "<=", self.date_end)]