From a092285f7752c3d31e182aabd4c43b4569f2cf63 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Tue, 31 Mar 2020 17:52:07 +0200 Subject: [PATCH] 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_window/models/base_time_weekday.py | 15 +- base_time_window/models/base_time_window.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(-) 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/base_time_weekday.py index 59ef2eda2..bf6489f5b 100644 --- a/base_time_window/models/base_time_weekday.py +++ b/base_time_window/models/base_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/base_time_window.py index 4786cfcd0..7fb5e14aa 100644 --- a/base_time_window/models/base_time_window.py +++ b/base_time_window/models/base_time_window.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 TimeWindow(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): + self.float_to_time(self.start) + + def get_end_time(self): + 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)], - } - )