中国本土应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
4.2KB

  1. # Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo import _, api, fields, models
  4. from odoo.exceptions import ValidationError
  5. class DateRange(models.Model):
  6. _name = "date.range"
  7. _description = "Date Range"
  8. _order = "type_name,date_start"
  9. @api.model
  10. def _default_company(self):
  11. return self.env.company
  12. name = fields.Char(required=True, translate=True)
  13. date_start = fields.Date(string="Start date", required=True)
  14. date_end = fields.Date(string="End date", required=True)
  15. type_id = fields.Many2one(
  16. comodel_name="date.range.type",
  17. string="Type",
  18. index=1,
  19. required=True,
  20. ondelete="restrict",
  21. domain="['|', ('company_id', '=', company_id), " "('company_id', '=', False)]",
  22. store=True,
  23. compute="_compute_type_id",
  24. readonly=False,
  25. )
  26. type_name = fields.Char(related="type_id.name", store=True, string="Type Name")
  27. company_id = fields.Many2one(
  28. comodel_name="res.company", string="Company", index=1, default=_default_company
  29. )
  30. active = fields.Boolean(
  31. help="The active field allows you to hide the date range without "
  32. "removing it.",
  33. default=True,
  34. )
  35. _sql_constraints = [
  36. (
  37. "date_range_uniq",
  38. "unique (name,type_id, company_id)",
  39. "A date range must be unique per company !",
  40. )
  41. ]
  42. @api.depends("company_id", "type_id.company_id")
  43. def _compute_type_id(self):
  44. """Enforce check of company consistency when changing company, here
  45. or in the type.
  46. """
  47. self._check_company_id_type_id()
  48. @api.constrains("company_id", "type_id")
  49. def _check_company_id_type_id(self):
  50. for rec in self.sudo():
  51. if (
  52. rec.company_id
  53. and rec.type_id.company_id
  54. and rec.company_id != rec.type_id.company_id
  55. ):
  56. raise ValidationError(
  57. _("%(name)s is not a valid range (%(date_start)s > %(date_end)s)")
  58. % {
  59. "name": rec.name,
  60. "date_start": rec.date_start,
  61. "date_end": rec.date_end,
  62. }
  63. )
  64. @api.constrains("type_id", "date_start", "date_end", "company_id")
  65. def _validate_range(self):
  66. for this in self:
  67. if this.date_start > this.date_end:
  68. raise ValidationError(
  69. _("%(name)s is not a valid range (%(date_start)s > %(date_end)s)")
  70. % {
  71. "name": this.name,
  72. "date_start": this.date_start,
  73. "date_end": this.date_end,
  74. }
  75. )
  76. if this.type_id.allow_overlap:
  77. continue
  78. # here we use a plain SQL query to benefit of the daterange
  79. # function available in PostgresSQL
  80. # (http://www.postgresql.org/docs/current/static/rangetypes.html)
  81. SQL = """
  82. SELECT
  83. id
  84. FROM
  85. date_range dt
  86. WHERE
  87. DATERANGE(dt.date_start, dt.date_end, '[]') &&
  88. DATERANGE(%s::date, %s::date, '[]')
  89. AND dt.id != %s
  90. AND dt.active
  91. AND dt.company_id = %s
  92. AND dt.type_id=%s;"""
  93. self.env.cr.execute(
  94. SQL,
  95. (
  96. this.date_start,
  97. this.date_end,
  98. this.id,
  99. this.company_id.id or None,
  100. this.type_id.id,
  101. ),
  102. )
  103. res = self.env.cr.fetchall()
  104. if res:
  105. dt = self.browse(res[0][0])
  106. raise ValidationError(
  107. _("%(thisname)s overlaps %(dtname)s")
  108. % {"thisname": this.name, "dtname": dt.name}
  109. )
  110. def get_domain(self, field_name):
  111. self.ensure_one()
  112. return [(field_name, ">=", self.date_start), (field_name, "<=", self.date_end)]
上海开阖软件有限公司 沪ICP备12045867号-1