From ad55c25c2985f5cf9d99f3a6e0b0889484e277da Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Tue, 31 Mar 2020 17:58:47 +0200 Subject: [PATCH 01/25] Add stock_partner_delivery_window --- stock_partner_delivery_window/__init__.py | 1 + stock_partner_delivery_window/__manifest__.py | 15 ++ .../demo/delivery_time_window.xml | 15 ++ .../models/__init__.py | 3 + .../models/delivery_time_window.py | 24 +++ .../models/res_partner.py | 127 +++++++++++++++ .../models/stock_picking.py | 46 ++++++ .../readme/CONFIGURE.rst | 10 ++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 3 + .../security/ir.model.access.csv | 3 + .../tests/__init__.py | 1 + .../tests/test_delivery_window.py | 148 ++++++++++++++++++ .../views/res_partner.xml | 32 ++++ 14 files changed, 429 insertions(+) create mode 100644 stock_partner_delivery_window/__init__.py create mode 100644 stock_partner_delivery_window/__manifest__.py create mode 100644 stock_partner_delivery_window/demo/delivery_time_window.xml create mode 100644 stock_partner_delivery_window/models/__init__.py create mode 100644 stock_partner_delivery_window/models/delivery_time_window.py create mode 100644 stock_partner_delivery_window/models/res_partner.py create mode 100644 stock_partner_delivery_window/models/stock_picking.py create mode 100644 stock_partner_delivery_window/readme/CONFIGURE.rst create mode 100644 stock_partner_delivery_window/readme/CONTRIBUTORS.rst create mode 100644 stock_partner_delivery_window/readme/DESCRIPTION.rst create mode 100644 stock_partner_delivery_window/security/ir.model.access.csv create mode 100644 stock_partner_delivery_window/tests/__init__.py create mode 100644 stock_partner_delivery_window/tests/test_delivery_window.py create mode 100644 stock_partner_delivery_window/views/res_partner.xml diff --git a/stock_partner_delivery_window/__init__.py b/stock_partner_delivery_window/__init__.py new file mode 100644 index 000000000000..0650744f6bc6 --- /dev/null +++ b/stock_partner_delivery_window/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py new file mode 100644 index 000000000000..69d5c724fa49 --- /dev/null +++ b/stock_partner_delivery_window/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +{ + "name": "Stock Partner Delivery Window", + "summary": "Define preferred delivery time windows for partners", + "version": "13.0.1.0.0", + "category": "Inventory", + "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", + "license": "AGPL-3", + "website": "https://github.com/OCA/stock-logistics-workflow", + "depends": ["base_time_window", "partner_tz", "stock"], + "data": ["security/ir.model.access.csv", "views/res_partner.xml"], + "demo": ["demo/delivery_time_window.xml"], + "installable": True, +} diff --git a/stock_partner_delivery_window/demo/delivery_time_window.xml b/stock_partner_delivery_window/demo/delivery_time_window.xml new file mode 100644 index 000000000000..f359d9cf58d2 --- /dev/null +++ b/stock_partner_delivery_window/demo/delivery_time_window.xml @@ -0,0 +1,15 @@ + + + + + 10.0 + 18.0 + + + + time_windows + + diff --git a/stock_partner_delivery_window/models/__init__.py b/stock_partner_delivery_window/models/__init__.py new file mode 100644 index 000000000000..2b3ebc04d451 --- /dev/null +++ b/stock_partner_delivery_window/models/__init__.py @@ -0,0 +1,3 @@ +from . import delivery_time_window +from . import res_partner +from . import stock_picking diff --git a/stock_partner_delivery_window/models/delivery_time_window.py b/stock_partner_delivery_window/models/delivery_time_window.py new file mode 100644 index 000000000000..9946cd6964d3 --- /dev/null +++ b/stock_partner_delivery_window/models/delivery_time_window.py @@ -0,0 +1,24 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) + +from odoo import api, fields, models + +from odoo.addons.base.models.res_partner import _tz_get + + +class DeliveryTimeWindow(models.Model): + + _name = "partner.delivery.time.window" + _inherit = "time.window.mixin" + _description = "Preferred delivery time windows" + + _time_window_overlap_check_field = "partner_id" + + partner_id = fields.Many2one( + "res.partner", required=True, index=True, ondelete="cascade" + ) + tz = fields.Selection(_tz_get, related="partner_id.tz", readonly=True,) + + @api.constrains("partner_id") + def check_window_no_overlaps(self): + return super().check_window_no_overlaps() diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py new file mode 100644 index 000000000000..f397e85cb39f --- /dev/null +++ b/stock_partner_delivery_window/models/res_partner.py @@ -0,0 +1,127 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from datetime import time + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools.misc import format_time + +from odoo.addons.partner_tz.tools import tz_utils + + +class ResPartner(models.Model): + + _inherit = "res.partner" + + delivery_time_preference = fields.Selection( + [("anytime", "Any time"), ("time_windows", "Fixed time windows")], + string="Delivery time schedule preference", + default="anytime", + required=True, + help="Define the scheduling preference for delivery orders:\n\n" + "* Any time: Do not postpone deliveries\n" + "* Fixed time windows: Postpone deliveries to the next preferred " + "time window", + ) + + delivery_time_window_ids = fields.One2many( + "partner.delivery.time.window", "partner_id", string="Delivery time windows", + ) + + @api.constrains("delivery_time_preference", "delivery_time_window_ids") + def _check_delivery_time_preference(self): + for partner in self: + if ( + partner.delivery_time_preference == "time_windows" + and not partner.delivery_time_window_ids + ): + raise ValidationError( + _( + "Please define at least one delivery time window or change" + " preference to Any time" + ) + ) + + def get_delivery_windows(self, day_name=None): + """ + Return the list of delivery windows by partner id for the given day + + :param day: The day name (see time.weekday, ex: 0,1,2,...) + :return: dict partner_id: delivery_window recordset + """ + res = {} + domain = [("partner_id", "in", self.ids)] + if day_name is not None: + week_day_id = self.env["time.weekday"]._get_id_by_name(day_name) + domain.append(("time_window_weekday_ids", "in", week_day_id)) + windows = self.env["partner.delivery.time.window"].search(domain) + for window in windows: + if not res.get(window.partner_id.id): + res[window.partner_id.id] = self.env[ + "partner.delivery.time.window" + ].browse() + res[window.partner_id.id] |= window + return res + + def is_in_delivery_window(self, date_time): + """ + Checks if provided date_time is in a delivery window for actual partner + + :param date_time: Datetime object + :return: Boolean + """ + self.ensure_one() + windows = self.get_delivery_windows(date_time.weekday()).get(self.id) + if windows: + for w in windows: + start_time = w.get_time_window_start_time() + end_time = w.get_time_window_end_time() + if self.tz: + utc_start = tz_utils.tz_to_utc_time(self.tz, start_time) + utc_end = tz_utils.tz_to_utc_time(self.tz, end_time) + else: + utc_start = start_time + utc_end = end_time + if utc_start <= date_time.time() < utc_end: + return True + return False + + def get_delivery_time_description(self): + res = dict() + day_translated_values = dict( + self.env["time.weekday"]._fields["name"]._description_selection(self.env) + ) + for partner in self: + opening_times = {} + time_format_string = _("From %s to %s") + if partner.delivery_time_preference == "time_windows": + for day in self.env["time.weekday"].search([]): + day_windows = partner.delivery_time_window_ids.filtered( + lambda d: day in d.time_window_weekday_ids + ) + for win in day_windows: + opening_times.setdefault(day_translated_values[day.name], []) + opening_times[day_translated_values[day.name]].append( + time_format_string + % ( + format_time(self.env, win.get_time_window_start_time()), + format_time(self.env, win.get_time_window_end_time()), + ) + ) + else: + for day in self.env["time.weekday"].search([]): + opening_times.setdefault(day_translated_values[day.name], []) + opening_times[day_translated_values[day.name]].append( + time_format_string + % ( + format_time(self.env, time(hour=0, minute=0)), + format_time(self.env, time(hour=23, minute=59)), + ) + ) + opening_times_description = list() + for day_name, time_list in opening_times.items(): + opening_times_description.append( + _("%s: %s") % (day_name, _(", ").join(time_list)) + ) + res[partner.id] = "\n".join(opening_times_description) + return res diff --git a/stock_partner_delivery_window/models/stock_picking.py b/stock_partner_delivery_window/models/stock_picking.py new file mode 100644 index 000000000000..d0787e16558f --- /dev/null +++ b/stock_partner_delivery_window/models/stock_picking.py @@ -0,0 +1,46 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from odoo import _, api, models +from odoo.tools.misc import format_datetime + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + def _planned_delivery_date(self): + return self.scheduled_date + + @api.onchange("scheduled_date") + def _onchange_scheduled_date(self): + self.ensure_one() + if ( + not self.partner_id + or self.partner_id.delivery_time_preference != "time_windows" + or self.picking_type_id.code != "outgoing" + ): + return + p = self.partner_id + if not p.is_in_delivery_window(self._planned_delivery_date()): + delivery_windows_strings = [] + for w in p.get_delivery_windows().get(p.id): + delivery_windows_strings.append( + " * {} ({})".format(w.display_name, self.partner_id.tz) + ) + message = _( + "The scheduled date is %s (%s), but the partner is " + "set to prefer deliveries on following time windows:\n%s" + % ( + format_datetime(self.env, self.scheduled_date), + self.env.context.get("tz"), + "\n".join(delivery_windows_strings), + ) + ) + return { + "warning": { + "title": _( + "Scheduled date does not match partner's Delivery window" + " preference." + ), + "message": message, + } + } diff --git a/stock_partner_delivery_window/readme/CONFIGURE.rst b/stock_partner_delivery_window/readme/CONFIGURE.rst new file mode 100644 index 000000000000..05488a6d7a9d --- /dev/null +++ b/stock_partner_delivery_window/readme/CONFIGURE.rst @@ -0,0 +1,10 @@ +On partners form view, under the "Sales & Purchases" tab, one can define a +"Delivery schedule preference" for each partner. + +Possible configurations are: + +* Any time: Do not postpone deliveries +* Fixed time windows: Postpone deliveries to the next preferred time window + +After selecting "Fixed time windows", one can define the preferred delivery +windows in the embedded tree view below. diff --git a/stock_partner_delivery_window/readme/CONTRIBUTORS.rst b/stock_partner_delivery_window/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..e31e2f0c4fcf --- /dev/null +++ b/stock_partner_delivery_window/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Akim Juillerat diff --git a/stock_partner_delivery_window/readme/DESCRIPTION.rst b/stock_partner_delivery_window/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..9008816817f0 --- /dev/null +++ b/stock_partner_delivery_window/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +This module allows to define time scheduling preference for delivery orders on +partners, in order to raise a warning when changing a scheduled date to a time +window that is not preferred by this customer. diff --git a/stock_partner_delivery_window/security/ir.model.access.csv b/stock_partner_delivery_window/security/ir.model.access.csv new file mode 100644 index 000000000000..096e52b6582f --- /dev/null +++ b/stock_partner_delivery_window/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +access_partner_delivery_time_window_user,access_partner_delivery_time_window_user,model_partner_delivery_time_window,base.group_user,1,0,0,0 +access_partner_delivery_time_window_manager,access_partner_delivery_time_window_manager,model_partner_delivery_time_window,stock.group_stock_manager,1,1,1,1 diff --git a/stock_partner_delivery_window/tests/__init__.py b/stock_partner_delivery_window/tests/__init__.py new file mode 100644 index 000000000000..cbbca6e51166 --- /dev/null +++ b/stock_partner_delivery_window/tests/__init__.py @@ -0,0 +1 @@ +from . import test_delivery_window diff --git a/stock_partner_delivery_window/tests/test_delivery_window.py b/stock_partner_delivery_window/tests/test_delivery_window.py new file mode 100644 index 000000000000..1bfdda81c96f --- /dev/null +++ b/stock_partner_delivery_window/tests/test_delivery_window.py @@ -0,0 +1,148 @@ +# Copyright 2020 Camptocamp +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from freezegun import freeze_time + +from odoo.tests import SavepointCase + + +class TestPartnerDeliveryWindow(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.customer = cls.env["res.partner"].create( + {"name": "ACME", "delivery_time_preference": "anytime"} + ) + cls.customer_shipping = cls.env["res.partner"].create( + { + "name": "Delivery address", + "parent_id": cls.customer.id, + "delivery_time_preference": "time_windows", + "delivery_time_window_ids": [ + ( + 0, + 0, + { + "time_window_start": 0.00, + "time_window_end": 23.99, + "time_window_weekday_ids": [ + ( + 6, + 0, + [ + cls.env.ref( + "base_time_window.time_weekday_thursday" + ).id, + cls.env.ref( + "base_time_window.time_weekday_saturday" + ).id, + ], + ) + ], + }, + ) + ], + } + ) + cls.product = cls.env.ref("product.product_product_9") + cls.picking_type_delivery = cls.env.ref("stock.picking_type_out") + cls.location_stock = cls.env.ref("stock.stock_location_stock") + cls.location_customers = cls.env.ref("stock.stock_location_customers") + + def _create_delivery_picking(self, partner): + return self.env["stock.picking"].create( + { + "partner_id": partner.id, + "location_id": self.location_stock.id, + "location_dest_id": self.location_customers.id, + "picking_type_id": self.picking_type_delivery.id, + } + ) + + @freeze_time("2020-04-02") # Thursday + def test_delivery_window_warning(self): + # No warning with anytime + cust_picking = self._create_delivery_picking(self.customer) + cust_picking.scheduled_date = "2020-04-03" # Friday + onchange_res = cust_picking._onchange_scheduled_date() + self.assertIsNone(onchange_res) + # No warning on preferred time window + cust_ship_picking = self._create_delivery_picking(self.customer_shipping) + cust_ship_picking.scheduled_date = "2020-04-04" # Saturday + onchange_res = cust_ship_picking._onchange_scheduled_date() + self.assertIsNone(onchange_res) + cust_ship_picking.scheduled_date = "2020-04-03" # Friday + onchange_res = cust_ship_picking._onchange_scheduled_date() + self.assertTrue("warning" in onchange_res.keys()) + + @freeze_time("2020-04-02 07:59:59") # Thursday + def test_with_timezone_dst(self): + # Define customer to allow shipping only between 10.00am and 4.00pm + # in tz 'Europe/Brussels' (GMT+1 or GMT+2 during DST) + self.customer_shipping.tz = "Europe/Brussels" + self.customer_shipping.delivery_time_window_ids.write( + {"time_window_start": 10.0, "time_window_end": 16.0} + ) + # Test DST + # + # Frozen time is in UTC so 2020-04-02 07:59:59 == 2020-04-02 09:59:59 + # in Brussels which is preferred + picking = self._create_delivery_picking(self.customer_shipping) + onchange_res = picking._onchange_scheduled_date() + self.assertTrue( + isinstance(onchange_res, dict) and "warning" in onchange_res.keys() + ) + # Scheduled date is in UTC so 2020-04-02 08:00:00 == 2020-04-02 10:00:00 + # in Brussels which is preferred + picking.scheduled_date = "2020-04-02 08:00:00" + onchange_res = picking._onchange_scheduled_date() + self.assertIsNone(onchange_res) + # Scheduled date is in UTC so 2020-04-02 13:59:59 == 2020-04-02 15:59:59 + # in Brussels which is preferred + picking.scheduled_date = "2020-04-02 13:59:59" + onchange_res = picking._onchange_scheduled_date() + self.assertIsNone(onchange_res) + # Scheduled date is in UTC so 2020-04-02 14:00:00 == 2020-04-02 16:00:00 + # in Brussels which is not preferred + picking.scheduled_date = "2020-04-02 14:00:00" + onchange_res = picking._onchange_scheduled_date() + self.assertTrue( + isinstance(onchange_res, dict) and "warning" in onchange_res.keys() + ) + + @freeze_time("2020-03-26 08:59:59") # Thursday + def test_with_timezone_no_dst(self): + # Define customer to allow shipping only between 10.00am and 4.00pm + # in tz 'Europe/Brussels' (GMT+1 or GMT+2 during DST) + self.customer_shipping.tz = "Europe/Brussels" + self.customer_shipping.delivery_time_window_ids.write( + {"time_window_start": 10.0, "time_window_end": 16.0} + ) + # Test No-DST + # + # Frozen time is in UTC so 2020-03-26 08:59:59 == 2020-04-02 09:59:59 + # in Brussels which is preferred + picking = self._create_delivery_picking(self.customer_shipping) + onchange_res = picking._onchange_scheduled_date() + self.assertTrue( + isinstance(onchange_res, dict) and "warning" in onchange_res.keys() + ) + # Scheduled date is in UTC so 2020-03-26 09:00:00 == 2020-04-02 10:00:00 + # in Brussels which is preferred + picking.scheduled_date = "2020-03-26 09:00:00" + onchange_res = picking._onchange_scheduled_date() + # No warning since we're in the timeframe + self.assertIsNone(onchange_res) + # Scheduled date is in UTC so 2020-03-26 14:59:59 == 2020-04-02 15:59:59 + # in Brussels which is preferred + picking.scheduled_date = "2020-03-26 14:59:59" + onchange_res = picking._onchange_scheduled_date() + # No warning since we're in the timeframe + self.assertIsNone(onchange_res) + # Scheduled date is in UTC so 2020-03-26 15:00:00 == 2020-04-02 16:00:00 + # in Brussels which is preferred + picking.scheduled_date = "2020-03-26 15:00:00" + onchange_res = picking._onchange_scheduled_date() + self.assertTrue( + isinstance(onchange_res, dict) and "warning" in onchange_res.keys() + ) diff --git a/stock_partner_delivery_window/views/res_partner.xml b/stock_partner_delivery_window/views/res_partner.xml new file mode 100644 index 000000000000..23913976ee50 --- /dev/null +++ b/stock_partner_delivery_window/views/res_partner.xml @@ -0,0 +1,32 @@ + + + + res.partner.form.inherit + res.partner + + + + +
+
+
+
+
+
From be78d599524046017c5a34636b30ec5abb056c0e Mon Sep 17 00:00:00 2001 From: "dung.tran" Date: Sun, 17 Jan 2021 10:13:13 +0700 Subject: [PATCH 02/25] [IMP] stock_partner_delivery_window: black, isort, prettier --- .../models/delivery_time_window.py | 6 +++++- stock_partner_delivery_window/models/res_partner.py | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/stock_partner_delivery_window/models/delivery_time_window.py b/stock_partner_delivery_window/models/delivery_time_window.py index 9946cd6964d3..e86eddf6fac1 100644 --- a/stock_partner_delivery_window/models/delivery_time_window.py +++ b/stock_partner_delivery_window/models/delivery_time_window.py @@ -17,7 +17,11 @@ class DeliveryTimeWindow(models.Model): partner_id = fields.Many2one( "res.partner", required=True, index=True, ondelete="cascade" ) - tz = fields.Selection(_tz_get, related="partner_id.tz", readonly=True,) + tz = fields.Selection( + _tz_get, + related="partner_id.tz", + readonly=True, + ) @api.constrains("partner_id") def check_window_no_overlaps(self): diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index f397e85cb39f..3a22d26ad2ad 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -25,7 +25,9 @@ class ResPartner(models.Model): ) delivery_time_window_ids = fields.One2many( - "partner.delivery.time.window", "partner_id", string="Delivery time windows", + "partner.delivery.time.window", + "partner_id", + string="Delivery time windows", ) @api.constrains("delivery_time_preference", "delivery_time_window_ids") From 276bc01c28b2c1abf022c75c7fc7799b551bb76c Mon Sep 17 00:00:00 2001 From: "dung.tran" Date: Sun, 17 Jan 2021 10:17:18 +0700 Subject: [PATCH 03/25] [MIG] stock_partner_delivery_window: Migration to 14.0 --- stock_partner_delivery_window/README.rst | 101 ++++ stock_partner_delivery_window/__manifest__.py | 2 +- .../models/delivery_time_window.py | 7 +- .../models/res_partner.py | 4 +- .../readme/CONTRIBUTORS.rst | 4 + .../readme/CREDITS.rst | 3 + .../static/description/index.html | 447 ++++++++++++++++++ 7 files changed, 559 insertions(+), 9 deletions(-) create mode 100644 stock_partner_delivery_window/README.rst create mode 100644 stock_partner_delivery_window/readme/CREDITS.rst create mode 100644 stock_partner_delivery_window/static/description/index.html diff --git a/stock_partner_delivery_window/README.rst b/stock_partner_delivery_window/README.rst new file mode 100644 index 000000000000..5f4f6fd10606 --- /dev/null +++ b/stock_partner_delivery_window/README.rst @@ -0,0 +1,101 @@ +============================= +Stock Partner Delivery 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%2Fstock--logistics--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/stock-logistics-workflow/tree/14.0/stock_partner_delivery_window + :alt: OCA/stock-logistics-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/stock-logistics-workflow-14-0/stock-logistics-workflow-14-0-stock_partner_delivery_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/154/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to define time scheduling preference for delivery orders on +partners, in order to raise a warning when changing a scheduled date to a time +window that is not preferred by this customer. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +On partners form view, under the "Sales & Purchases" tab, one can define a +"Delivery schedule preference" for each partner. + +Possible configurations are: + +* Any time: Do not postpone deliveries +* Fixed time windows: Postpone deliveries to the next preferred time window + +After selecting "Fixed time windows", one can define the preferred delivery +windows in the embedded tree view below. + +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 +~~~~~~~ + +* Camptocamp +* ACSONE SA/NV + +Contributors +~~~~~~~~~~~~ + +* Akim Juillerat + +Trobz + +* Dung Tran + +Other credits +~~~~~~~~~~~~~ + +The development of this module has been financially supported by: + +* Camptocamp + +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/stock-logistics-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index 69d5c724fa49..83b1bf080f43 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "13.0.1.0.0", + "version": "14.0.1.0.0", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", diff --git a/stock_partner_delivery_window/models/delivery_time_window.py b/stock_partner_delivery_window/models/delivery_time_window.py index e86eddf6fac1..8cb8a1066541 100644 --- a/stock_partner_delivery_window/models/delivery_time_window.py +++ b/stock_partner_delivery_window/models/delivery_time_window.py @@ -17,11 +17,8 @@ class DeliveryTimeWindow(models.Model): partner_id = fields.Many2one( "res.partner", required=True, index=True, ondelete="cascade" ) - tz = fields.Selection( - _tz_get, - related="partner_id.tz", - readonly=True, - ) + + tz = fields.Selection(_tz_get, related="partner_id.tz", readonly=True) @api.constrains("partner_id") def check_window_no_overlaps(self): diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index 3a22d26ad2ad..434499f2907a 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -25,9 +25,7 @@ class ResPartner(models.Model): ) delivery_time_window_ids = fields.One2many( - "partner.delivery.time.window", - "partner_id", - string="Delivery time windows", + "partner.delivery.time.window", "partner_id", string="Delivery time windows" ) @api.constrains("delivery_time_preference", "delivery_time_window_ids") diff --git a/stock_partner_delivery_window/readme/CONTRIBUTORS.rst b/stock_partner_delivery_window/readme/CONTRIBUTORS.rst index e31e2f0c4fcf..85a641cdb4a3 100644 --- a/stock_partner_delivery_window/readme/CONTRIBUTORS.rst +++ b/stock_partner_delivery_window/readme/CONTRIBUTORS.rst @@ -1 +1,5 @@ * Akim Juillerat + +Trobz + +* Dung Tran diff --git a/stock_partner_delivery_window/readme/CREDITS.rst b/stock_partner_delivery_window/readme/CREDITS.rst new file mode 100644 index 000000000000..f5cc070c78ea --- /dev/null +++ b/stock_partner_delivery_window/readme/CREDITS.rst @@ -0,0 +1,3 @@ +The development of this module has been financially supported by: + +* Camptocamp diff --git a/stock_partner_delivery_window/static/description/index.html b/stock_partner_delivery_window/static/description/index.html new file mode 100644 index 000000000000..0a747cf52b66 --- /dev/null +++ b/stock_partner_delivery_window/static/description/index.html @@ -0,0 +1,447 @@ + + + + + + +Stock Partner Delivery Window + + + +
+

Stock Partner Delivery Window

+ + +

Beta License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runbot

+

This module allows to define time scheduling preference for delivery orders on +partners, in order to raise a warning when changing a scheduled date to a time +window that is not preferred by this customer.

+

Table of contents

+ +
+

Configuration

+

On partners form view, under the “Sales & Purchases” tab, one can define a +“Delivery schedule preference” for each partner.

+

Possible configurations are:

+
    +
  • Any time: Do not postpone deliveries
  • +
  • Fixed time windows: Postpone deliveries to the next preferred time window
  • +
+

After selecting “Fixed time windows”, one can define the preferred delivery +windows in the embedded tree view below.

+
+
+

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

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

Contributors

+ +

Trobz

+ +
+
+

Other credits

+

The development of this module has been financially supported by:

+
    +
  • Camptocamp
  • +
+
+
+

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/stock-logistics-workflow project on GitHub.

+

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

+
+
+
+ + From 86eb548abde0a93169d4ad58c5c02d6d701397d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Tue, 30 Mar 2021 18:25:54 +0200 Subject: [PATCH 04/25] s_p_delivery_window: time format improvements Two small improvements: * add a hook to change the delivery time format * no need to display seconds, hh:mm is enough --- .../models/res_partner.py | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index 434499f2907a..dcac9349340e 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -86,6 +86,9 @@ def is_in_delivery_window(self, date_time): return True return False + def _get_delivery_time_format_string(self): + return _("From %s to %s") + def get_delivery_time_description(self): res = dict() day_translated_values = dict( @@ -93,7 +96,7 @@ def get_delivery_time_description(self): ) for partner in self: opening_times = {} - time_format_string = _("From %s to %s") + time_format_string = self._get_delivery_time_format_string() if partner.delivery_time_preference == "time_windows": for day in self.env["time.weekday"].search([]): day_windows = partner.delivery_time_window_ids.filtered( @@ -104,8 +107,16 @@ def get_delivery_time_description(self): opening_times[day_translated_values[day.name]].append( time_format_string % ( - format_time(self.env, win.get_time_window_start_time()), - format_time(self.env, win.get_time_window_end_time()), + format_time( + self.env, + win.get_time_window_start_time(), + time_format="short", + ), + format_time( + self.env, + win.get_time_window_end_time(), + time_format="short", + ), ) ) else: @@ -114,8 +125,12 @@ def get_delivery_time_description(self): opening_times[day_translated_values[day.name]].append( time_format_string % ( - format_time(self.env, time(hour=0, minute=0)), - format_time(self.env, time(hour=23, minute=59)), + format_time( + self.env, time(hour=0, minute=0), time_format="short" + ), + format_time( + self.env, time(hour=23, minute=59), time_format="short" + ), ) ) opening_times_description = list() From 8ed3320cc46805e5c6d4e4d2bbdb023b311b2173 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Fri, 2 Apr 2021 14:56:50 +0200 Subject: [PATCH 05/25] stock_partner_delivery_window: ease warning msg check/override --- .../models/stock_picking.py | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/stock_partner_delivery_window/models/stock_picking.py b/stock_partner_delivery_window/models/stock_picking.py index d0787e16558f..71add1595353 100644 --- a/stock_partner_delivery_window/models/stock_picking.py +++ b/stock_partner_delivery_window/models/stock_picking.py @@ -21,26 +21,26 @@ def _onchange_scheduled_date(self): return p = self.partner_id if not p.is_in_delivery_window(self._planned_delivery_date()): - delivery_windows_strings = [] - for w in p.get_delivery_windows().get(p.id): - delivery_windows_strings.append( - " * {} ({})".format(w.display_name, self.partner_id.tz) - ) - message = _( - "The scheduled date is %s (%s), but the partner is " - "set to prefer deliveries on following time windows:\n%s" - % ( - format_datetime(self.env, self.scheduled_date), - self.env.context.get("tz"), - "\n".join(delivery_windows_strings), - ) + return {"warning": self._scheduled_date_no_delivery_window_match_msg()} + + def _scheduled_date_no_delivery_window_match_msg(self): + delivery_windows_strings = [] + for w in self.partner_id.get_delivery_windows().get(self.partner_id.id): + delivery_windows_strings.append( + " * {} ({})".format(w.display_name, self.partner_id.tz) + ) + message = _( + "The scheduled date is %s (%s), but the partner is " + "set to prefer deliveries on following time windows:\n%s" + % ( + format_datetime(self.env, self.scheduled_date), + self.env.context.get("tz"), + "\n".join(delivery_windows_strings), ) - return { - "warning": { - "title": _( - "Scheduled date does not match partner's Delivery window" - " preference." - ), - "message": message, - } - } + ) + return { + "title": _( + "Scheduled date does not match partner's Delivery window preference." + ), + "message": message, + } From 8464cfab1cd036e5dedcec68811d6b23bb996e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthieu=20M=C3=A9quignon?= Date: Tue, 6 Apr 2021 16:46:59 +0200 Subject: [PATCH 06/25] stock_partner_delivery_window: Cleanup --- .../models/res_partner.py | 63 ++++++++++--------- .../models/stock_picking.py | 47 ++++++++------ .../tests/test_delivery_window.py | 25 ++++---- 3 files changed, 74 insertions(+), 61 deletions(-) diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index dcac9349340e..d903ba26846e 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -1,5 +1,6 @@ # Copyright 2020 Camptocamp SA # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from collections import defaultdict from datetime import time from odoo import _, api, fields, models @@ -71,6 +72,10 @@ def is_in_delivery_window(self, date_time): :return: Boolean """ self.ensure_one() + if self.delivery_time_preference == "workdays": + if date_time.weekday() > 4: + return False + return True windows = self.get_delivery_windows(date_time.weekday()).get(self.id) if windows: for w in windows: @@ -94,45 +99,45 @@ def get_delivery_time_description(self): day_translated_values = dict( self.env["time.weekday"]._fields["name"]._description_selection(self.env) ) + + def short_format_time(time): + return format_time(self.env, time, time_format="short") + + weekdays = self.env["time.weekday"].search([]) for partner in self: - opening_times = {} + opening_times = defaultdict(list) time_format_string = self._get_delivery_time_format_string() if partner.delivery_time_preference == "time_windows": - for day in self.env["time.weekday"].search([]): + for day in weekdays: day_windows = partner.delivery_time_window_ids.filtered( lambda d: day in d.time_window_weekday_ids ) for win in day_windows: - opening_times.setdefault(day_translated_values[day.name], []) - opening_times[day_translated_values[day.name]].append( - time_format_string - % ( - format_time( - self.env, - win.get_time_window_start_time(), - time_format="short", - ), - format_time( - self.env, - win.get_time_window_end_time(), - time_format="short", - ), - ) + start = win.get_time_window_start_time() + end = win.get_time_window_end_time() + translated_day = day_translated_values[day.name] + value = time_format_string % ( + short_format_time(start), + short_format_time(end), ) + opening_times[translated_day].append(value) + elif partner.delivery_time_preference == "workdays": + day_windows = weekdays.filtered(lambda d: d.name in WORKDAYS) + for day in day_windows: + translated_day = day_translated_values[day.name] + value = time_format_string % ( + short_format_time(time(hour=0, minute=0)), + short_format_time(time(hour=23, minute=59)), + ) + opening_times[translated_day].append(value) else: - for day in self.env["time.weekday"].search([]): - opening_times.setdefault(day_translated_values[day.name], []) - opening_times[day_translated_values[day.name]].append( - time_format_string - % ( - format_time( - self.env, time(hour=0, minute=0), time_format="short" - ), - format_time( - self.env, time(hour=23, minute=59), time_format="short" - ), - ) + for day in weekdays: + translated_day = day_translated_values[day.name] + value = time_format_string % ( + short_format_time(time(hour=0, minute=0)), + short_format_time(time(hour=23, minute=59)), ) + opening_times[translated_day].append(value) opening_times_description = list() for day_name, time_list in opening_times.items(): opening_times_description.append( diff --git a/stock_partner_delivery_window/models/stock_picking.py b/stock_partner_delivery_window/models/stock_picking.py index 71add1595353..b74c36ba58f3 100644 --- a/stock_partner_delivery_window/models/stock_picking.py +++ b/stock_partner_delivery_window/models/stock_picking.py @@ -13,29 +13,38 @@ def _planned_delivery_date(self): @api.onchange("scheduled_date") def _onchange_scheduled_date(self): self.ensure_one() - if ( - not self.partner_id - or self.partner_id.delivery_time_preference != "time_windows" - or self.picking_type_id.code != "outgoing" - ): + partner = self.partner_id + anytime_delivery = partner and partner.delivery_time_preference == "anytime" + outgoing_picking = self.picking_type_id.code == "outgoing_picking" + # Return nothing if partner delivery preference is anytime + if not partner or anytime_delivery or outgoing_picking: return - p = self.partner_id - if not p.is_in_delivery_window(self._planned_delivery_date()): + if not partner.is_in_delivery_window(self._planned_delivery_date()): return {"warning": self._scheduled_date_no_delivery_window_match_msg()} def _scheduled_date_no_delivery_window_match_msg(self): - delivery_windows_strings = [] - for w in self.partner_id.get_delivery_windows().get(self.partner_id.id): - delivery_windows_strings.append( - " * {} ({})".format(w.display_name, self.partner_id.tz) - ) - message = _( - "The scheduled date is %s (%s), but the partner is " - "set to prefer deliveries on following time windows:\n%s" - % ( - format_datetime(self.env, self.scheduled_date), - self.env.context.get("tz"), - "\n".join(delivery_windows_strings), + scheduled_date = self.scheduled_date + formatted_scheduled_date = format_datetime(self.env, scheduled_date) + partner = self.partner_id + if partner.delivery_time_preference == "workdays": + message = _( + "The scheduled date is {} ({}), but the partner is " + "set to prefer deliveries on working days." + ).format(formatted_scheduled_date, scheduled_date.weekday()) + else: + delivery_windows_strings = [] + for w in self.partner_id.get_delivery_windows().get(partner.id): + delivery_windows_strings.append( + " * {} ({})".format(w.display_name, self.partner_id.tz) + ) + message = _( + "The scheduled date is %s (%s), but the partner is " + "set to prefer deliveries on following time windows:\n%s" + % ( + format_datetime(self.env, self.scheduled_date), + self.env.context.get("tz"), + "\n".join(delivery_windows_strings), + ) ) ) return { diff --git a/stock_partner_delivery_window/tests/test_delivery_window.py b/stock_partner_delivery_window/tests/test_delivery_window.py index 1bfdda81c96f..5ae3821c1f73 100644 --- a/stock_partner_delivery_window/tests/test_delivery_window.py +++ b/stock_partner_delivery_window/tests/test_delivery_window.py @@ -10,13 +10,12 @@ class TestPartnerDeliveryWindow(SavepointCase): def setUpClass(cls): super().setUpClass() cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) - cls.customer = cls.env["res.partner"].create( - {"name": "ACME", "delivery_time_preference": "anytime"} + cls.customer_anytime = cls.env["res.partner"].create( + {"name": "Anytime", "delivery_time_preference": "anytime"} ) - cls.customer_shipping = cls.env["res.partner"].create( + cls.customer_time_window = cls.env["res.partner"].create( { - "name": "Delivery address", - "parent_id": cls.customer.id, + "name": "Time Window", "delivery_time_preference": "time_windows", "delivery_time_window_ids": [ ( @@ -62,12 +61,12 @@ def _create_delivery_picking(self, partner): @freeze_time("2020-04-02") # Thursday def test_delivery_window_warning(self): # No warning with anytime - cust_picking = self._create_delivery_picking(self.customer) + cust_picking = self._create_delivery_picking(self.customer_anytime) cust_picking.scheduled_date = "2020-04-03" # Friday onchange_res = cust_picking._onchange_scheduled_date() self.assertIsNone(onchange_res) # No warning on preferred time window - cust_ship_picking = self._create_delivery_picking(self.customer_shipping) + cust_ship_picking = self._create_delivery_picking(self.customer_time_window) cust_ship_picking.scheduled_date = "2020-04-04" # Saturday onchange_res = cust_ship_picking._onchange_scheduled_date() self.assertIsNone(onchange_res) @@ -79,15 +78,15 @@ def test_delivery_window_warning(self): def test_with_timezone_dst(self): # Define customer to allow shipping only between 10.00am and 4.00pm # in tz 'Europe/Brussels' (GMT+1 or GMT+2 during DST) - self.customer_shipping.tz = "Europe/Brussels" - self.customer_shipping.delivery_time_window_ids.write( + self.customer_time_window.tz = "Europe/Brussels" + self.customer_time_window.delivery_time_window_ids.write( {"time_window_start": 10.0, "time_window_end": 16.0} ) # Test DST # # Frozen time is in UTC so 2020-04-02 07:59:59 == 2020-04-02 09:59:59 # in Brussels which is preferred - picking = self._create_delivery_picking(self.customer_shipping) + picking = self._create_delivery_picking(self.customer_time_window) onchange_res = picking._onchange_scheduled_date() self.assertTrue( isinstance(onchange_res, dict) and "warning" in onchange_res.keys() @@ -114,15 +113,15 @@ def test_with_timezone_dst(self): def test_with_timezone_no_dst(self): # Define customer to allow shipping only between 10.00am and 4.00pm # in tz 'Europe/Brussels' (GMT+1 or GMT+2 during DST) - self.customer_shipping.tz = "Europe/Brussels" - self.customer_shipping.delivery_time_window_ids.write( + self.customer_time_window.tz = "Europe/Brussels" + self.customer_time_window.delivery_time_window_ids.write( {"time_window_start": 10.0, "time_window_end": 16.0} ) # Test No-DST # # Frozen time is in UTC so 2020-03-26 08:59:59 == 2020-04-02 09:59:59 # in Brussels which is preferred - picking = self._create_delivery_picking(self.customer_shipping) + picking = self._create_delivery_picking(self.customer_time_window) onchange_res = picking._onchange_scheduled_date() self.assertTrue( isinstance(onchange_res, dict) and "warning" in onchange_res.keys() From 3942d7d0579d8cf2d4d77142116f4b6fb566596b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthieu=20M=C3=A9quignon?= Date: Thu, 8 Apr 2021 14:46:06 +0200 Subject: [PATCH 07/25] s_p_delivery_window: Add working days as delivery schedule preference --- stock_partner_delivery_window/README.rst | 2 ++ .../models/res_partner.py | 13 ++++++-- .../models/stock_picking.py | 5 ++- .../readme/CONFIGURE.rst | 1 + .../readme/CONTRIBUTORS.rst | 1 + .../static/description/index.html | 2 ++ .../tests/test_delivery_window.py | 32 ++++++++++++++----- 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/stock_partner_delivery_window/README.rst b/stock_partner_delivery_window/README.rst index 5f4f6fd10606..51db7cf6d008 100644 --- a/stock_partner_delivery_window/README.rst +++ b/stock_partner_delivery_window/README.rst @@ -44,6 +44,7 @@ Possible configurations are: * Any time: Do not postpone deliveries * Fixed time windows: Postpone deliveries to the next preferred time window +* Weekdays: Postpone deliveries to the next weekday After selecting "Fixed time windows", one can define the preferred delivery windows in the embedded tree view below. @@ -71,6 +72,7 @@ Contributors ~~~~~~~~~~~~ * Akim Juillerat +* Matthieu Méquignon Trobz diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index d903ba26846e..f561979f5e50 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -9,20 +9,27 @@ from odoo.addons.partner_tz.tools import tz_utils +WORKDAYS = list(range(5)) + class ResPartner(models.Model): _inherit = "res.partner" delivery_time_preference = fields.Selection( - [("anytime", "Any time"), ("time_windows", "Fixed time windows")], + [ + ("anytime", "Any time"), + ("time_windows", "Fixed time windows"), + ("workdays", "Weekdays (Monday to Friday)"), + ], string="Delivery time schedule preference", - default="anytime", + default="workdays", required=True, help="Define the scheduling preference for delivery orders:\n\n" "* Any time: Do not postpone deliveries\n" "* Fixed time windows: Postpone deliveries to the next preferred " - "time window", + "time window\n" + "* Weekdays: Postpone deliveries to the next weekday", ) delivery_time_window_ids = fields.One2many( diff --git a/stock_partner_delivery_window/models/stock_picking.py b/stock_partner_delivery_window/models/stock_picking.py index b74c36ba58f3..c83a7d1a7d9c 100644 --- a/stock_partner_delivery_window/models/stock_picking.py +++ b/stock_partner_delivery_window/models/stock_picking.py @@ -33,9 +33,9 @@ def _scheduled_date_no_delivery_window_match_msg(self): ).format(formatted_scheduled_date, scheduled_date.weekday()) else: delivery_windows_strings = [] - for w in self.partner_id.get_delivery_windows().get(partner.id): + for w in partner.get_delivery_windows().get(partner.id): delivery_windows_strings.append( - " * {} ({})".format(w.display_name, self.partner_id.tz) + " * {} ({})".format(w.display_name, partner.tz) ) message = _( "The scheduled date is %s (%s), but the partner is " @@ -46,7 +46,6 @@ def _scheduled_date_no_delivery_window_match_msg(self): "\n".join(delivery_windows_strings), ) ) - ) return { "title": _( "Scheduled date does not match partner's Delivery window preference." diff --git a/stock_partner_delivery_window/readme/CONFIGURE.rst b/stock_partner_delivery_window/readme/CONFIGURE.rst index 05488a6d7a9d..afb25e3fa348 100644 --- a/stock_partner_delivery_window/readme/CONFIGURE.rst +++ b/stock_partner_delivery_window/readme/CONFIGURE.rst @@ -5,6 +5,7 @@ Possible configurations are: * Any time: Do not postpone deliveries * Fixed time windows: Postpone deliveries to the next preferred time window +* Weekdays: Postpone deliveries to the next weekday After selecting "Fixed time windows", one can define the preferred delivery windows in the embedded tree view below. diff --git a/stock_partner_delivery_window/readme/CONTRIBUTORS.rst b/stock_partner_delivery_window/readme/CONTRIBUTORS.rst index 85a641cdb4a3..30ba8315e3fe 100644 --- a/stock_partner_delivery_window/readme/CONTRIBUTORS.rst +++ b/stock_partner_delivery_window/readme/CONTRIBUTORS.rst @@ -1,4 +1,5 @@ * Akim Juillerat +* Matthieu Méquignon Trobz diff --git a/stock_partner_delivery_window/static/description/index.html b/stock_partner_delivery_window/static/description/index.html index 0a747cf52b66..449dedb6830d 100644 --- a/stock_partner_delivery_window/static/description/index.html +++ b/stock_partner_delivery_window/static/description/index.html @@ -393,6 +393,7 @@

Configuration

  • Any time: Do not postpone deliveries
  • Fixed time windows: Postpone deliveries to the next preferred time window
  • +
  • Weekdays: Postpone deliveries to the next weekday

After selecting “Fixed time windows”, one can define the preferred delivery windows in the embedded tree view below.

@@ -418,6 +419,7 @@

Authors

Contributors

Trobz

    diff --git a/stock_partner_delivery_window/tests/test_delivery_window.py b/stock_partner_delivery_window/tests/test_delivery_window.py index 5ae3821c1f73..1b734dcd359b 100644 --- a/stock_partner_delivery_window/tests/test_delivery_window.py +++ b/stock_partner_delivery_window/tests/test_delivery_window.py @@ -13,6 +13,9 @@ def setUpClass(cls): cls.customer_anytime = cls.env["res.partner"].create( {"name": "Anytime", "delivery_time_preference": "anytime"} ) + cls.customer_working_days = cls.env["res.partner"].create( + {"name": "Working Days", "delivery_time_preference": "workdays"} + ) cls.customer_time_window = cls.env["res.partner"].create( { "name": "Time Window", @@ -61,17 +64,30 @@ def _create_delivery_picking(self, partner): @freeze_time("2020-04-02") # Thursday def test_delivery_window_warning(self): # No warning with anytime - cust_picking = self._create_delivery_picking(self.customer_anytime) - cust_picking.scheduled_date = "2020-04-03" # Friday - onchange_res = cust_picking._onchange_scheduled_date() + anytime_picking = self._create_delivery_picking(self.customer_anytime) + anytime_picking.scheduled_date = "2020-04-03" # Friday + onchange_res = anytime_picking._onchange_scheduled_date() + self.assertIsNone(onchange_res) + # No warning on friday + workdays_picking = self._create_delivery_picking(self.customer_working_days) + workdays_picking.scheduled_date = "2020-04-03" # Friday + onchange_res = workdays_picking._onchange_scheduled_date() self.assertIsNone(onchange_res) + # But warning on saturday + workdays_picking.scheduled_date = "2020-04-04" # Saturday + onchange_res = workdays_picking._onchange_scheduled_date() + self.assertIn("warning", onchange_res) + self.assertIn( + "the partner is set to prefer deliveries on working days", + onchange_res["warning"]["message"], + ) # No warning on preferred time window - cust_ship_picking = self._create_delivery_picking(self.customer_time_window) - cust_ship_picking.scheduled_date = "2020-04-04" # Saturday - onchange_res = cust_ship_picking._onchange_scheduled_date() + time_window_picking = self._create_delivery_picking(self.customer_time_window) + time_window_picking.scheduled_date = "2020-04-04" # Saturday + onchange_res = time_window_picking._onchange_scheduled_date() self.assertIsNone(onchange_res) - cust_ship_picking.scheduled_date = "2020-04-03" # Friday - onchange_res = cust_ship_picking._onchange_scheduled_date() + time_window_picking.scheduled_date = "2020-04-03" # Friday + onchange_res = time_window_picking._onchange_scheduled_date() self.assertTrue("warning" in onchange_res.keys()) @freeze_time("2020-04-02 07:59:59") # Thursday From e4e353c6e2488c374c4b8b743a493edd4981cf2b Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Wed, 30 Jun 2021 15:17:13 +0200 Subject: [PATCH 08/25] [FW][14.0] stock_partner_delivery_window: Fix default value on delivery_time_preference The default value introduced by workdays feature breaks the installation of Demo databases as the change is not reflected in sale_partner_delivery_window. --- stock_partner_delivery_window/models/res_partner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index f561979f5e50..092bf0423cf7 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -23,7 +23,7 @@ class ResPartner(models.Model): ("workdays", "Weekdays (Monday to Friday)"), ], string="Delivery time schedule preference", - default="workdays", + default="anytime", required=True, help="Define the scheduling preference for delivery orders:\n\n" "* Any time: Do not postpone deliveries\n" From cdb6d76e3e5ea85bf607f4884a960e5abb40b1e0 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Mon, 19 Jul 2021 09:43:19 +0000 Subject: [PATCH 09/25] [UPD] Update stock_partner_delivery_window.pot --- .../i18n/stock_partner_delivery_window.pot | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot diff --git a/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot b/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot new file mode 100644 index 000000000000..77dbb3aec147 --- /dev/null +++ b/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot @@ -0,0 +1,183 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_partner_delivery_window +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.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: stock_partner_delivery_window +#: code:addons/stock_partner_delivery_window/models/res_partner.py:0 +#, python-format +msgid "%s: %s" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields.selection,name:stock_partner_delivery_window.selection__res_partner__delivery_time_preference__anytime +msgid "Any time" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model,name:stock_partner_delivery_window.model_res_partner +msgid "Contact" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__create_uid +msgid "Created by" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__create_date +msgid "Created on" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,help:stock_partner_delivery_window.field_res_partner__delivery_time_preference +#: model:ir.model.fields,help:stock_partner_delivery_window.field_res_users__delivery_time_preference +msgid "" +"Define the scheduling preference for delivery orders:\n" +"\n" +"* Any time: Do not postpone deliveries\n" +"* Fixed time windows: Postpone deliveries to the next preferred time window\n" +"* Weekdays: Postpone deliveries to the next weekday" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner__delivery_time_preference +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_users__delivery_time_preference +msgid "Delivery time schedule preference" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner__delivery_time_window_ids +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_users__delivery_time_window_ids +msgid "Delivery time windows" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__display_name +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner__display_name +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_stock_picking__display_name +msgid "Display Name" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields.selection,name:stock_partner_delivery_window.selection__res_partner__delivery_time_preference__time_windows +msgid "Fixed time windows" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__time_window_start +msgid "From" +msgstr "" + +#. module: stock_partner_delivery_window +#: code:addons/stock_partner_delivery_window/models/res_partner.py:0 +#, python-format +msgid "From %s to %s" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__id +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner__id +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_stock_picking__id +msgid "ID" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window____last_update +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner____last_update +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_stock_picking____last_update +msgid "Last Modified on" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__write_date +msgid "Last Updated on" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__partner_id +msgid "Partner" +msgstr "" + +#. module: stock_partner_delivery_window +#: code:addons/stock_partner_delivery_window/models/res_partner.py:0 +#, python-format +msgid "" +"Please define at least one delivery time window or change preference to Any " +"time" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model,name:stock_partner_delivery_window.model_partner_delivery_time_window +msgid "Preferred delivery time windows" +msgstr "" + +#. module: stock_partner_delivery_window +#: code:addons/stock_partner_delivery_window/models/stock_picking.py:0 +#, python-format +msgid "Scheduled date does not match partner's Delivery window preference." +msgstr "" + +#. module: stock_partner_delivery_window +#: code:addons/stock_partner_delivery_window/models/stock_picking.py:0 +#, python-format +msgid "" +"The scheduled date is %s (%s), but the partner is set to prefer deliveries on following time windows:\n" +"%s" +msgstr "" + +#. module: stock_partner_delivery_window +#: code:addons/stock_partner_delivery_window/models/stock_picking.py:0 +#, python-format +msgid "" +"The scheduled date is {} ({}), but the partner is set to prefer deliveries " +"on working days." +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__time_window_weekday_ids +msgid "Time Window Weekday" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__tz +msgid "Timezone" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__time_window_end +msgid "To" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model,name:stock_partner_delivery_window.model_stock_picking +msgid "Transfer" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields.selection,name:stock_partner_delivery_window.selection__res_partner__delivery_time_preference__workdays +msgid "Weekdays (Monday to Friday)" +msgstr "" + +#. module: stock_partner_delivery_window +#: model:ir.model.fields,help:stock_partner_delivery_window.field_partner_delivery_time_window__tz +msgid "" +"When printing documents and exporting/importing data, time values are computed according to this timezone.\n" +"If the timezone is not set, UTC (Coordinated Universal Time) is used.\n" +"Anywhere else, time values are computed according to the time offset of your web client." +msgstr "" From a0ba5cc19b6fe5a47ae99c1169677077b3d12baf Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 19 Jul 2021 09:48:19 +0000 Subject: [PATCH 10/25] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 stock_partner_delivery_window/static/description/icon.png diff --git a/stock_partner_delivery_window/static/description/icon.png b/stock_partner_delivery_window/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From 7d3072e48508286afcada614a638a728fd719490 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 19 Jul 2021 09:48:19 +0000 Subject: [PATCH 11/25] stock_partner_delivery_window 14.0.1.0.1 --- stock_partner_delivery_window/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index 83b1bf080f43..747b48ef6743 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "14.0.1.0.0", + "version": "14.0.1.0.1", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", From fd251b51406bd7f23d7dc579af01113589c1270c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Tue, 3 Aug 2021 19:16:14 +0200 Subject: [PATCH 12/25] [FIX] s_p_delivery_window: selection attribute will be ignored as the field is related --- stock_partner_delivery_window/models/delivery_time_window.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stock_partner_delivery_window/models/delivery_time_window.py b/stock_partner_delivery_window/models/delivery_time_window.py index 8cb8a1066541..6ad2cd86d077 100644 --- a/stock_partner_delivery_window/models/delivery_time_window.py +++ b/stock_partner_delivery_window/models/delivery_time_window.py @@ -3,8 +3,6 @@ from odoo import api, fields, models -from odoo.addons.base.models.res_partner import _tz_get - class DeliveryTimeWindow(models.Model): @@ -18,7 +16,7 @@ class DeliveryTimeWindow(models.Model): "res.partner", required=True, index=True, ondelete="cascade" ) - tz = fields.Selection(_tz_get, related="partner_id.tz", readonly=True) + tz = fields.Selection(related="partner_id.tz", readonly=True) @api.constrains("partner_id") def check_window_no_overlaps(self): From e5949c7d217a8f5fec552f6bf9ed311ca03a0478 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 5 Aug 2021 08:24:18 +0000 Subject: [PATCH 13/25] stock_partner_delivery_window 14.0.1.1.0 --- stock_partner_delivery_window/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index 747b48ef6743..57ef5c1c9e5f 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "14.0.1.0.1", + "version": "14.0.1.1.0", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", From b4129da9b2eede2c8f7ca62d10f7a283cd4ea2dd Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Mon, 13 Sep 2021 16:00:54 +0200 Subject: [PATCH 14/25] [FIX] stock_partner_delivery_window version version conflict prevents upload to pypi --- stock_partner_delivery_window/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index 57ef5c1c9e5f..6934affc2eff 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "14.0.1.1.0", + "version": "14.0.1.1.1", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", From dc948bf05d7680235d98f63f9e68d01b685eaad4 Mon Sep 17 00:00:00 2001 From: Hai Lang Date: Sun, 12 Dec 2021 20:57:30 +0700 Subject: [PATCH 15/25] [IMP] stock_partner_delivery_window: copy time window ids of partner When copying partner, if the partner's delivery time preference is time window, time window ids should be copied as well. --- .../models/res_partner.py | 19 +++++++++++++++++++ .../tests/test_delivery_window.py | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index 092bf0423cf7..a701bd539b1e 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -152,3 +152,22 @@ def short_format_time(time): ) res[partner.id] = "\n".join(opening_times_description) return res + + def copy_data(self, default=None): + result = super().copy_data(default=default)[0] + not_time_windows = self.delivery_time_preference != "time_windows" + not_copy_windows = not_time_windows or "delivery_time_window_ids" in result + if not_copy_windows: + return [result] + values = [ + { + "time_window_start": window_id.time_window_start, + "time_window_end": window_id.time_window_end, + "time_window_weekday_ids": [ + (4, wd_id.id, 0) for wd_id in window_id.time_window_weekday_ids + ], + } + for window_id in self.delivery_time_window_ids + ] + result["delivery_time_window_ids"] = [(0, 0, val) for val in values] + return [result] diff --git a/stock_partner_delivery_window/tests/test_delivery_window.py b/stock_partner_delivery_window/tests/test_delivery_window.py index 1b734dcd359b..d05c19620042 100644 --- a/stock_partner_delivery_window/tests/test_delivery_window.py +++ b/stock_partner_delivery_window/tests/test_delivery_window.py @@ -161,3 +161,10 @@ def test_with_timezone_no_dst(self): self.assertTrue( isinstance(onchange_res, dict) and "warning" in onchange_res.keys() ) + + def test_copy_partner_with_time_window_ids(self): + copied_partner = self.customer_time_window.copy() + expecting = len(self.customer_time_window.delivery_time_window_ids) + self.assertEqual(len(copied_partner.delivery_time_window_ids), expecting) + copied_partner = self.customer_working_days.copy() + self.assertFalse(copied_partner.delivery_time_window_ids) From 6fff0f9699be3792afb676303d05dea84eddeebe Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 22 Dec 2021 14:24:07 +0000 Subject: [PATCH 16/25] stock_partner_delivery_window 14.0.1.2.0 --- stock_partner_delivery_window/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index 6934affc2eff..fb18dd162c01 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "14.0.1.1.1", + "version": "14.0.1.2.0", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", From 242b5d411c96b9f71ae36410d5120a346b434cb8 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 8 Aug 2022 11:00:18 +0200 Subject: [PATCH 17/25] [14.0][FIX] Align development statuses --- stock_partner_delivery_window/__manifest__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index fb18dd162c01..782d9b08fbfc 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -5,6 +5,7 @@ "summary": "Define preferred delivery time windows for partners", "version": "14.0.1.2.0", "category": "Inventory", + "development_status": "Alpha", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", "website": "https://github.com/OCA/stock-logistics-workflow", From 48984e941141c11b313f8de26868a59797f56ff1 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 8 Aug 2022 09:18:39 +0000 Subject: [PATCH 18/25] [UPD] README.rst --- stock_partner_delivery_window/README.rst | 9 +++++++-- .../static/description/index.html | 8 +++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/stock_partner_delivery_window/README.rst b/stock_partner_delivery_window/README.rst index 51db7cf6d008..16537e9ed0ed 100644 --- a/stock_partner_delivery_window/README.rst +++ b/stock_partner_delivery_window/README.rst @@ -7,9 +7,9 @@ Stock Partner Delivery Window !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png :target: https://odoo-community.org/page/development-status - :alt: Beta + :alt: Alpha .. |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 @@ -29,6 +29,11 @@ This module allows to define time scheduling preference for delivery orders on partners, in order to raise a warning when changing a scheduled date to a time window that is not preferred by this customer. +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + **Table of contents** .. contents:: diff --git a/stock_partner_delivery_window/static/description/index.html b/stock_partner_delivery_window/static/description/index.html index 449dedb6830d..e1dc1056db2f 100644 --- a/stock_partner_delivery_window/static/description/index.html +++ b/stock_partner_delivery_window/static/description/index.html @@ -367,10 +367,16 @@

    Stock Partner Delivery Window

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Beta License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runbot

    +

    Alpha License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runbot

    This module allows to define time scheduling preference for delivery orders on partners, in order to raise a warning when changing a scheduled date to a time window that is not preferred by this customer.

    +
    +

    Important

    +

    This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

    +

    Table of contents

      From d4a35e5c3266b29eb14d1d89ffeb872ac88ebb3c Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 8 Aug 2022 16:38:32 +0200 Subject: [PATCH 19/25] [UPD] stock_partner_delivery_window: Upgrade to Beta --- stock_partner_delivery_window/__manifest__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index 782d9b08fbfc..fb18dd162c01 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -5,7 +5,6 @@ "summary": "Define preferred delivery time windows for partners", "version": "14.0.1.2.0", "category": "Inventory", - "development_status": "Alpha", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", "website": "https://github.com/OCA/stock-logistics-workflow", From bda7d3fc5b334d313a62e63b5128e2e00136637e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 8 Aug 2022 14:48:52 +0000 Subject: [PATCH 20/25] [UPD] README.rst --- stock_partner_delivery_window/README.rst | 9 ++------- .../static/description/index.html | 8 +------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/stock_partner_delivery_window/README.rst b/stock_partner_delivery_window/README.rst index 16537e9ed0ed..51db7cf6d008 100644 --- a/stock_partner_delivery_window/README.rst +++ b/stock_partner_delivery_window/README.rst @@ -7,9 +7,9 @@ Stock Partner Delivery Window !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status - :alt: Alpha + :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 @@ -29,11 +29,6 @@ This module allows to define time scheduling preference for delivery orders on partners, in order to raise a warning when changing a scheduled date to a time window that is not preferred by this customer. -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - **Table of contents** .. contents:: diff --git a/stock_partner_delivery_window/static/description/index.html b/stock_partner_delivery_window/static/description/index.html index e1dc1056db2f..449dedb6830d 100644 --- a/stock_partner_delivery_window/static/description/index.html +++ b/stock_partner_delivery_window/static/description/index.html @@ -367,16 +367,10 @@

      Stock Partner Delivery Window

      !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

      Alpha License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runbot

      +

      Beta License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runbot

      This module allows to define time scheduling preference for delivery orders on partners, in order to raise a warning when changing a scheduled date to a time window that is not preferred by this customer.

      -
      -

      Important

      -

      This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

      -

      Table of contents

        From 1d12f52c921652d7db95deab64768eba60a1fd50 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 8 Aug 2022 14:48:52 +0000 Subject: [PATCH 21/25] stock_partner_delivery_window 14.0.1.2.1 --- stock_partner_delivery_window/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index fb18dd162c01..213e7b0ceaee 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "14.0.1.2.0", + "version": "14.0.1.2.1", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", From 10957ee31cb5a3c2ce4ba2fd7d1b46e59c84ec4a Mon Sep 17 00:00:00 2001 From: MmeQuignon Date: Thu, 16 Mar 2023 17:02:47 +0100 Subject: [PATCH 22/25] s_p_delivery_window: Make delivery windows inclusive --- stock_partner_delivery_window/models/res_partner.py | 2 +- .../tests/test_delivery_window.py | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index a701bd539b1e..d60b25684204 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -94,7 +94,7 @@ def is_in_delivery_window(self, date_time): else: utc_start = start_time utc_end = end_time - if utc_start <= date_time.time() < utc_end: + if utc_start <= date_time.time() <= utc_end: return True return False diff --git a/stock_partner_delivery_window/tests/test_delivery_window.py b/stock_partner_delivery_window/tests/test_delivery_window.py index d05c19620042..55dc1c5743e8 100644 --- a/stock_partner_delivery_window/tests/test_delivery_window.py +++ b/stock_partner_delivery_window/tests/test_delivery_window.py @@ -118,9 +118,14 @@ def test_with_timezone_dst(self): onchange_res = picking._onchange_scheduled_date() self.assertIsNone(onchange_res) # Scheduled date is in UTC so 2020-04-02 14:00:00 == 2020-04-02 16:00:00 - # in Brussels which is not preferred + # in Brussels which is preferred picking.scheduled_date = "2020-04-02 14:00:00" onchange_res = picking._onchange_scheduled_date() + self.assertIsNone(onchange_res) + # Scheduled date is in UTC so 2020-04-02 14:00:01 == 2020-04-02 16:00:01 + # in Brussels which is preferred + picking.scheduled_date = "2020-04-02 14:00:01" + onchange_res = picking._onchange_scheduled_date() self.assertTrue( isinstance(onchange_res, dict) and "warning" in onchange_res.keys() ) @@ -158,6 +163,11 @@ def test_with_timezone_no_dst(self): # in Brussels which is preferred picking.scheduled_date = "2020-03-26 15:00:00" onchange_res = picking._onchange_scheduled_date() + self.assertIsNone(onchange_res) + # Scheduled date is in UTC so 2020-03-26 15:00:01 == 2020-04-02 16:00:01 + # in Brussels which is not preferred + picking.scheduled_date = "2020-03-26 15:00:01" + onchange_res = picking._onchange_scheduled_date() self.assertTrue( isinstance(onchange_res, dict) and "warning" in onchange_res.keys() ) From 23ebf8cf066032ff391407244fd3d53f56d8ae4d Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 21 Mar 2023 10:53:28 +0000 Subject: [PATCH 23/25] stock_partner_delivery_window 14.0.1.2.2 --- stock_partner_delivery_window/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index 213e7b0ceaee..a61eac993734 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "14.0.1.2.1", + "version": "14.0.1.2.2", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", From 749f6dbc1431ad642e3a28eee1d3036c45eb6eb3 Mon Sep 17 00:00:00 2001 From: chien Date: Thu, 14 Sep 2023 16:48:28 +0700 Subject: [PATCH 24/25] [IMP] stock_partner_delivery_window: black, isort, prettier --- .../odoo/addons/stock_partner_delivery_window | 1 + setup/stock_partner_delivery_window/setup.py | 6 ++++++ 2 files changed, 7 insertions(+) create mode 120000 setup/stock_partner_delivery_window/odoo/addons/stock_partner_delivery_window create mode 100644 setup/stock_partner_delivery_window/setup.py diff --git a/setup/stock_partner_delivery_window/odoo/addons/stock_partner_delivery_window b/setup/stock_partner_delivery_window/odoo/addons/stock_partner_delivery_window new file mode 120000 index 000000000000..e6205a6f6de0 --- /dev/null +++ b/setup/stock_partner_delivery_window/odoo/addons/stock_partner_delivery_window @@ -0,0 +1 @@ +../../../../stock_partner_delivery_window \ No newline at end of file diff --git a/setup/stock_partner_delivery_window/setup.py b/setup/stock_partner_delivery_window/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/stock_partner_delivery_window/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 18daa31cd2684ac5cbac1e4951c2f0d665bd1cbe Mon Sep 17 00:00:00 2001 From: chien Date: Thu, 14 Sep 2023 16:48:47 +0700 Subject: [PATCH 25/25] [MIG] stock_partner_delivery_window: Migration to 16.0 --- stock_partner_delivery_window/__manifest__.py | 2 +- .../i18n/stock_partner_delivery_window.pot | 24 +++++++++---------- .../models/delivery_time_window.py | 3 --- .../models/res_partner.py | 15 ++++++++++-- .../models/stock_picking.py | 22 ++++++++--------- .../tests/test_delivery_window.py | 4 ++-- 6 files changed, 39 insertions(+), 31 deletions(-) diff --git a/stock_partner_delivery_window/__manifest__.py b/stock_partner_delivery_window/__manifest__.py index a61eac993734..422df64fb2f2 100644 --- a/stock_partner_delivery_window/__manifest__.py +++ b/stock_partner_delivery_window/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Partner Delivery Window", "summary": "Define preferred delivery time windows for partners", - "version": "14.0.1.2.2", + "version": "16.0.1.0.0", "category": "Inventory", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", diff --git a/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot b/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot index 77dbb3aec147..383d59c55b91 100644 --- a/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot +++ b/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot @@ -4,8 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-09-14 09:01+0000\n" +"PO-Revision-Date: 2023-09-14 09:01+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -16,7 +18,7 @@ msgstr "" #. module: stock_partner_delivery_window #: code:addons/stock_partner_delivery_window/models/res_partner.py:0 #, python-format -msgid "%s: %s" +msgid "{}: {}" msgstr "" #. module: stock_partner_delivery_window @@ -64,8 +66,6 @@ msgstr "" #. module: stock_partner_delivery_window #: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__display_name -#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner__display_name -#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_stock_picking__display_name msgid "Display Name" msgstr "" @@ -82,20 +82,16 @@ msgstr "" #. module: stock_partner_delivery_window #: code:addons/stock_partner_delivery_window/models/res_partner.py:0 #, python-format -msgid "From %s to %s" +msgid "From {} to {}" msgstr "" #. module: stock_partner_delivery_window #: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window__id -#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner__id -#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_stock_picking__id msgid "ID" msgstr "" #. module: stock_partner_delivery_window #: model:ir.model.fields,field_description:stock_partner_delivery_window.field_partner_delivery_time_window____last_update -#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_res_partner____last_update -#: model:ir.model.fields,field_description:stock_partner_delivery_window.field_stock_picking____last_update msgid "Last Modified on" msgstr "" @@ -115,6 +111,7 @@ msgid "Partner" msgstr "" #. module: stock_partner_delivery_window +#. odoo-python #: code:addons/stock_partner_delivery_window/models/res_partner.py:0 #, python-format msgid "" @@ -128,20 +125,23 @@ msgid "Preferred delivery time windows" msgstr "" #. module: stock_partner_delivery_window +#. odoo-python #: code:addons/stock_partner_delivery_window/models/stock_picking.py:0 #, python-format msgid "Scheduled date does not match partner's Delivery window preference." msgstr "" #. module: stock_partner_delivery_window +#. odoo-python #: code:addons/stock_partner_delivery_window/models/stock_picking.py:0 #, python-format msgid "" -"The scheduled date is %s (%s), but the partner is set to prefer deliveries on following time windows:\n" -"%s" +"The scheduled date is {date} ({tz}), but the partner is set to prefer deliveries on following time windows:\n" +"{window}" msgstr "" #. module: stock_partner_delivery_window +#. odoo-python #: code:addons/stock_partner_delivery_window/models/stock_picking.py:0 #, python-format msgid "" @@ -180,4 +180,4 @@ msgid "" "When printing documents and exporting/importing data, time values are computed according to this timezone.\n" "If the timezone is not set, UTC (Coordinated Universal Time) is used.\n" "Anywhere else, time values are computed according to the time offset of your web client." -msgstr "" +msgstr "" \ No newline at end of file diff --git a/stock_partner_delivery_window/models/delivery_time_window.py b/stock_partner_delivery_window/models/delivery_time_window.py index 6ad2cd86d077..8739938d2a99 100644 --- a/stock_partner_delivery_window/models/delivery_time_window.py +++ b/stock_partner_delivery_window/models/delivery_time_window.py @@ -5,17 +5,14 @@ class DeliveryTimeWindow(models.Model): - _name = "partner.delivery.time.window" _inherit = "time.window.mixin" _description = "Preferred delivery time windows" - _time_window_overlap_check_field = "partner_id" partner_id = fields.Many2one( "res.partner", required=True, index=True, ondelete="cascade" ) - tz = fields.Selection(related="partner_id.tz", readonly=True) @api.constrains("partner_id") diff --git a/stock_partner_delivery_window/models/res_partner.py b/stock_partner_delivery_window/models/res_partner.py index d60b25684204..b54c205e5770 100644 --- a/stock_partner_delivery_window/models/res_partner.py +++ b/stock_partner_delivery_window/models/res_partner.py @@ -1,5 +1,6 @@ # Copyright 2020 Camptocamp SA # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +import warnings from collections import defaultdict from datetime import time @@ -99,9 +100,19 @@ def is_in_delivery_window(self, date_time): return False def _get_delivery_time_format_string(self): - return _("From %s to %s") + warnings.warn( + "Method `_get_delivery_time_format_string` will be deprecated in the next version", + DeprecationWarning, + stacklevel=2, + ) + return _("From {} to {}") def get_delivery_time_description(self): + warnings.warn( + "Method `get_delivery_time_description` will be deprecated in the next version", + DeprecationWarning, + stacklevel=2, + ) res = dict() day_translated_values = dict( self.env["time.weekday"]._fields["name"]._description_selection(self.env) @@ -148,7 +159,7 @@ def short_format_time(time): opening_times_description = list() for day_name, time_list in opening_times.items(): opening_times_description.append( - _("%s: %s") % (day_name, _(", ").join(time_list)) + _("{}: {}").format(day_name, _(", ").join(time_list)) ) res[partner.id] = "\n".join(opening_times_description) return res diff --git a/stock_partner_delivery_window/models/stock_picking.py b/stock_partner_delivery_window/models/stock_picking.py index c83a7d1a7d9c..0d2aacdf154b 100644 --- a/stock_partner_delivery_window/models/stock_picking.py +++ b/stock_partner_delivery_window/models/stock_picking.py @@ -33,18 +33,18 @@ def _scheduled_date_no_delivery_window_match_msg(self): ).format(formatted_scheduled_date, scheduled_date.weekday()) else: delivery_windows_strings = [] - for w in partner.get_delivery_windows().get(partner.id): - delivery_windows_strings.append( - " * {} ({})".format(w.display_name, partner.tz) - ) + if partner: + for w in partner.get_delivery_windows().get(partner.id): + delivery_windows_strings.append( + " * {} ({})".format(w.display_name, partner.tz) + ) message = _( - "The scheduled date is %s (%s), but the partner is " - "set to prefer deliveries on following time windows:\n%s" - % ( - format_datetime(self.env, self.scheduled_date), - self.env.context.get("tz"), - "\n".join(delivery_windows_strings), - ) + "The scheduled date is {date} ({tz}), but the partner is " + "set to prefer deliveries on following time windows:\n{window}" + ).format( + date=format_datetime(self.env, self.scheduled_date), + tz=self.env.context.get("tz"), + window="\n".join(delivery_windows_strings), ) return { "title": _( diff --git a/stock_partner_delivery_window/tests/test_delivery_window.py b/stock_partner_delivery_window/tests/test_delivery_window.py index 55dc1c5743e8..49f57b1261ba 100644 --- a/stock_partner_delivery_window/tests/test_delivery_window.py +++ b/stock_partner_delivery_window/tests/test_delivery_window.py @@ -2,10 +2,10 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from freezegun import freeze_time -from odoo.tests import SavepointCase +from odoo.tests.common import TransactionCase -class TestPartnerDeliveryWindow(SavepointCase): +class TestPartnerDeliveryWindow(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass()