From 5b548aa4e3f5fa1d61c600e1abe427510bc67867 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Tue, 31 Mar 2020 17:58:47 +0200 Subject: [PATCH 01/36] 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 9dac386da08b04c27e4a5298f9dae0480ed73047 Mon Sep 17 00:00:00 2001 From: "dung.tran" Date: Sun, 17 Jan 2021 10:13:13 +0700 Subject: [PATCH 02/36] [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 7a7b7180938a254e75558a0e075f4e03ea674f40 Mon Sep 17 00:00:00 2001 From: "dung.tran" Date: Sun, 17 Jan 2021 10:17:18 +0700 Subject: [PATCH 03/36] [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 3d4e0e6ae55ff1e2a86770b2100b6e4a3e0a02a0 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/36] 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 7b48a3be0a621e6078ae463d5af9af2c63f5f99c Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Fri, 2 Apr 2021 14:56:50 +0200 Subject: [PATCH 05/36] 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 a2671f0a76119a3618f53c294ba1471458859d9b 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/36] 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 ca41490d29d1f5b861c0297d7b7a386d435c4752 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/36] 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 dcb929c4ecc9f69bde5f046ea9230460598b7c08 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Wed, 30 Jun 2021 15:17:13 +0200 Subject: [PATCH 08/36] [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 35766dcfa7646930ff235b142e76ab59ba045b01 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Mon, 19 Jul 2021 09:43:19 +0000 Subject: [PATCH 09/36] [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 ee175c19f5a5cca655e67509a734af8c53d81604 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 19 Jul 2021 09:48:19 +0000 Subject: [PATCH 10/36] [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 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From 76bc943955f93b95bfa85578963927dd1965bf7f Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 19 Jul 2021 09:48:19 +0000 Subject: [PATCH 11/36] 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 2de493fadead3bb3d3808a9ce8518367303d6e3b 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/36] [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 afd1b2b2cce9353227710cdf79c34c49bca97abe Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 5 Aug 2021 08:24:18 +0000 Subject: [PATCH 13/36] 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 206dcdad78a5992a723fc51c890fbae784ec8024 Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Mon, 13 Sep 2021 16:00:54 +0200 Subject: [PATCH 14/36] [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 194eb9f7095b7de259d5a5b7f3e28c8761a56a31 Mon Sep 17 00:00:00 2001 From: Hai Lang Date: Sun, 12 Dec 2021 20:57:30 +0700 Subject: [PATCH 15/36] [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 d9d910c1ab84ceb9b137cfa60eb846f1d1f8d892 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 22 Dec 2021 14:24:07 +0000 Subject: [PATCH 16/36] 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 e9bb168e24c4d1659d4484359d7a8e18881ad107 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 8 Aug 2022 11:00:18 +0200 Subject: [PATCH 17/36] [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 8f30e129fcf28c29af87edab1c0d47b2af375de3 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 8 Aug 2022 09:18:39 +0000 Subject: [PATCH 18/36] [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 521302696136a1d32f864ad0ede8765b4185be31 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 8 Aug 2022 16:38:32 +0200 Subject: [PATCH 19/36] [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 1458d3fc75edc6bbf257377f4b220f9ea08c4347 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 8 Aug 2022 14:48:52 +0000 Subject: [PATCH 20/36] [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 d487d54f7ca7dfeb8e0e7a0b3abeaffa37e74425 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 8 Aug 2022 14:48:52 +0000 Subject: [PATCH 21/36] 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 8038dd94461268b7ee4f9f9a3e9333d87e829e5a Mon Sep 17 00:00:00 2001 From: MmeQuignon Date: Thu, 16 Mar 2023 17:02:47 +0100 Subject: [PATCH 22/36] 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 1e668ef7b96346dd1ea71af47ae4d6ef1438c005 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 21 Mar 2023 10:53:28 +0000 Subject: [PATCH 23/36] 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 833716ac947e96c9a21c169f98d6e57ac6e9112d Mon Sep 17 00:00:00 2001 From: chien Date: Thu, 14 Sep 2023 16:48:47 +0700 Subject: [PATCH 24/36] [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() From 9845e06948ad187806b263e00ce29258bad8ab87 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 10 Oct 2023 11:51:30 +0000 Subject: [PATCH 25/36] [UPD] Update stock_partner_delivery_window.pot --- .../i18n/stock_partner_delivery_window.pot | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) 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 383d59c55b91..675cad797e93 100644 --- a/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot +++ b/stock_partner_delivery_window/i18n/stock_partner_delivery_window.pot @@ -6,8 +6,6 @@ msgid "" msgstr "" "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" @@ -15,12 +13,6 @@ msgstr "" "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 "{}: {}" -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" @@ -80,6 +72,7 @@ msgid "From" msgstr "" #. module: stock_partner_delivery_window +#. odoo-python #: code:addons/stock_partner_delivery_window/models/res_partner.py:0 #, python-format msgid "From {} to {}" @@ -180,4 +173,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 "" \ No newline at end of file +msgstr "" From b8f52a61ca0ba8d783033e2ef59e2d74557dec54 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 10 Oct 2023 11:55:52 +0000 Subject: [PATCH 26/36] [BOT] post-merge updates --- stock_partner_delivery_window/README.rst | 23 ++++++---- .../static/description/index.html | 46 ++++++++++--------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/stock_partner_delivery_window/README.rst b/stock_partner_delivery_window/README.rst index 51db7cf6d008..8f5bbadc0a23 100644 --- a/stock_partner_delivery_window/README.rst +++ b/stock_partner_delivery_window/README.rst @@ -2,10 +2,13 @@ Stock Partner Delivery Window ============================= -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7773d26fe73742600130b0050107915c92fb1cf4110f6f0f608e8072885928bb + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -14,16 +17,16 @@ Stock Partner Delivery Window :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--workflow-lightgray.png?logo=github - :target: https://github.com/OCA/stock-logistics-workflow/tree/14.0/stock_partner_delivery_window + :target: https://github.com/OCA/stock-logistics-workflow/tree/16.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 + :target: https://translation.odoo-community.org/projects/stock-logistics-workflow-16-0/stock-logistics-workflow-16-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 +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-workflow&target_branch=16.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|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 @@ -54,8 +57,8 @@ 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 `_. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -98,6 +101,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/stock-logistics-workflow `_ project on GitHub. +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/static/description/index.html b/stock_partner_delivery_window/static/description/index.html index 449dedb6830d..eedac71453ba 100644 --- a/stock_partner_delivery_window/static/description/index.html +++ b/stock_partner_delivery_window/static/description/index.html @@ -1,20 +1,20 @@ - + - + Stock Partner Delivery Window