From 62cf11f0a3d6a37ba2a20d844f5350bb9a32a7ae Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Mon, 1 Apr 2024 20:17:42 +0200 Subject: [PATCH] [OU-IMP] delivery: Added specific method for handling numeric ranges The other algorithm is not OK when dealing numeric ranges, as it also generates the prefixes for the rest of the alphanumeric values, when it's clear that we are not wanting such cases (although previous v15 string comparison allowed it without intent). TT43606 --- .../delivery/16.0.1.0/post-migration.py | 94 +++++++++++++------ .../16.0.1.0/upgrade_analysis_work.txt | 17 +++- 2 files changed, 78 insertions(+), 33 deletions(-) diff --git a/openupgrade_scripts/scripts/delivery/16.0.1.0/post-migration.py b/openupgrade_scripts/scripts/delivery/16.0.1.0/post-migration.py index b6678318d709..1fe33cfcbb89 100644 --- a/openupgrade_scripts/scripts/delivery/16.0.1.0/post-migration.py +++ b/openupgrade_scripts/scripts/delivery/16.0.1.0/post-migration.py @@ -1,10 +1,9 @@ # SPDX-FileCopyrightText: 2023 Coop IT Easy SC -# +# SPDX-FileCopyrightText: 2024 Tecnativa - Pedro M. Baeza # SPDX-License-Identifier: AGPL-3.0-or-later import logging import string -from inspect import cleandoc from openupgradelib import openupgrade @@ -80,7 +79,6 @@ def range_to_prefixes(start, end): f"{start!r} and {end!r} do not have spaces or dashes in identical" f" locations" ) - prefixes = set() not_prefixes = set() alphanum = start @@ -101,36 +99,76 @@ def range_to_prefixes(start, end): return prefixes +def numerical_range_to_prefixes(min_, max_): + """Adapted from https://github.com/voronind/range-regex.""" + + def fill_by_nines(integer, nines_count): + return int(str(integer)[:-nines_count] + "9" * nines_count) + + def fill_by_zeros(integer, zeros_count): + return integer - integer % 10**zeros_count + + def split_to_ranges(min_, max_): + stops = {max_} + nines_count = 1 + stop = fill_by_nines(min_, nines_count) + while min_ <= stop < max_: + stops.add(stop) + nines_count += 1 + stop = fill_by_nines(min_, nines_count) + zeros_count = 1 + stop = fill_by_zeros(max_ + 1, zeros_count) - 1 + while min_ < stop <= max_: + stops.add(stop) + zeros_count += 1 + stop = fill_by_zeros(max_ + 1, zeros_count) - 1 + stops = list(stops) + stops.sort() + return stops + + subpatterns = [] + start = min_ + for stop in split_to_ranges(min_, max_): + pattern = "" + any_digit_count = 0 + for start_digit, stop_digit in zip(str(start), str(stop)): + if start_digit == stop_digit: + pattern += start_digit + elif start_digit != "0" or stop_digit != "9": + pattern += "[{}-{}]".format(start_digit, stop_digit) + else: + any_digit_count += 1 + if any_digit_count: + pattern += r"\d" + if any_digit_count > 1: + pattern += "{{{}}}".format(any_digit_count) + subpatterns.append(pattern) + start = stop + 1 + return subpatterns + + @openupgrade.migrate() def migrate(env, version): - delivery_methods = env["delivery.carrier"].search([]) - if not delivery_methods: - return - _logger.warning( - cleandoc( - """ - TODO: warn that this creates weird results that are technically - correct. - """ - ) + delivery_methods = env["delivery.carrier"].search( + [("zip_from", "!=", False), ("zip_to", "!=", False)] ) for method in delivery_methods: - try: - prefixes = range_to_prefixes(method.zip_from, method.zip_to) - except Exception as error: - _logger.error( - f"Failed to convert the zip range '{method.zip_from} --" - f" {method.zip_to}'of delivery method {method!r} to a set of" - f" prefixes. Got error:\n\n{error}" + if method.zip_from.isnumeric() and method.zip_to.isnumeric(): + prefixes = numerical_range_to_prefixes( + int(method.zip_from), int(method.zip_to) ) - continue - - for prefix in prefixes: + else: try: - prefix_record = env["delivery.zip.prefix"].create({"name": prefix}) - # TODO: which exception? - except Exception: - prefix_record = env["delivery.zip.prefix"].search( - [("name", "=", prefix)] + prefixes = range_to_prefixes(method.zip_from, method.zip_to) + except Exception as error: + _logger.error( + f"Failed to convert the zip range '{method.zip_from} --" + f" {method.zip_to}'of delivery method {method!r} to a set of" + f" prefixes. Got error:\n\n{error}" ) + continue + for prefix in prefixes: + prefix_record = env["delivery.zip.prefix"].search([("name", "=", prefix)]) + if not prefix_record: + prefix_record = env["delivery.zip.prefix"].create({"name": prefix}) method.zip_prefix_ids |= prefix_record diff --git a/openupgrade_scripts/scripts/delivery/16.0.1.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/delivery/16.0.1.0/upgrade_analysis_work.txt index f74468f54e98..14ebdc503b58 100644 --- a/openupgrade_scripts/scripts/delivery/16.0.1.0/upgrade_analysis_work.txt +++ b/openupgrade_scripts/scripts/delivery/16.0.1.0/upgrade_analysis_work.txt @@ -2,16 +2,23 @@ new model delivery.zip.prefix ---Fields in module 'delivery'--- delivery / delivery.carrier / carrier_description (text) : NEW +# NOTHING TO DO: New feature for showing in the sales order a description for the delivery method. + delivery / delivery.carrier / shipping_insurance (integer) : NEW hasdefault: default -# NOTHING TO DO +# NOTHING TO DO: New feature for indicating to the providers the insurance percentage covered. + delivery / delivery.carrier / zip_from (char) : DEL -delivery / delivery.carrier / zip_prefix_ids (many2many) : NEW relation: delivery.zip.prefix delivery / delivery.carrier / zip_to (char) : DEL +delivery / delivery.carrier / zip_prefix_ids (many2many) : NEW relation: delivery.zip.prefix delivery / delivery.zip.prefix / name (char) : NEW required -# TODO +# DONE: post-migration: Extract prefixes as regexp. + delivery / product.template / country_of_origin (many2one) : NEW relation: res.country +# NOTHING TO DO: New field for Intrastat. May should be filled from OCA Intrastat modules + delivery / stock.move.line / carrier_name (char) : NEW isrelated: related, stored -# NOTHING TO DO +# NOTHING TO DO: Related stored already handled in a fast way by ORM. + ---XML records in module 'delivery'--- NEW ir.actions.act_window: delivery.action_delivery_zip_prefix_list NEW ir.model.access: delivery.access_delivery_carrier_system @@ -25,4 +32,4 @@ NEW ir.ui.view: delivery.label_package_template_view_delivery NEW ir.ui.view: delivery.stock_move_line_view_search_delivery NEW ir.ui.view: delivery.view_picking_type_form_delivery NEW ir.ui.view: delivery.view_stock_rule_form_delivery -# NOTHING TO DO +# NOTHING TO DO: noupdate=0 records handled by ORM.