From 0760e9f65964533e416e6eb5553fc97309ce4ca1 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Mon, 30 Mar 2020 15:42:10 +0200 Subject: [PATCH 01/20] Create module base_time_window --- base_time_window/__init__.py | 2 ++ base_time_window/__manifest__.py | 13 +++++++++++++ base_time_window/models/__init__.py | 2 ++ base_time_window/tests/__init__.py | 2 ++ 4 files changed, 19 insertions(+) create mode 100644 base_time_window/__init__.py create mode 100644 base_time_window/__manifest__.py create mode 100644 base_time_window/models/__init__.py create mode 100644 base_time_window/tests/__init__.py diff --git a/base_time_window/__init__.py b/base_time_window/__init__.py new file mode 100644 index 000000000..5437c31a2 --- /dev/null +++ b/base_time_window/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) diff --git a/base_time_window/__manifest__.py b/base_time_window/__manifest__.py new file mode 100644 index 000000000..6e04aa360 --- /dev/null +++ b/base_time_window/__manifest__.py @@ -0,0 +1,13 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +{ + "name": "Base Time Window", + "summary": "Base model to handle time windows", + "version": "13.0.1.0.0", + "category": "Technical Settings", + "author": "ACSONE SA/NV, Camptocamp, Odoo Community Association (OCA)", + "license": "AGPL-3", + "website": "https://github.com/OCA/server-tools", + "depends": ["base"], + "installable": True, +} diff --git a/base_time_window/models/__init__.py b/base_time_window/models/__init__.py new file mode 100644 index 000000000..5437c31a2 --- /dev/null +++ b/base_time_window/models/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) diff --git a/base_time_window/tests/__init__.py b/base_time_window/tests/__init__.py new file mode 100644 index 000000000..5437c31a2 --- /dev/null +++ b/base_time_window/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) From 7947f599f047c23f8adcbc1b92111a58775937ac Mon Sep 17 00:00:00 2001 From: "Laurent Mignong (ACSONE)" Date: Mon, 30 Mar 2020 15:53:04 +0200 Subject: [PATCH 02/20] Import files from Acsone --- base_time_window/data/time_weekday.xml | 34 ++++ base_time_window/models/base_time_weekday.py | 70 +++++++ base_time_window/models/base_time_window.py | 96 +++++++++ base_time_window/security/ir.model.access.xml | 35 ++++ .../tests/test_delivery_window.py | 187 ++++++++++++++++++ 5 files changed, 422 insertions(+) create mode 100644 base_time_window/data/time_weekday.xml create mode 100644 base_time_window/models/base_time_weekday.py create mode 100644 base_time_window/models/base_time_window.py create mode 100644 base_time_window/security/ir.model.access.xml create mode 100644 base_time_window/tests/test_delivery_window.py diff --git a/base_time_window/data/time_weekday.xml b/base_time_window/data/time_weekday.xml new file mode 100644 index 000000000..6d1f14bf4 --- /dev/null +++ b/base_time_window/data/time_weekday.xml @@ -0,0 +1,34 @@ + + + + + + + 0 + + + + 1 + + + + 2 + + + + 3 + + + + 4 + + + + 5 + + + + 6 + + diff --git a/base_time_window/models/base_time_weekday.py b/base_time_window/models/base_time_weekday.py new file mode 100644 index 000000000..59ef2eda2 --- /dev/null +++ b/base_time_window/models/base_time_weekday.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models, tools + + +class DeliveryWeekDay(models.Model): + + _name = "delivery.week.day" + _description = "Delivery Week Day" + + name = fields.Selection( + selection=[ + ("0", "Monday"), + ("1", "Tuesday"), + ("2", "Wednesday"), + ("3", "Thursday"), + ("4", "Friday"), + ("5", "Saturday"), + ("6", "Sunday"), + ], + required=True, + ) + _sql_constraints = [ + ("name_uniq", "UNIQUE(name)", _("Name must be unique")) + ] + + @api.depends("name") + def _compute_display_name(self): + """ + WORKAROUND since Odoo doesn't handle properly records where name is + a selection + """ + translated_values = dict( + self._fields["name"]._description_selection(self.env) + ) + for record in self: + record.display_name = translated_values[record.name] + + @api.multi + def name_get(self): + """ + WORKAROUND since Odoo doesn't handle properly records where name is + a selection + """ + return [(r.id, r.display_name) for r in self] + + @api.model + @tools.ormcache("name") + def _get_id_by_name(self, name): + return self.search([("name", "=", name)], limit=1).id + + @api.model + def create(self, vals): + result = super(DeliveryWeekDay, self).create(vals) + self._get_id_by_name.clear_cache(self) + return result + + @api.multi + def write(self, vals): + result = super(DeliveryWeekDay, self).write(vals) + self._get_id_by_name.clear_cache(self) + return result + + @api.multi + def unlink(self): + result = super(DeliveryWeekDay, self).unlink() + self._get_id_by_name.clear_cache(self) + return result diff --git a/base_time_window/models/base_time_window.py b/base_time_window/models/base_time_window.py new file mode 100644 index 000000000..4786cfcd0 --- /dev/null +++ b/base_time_window/models/base_time_window.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import math + +from psycopg2.extensions import AsIs + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class DeliveryWindow(models.Model): + + _name = "delivery.window" + _description = "Delivery Window" + _order = "partner_id, start" + + start = fields.Float("From", required=True) + end = fields.Float("To", required=True) + week_day_ids = fields.Many2many( + comodel_name="alc.delivery.week.day", required=True + ) + partner_id = fields.Many2one( + "res.partner", required=True, index=True, ondelete='cascade' + ) + + @api.constrains("start", "end", "week_day_ids") + def check_window_no_onverlaps(self): + week_days_field = self._fields["week_day_ids"] + for record in self: + if record.start > record.end: + raise ValidationError( + _("%s must be > %s") + % ( + self.float_to_time_repr(record.end), + self.float_to_time_repr(record.start), + ) + ) + # here we use a plain SQL query to benefit of the numrange + # function available in PostgresSQL + # (http://www.postgresql.org/docs/current/static/rangetypes.html) + SQL = """ + SELECT + id + FROM + %(table)s w + join %(relation)s as d + on d.%(relation_window_fkey)s = w.id + WHERE + NUMRANGE(w.start::numeric, w.end::numeric) && + NUMRANGE(%(start)s::numeric, %(end)s::numeric) + AND w.id != %(window_id)s + AND d.%(relation_week_day_fkey)s in %(week_day_ids)s + AND w.partner_id = %(partner_id)s""" + self.env.cr.execute( + SQL, + dict( + table=AsIs(self._table), + relation=AsIs(week_days_field.relation), + relation_window_fkey=AsIs(week_days_field.column1), + relation_week_day_fkey=AsIs(week_days_field.column2), + start=record.start, + end=record.end, + window_id=record.id, + week_day_ids=tuple(record.week_day_ids.ids), + partner_id=record.partner_id.id, + ), + ) + res = self.env.cr.fetchall() + if res: + other = self.browse(res[0][0]) + raise ValidationError( + _("%s overlaps %s") + % (record.display_name, other.display_name) + ) + + @api.depends("start", "end", "week_day_ids") + def _compute_display_name(self): + for record in self: + "{days}: From {start} to {end}".format( + days=", ".join(record.week_day_ids.mapped("display_name")), + start=self.float_to_time_repr(record.start), + end=self.float_to_time_repr(record.end), + ) + + @api.model + def float_to_time_repr(self, value): + pattern = "%02d:%02d" + hour = math.floor(value) + min = round((value % 1) * 60) + if min == 60: + min = 0 + hour += 1 + + return pattern % (hour, min) diff --git a/base_time_window/security/ir.model.access.xml b/base_time_window/security/ir.model.access.xml new file mode 100644 index 000000000..a6b3fd50f --- /dev/null +++ b/base_time_window/security/ir.model.access.xml @@ -0,0 +1,35 @@ + + + + + + delivery.window.day access read + + + + + + + + + + delivery.window access read + + + + + + + + + + delivery.window access read + + + + + + + + diff --git a/base_time_window/tests/test_delivery_window.py b/base_time_window/tests/test_delivery_window.py new file mode 100644 index 000000000..0462f131e --- /dev/null +++ b/base_time_window/tests/test_delivery_window.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError +from odoo.tests import SavepointCase + + +class TestDeliveryWindow(SavepointCase): + @classmethod + def setUpClass(cls): + super(TestDeliveryWindow, cls).setUpClass() + cls.partner_1 = cls.env['res.partner'].create({'name': 'partner 1'}) + cls.partner_2 = cls.env['res.partner'].create({'name': 'patner 2'}) + cls.DeliveryWindow = cls.env["delivery.window"] + cls.monday = cls.env.ref( + "partner_delivery_window.delivery_weed_day_monday" + ) + cls.sunday = cls.env.ref( + "partner_delivery_window.delivery_weed_day_sunday" + ) + + def test_00(self): + """ + Data: + A partner without delivery window + Test Case: + Add a delivery window + Expected result: + A delivery window is created for the partner + """ + + self.assertFalse(self.partner_1.delivery_window_ids) + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 10.0, + "end": 12.0, + "week_day_ids": [(4, self.monday.id)], + } + ) + self.assertTrue(self.partner_1.delivery_window_ids) + delivery_window = self.partner_1.delivery_window_ids + self.assertEqual(delivery_window.start, 10.0) + self.assertEqual(delivery_window.end, 12.0) + self.assertEqual(delivery_window.week_day_ids, self.monday) + + def test_01(self): + """ + Data: + A partner without delivery window + Test Case: + 1 Add a delivery window + 2 unlink the partner + Expected result: + 1 A delivery window is created for the partner + 2 The delivery window is removed + """ + partner_id = self.partner_1.id + self.assertFalse(self.partner_1.delivery_window_ids) + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 10.0, + "end": 12.0, + "week_day_ids": [(4, self.monday.id)], + } + ) + self.assertTrue(self.partner_1.delivery_window_ids) + delivery_window = self.DeliveryWindow.search( + [("partner_id", "=", partner_id)] + ) + self.assertTrue(delivery_window) + self.partner_1.unlink() + self.assertFalse(delivery_window.exists()) + + def test_02(self): + """ + Data: + A partner without delivery window + Test Case: + 1 Add a delivery window + 2 Add a second delivery window that overlaps the first one (same day) + Expected result: + 1 A delivery window is created for the partner + 2 ValidationError is raised + """ + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 10.0, + "end": 12.0, + "week_day_ids": [(4, self.monday.id)], + } + ) + with self.assertRaises(ValidationError): + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 11.0, + "end": 13.0, + "week_day_ids": [(4, self.monday.id), (4, self.sunday.id)], + } + ) + + def test_03(self): + """ + Data: + A partner without delivery window + Test Case: + 1 Add a delivery window + 2 Add a second delivery window that overlaps the first one (another day) + Expected result: + 1 A delivery window is created for the partner + 2 A second delivery window is created for the partner + """ + self.assertFalse(self.partner_1.delivery_window_ids) + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 10.0, + "end": 12.0, + "week_day_ids": [(4, self.monday.id)], + } + ) + self.assertTrue(self.partner_1.delivery_window_ids) + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 11.0, + "end": 13.0, + "week_day_ids": [(4, self.sunday.id)], + } + ) + self.assertEquals(len(self.partner_1.delivery_window_ids), 2) + + def test_04(self): + """ + Data: + Partner 1 without delivery window + Partner 2 without delivery window + Test Case: + 1 Add a delivery window to partner 1 + 2 Add the same delivery window to partner 2 + Expected result: + 1 A delivery window is created for the partner 1 + 1 A delivery window is created for the partner 2 + """ + self.assertFalse(self.partner_1.delivery_window_ids) + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 10.0, + "end": 12.0, + "week_day_ids": [(4, self.monday.id)], + } + ) + self.assertTrue(self.partner_1.delivery_window_ids) + self.assertFalse(self.partner_2.delivery_window_ids) + self.DeliveryWindow.create( + { + "partner_id": self.partner_2.id, + "start": 10.0, + "end": 12.0, + "week_day_ids": [(4, self.monday.id)], + } + ) + self.assertTrue(self.partner_2.delivery_window_ids) + + def test_05(self): + """"" + Data: + Partner 1 without delivery window + Test Case: + Add a delivery window to partner 1 with end > start + Expected result: + ValidationError is raised + """ + with self.assertRaises(ValidationError): + self.DeliveryWindow.create( + { + "partner_id": self.partner_1.id, + "start": 14.0, + "end": 12.0, + "week_day_ids": [(4, self.monday.id)], + } + ) From 67f2168d2fd199c531d08175721c6a01ce0045dc Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Tue, 31 Mar 2020 17:52:07 +0200 Subject: [PATCH 03/20] Adapt module to v13.0 and new usage --- base_time_window/__init__.py | 3 +- base_time_window/__manifest__.py | 4 + base_time_window/data/time_weekday.xml | 14 +- base_time_window/models/__init__.py | 4 +- .../{base_time_weekday.py => time_weekday.py} | 15 +- ...se_time_window.py => time_window_mixin.py} | 73 ++++--- base_time_window/readme/CONTRIBUTORS.rst | 2 + base_time_window/readme/DESCRIPTION.rst | 1 + base_time_window/security/ir.model.access.xml | 26 +-- base_time_window/tests/__init__.py | 2 - .../tests/test_delivery_window.py | 187 ------------------ 11 files changed, 71 insertions(+), 260 deletions(-) rename base_time_window/models/{base_time_weekday.py => time_weekday.py} (83%) rename base_time_window/models/{base_time_window.py => time_window_mixin.py} (54%) create mode 100644 base_time_window/readme/CONTRIBUTORS.rst create mode 100644 base_time_window/readme/DESCRIPTION.rst delete mode 100644 base_time_window/tests/__init__.py delete mode 100644 base_time_window/tests/test_delivery_window.py diff --git a/base_time_window/__init__.py b/base_time_window/__init__.py index 5437c31a2..0650744f6 100644 --- a/base_time_window/__init__.py +++ b/base_time_window/__init__.py @@ -1,2 +1 @@ -# Copyright 2020 Camptocamp SA -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from . import models diff --git a/base_time_window/__manifest__.py b/base_time_window/__manifest__.py index 6e04aa360..353c0b3f9 100644 --- a/base_time_window/__manifest__.py +++ b/base_time_window/__manifest__.py @@ -9,5 +9,9 @@ "license": "AGPL-3", "website": "https://github.com/OCA/server-tools", "depends": ["base"], + "data": [ + "data/time_weekday.xml", + "security/ir.model.access.xml" + ], "installable": True, } diff --git a/base_time_window/data/time_weekday.xml b/base_time_window/data/time_weekday.xml index 6d1f14bf4..14407fddf 100644 --- a/base_time_window/data/time_weekday.xml +++ b/base_time_window/data/time_weekday.xml @@ -4,31 +4,31 @@ - + 0 - + 1 - + 2 - + 3 - + 4 - + 5 - + 6 diff --git a/base_time_window/models/__init__.py b/base_time_window/models/__init__.py index 5437c31a2..b878f0eaf 100644 --- a/base_time_window/models/__init__.py +++ b/base_time_window/models/__init__.py @@ -1,2 +1,2 @@ -# Copyright 2020 Camptocamp SA -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from . import base_time_weekday +from . import base_time_window diff --git a/base_time_window/models/base_time_weekday.py b/base_time_window/models/time_weekday.py similarity index 83% rename from base_time_window/models/base_time_weekday.py rename to base_time_window/models/time_weekday.py index 59ef2eda2..bf6489f5b 100644 --- a/base_time_window/models/base_time_weekday.py +++ b/base_time_window/models/time_weekday.py @@ -5,10 +5,10 @@ from odoo import _, api, fields, models, tools -class DeliveryWeekDay(models.Model): +class TimeWeekday(models.Model): - _name = "delivery.week.day" - _description = "Delivery Week Day" + _name = "time.weekday" + _description = "Time Week Day" name = fields.Selection( selection=[ @@ -38,7 +38,6 @@ class DeliveryWeekDay(models.Model): for record in self: record.display_name = translated_values[record.name] - @api.multi def name_get(self): """ WORKAROUND since Odoo doesn't handle properly records where name is @@ -53,18 +52,16 @@ class DeliveryWeekDay(models.Model): @api.model def create(self, vals): - result = super(DeliveryWeekDay, self).create(vals) + result = super().create(vals) self._get_id_by_name.clear_cache(self) return result - @api.multi def write(self, vals): - result = super(DeliveryWeekDay, self).write(vals) + result = super().write(vals) self._get_id_by_name.clear_cache(self) return result - @api.multi def unlink(self): - result = super(DeliveryWeekDay, self).unlink() + result = super().unlink() self._get_id_by_name.clear_cache(self) return result diff --git a/base_time_window/models/base_time_window.py b/base_time_window/models/time_window_mixin.py similarity index 54% rename from base_time_window/models/base_time_window.py rename to base_time_window/models/time_window_mixin.py index 4786cfcd0..68b24ca70 100644 --- a/base_time_window/models/base_time_window.py +++ b/base_time_window/models/time_window_mixin.py @@ -3,6 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import math +from datetime import time from psycopg2.extensions import AsIs @@ -10,24 +11,24 @@ from odoo import _, api, fields, models from odoo.exceptions import ValidationError -class DeliveryWindow(models.Model): +class TimeWindowMixin(models.AbstractModel): - _name = "delivery.window" - _description = "Delivery Window" - _order = "partner_id, start" + _name = "time.window.mixin" + _description = "Time Window" + _order = "start" + + # TODO patch api.constrains with field here? + _overlap_check_field = False start = fields.Float("From", required=True) end = fields.Float("To", required=True) - week_day_ids = fields.Many2many( - comodel_name="alc.delivery.week.day", required=True - ) - partner_id = fields.Many2one( - "res.partner", required=True, index=True, ondelete='cascade' + weekday_ids = fields.Many2many( + comodel_name="time.weekday", required=True ) - @api.constrains("start", "end", "week_day_ids") - def check_window_no_onverlaps(self): - week_days_field = self._fields["week_day_ids"] + @api.constrains("start", "end", "weekday_ids") + def check_window_no_overlaps(self): + weekdays_field = self._fields["weekday_ids"] for record in self: if record.start > record.end: raise ValidationError( @@ -51,20 +52,21 @@ class DeliveryWindow(models.Model): NUMRANGE(w.start::numeric, w.end::numeric) && NUMRANGE(%(start)s::numeric, %(end)s::numeric) AND w.id != %(window_id)s - AND d.%(relation_week_day_fkey)s in %(week_day_ids)s - AND w.partner_id = %(partner_id)s""" + AND d.%(relation_week_day_fkey)s in %(weekday_ids)s + AND w.%(check_field)s = %(check_field_id)s;""" self.env.cr.execute( SQL, dict( table=AsIs(self._table), - relation=AsIs(week_days_field.relation), - relation_window_fkey=AsIs(week_days_field.column1), - relation_week_day_fkey=AsIs(week_days_field.column2), + relation=AsIs(weekdays_field.relation), + relation_window_fkey=AsIs(weekdays_field.column1), + relation_week_day_fkey=AsIs(weekdays_field.column2), start=record.start, end=record.end, window_id=record.id, - week_day_ids=tuple(record.week_day_ids.ids), - partner_id=record.partner_id.id, + weekday_ids=tuple(record.weekday_ids.ids), + check_field=AsIs(self._overlap_check_field), + check_field_id=record[self._overlap_check_field].id, ), ) res = self.env.cr.fetchall() @@ -75,22 +77,37 @@ class DeliveryWindow(models.Model): % (record.display_name, other.display_name) ) - @api.depends("start", "end", "week_day_ids") + @api.depends("start", "end", "weekday_ids") def _compute_display_name(self): for record in self: - "{days}: From {start} to {end}".format( - days=", ".join(record.week_day_ids.mapped("display_name")), + record.display_name = _("{days}: From {start} to {end}").format( + days=", ".join(record.weekday_ids.mapped("display_name")), start=self.float_to_time_repr(record.start), end=self.float_to_time_repr(record.end), ) + @api.model + def _get_hour_min_from_value(self, value): + hour = math.floor(value) + minute = round((value % 1) * 60) + if minute == 60: + minute = 0 + hour += 1 + return hour, minute + @api.model def float_to_time_repr(self, value): pattern = "%02d:%02d" - hour = math.floor(value) - min = round((value % 1) * 60) - if min == 60: - min = 0 - hour += 1 + hour, minute = self._get_hour_min_from_value(value) + return pattern % (hour, minute) - return pattern % (hour, min) + @api.model + def float_to_time(self, value): + hour, minute = self._get_hour_min_from_value(value) + return time(hour=hour, minute=minute) + + def get_start_time(self): + return self.float_to_time(self.start) + + def get_end_time(self): + return self.float_to_time(self.end) diff --git a/base_time_window/readme/CONTRIBUTORS.rst b/base_time_window/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..d7222fd22 --- /dev/null +++ b/base_time_window/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Laurent Mignon +* Akim Juillerat diff --git a/base_time_window/readme/DESCRIPTION.rst b/base_time_window/readme/DESCRIPTION.rst new file mode 100644 index 000000000..f8c3d63ba --- /dev/null +++ b/base_time_window/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module provides base classes to manage time windows. diff --git a/base_time_window/security/ir.model.access.xml b/base_time_window/security/ir.model.access.xml index a6b3fd50f..440f0c5c1 100644 --- a/base_time_window/security/ir.model.access.xml +++ b/base_time_window/security/ir.model.access.xml @@ -3,33 +3,13 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> - - delivery.window.day access read - + + time.weekday access read + - - - delivery.window access read - - - - - - - - - - delivery.window access read - - - - - - - diff --git a/base_time_window/tests/__init__.py b/base_time_window/tests/__init__.py deleted file mode 100644 index 5437c31a2..000000000 --- a/base_time_window/tests/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright 2020 Camptocamp SA -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) diff --git a/base_time_window/tests/test_delivery_window.py b/base_time_window/tests/test_delivery_window.py deleted file mode 100644 index 0462f131e..000000000 --- a/base_time_window/tests/test_delivery_window.py +++ /dev/null @@ -1,187 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 ACSONE SA/NV -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.exceptions import ValidationError -from odoo.tests import SavepointCase - - -class TestDeliveryWindow(SavepointCase): - @classmethod - def setUpClass(cls): - super(TestDeliveryWindow, cls).setUpClass() - cls.partner_1 = cls.env['res.partner'].create({'name': 'partner 1'}) - cls.partner_2 = cls.env['res.partner'].create({'name': 'patner 2'}) - cls.DeliveryWindow = cls.env["delivery.window"] - cls.monday = cls.env.ref( - "partner_delivery_window.delivery_weed_day_monday" - ) - cls.sunday = cls.env.ref( - "partner_delivery_window.delivery_weed_day_sunday" - ) - - def test_00(self): - """ - Data: - A partner without delivery window - Test Case: - Add a delivery window - Expected result: - A delivery window is created for the partner - """ - - self.assertFalse(self.partner_1.delivery_window_ids) - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 10.0, - "end": 12.0, - "week_day_ids": [(4, self.monday.id)], - } - ) - self.assertTrue(self.partner_1.delivery_window_ids) - delivery_window = self.partner_1.delivery_window_ids - self.assertEqual(delivery_window.start, 10.0) - self.assertEqual(delivery_window.end, 12.0) - self.assertEqual(delivery_window.week_day_ids, self.monday) - - def test_01(self): - """ - Data: - A partner without delivery window - Test Case: - 1 Add a delivery window - 2 unlink the partner - Expected result: - 1 A delivery window is created for the partner - 2 The delivery window is removed - """ - partner_id = self.partner_1.id - self.assertFalse(self.partner_1.delivery_window_ids) - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 10.0, - "end": 12.0, - "week_day_ids": [(4, self.monday.id)], - } - ) - self.assertTrue(self.partner_1.delivery_window_ids) - delivery_window = self.DeliveryWindow.search( - [("partner_id", "=", partner_id)] - ) - self.assertTrue(delivery_window) - self.partner_1.unlink() - self.assertFalse(delivery_window.exists()) - - def test_02(self): - """ - Data: - A partner without delivery window - Test Case: - 1 Add a delivery window - 2 Add a second delivery window that overlaps the first one (same day) - Expected result: - 1 A delivery window is created for the partner - 2 ValidationError is raised - """ - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 10.0, - "end": 12.0, - "week_day_ids": [(4, self.monday.id)], - } - ) - with self.assertRaises(ValidationError): - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 11.0, - "end": 13.0, - "week_day_ids": [(4, self.monday.id), (4, self.sunday.id)], - } - ) - - def test_03(self): - """ - Data: - A partner without delivery window - Test Case: - 1 Add a delivery window - 2 Add a second delivery window that overlaps the first one (another day) - Expected result: - 1 A delivery window is created for the partner - 2 A second delivery window is created for the partner - """ - self.assertFalse(self.partner_1.delivery_window_ids) - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 10.0, - "end": 12.0, - "week_day_ids": [(4, self.monday.id)], - } - ) - self.assertTrue(self.partner_1.delivery_window_ids) - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 11.0, - "end": 13.0, - "week_day_ids": [(4, self.sunday.id)], - } - ) - self.assertEquals(len(self.partner_1.delivery_window_ids), 2) - - def test_04(self): - """ - Data: - Partner 1 without delivery window - Partner 2 without delivery window - Test Case: - 1 Add a delivery window to partner 1 - 2 Add the same delivery window to partner 2 - Expected result: - 1 A delivery window is created for the partner 1 - 1 A delivery window is created for the partner 2 - """ - self.assertFalse(self.partner_1.delivery_window_ids) - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 10.0, - "end": 12.0, - "week_day_ids": [(4, self.monday.id)], - } - ) - self.assertTrue(self.partner_1.delivery_window_ids) - self.assertFalse(self.partner_2.delivery_window_ids) - self.DeliveryWindow.create( - { - "partner_id": self.partner_2.id, - "start": 10.0, - "end": 12.0, - "week_day_ids": [(4, self.monday.id)], - } - ) - self.assertTrue(self.partner_2.delivery_window_ids) - - def test_05(self): - """"" - Data: - Partner 1 without delivery window - Test Case: - Add a delivery window to partner 1 with end > start - Expected result: - ValidationError is raised - """ - with self.assertRaises(ValidationError): - self.DeliveryWindow.create( - { - "partner_id": self.partner_1.id, - "start": 14.0, - "end": 12.0, - "week_day_ids": [(4, self.monday.id)], - } - ) From c56676d281fe950a2a83831809c204338f6d6b92 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Wed, 1 Apr 2020 11:16:57 +0200 Subject: [PATCH 04/20] Adapt test module --- base_time_window/models/__init__.py | 4 ++-- base_time_window/readme/DESCRIPTION.rst | 3 ++- base_time_window/readme/USAGE.rst | 30 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 base_time_window/readme/USAGE.rst diff --git a/base_time_window/models/__init__.py b/base_time_window/models/__init__.py index b878f0eaf..122ebbf3e 100644 --- a/base_time_window/models/__init__.py +++ b/base_time_window/models/__init__.py @@ -1,2 +1,2 @@ -from . import base_time_weekday -from . import base_time_window +from . import time_weekday +from . import time_window_mixin diff --git a/base_time_window/readme/DESCRIPTION.rst b/base_time_window/readme/DESCRIPTION.rst index f8c3d63ba..ad077245b 100644 --- a/base_time_window/readme/DESCRIPTION.rst +++ b/base_time_window/readme/DESCRIPTION.rst @@ -1 +1,2 @@ -This module provides base classes to manage time windows. +This module provides base classes and models to manage time windows through +`time.window.mixin`. diff --git a/base_time_window/readme/USAGE.rst b/base_time_window/readme/USAGE.rst new file mode 100644 index 000000000..f27eb7352 --- /dev/null +++ b/base_time_window/readme/USAGE.rst @@ -0,0 +1,30 @@ +Example implementation for the mixin can be found in module `test_base_time_window`. + +As a time window will always be linked to a related model thourgh a M2o relation, +when defining the new model inheriting the mixin, one should pay attention to the +following points in order to have the overlapping check work properly: + +- Define class property `_overlap_check_field`: This must state the M2o field to + use for the to check of overlapping time window records linked to a specific + record of the related model. + +- Add the M2o field to the related model in the `api.constrains`: + + +For example: + +.. code-block:: python + + class PartnerTimeWindow(models.Model): + _name = 'partner.time.window' + _inherit = 'time.window.mixin' + + partner_id = fields.Many2one( + res.partner', required=True, index=True, ondelete='cascade' + ) + + _overlap_check_field = 'partner_id' + + @api.constrains('partner_id') + def check_window_no_overlaps(self): + return super().check_window_no_overlaps() From e3910a572b755bfd9624a6f9ed4b04de2412c43b Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Fri, 3 Apr 2020 12:12:55 +0200 Subject: [PATCH 05/20] Fixes and ROADMAP --- base_time_window/models/time_window_mixin.py | 51 +++++++++++--------- base_time_window/readme/ROADMAP.rst | 11 +++++ 2 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 base_time_window/readme/ROADMAP.rst diff --git a/base_time_window/models/time_window_mixin.py b/base_time_window/models/time_window_mixin.py index 68b24ca70..d4bb4d192 100644 --- a/base_time_window/models/time_window_mixin.py +++ b/base_time_window/models/time_window_mixin.py @@ -9,35 +9,38 @@ from psycopg2.extensions import AsIs from odoo import _, api, fields, models from odoo.exceptions import ValidationError +from odoo.tools.misc import format_time class TimeWindowMixin(models.AbstractModel): _name = "time.window.mixin" _description = "Time Window" - _order = "start" + _order = "time_window_start" # TODO patch api.constrains with field here? - _overlap_check_field = False + _time_window_overlap_check_field = False - start = fields.Float("From", required=True) - end = fields.Float("To", required=True) - weekday_ids = fields.Many2many( + time_window_start = fields.Float("From", required=True) + time_window_end = fields.Float("To", required=True) + time_window_weekday_ids = fields.Many2many( comodel_name="time.weekday", required=True ) - @api.constrains("start", "end", "weekday_ids") + @api.constrains("time_window_start", "time_window_end", "time_window_weekday_ids") def check_window_no_overlaps(self): - weekdays_field = self._fields["weekday_ids"] + weekdays_field = self._fields["time_window_weekday_ids"] for record in self: - if record.start > record.end: + if record.time_window_start > record.time_window_end: raise ValidationError( _("%s must be > %s") % ( - self.float_to_time_repr(record.end), - self.float_to_time_repr(record.start), + self.float_to_time_repr(record.time_window_end), + self.float_to_time_repr(record.time_window_start), ) ) + if not record.time_window_weekday_ids: + raise ValidationError(_("At least one time.weekday is required")) # here we use a plain SQL query to benefit of the numrange # function available in PostgresSQL # (http://www.postgresql.org/docs/current/static/rangetypes.html) @@ -49,7 +52,7 @@ class TimeWindowMixin(models.AbstractModel): join %(relation)s as d on d.%(relation_window_fkey)s = w.id WHERE - NUMRANGE(w.start::numeric, w.end::numeric) && + NUMRANGE(w.time_window_start::numeric, w.time_window_end::numeric) && NUMRANGE(%(start)s::numeric, %(end)s::numeric) AND w.id != %(window_id)s AND d.%(relation_week_day_fkey)s in %(weekday_ids)s @@ -61,12 +64,12 @@ class TimeWindowMixin(models.AbstractModel): relation=AsIs(weekdays_field.relation), relation_window_fkey=AsIs(weekdays_field.column1), relation_week_day_fkey=AsIs(weekdays_field.column2), - start=record.start, - end=record.end, + start=record.time_window_start, + end=record.time_window_end, window_id=record.id, - weekday_ids=tuple(record.weekday_ids.ids), - check_field=AsIs(self._overlap_check_field), - check_field_id=record[self._overlap_check_field].id, + weekday_ids=tuple(record.time_window_weekday_ids.ids), + check_field=AsIs(self._time_window_overlap_check_field), + check_field_id=record[self._time_window_overlap_check_field].id, ), ) res = self.env.cr.fetchall() @@ -77,13 +80,13 @@ class TimeWindowMixin(models.AbstractModel): % (record.display_name, other.display_name) ) - @api.depends("start", "end", "weekday_ids") + @api.depends("time_window_start", "time_window_end", "time_window_weekday_ids") def _compute_display_name(self): for record in self: record.display_name = _("{days}: From {start} to {end}").format( - days=", ".join(record.weekday_ids.mapped("display_name")), - start=self.float_to_time_repr(record.start), - end=self.float_to_time_repr(record.end), + days=", ".join(record.time_window_weekday_ids.mapped("display_name")), + start=format_time(self.env, record.get_time_window_start_time()), + end=format_time(self.env, record.get_time_window_end_time()), ) @api.model @@ -106,8 +109,8 @@ class TimeWindowMixin(models.AbstractModel): hour, minute = self._get_hour_min_from_value(value) return time(hour=hour, minute=minute) - def get_start_time(self): - return self.float_to_time(self.start) + def get_time_window_start_time(self): + return self.float_to_time(self.time_window_start) - def get_end_time(self): - return self.float_to_time(self.end) + def get_time_window_end_time(self): + return self.float_to_time(self.time_window_end) diff --git a/base_time_window/readme/ROADMAP.rst b/base_time_window/readme/ROADMAP.rst new file mode 100644 index 000000000..50b5d9b78 --- /dev/null +++ b/base_time_window/readme/ROADMAP.rst @@ -0,0 +1,11 @@ +* Storing times using `float_time` widget requires extra processing to ensure + computations are done in the right timezone, because the value is not stored + as UTC in the database, and must therefore be related to a `tz` field. + + `float_time` in this sense should only be used for durations and not for a + "point in time" as this is always needs a Date for a timezone conversion to + be done properly. (Because a conversion from UTC to e.g. Europe/Brussels won't + give the same result in winter or summer because of Daylight Saving Time). + + Therefore the right move would be to use a `resource.calendar` to define time + windows using Datetime with recurrences. From 02feb9457d3014776cde7c3189c9522029b0a8a6 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Wed, 15 Apr 2020 12:45:17 +0200 Subject: [PATCH 06/20] [IMP] base_time_window: black, isort --- base_time_window/__manifest__.py | 5 +---- base_time_window/data/time_weekday.xml | 10 +--------- base_time_window/models/time_weekday.py | 9 ++------- base_time_window/models/time_window_mixin.py | 9 ++++----- base_time_window/security/ir.model.access.xml | 15 +++++++-------- 5 files changed, 15 insertions(+), 33 deletions(-) diff --git a/base_time_window/__manifest__.py b/base_time_window/__manifest__.py index 353c0b3f9..7c4b6b582 100644 --- a/base_time_window/__manifest__.py +++ b/base_time_window/__manifest__.py @@ -9,9 +9,6 @@ "license": "AGPL-3", "website": "https://github.com/OCA/server-tools", "depends": ["base"], - "data": [ - "data/time_weekday.xml", - "security/ir.model.access.xml" - ], + "data": ["data/time_weekday.xml", "security/ir.model.access.xml"], "installable": True, } diff --git a/base_time_window/data/time_weekday.xml b/base_time_window/data/time_weekday.xml index 14407fddf..8c2837e5d 100644 --- a/base_time_window/data/time_weekday.xml +++ b/base_time_window/data/time_weekday.xml @@ -1,33 +1,25 @@ - + - - 0 - 1 - 2 - 3 - 4 - 5 - 6 diff --git a/base_time_window/models/time_weekday.py b/base_time_window/models/time_weekday.py index bf6489f5b..78d17ecd3 100644 --- a/base_time_window/models/time_weekday.py +++ b/base_time_window/models/time_weekday.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2020 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -22,9 +21,7 @@ class TimeWeekday(models.Model): ], required=True, ) - _sql_constraints = [ - ("name_uniq", "UNIQUE(name)", _("Name must be unique")) - ] + _sql_constraints = [("name_uniq", "UNIQUE(name)", _("Name must be unique"))] @api.depends("name") def _compute_display_name(self): @@ -32,9 +29,7 @@ class TimeWeekday(models.Model): WORKAROUND since Odoo doesn't handle properly records where name is a selection """ - translated_values = dict( - self._fields["name"]._description_selection(self.env) - ) + translated_values = dict(self._fields["name"]._description_selection(self.env)) for record in self: record.display_name = translated_values[record.name] diff --git a/base_time_window/models/time_window_mixin.py b/base_time_window/models/time_window_mixin.py index d4bb4d192..da62f71d4 100644 --- a/base_time_window/models/time_window_mixin.py +++ b/base_time_window/models/time_window_mixin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2020 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -52,8 +51,9 @@ class TimeWindowMixin(models.AbstractModel): join %(relation)s as d on d.%(relation_window_fkey)s = w.id WHERE - NUMRANGE(w.time_window_start::numeric, w.time_window_end::numeric) && - NUMRANGE(%(start)s::numeric, %(end)s::numeric) + NUMRANGE(w.time_window_start::numeric, + w.time_window_end::numeric) && + NUMRANGE(%(start)s::numeric, %(end)s::numeric) AND w.id != %(window_id)s AND d.%(relation_week_day_fkey)s in %(weekday_ids)s AND w.%(check_field)s = %(check_field_id)s;""" @@ -76,8 +76,7 @@ class TimeWindowMixin(models.AbstractModel): if res: other = self.browse(res[0][0]) raise ValidationError( - _("%s overlaps %s") - % (record.display_name, other.display_name) + _("%s overlaps %s") % (record.display_name, other.display_name) ) @api.depends("time_window_start", "time_window_end", "time_window_weekday_ids") diff --git a/base_time_window/security/ir.model.access.xml b/base_time_window/security/ir.model.access.xml index 440f0c5c1..886ae01b9 100644 --- a/base_time_window/security/ir.model.access.xml +++ b/base_time_window/security/ir.model.access.xml @@ -1,15 +1,14 @@ - + - time.weekday access read - - - - - - + + + + + + From f5c6d92174d5554a32c2b977482e9a6a93c5c707 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Wed, 15 Apr 2020 14:01:14 +0000 Subject: [PATCH 07/20] [UPD] Update base_time_window.pot --- base_time_window/i18n/base_time_window.pot | 148 +++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 base_time_window/i18n/base_time_window.pot diff --git a/base_time_window/i18n/base_time_window.pot b/base_time_window/i18n/base_time_window.pot new file mode 100644 index 000000000..148b303e4 --- /dev/null +++ b/base_time_window/i18n/base_time_window.pot @@ -0,0 +1,148 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_time_window +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "%s must be > %s" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "%s overlaps %s" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "At least one time.weekday is required" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__create_uid +msgid "Created by" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__create_date +msgid "Created on" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__display_name +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__display_name +msgid "Display Name" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__4 +msgid "Friday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_start +msgid "From" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__id +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__id +msgid "ID" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday____last_update +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin____last_update +msgid "Last Modified on" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__write_date +msgid "Last Updated on" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__0 +msgid "Monday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__name +msgid "Name" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_weekday.py:0 +#: model:ir.model.constraint,message:base_time_window.constraint_time_weekday_name_uniq +#, python-format +msgid "Name must be unique" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__5 +msgid "Saturday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__6 +msgid "Sunday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__3 +msgid "Thursday" +msgstr "" + +#. module: base_time_window +#: model:ir.model,name:base_time_window.model_time_weekday +msgid "Time Week Day" +msgstr "" + +#. module: base_time_window +#: model:ir.model,name:base_time_window.model_time_window_mixin +msgid "Time Window" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_weekday_ids +msgid "Time Window Weekday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_end +msgid "To" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__1 +msgid "Tuesday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__2 +msgid "Wednesday" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "{days}: From {start} to {end}" +msgstr "" From ee132b9d9ec216e6554990e3601f385ab77820c4 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 15 Apr 2020 14:14:50 +0000 Subject: [PATCH 08/20] [UPD] README.rst --- base_time_window/README.rst | 125 +++++ .../static/description/index.html | 468 ++++++++++++++++++ 2 files changed, 593 insertions(+) create mode 100644 base_time_window/README.rst create mode 100644 base_time_window/static/description/index.html diff --git a/base_time_window/README.rst b/base_time_window/README.rst new file mode 100644 index 000000000..b1de1e3f0 --- /dev/null +++ b/base_time_window/README.rst @@ -0,0 +1,125 @@ +================ +Base Time Window +================ + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/13.0/base_time_window + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-13-0/server-tools-13-0-base_time_window + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/149/13.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides base classes and models to manage time windows through +`time.window.mixin`. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Example implementation for the mixin can be found in module `test_base_time_window`. + +As a time window will always be linked to a related model thourgh a M2o relation, +when defining the new model inheriting the mixin, one should pay attention to the +following points in order to have the overlapping check work properly: + +- Define class property `_overlap_check_field`: This must state the M2o field to + use for the to check of overlapping time window records linked to a specific + record of the related model. + +- Add the M2o field to the related model in the `api.constrains`: + + +For example: + +.. code-block:: python + + class PartnerTimeWindow(models.Model): + _name = 'partner.time.window' + _inherit = 'time.window.mixin' + + partner_id = fields.Many2one( + res.partner', required=True, index=True, ondelete='cascade' + ) + + _overlap_check_field = 'partner_id' + + @api.constrains('partner_id') + def check_window_no_overlaps(self): + return super().check_window_no_overlaps() + +Known issues / Roadmap +====================== + +* Storing times using `float_time` widget requires extra processing to ensure + computations are done in the right timezone, because the value is not stored + as UTC in the database, and must therefore be related to a `tz` field. + + `float_time` in this sense should only be used for durations and not for a + "point in time" as this is always needs a Date for a timezone conversion to + be done properly. (Because a conversion from UTC to e.g. Europe/Brussels won't + give the same result in winter or summer because of Daylight Saving Time). + + Therefore the right move would be to use a `resource.calendar` to define time + windows using Datetime with recurrences. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ACSONE SA/NV +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* Laurent Mignon +* Akim Juillerat + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_time_window/static/description/index.html b/base_time_window/static/description/index.html new file mode 100644 index 000000000..4871c2486 --- /dev/null +++ b/base_time_window/static/description/index.html @@ -0,0 +1,468 @@ + + + + + + +Base Time Window + + + +
+

Base Time Window

+ + +

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

This module provides base classes and models to manage time windows through +time.window.mixin.

+

Table of contents

+ +
+

Usage

+

Example implementation for the mixin can be found in module test_base_time_window.

+

As a time window will always be linked to a related model thourgh a M2o relation, +when defining the new model inheriting the mixin, one should pay attention to the +following points in order to have the overlapping check work properly:

+
    +
  • Define class property _overlap_check_field: This must state the M2o field to +use for the to check of overlapping time window records linked to a specific +record of the related model.
  • +
  • Add the M2o field to the related model in the api.constrains:
  • +
+

For example:

+
+class PartnerTimeWindow(models.Model):
+    _name = 'partner.time.window'
+    _inherit = 'time.window.mixin'
+
+    partner_id = fields.Many2one(
+        res.partner', required=True, index=True, ondelete='cascade'
+    )
+
+    _overlap_check_field = 'partner_id'
+
+    @api.constrains('partner_id')
+    def check_window_no_overlaps(self):
+        return super().check_window_no_overlaps()
+
+
+
+

Known issues / Roadmap

+
    +
  • Storing times using float_time widget requires extra processing to ensure +computations are done in the right timezone, because the value is not stored +as UTC in the database, and must therefore be related to a tz field.

    +

    float_time in this sense should only be used for durations and not for a +“point in time” as this is always needs a Date for a timezone conversion to +be done properly. (Because a conversion from UTC to e.g. Europe/Brussels won’t +give the same result in winter or summer because of Daylight Saving Time).

    +

    Therefore the right move would be to use a resource.calendar to define time +windows using Datetime with recurrences.

    +
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/server-tools project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 0c7af185fb5dc86ab5a062811bae16b313ecbcb6 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 15 Apr 2020 14:14:50 +0000 Subject: [PATCH 09/20] [ADD] icon.png --- base_time_window/static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 base_time_window/static/description/icon.png diff --git a/base_time_window/static/description/icon.png b/base_time_window/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From cbe187c73d60a630fcee3c5b822adaf7e8885483 Mon Sep 17 00:00:00 2001 From: "dung.tran" Date: Mon, 11 Jan 2021 18:50:12 +0700 Subject: [PATCH 10/20] [MIG] base_time_window: Migration to 14.0 --- base_time_window/README.rst | 21 +++++++++++++----- base_time_window/__manifest__.py | 2 +- base_time_window/readme/CONTRIBUTORS.rst | 4 ++++ base_time_window/readme/CREDITS.rst | 3 +++ .../static/description/index.html | 22 ++++++++++++++----- 5 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 base_time_window/readme/CREDITS.rst diff --git a/base_time_window/README.rst b/base_time_window/README.rst index b1de1e3f0..a5baf8dd2 100644 --- a/base_time_window/README.rst +++ b/base_time_window/README.rst @@ -14,13 +14,13 @@ Base Time Window :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github - :target: https://github.com/OCA/server-tools/tree/13.0/base_time_window + :target: https://github.com/OCA/server-tools/tree/14.0/base_time_window :alt: OCA/server-tools .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/server-tools-13-0/server-tools-13-0-base_time_window + :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-base_time_window :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/149/13.0 + :target: https://runbot.odoo-community.org/runbot/149/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -88,7 +88,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -107,6 +107,17 @@ Contributors * Laurent Mignon * Akim Juillerat +Trobz + +* Dung Tran + +Other credits +~~~~~~~~~~~~~ + +The development of this module has been financially supported by: + +* Camptocamp + Maintainers ~~~~~~~~~~~ @@ -120,6 +131,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/server-tools `_ project on GitHub. +This module is part of the `OCA/server-tools `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_time_window/__manifest__.py b/base_time_window/__manifest__.py index 7c4b6b582..52dfb12e6 100644 --- a/base_time_window/__manifest__.py +++ b/base_time_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Base Time Window", "summary": "Base model to handle time windows", - "version": "13.0.1.0.0", + "version": "14.0.1.0.0", "category": "Technical Settings", "author": "ACSONE SA/NV, Camptocamp, Odoo Community Association (OCA)", "license": "AGPL-3", diff --git a/base_time_window/readme/CONTRIBUTORS.rst b/base_time_window/readme/CONTRIBUTORS.rst index d7222fd22..aa25acd2a 100644 --- a/base_time_window/readme/CONTRIBUTORS.rst +++ b/base_time_window/readme/CONTRIBUTORS.rst @@ -1,2 +1,6 @@ * Laurent Mignon * Akim Juillerat + +Trobz + +* Dung Tran diff --git a/base_time_window/readme/CREDITS.rst b/base_time_window/readme/CREDITS.rst new file mode 100644 index 000000000..f5cc070c7 --- /dev/null +++ b/base_time_window/readme/CREDITS.rst @@ -0,0 +1,3 @@ +The development of this module has been financially supported by: + +* Camptocamp diff --git a/base_time_window/static/description/index.html b/base_time_window/static/description/index.html index 4871c2486..177c3ef8b 100644 --- a/base_time_window/static/description/index.html +++ b/base_time_window/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

This module provides base classes and models to manage time windows through time.window.mixin.

Table of contents

@@ -379,7 +379,8 @@ ul.auto-toc {
  • Credits
  • @@ -433,7 +434,7 @@ windows using Datetime with recurrences.

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    @@ -451,15 +452,26 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
  • Laurent Mignon <laurent.mignon@acsone.eu>
  • Akim Juillerat <akim.juillerat@camptocamp.com>
  • +

    Trobz

    + +
    +
    +

    Other credits

    +

    The development of this module has been financially supported by:

    +
      +
    • Camptocamp
    • +
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    -

    This module is part of the OCA/server-tools project on GitHub.

    +

    This module is part of the OCA/server-tools project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    From c213a0e94a6326bc489a2cc7eba29a81662480d4 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Mon, 21 Jun 2021 13:29:07 +0000 Subject: [PATCH 11/20] [UPD] Update base_time_window.pot --- base_time_window/i18n/base_time_window.pot | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/base_time_window/i18n/base_time_window.pot b/base_time_window/i18n/base_time_window.pot index 148b303e4..543b71ea5 100644 --- a/base_time_window/i18n/base_time_window.pot +++ b/base_time_window/i18n/base_time_window.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 13.0\n" +"Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -101,6 +101,12 @@ msgstr "" msgid "Saturday" msgstr "" +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__smart_search +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__smart_search +msgid "Smart Search" +msgstr "" + #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__6 msgid "Sunday" From bbc233f97e3e7a71c754805ac3af4c3496964dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthieu=20M=C3=A9quignon?= Date: Wed, 15 Sep 2021 18:44:30 +0200 Subject: [PATCH 12/20] base_time_window: Disallow hours > 23 --- base_time_window/models/time_window_mixin.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/base_time_window/models/time_window_mixin.py b/base_time_window/models/time_window_mixin.py index da62f71d4..a80947d98 100644 --- a/base_time_window/models/time_window_mixin.py +++ b/base_time_window/models/time_window_mixin.py @@ -88,6 +88,19 @@ class TimeWindowMixin(models.AbstractModel): end=format_time(self.env, record.get_time_window_end_time()), ) + @api.constrains("time_window_start", "time_window_end") + def _check_window_under_twenty_four_hours(self): + error_msg = _("Hour should be between 00 and 23") + for record in self: + if record.time_window_start: + hour, minute = self._get_hour_min_from_value(record.time_window_start) + if hour > 23: + raise ValidationError(error_msg) + if record.time_window_end: + hour, minute = self._get_hour_min_from_value(record.time_window_end) + if hour > 23: + raise ValidationError(error_msg) + @api.model def _get_hour_min_from_value(self, value): hour = math.floor(value) From 79e92480cadc141608e437a82f638f5d3f5aadd2 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Wed, 12 Jan 2022 07:10:08 +0000 Subject: [PATCH 13/20] [UPD] Update base_time_window.pot --- base_time_window/i18n/base_time_window.pot | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/base_time_window/i18n/base_time_window.pot b/base_time_window/i18n/base_time_window.pot index 543b71ea5..4ae1e4058 100644 --- a/base_time_window/i18n/base_time_window.pot +++ b/base_time_window/i18n/base_time_window.pot @@ -57,6 +57,12 @@ msgstr "" msgid "From" msgstr "" +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "Hour should be between 00 and 23" +msgstr "" + #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__id #: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__id From db038c4e2e41c00c5f30da94a42ceb58f9ce2b78 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 12 Jan 2022 07:29:07 +0000 Subject: [PATCH 14/20] base_time_window 14.0.1.0.1 --- base_time_window/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base_time_window/__manifest__.py b/base_time_window/__manifest__.py index 52dfb12e6..ebf61a702 100644 --- a/base_time_window/__manifest__.py +++ b/base_time_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Base Time Window", "summary": "Base model to handle time windows", - "version": "14.0.1.0.0", + "version": "14.0.1.0.1", "category": "Technical Settings", "author": "ACSONE SA/NV, Camptocamp, Odoo Community Association (OCA)", "license": "AGPL-3", From 1b9e58d0b826665de3f1ffc37e08df07142e4069 Mon Sep 17 00:00:00 2001 From: Jasmin Solanki Date: Fri, 8 Jul 2022 15:43:57 +0530 Subject: [PATCH 15/20] [MIG] base_time_window: Migration to 15.0 --- base_time_window/__manifest__.py | 2 +- base_time_window/models/time_window_mixin.py | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/base_time_window/__manifest__.py b/base_time_window/__manifest__.py index ebf61a702..327fa0df5 100644 --- a/base_time_window/__manifest__.py +++ b/base_time_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Base Time Window", "summary": "Base model to handle time windows", - "version": "14.0.1.0.1", + "version": "15.0.1.0.0", "category": "Technical Settings", "author": "ACSONE SA/NV, Camptocamp, Odoo Community Association (OCA)", "license": "AGPL-3", diff --git a/base_time_window/models/time_window_mixin.py b/base_time_window/models/time_window_mixin.py index a80947d98..b8079043a 100644 --- a/base_time_window/models/time_window_mixin.py +++ b/base_time_window/models/time_window_mixin.py @@ -12,7 +12,6 @@ from odoo.tools.misc import format_time class TimeWindowMixin(models.AbstractModel): - _name = "time.window.mixin" _description = "Time Window" _order = "time_window_start" @@ -32,10 +31,14 @@ class TimeWindowMixin(models.AbstractModel): for record in self: if record.time_window_start > record.time_window_end: raise ValidationError( - _("%s must be > %s") + _("%(end_time)s must be > %(start_time)s") % ( - self.float_to_time_repr(record.time_window_end), - self.float_to_time_repr(record.time_window_start), + { + "end_time": self.float_to_time_repr(record.time_window_end), + "start_time": self.float_to_time_repr( + record.time_window_start + ), + } ) ) if not record.time_window_weekday_ids: @@ -76,7 +79,13 @@ class TimeWindowMixin(models.AbstractModel): if res: other = self.browse(res[0][0]) raise ValidationError( - _("%s overlaps %s") % (record.display_name, other.display_name) + _("%(record_name)s overlaps %(other_name)s") + % ( + { + "record_name": record.display_name, + "other_name": other.display_name, + } + ) ) @api.depends("time_window_start", "time_window_end", "time_window_weekday_ids") From 5662300588fe2368ba7fd20df6aaeb19745e58b8 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Fri, 15 Jul 2022 09:14:17 +0000 Subject: [PATCH 16/20] [UPD] Update base_time_window.pot --- base_time_window/i18n/base_time_window.pot | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/base_time_window/i18n/base_time_window.pot b/base_time_window/i18n/base_time_window.pot index 4ae1e4058..228cf71b1 100644 --- a/base_time_window/i18n/base_time_window.pot +++ b/base_time_window/i18n/base_time_window.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" +"Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -16,13 +16,13 @@ msgstr "" #. module: base_time_window #: code:addons/base_time_window/models/time_window_mixin.py:0 #, python-format -msgid "%s must be > %s" +msgid "%(end_time)s must be > %(start_time)s" msgstr "" #. module: base_time_window #: code:addons/base_time_window/models/time_window_mixin.py:0 #, python-format -msgid "%s overlaps %s" +msgid "%(record_name)s overlaps %(other_name)s" msgstr "" #. module: base_time_window @@ -43,7 +43,6 @@ msgstr "" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__display_name -#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__display_name msgid "Display Name" msgstr "" @@ -65,13 +64,11 @@ msgstr "" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__id -#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__id msgid "ID" msgstr "" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday____last_update -#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin____last_update msgid "Last Modified on" msgstr "" @@ -107,12 +104,6 @@ msgstr "" msgid "Saturday" msgstr "" -#. module: base_time_window -#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__smart_search -#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__smart_search -msgid "Smart Search" -msgstr "" - #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__6 msgid "Sunday" From 1265d8c36d44e2f8db9826784f62173d8698ec06 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 15 Jul 2022 09:17:13 +0000 Subject: [PATCH 17/20] [UPD] README.rst --- base_time_window/README.rst | 10 +++++----- base_time_window/static/description/index.html | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/base_time_window/README.rst b/base_time_window/README.rst index a5baf8dd2..59c1f1de1 100644 --- a/base_time_window/README.rst +++ b/base_time_window/README.rst @@ -14,13 +14,13 @@ Base Time Window :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github - :target: https://github.com/OCA/server-tools/tree/14.0/base_time_window + :target: https://github.com/OCA/server-tools/tree/15.0/base_time_window :alt: OCA/server-tools .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-base_time_window + :target: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-base_time_window :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/149/14.0 + :target: https://runbot.odoo-community.org/runbot/149/15.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -88,7 +88,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -131,6 +131,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/server-tools `_ project on GitHub. +This module is part of the `OCA/server-tools `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_time_window/static/description/index.html b/base_time_window/static/description/index.html index 177c3ef8b..edc04dae1 100644 --- a/base_time_window/static/description/index.html +++ b/base_time_window/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

    +

    Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

    This module provides base classes and models to manage time windows through time.window.mixin.

    Table of contents

    @@ -434,7 +434,7 @@ windows using Datetime with recurrences.

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

    @@ -471,7 +471,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    -

    This module is part of the OCA/server-tools project on GitHub.

    +

    This module is part of the OCA/server-tools project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    From 3cb3da5a984edca347467b7e487429d964bd2778 Mon Sep 17 00:00:00 2001 From: Ignacio Buioli Date: Sun, 4 Sep 2022 03:50:36 +0000 Subject: [PATCH 18/20] Added translation using Weblate (Spanish (Argentina)) --- base_time_window/i18n/es_AR.po | 152 +++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 base_time_window/i18n/es_AR.po diff --git a/base_time_window/i18n/es_AR.po b/base_time_window/i18n/es_AR.po new file mode 100644 index 000000000..c7072a676 --- /dev/null +++ b/base_time_window/i18n/es_AR.po @@ -0,0 +1,152 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_time_window +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es_AR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "%(end_time)s must be > %(start_time)s" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "%(record_name)s overlaps %(other_name)s" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "At least one time.weekday is required" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__create_uid +msgid "Created by" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__create_date +msgid "Created on" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__display_name +msgid "Display Name" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__4 +msgid "Friday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_start +msgid "From" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "Hour should be between 00 and 23" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__id +msgid "ID" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday____last_update +msgid "Last Modified on" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__write_date +msgid "Last Updated on" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__0 +msgid "Monday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_weekday__name +msgid "Name" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_weekday.py:0 +#: model:ir.model.constraint,message:base_time_window.constraint_time_weekday_name_uniq +#, python-format +msgid "Name must be unique" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__5 +msgid "Saturday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__6 +msgid "Sunday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__3 +msgid "Thursday" +msgstr "" + +#. module: base_time_window +#: model:ir.model,name:base_time_window.model_time_weekday +msgid "Time Week Day" +msgstr "" + +#. module: base_time_window +#: model:ir.model,name:base_time_window.model_time_window_mixin +msgid "Time Window" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_weekday_ids +msgid "Time Window Weekday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_end +msgid "To" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__1 +msgid "Tuesday" +msgstr "" + +#. module: base_time_window +#: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__2 +msgid "Wednesday" +msgstr "" + +#. module: base_time_window +#: code:addons/base_time_window/models/time_window_mixin.py:0 +#, python-format +msgid "{days}: From {start} to {end}" +msgstr "" From 3ac0ab55b6a964bcab9dcaf7b0b4965dd0d02571 Mon Sep 17 00:00:00 2001 From: Ignacio Buioli Date: Sun, 4 Sep 2022 04:02:33 +0000 Subject: [PATCH 19/20] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (26 of 26 strings) Translation: server-tools-15.0/server-tools-15.0-base_time_window Translate-URL: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-base_time_window/es_AR/ --- base_time_window/i18n/es_AR.po | 56 ++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/base_time_window/i18n/es_AR.po b/base_time_window/i18n/es_AR.po index c7072a676..23e4a15d3 100644 --- a/base_time_window/i18n/es_AR.po +++ b/base_time_window/i18n/es_AR.po @@ -6,147 +6,149 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2022-09-04 06:07+0000\n" +"Last-Translator: Ignacio Buioli \n" "Language-Team: none\n" "Language: es_AR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" #. module: base_time_window #: code:addons/base_time_window/models/time_window_mixin.py:0 #, python-format msgid "%(end_time)s must be > %(start_time)s" -msgstr "" +msgstr "%(end_time)s debe ser > %(start_time)s" #. module: base_time_window #: code:addons/base_time_window/models/time_window_mixin.py:0 #, python-format msgid "%(record_name)s overlaps %(other_name)s" -msgstr "" +msgstr "%(record_name)s se superpone %(other_name)s" #. module: base_time_window #: code:addons/base_time_window/models/time_window_mixin.py:0 #, python-format msgid "At least one time.weekday is required" -msgstr "" +msgstr "Se requiere al menos una vez al día de la semana" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__create_uid msgid "Created by" -msgstr "" +msgstr "Creado por" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__create_date msgid "Created on" -msgstr "" +msgstr "Creado en" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__display_name msgid "Display Name" -msgstr "" +msgstr "Mostrar Nombre" #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__4 msgid "Friday" -msgstr "" +msgstr "Viernes" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_start msgid "From" -msgstr "" +msgstr "Desde" #. module: base_time_window #: code:addons/base_time_window/models/time_window_mixin.py:0 #, python-format msgid "Hour should be between 00 and 23" -msgstr "" +msgstr "Las horas deben ser entre 00 y 23" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__id msgid "ID" -msgstr "" +msgstr "ID" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday____last_update msgid "Last Modified on" -msgstr "" +msgstr "Última modificación en" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__write_uid msgid "Last Updated by" -msgstr "" +msgstr "Última actualización realizada por" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__write_date msgid "Last Updated on" -msgstr "" +msgstr "Última actualización el" #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__0 msgid "Monday" -msgstr "" +msgstr "Lunes" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_weekday__name msgid "Name" -msgstr "" +msgstr "Nombre" #. module: base_time_window #: code:addons/base_time_window/models/time_weekday.py:0 #: model:ir.model.constraint,message:base_time_window.constraint_time_weekday_name_uniq #, python-format msgid "Name must be unique" -msgstr "" +msgstr "El nombre debe ser único" #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__5 msgid "Saturday" -msgstr "" +msgstr "Sábado" #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__6 msgid "Sunday" -msgstr "" +msgstr "Domingo" #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__3 msgid "Thursday" -msgstr "" +msgstr "Jueves" #. module: base_time_window #: model:ir.model,name:base_time_window.model_time_weekday msgid "Time Week Day" -msgstr "" +msgstr "Hora Semana Día" #. module: base_time_window #: model:ir.model,name:base_time_window.model_time_window_mixin msgid "Time Window" -msgstr "" +msgstr "Ventana de Tiempo" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_weekday_ids msgid "Time Window Weekday" -msgstr "" +msgstr "Ventana de Tiempo Día de la semana" #. module: base_time_window #: model:ir.model.fields,field_description:base_time_window.field_time_window_mixin__time_window_end msgid "To" -msgstr "" +msgstr "Hasta" #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__1 msgid "Tuesday" -msgstr "" +msgstr "Martes" #. module: base_time_window #: model:ir.model.fields.selection,name:base_time_window.selection__time_weekday__name__2 msgid "Wednesday" -msgstr "" +msgstr "Miércoles" #. module: base_time_window #: code:addons/base_time_window/models/time_window_mixin.py:0 #, python-format msgid "{days}: From {start} to {end}" -msgstr "" +msgstr "{days}: Desde {start} hasta {end}" From d01e665eeb53f0ec577c91b74f26c1f895ab3369 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Tue, 21 Feb 2023 22:49:26 +0100 Subject: [PATCH 20/20] [16.0][MIG] - base_time_window --- base_time_window/__manifest__.py | 2 +- base_time_window/models/time_weekday.py | 8 ++++---- setup/base_time_window/odoo/addons/base_time_window | 1 + setup/base_time_window/setup.py | 6 ++++++ 4 files changed, 12 insertions(+), 5 deletions(-) create mode 120000 setup/base_time_window/odoo/addons/base_time_window create mode 100644 setup/base_time_window/setup.py diff --git a/base_time_window/__manifest__.py b/base_time_window/__manifest__.py index 327fa0df5..7e8deb02a 100644 --- a/base_time_window/__manifest__.py +++ b/base_time_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Base Time Window", "summary": "Base model to handle time windows", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "category": "Technical Settings", "author": "ACSONE SA/NV, Camptocamp, Odoo Community Association (OCA)", "license": "AGPL-3", diff --git a/base_time_window/models/time_weekday.py b/base_time_window/models/time_weekday.py index 78d17ecd3..0307342f4 100644 --- a/base_time_window/models/time_weekday.py +++ b/base_time_window/models/time_weekday.py @@ -45,11 +45,11 @@ class TimeWeekday(models.Model): def _get_id_by_name(self, name): return self.search([("name", "=", name)], limit=1).id - @api.model - def create(self, vals): - result = super().create(vals) + @api.model_create_multi + def create(self, vals_list): + records = super().create(vals_list) self._get_id_by_name.clear_cache(self) - return result + return records def write(self, vals): result = super().write(vals) diff --git a/setup/base_time_window/odoo/addons/base_time_window b/setup/base_time_window/odoo/addons/base_time_window new file mode 120000 index 000000000..d4e4791f4 --- /dev/null +++ b/setup/base_time_window/odoo/addons/base_time_window @@ -0,0 +1 @@ +../../../../base_time_window \ No newline at end of file diff --git a/setup/base_time_window/setup.py b/setup/base_time_window/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/base_time_window/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)