From 12f61822bf7449ef2643a0f2a97436a40ab8df49 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 4 Dec 2023 11:44:59 +0100 Subject: [PATCH 001/357] [ADD] stock_full_location_reservation: Extend reservation to full content of location --- stock_full_location_reservation/README.rst | 97 ++++ stock_full_location_reservation/__init__.py | 1 + .../__manifest__.py | 17 + .../models/__init__.py | 4 + .../models/stock_move.py | 77 ++++ .../models/stock_move_line.py | 63 +++ .../models/stock_picking.py | 32 ++ .../models/stock_picking_type.py | 13 + .../readme/CONFIGURE.rst | 1 + .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 7 + .../security/groups.xml | 6 + .../static/description/index.html | 434 ++++++++++++++++++ .../tests/__init__.py | 2 + .../tests/common.py | 81 ++++ .../tests/test_full_location_reservation.py | 110 +++++ .../views/stock_picking_type_views.xml | 15 + .../views/stock_picking_views.xml | 27 ++ 18 files changed, 989 insertions(+) create mode 100644 stock_full_location_reservation/README.rst create mode 100644 stock_full_location_reservation/__init__.py create mode 100644 stock_full_location_reservation/__manifest__.py create mode 100644 stock_full_location_reservation/models/__init__.py create mode 100644 stock_full_location_reservation/models/stock_move.py create mode 100644 stock_full_location_reservation/models/stock_move_line.py create mode 100644 stock_full_location_reservation/models/stock_picking.py create mode 100644 stock_full_location_reservation/models/stock_picking_type.py create mode 100644 stock_full_location_reservation/readme/CONFIGURE.rst create mode 100644 stock_full_location_reservation/readme/CONTRIBUTORS.rst create mode 100644 stock_full_location_reservation/readme/DESCRIPTION.rst create mode 100644 stock_full_location_reservation/security/groups.xml create mode 100644 stock_full_location_reservation/static/description/index.html create mode 100644 stock_full_location_reservation/tests/__init__.py create mode 100644 stock_full_location_reservation/tests/common.py create mode 100644 stock_full_location_reservation/tests/test_full_location_reservation.py create mode 100644 stock_full_location_reservation/views/stock_picking_type_views.xml create mode 100644 stock_full_location_reservation/views/stock_picking_views.xml diff --git a/stock_full_location_reservation/README.rst b/stock_full_location_reservation/README.rst new file mode 100644 index 00000000000..508db9870ae --- /dev/null +++ b/stock_full_location_reservation/README.rst @@ -0,0 +1,97 @@ +=============================== +Stock full location reservation +=============================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:b38409babd88e4fd7f1d1e78c4b74f8df1d3c69a27c65fcc334388a293dca5b3 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/14.0/stock_full_location_reservation + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-stock_full_location_reservation + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Allow to extend a reservation to the full content of the source location. + +For example, if you have a reassort move for 2 units but the source location +contains 20 units, this module allows to extend the reservation to the 20 units +to move the complete content of the source location. + +This can typically be used with shopfloor location content transfer scenario. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +On the operation type, configure if the full reservation button action is visible on related transfers + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* MT Software +* BCIM + +Contributors +~~~~~~~~~~~~ + +* Michael Tietz (MT Software) +* Jacques-Etienne Baudoux (BCIM) + +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. + +.. |maintainer-mt-software-de| image:: https://github.com/mt-software-de.png?size=40px + :target: https://github.com/mt-software-de + :alt: mt-software-de + +Current `maintainer `__: + +|maintainer-mt-software-de| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_full_location_reservation/__init__.py b/stock_full_location_reservation/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/stock_full_location_reservation/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_full_location_reservation/__manifest__.py b/stock_full_location_reservation/__manifest__.py new file mode 100644 index 00000000000..eafb50b5f99 --- /dev/null +++ b/stock_full_location_reservation/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2023 Michael Tietz (MT Software) +{ + "name": "Stock full location reservation", + "summary": "Extend reservation to full content of location", + "author": "MT Software, BCIM, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/wms", + "category": "Warehouse Management", + "version": "14.0.1.0.0", + "license": "AGPL-3", + "depends": ["stock"], + "data": [ + "security/groups.xml", + "views/stock_picking_views.xml", + "views/stock_picking_type_views.xml", + ], + "maintainers": ["mt-software-de"], +} diff --git a/stock_full_location_reservation/models/__init__.py b/stock_full_location_reservation/models/__init__.py new file mode 100644 index 00000000000..27972ac5f52 --- /dev/null +++ b/stock_full_location_reservation/models/__init__.py @@ -0,0 +1,4 @@ +from . import stock_move +from . import stock_move_line +from . import stock_picking +from . import stock_picking_type diff --git a/stock_full_location_reservation/models/stock_move.py b/stock_full_location_reservation/models/stock_move.py new file mode 100644 index 00000000000..20a9cc62796 --- /dev/null +++ b/stock_full_location_reservation/models/stock_move.py @@ -0,0 +1,77 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class StockMove(models.Model): + _inherit = "stock.move" + + is_full_location_reservation = fields.Boolean( + "Full location reservation move", default=False + ) + + def _filter_full_location_reservation_moves(self): + return self.filtered(lambda m: m.is_full_location_reservation) + + def _do_unreserve(self): + if self.env.context.get("skip_undo_full_location_reservation"): + return super()._do_unreserve() + full_location_moves = self._filter_full_location_reservation_moves() + full_location_moves._undo_full_location_reservation() + return super(StockMove, (self - full_location_moves))._do_unreserve() + + def undo_full_location_reservation(self): + full_location_moves = self._filter_full_location_reservation_moves() + full_location_moves._undo_full_location_reservation() + + def _undo_full_location_reservation(self): + if not self.exists(): + return + self = self.with_context(skip_undo_full_location_reservation=True) + self._do_unreserve() + self._action_cancel() + self.unlink() + + def _prepare_full_location_reservation_package_level_vals(self, package): + return { + "package_id": package.id, + "company_id": self.company_id.id, + } + + def _full_location_reservation_create_package_level(self, package): + return self.env["stock.package_level"].create( + self._prepare_full_location_reservation_package_level_vals(package) + ) + + def _full_location_reservation_prepare_move_vals( + self, product, qty, location, package=None + ): + self.ensure_one() + package_level_id = False + if package: + package_level_id = self._full_location_reservation_create_package_level( + package + ).id + return { + "is_full_location_reservation": True, + "product_uom_qty": qty, + "name": product.name, + "product_uom": product.uom_id.id, + "product_id": product.id, + "location_id": location.id, + "location_dest_id": self.picking_id.location_dest_id.id, + "picking_id": self.picking_id.id, + "package_level_id": package_level_id, + } + + def _full_location_reservation_create_move( + self, product, qty, location, package=None + ): + return self.create( + self._full_location_reservation_prepare_move_vals( + product, qty, location, package + ) + ) + + def _full_location_reservation(self, package_only=None): + return self.move_line_ids._full_location_reservation(package_only) diff --git a/stock_full_location_reservation/models/stock_move_line.py b/stock_full_location_reservation/models/stock_move_line.py new file mode 100644 index 00000000000..dba21efe243 --- /dev/null +++ b/stock_full_location_reservation/models/stock_move_line.py @@ -0,0 +1,63 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from collections import defaultdict + +from odoo import models +from odoo.osv import expression +from odoo.tools.float_utils import float_compare + + +class StockMoveLine(models.Model): + _inherit = "stock.move.line" + + def _prepare_full_location_reservation_quants_domain(self, package_only=None): + domains = [] + for line in self: + domain = [("location_id", "=", line.location_id.id)] + if package_only: + if line.package_id: + domain += [("package_id", "=", line.package_id.id)] + else: + continue + domains.append(domain) + return expression.OR(domains) + + def _get_full_location_reservation_quants(self, package_only=None): + domain = self._prepare_full_location_reservation_quants_domain(package_only) + return self.env["stock.quant"].search(domain) + + def _get_full_location_reservable_qties(self, package_only=None): + quants = self._get_full_location_reservation_quants(package_only) + res = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: 0))) + for quant in quants: + qty_available = quant.available_quantity + if ( + float_compare( + qty_available, 0, precision_rounding=quant.product_uom_id.rounding + ) + > 0 + ): + res[quant.location_id][quant.package_id][ + quant.product_id + ] += qty_available + return res + + def _full_location_reservation(self, package_only=None): + reservable_qties = self._get_full_location_reservable_qties(package_only) + moves_to_assign_ids = [] + for line in self: + qties = reservable_qties.get(line.location_id, {}).get(line.package_id, {}) + if not qties: + continue + for product, qty in qties.items(): + moves_to_assign_ids.append( + line.move_id._full_location_reservation_create_move( + product, qty, line.location_id, line.package_id + ).id + ) + reservable_qties[line.location_id].pop(line.package_id) + moves_to_assign = self.move_id.browse(moves_to_assign_ids) + if moves_to_assign: + moves_to_assign._action_confirm() + moves_to_assign._action_assign() + return moves_to_assign diff --git a/stock_full_location_reservation/models/stock_picking.py b/stock_full_location_reservation/models/stock_picking.py new file mode 100644 index 00000000000..b8b96913e0a --- /dev/null +++ b/stock_full_location_reservation/models/stock_picking.py @@ -0,0 +1,32 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + is_full_location_reservation_visible = fields.Boolean( + "Is full location reservation visible", + related="picking_type_id.is_full_location_reservation_visible", + ) + has_full_location_reservations = fields.Boolean( + "Has full location reservations", + compute="_compute_has_full_location_reservations", + ) + + @api.depends("move_lines.is_full_location_reservation") + def _compute_has_full_location_reservations(self): + for rec in self: + rec.has_full_location_reservations = ( + rec.move_lines.filtered(lambda m: m.is_full_location_reservation) + and True + or False + ) + + def do_full_location_reservation(self): + self.move_lines._full_location_reservation() + + def undo_full_location_reservation(self): + self.move_lines.undo_full_location_reservation() diff --git a/stock_full_location_reservation/models/stock_picking_type.py b/stock_full_location_reservation/models/stock_picking_type.py new file mode 100644 index 00000000000..b434ea2c651 --- /dev/null +++ b/stock_full_location_reservation/models/stock_picking_type.py @@ -0,0 +1,13 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class StockPickingType(models.Model): + _inherit = "stock.picking.type" + + is_full_location_reservation_visible = fields.Boolean( + "Is full location reservation visible", + help="""If this is checked, the full reservation of a the picking is visible""", + ) diff --git a/stock_full_location_reservation/readme/CONFIGURE.rst b/stock_full_location_reservation/readme/CONFIGURE.rst new file mode 100644 index 00000000000..2e4391267a2 --- /dev/null +++ b/stock_full_location_reservation/readme/CONFIGURE.rst @@ -0,0 +1 @@ +On the operation type, configure if the full reservation button action is visible on related transfers diff --git a/stock_full_location_reservation/readme/CONTRIBUTORS.rst b/stock_full_location_reservation/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..03c3145a2be --- /dev/null +++ b/stock_full_location_reservation/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Michael Tietz (MT Software) +* Jacques-Etienne Baudoux (BCIM) diff --git a/stock_full_location_reservation/readme/DESCRIPTION.rst b/stock_full_location_reservation/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..145887b0d27 --- /dev/null +++ b/stock_full_location_reservation/readme/DESCRIPTION.rst @@ -0,0 +1,7 @@ +Allow to extend a reservation to the full content of the source location. + +For example, if you have a reassort move for 2 units but the source location +contains 20 units, this module allows to extend the reservation to the 20 units +to move the complete content of the source location. + +This can typically be used with shopfloor location content transfer scenario. diff --git a/stock_full_location_reservation/security/groups.xml b/stock_full_location_reservation/security/groups.xml new file mode 100644 index 00000000000..28430bf76f3 --- /dev/null +++ b/stock_full_location_reservation/security/groups.xml @@ -0,0 +1,6 @@ + + + Full location reservation + + + diff --git a/stock_full_location_reservation/static/description/index.html b/stock_full_location_reservation/static/description/index.html new file mode 100644 index 00000000000..7fa2016c2a7 --- /dev/null +++ b/stock_full_location_reservation/static/description/index.html @@ -0,0 +1,434 @@ + + + + + + +Stock full location reservation + + + +
+

Stock full location reservation

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Allow to extend a reservation to the full content of the source location.

+

For example, if you have a reassort move for 2 units but the source location +contains 20 units, this module allows to extend the reservation to the 20 units +to move the complete content of the source location.

+

This can typically be used with shopfloor location content transfer scenario.

+

Table of contents

+ +
+

Configuration

+

On the operation type, configure if the full reservation button action is visible on related transfers

+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • MT Software
  • +
  • BCIM
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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

+

Current maintainer:

+

mt-software-de

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_full_location_reservation/tests/__init__.py b/stock_full_location_reservation/tests/__init__.py new file mode 100644 index 00000000000..773c467311a --- /dev/null +++ b/stock_full_location_reservation/tests/__init__.py @@ -0,0 +1,2 @@ +from . import common +from . import test_full_location_reservation diff --git a/stock_full_location_reservation/tests/common.py b/stock_full_location_reservation/tests/common.py new file mode 100644 index 00000000000..a6412661e26 --- /dev/null +++ b/stock_full_location_reservation/tests/common.py @@ -0,0 +1,81 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo.addons.stock.tests.common import TestStockCommon + + +class TestStockFullLocationReservationCommon(TestStockCommon): + @classmethod + def setUpClass(cls): + super(TestStockFullLocationReservationCommon, cls).setUpClass() + cls.picking_type = cls.env.ref("stock.picking_type_out") + cls.picking_type.is_full_location_reservation_visible = True + cls.location = cls.env.ref("stock.stock_location_stock") + cls.location_rack = cls.location.create( + {"name": "Rack", "location_id": cls.location.id} + ) + cls.location_rack_child = cls.location.create( + {"name": "Rack child", "location_id": cls.location_rack.id} + ) + cls.customer_location = cls.env.ref("stock.stock_location_customers") + + def _create_quant(self, product, location, qty, package=None): + package_id = package and package.id + return self.env["stock.quant"].create( + { + "product_id": product.id, + "location_id": location.id, + "quantity": qty, + "package_id": package_id, + } + ) + + def _create_quants(self, vals): + for val in vals: + self._create_quant(*val) + + def _create_move(self, picking, product, qty, package=None): + package_level_id = False + if package: + package_level_id = ( + self.env["stock.package_level"] + .create({"package_id": package.id, "company_id": picking.company_id.id}) + .id + ) + return self.MoveObj.create( + { + "name": product.name, + "product_id": product.id, + "product_uom_qty": qty, + "product_uom": product.uom_id.id, + "picking_id": picking.id, + "location_id": picking.location_id.id, + "location_dest_id": picking.location_dest_id.id, + "package_level_id": package_level_id, + } + ) + + def _create_picking(self, location, location_dest, picking_type, moves): + picking = self.PickingObj.create( + { + "picking_type_id": picking_type.id, + "location_id": location.id, + "location_dest_id": location_dest.id, + } + ) + for move in moves: + vals = [picking] + move + self._create_move(*vals) + return picking + + def _check_move_line_len(self, pick, length, filter_func=None): + moves = pick.move_lines + if filter_func: + moves = moves.filtered(filter_func) + + self.assertEqual( + len(moves), + length, + ) + + def _filter_func(self, m): + return m.is_full_location_reservation diff --git a/stock_full_location_reservation/tests/test_full_location_reservation.py b/stock_full_location_reservation/tests/test_full_location_reservation.py new file mode 100644 index 00000000000..2683c109cc2 --- /dev/null +++ b/stock_full_location_reservation/tests/test_full_location_reservation.py @@ -0,0 +1,110 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo.addons.stock_full_location_reservation.tests.common import ( + TestStockFullLocationReservationCommon, +) + + +class TestFullLocationReservation(TestStockFullLocationReservationCommon): + def test_full_location_reservation(self): + picking = self._create_picking( + self.location_rack, + self.customer_location, + self.picking_type, + [[self.productA, 5]], + ) + + picking.action_confirm() + self._check_move_line_len(picking, 1) + + picking.do_full_location_reservation() + self._check_move_line_len(picking, 1) + + self._create_quants( + [ + (self.productA, self.location_rack_child, 10.0), + (self.productB, self.location_rack_child, 10.0), + ] + ) + + picking.do_full_location_reservation() + self._check_move_line_len(picking, 1) + + picking.action_assign() + + picking.do_full_location_reservation() + + self._check_move_line_len(picking, 3) + self._check_move_line_len(picking, 2, self._filter_func) + + # repeat test to check undo in do + picking.do_full_location_reservation() + + self._check_move_line_len(picking, 3) + self._check_move_line_len(picking, 2, self._filter_func) + + moves = picking.move_lines.filtered(self._filter_func) + self.assertEqual(moves.location_id, self.location_rack_child) + + picking.undo_full_location_reservation() + + self._check_move_line_len(picking, 1) + self._check_move_line_len(picking, 0, self._filter_func) + + def test_multiple_pickings(self): + picking = self._create_picking( + self.location_rack, + self.customer_location, + self.picking_type, + [[self.productA, 1]], + ) + + picking2 = self._create_picking( + self.location_rack, + self.customer_location, + self.picking_type, + [[self.productA, 1]], + ) + + pickings = picking | picking2 + + self._create_quants( + [ + (self.productA, self.location_rack_child, 10.0), + (self.productB, self.location_rack_child, 10.0), + ] + ) + + pickings.action_confirm() + pickings.action_assign() + + pickings.do_full_location_reservation() + self._check_move_line_len(pickings, 4) + self._check_move_line_len(pickings, 2, self._filter_func) + + def test_package_only(self): + package = self.env["stock.quant.package"].create({"name": "test package"}) + self._create_quants( + [ + (self.productA, self.location_rack_child, 10.0), + (self.productA, self.location_rack_child, 10.0, package), + ] + ) + picking = self._create_picking( + self.location_rack, + self.customer_location, + self.picking_type, + [ + [self.productA, 1], + [self.productA, 1, package], + ], + ) + picking.action_confirm() + picking.action_assign() + + self.assertEqual(picking.move_line_ids.package_id, package) + self._check_move_line_len(picking, 2) + picking.move_lines._full_location_reservation(package_only=True) + self._check_move_line_len(picking, 3) + self.assertEqual(picking.move_line_ids.package_id, package) + self.assertEqual(sum(picking.move_line_ids.mapped("product_qty")), 11) diff --git a/stock_full_location_reservation/views/stock_picking_type_views.xml b/stock_full_location_reservation/views/stock_picking_type_views.xml new file mode 100644 index 00000000000..bab73297dd5 --- /dev/null +++ b/stock_full_location_reservation/views/stock_picking_type_views.xml @@ -0,0 +1,15 @@ + + + Operation Types + stock.picking.type + + + + + + + + diff --git a/stock_full_location_reservation/views/stock_picking_views.xml b/stock_full_location_reservation/views/stock_picking_views.xml new file mode 100644 index 00000000000..31a1bd09c35 --- /dev/null +++ b/stock_full_location_reservation/views/stock_picking_views.xml @@ -0,0 +1,27 @@ + + + stock.picking full location reservation + stock.picking + + + + + + From ae07b8cac0683eabc6fad9c1d04161a4cba5f726 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 4 Dec 2023 14:34:23 +0100 Subject: [PATCH 002/357] [IMP] stock_full_location_reservation: pre-commit stuff --- .../odoo/addons/stock_full_location_reservation | 1 + setup/stock_full_location_reservation/setup.py | 6 ++++++ 2 files changed, 7 insertions(+) create mode 120000 setup/stock_full_location_reservation/odoo/addons/stock_full_location_reservation create mode 100644 setup/stock_full_location_reservation/setup.py diff --git a/setup/stock_full_location_reservation/odoo/addons/stock_full_location_reservation b/setup/stock_full_location_reservation/odoo/addons/stock_full_location_reservation new file mode 120000 index 00000000000..649b3ae0a50 --- /dev/null +++ b/setup/stock_full_location_reservation/odoo/addons/stock_full_location_reservation @@ -0,0 +1 @@ +../../../../stock_full_location_reservation \ No newline at end of file diff --git a/setup/stock_full_location_reservation/setup.py b/setup/stock_full_location_reservation/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/stock_full_location_reservation/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From e578e2ae331777eea6c4c5b8e060651aede12c2e Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Tue, 5 Dec 2023 12:12:11 +0100 Subject: [PATCH 003/357] [MIG] stock_full_location_reservation: Migration to 16.0 --- stock_full_location_reservation/README.rst | 12 ++++++------ stock_full_location_reservation/__manifest__.py | 2 +- .../models/stock_picking.py | 8 ++++---- .../static/description/index.html | 8 ++++---- stock_full_location_reservation/tests/common.py | 2 +- .../tests/test_full_location_reservation.py | 6 +++--- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/stock_full_location_reservation/README.rst b/stock_full_location_reservation/README.rst index 508db9870ae..29cd28941bf 100644 --- a/stock_full_location_reservation/README.rst +++ b/stock_full_location_reservation/README.rst @@ -7,7 +7,7 @@ Stock full location reservation !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b38409babd88e4fd7f1d1e78c4b74f8df1d3c69a27c65fcc334388a293dca5b3 + !! source digest: sha256:408dfd3f2912eb7cc8496e999d7038726421103919c456f25465ff52e8ef3312 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -17,13 +17,13 @@ Stock full location reservation :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github - :target: https://github.com/OCA/wms/tree/14.0/stock_full_location_reservation + :target: https://github.com/OCA/wms/tree/16.0/stock_full_location_reservation :alt: OCA/wms .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-stock_full_location_reservation + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_full_location_reservation :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -52,7 +52,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -92,6 +92,6 @@ Current `maintainer `__: |maintainer-mt-software-de| -This module is part of the `OCA/wms `_ project on GitHub. +This module is part of the `OCA/wms `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_full_location_reservation/__manifest__.py b/stock_full_location_reservation/__manifest__.py index eafb50b5f99..18a569e4740 100644 --- a/stock_full_location_reservation/__manifest__.py +++ b/stock_full_location_reservation/__manifest__.py @@ -5,7 +5,7 @@ "author": "MT Software, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "14.0.1.0.0", + "version": "16.0.1.0.0", "license": "AGPL-3", "depends": ["stock"], "data": [ diff --git a/stock_full_location_reservation/models/stock_picking.py b/stock_full_location_reservation/models/stock_picking.py index b8b96913e0a..1ba474df72d 100644 --- a/stock_full_location_reservation/models/stock_picking.py +++ b/stock_full_location_reservation/models/stock_picking.py @@ -16,17 +16,17 @@ class StockPicking(models.Model): compute="_compute_has_full_location_reservations", ) - @api.depends("move_lines.is_full_location_reservation") + @api.depends("move_ids.is_full_location_reservation") def _compute_has_full_location_reservations(self): for rec in self: rec.has_full_location_reservations = ( - rec.move_lines.filtered(lambda m: m.is_full_location_reservation) + rec.move_ids.filtered(lambda m: m.is_full_location_reservation) and True or False ) def do_full_location_reservation(self): - self.move_lines._full_location_reservation() + self.move_ids._full_location_reservation() def undo_full_location_reservation(self): - self.move_lines.undo_full_location_reservation() + self.move_ids.undo_full_location_reservation() diff --git a/stock_full_location_reservation/static/description/index.html b/stock_full_location_reservation/static/description/index.html index 7fa2016c2a7..19e884b9b50 100644 --- a/stock_full_location_reservation/static/description/index.html +++ b/stock_full_location_reservation/static/description/index.html @@ -367,9 +367,9 @@

Stock full location reservation

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:b38409babd88e4fd7f1d1e78c4b74f8df1d3c69a27c65fcc334388a293dca5b3 +!! source digest: sha256:408dfd3f2912eb7cc8496e999d7038726421103919c456f25465ff52e8ef3312 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Allow to extend a reservation to the full content of the source location.

For example, if you have a reassort move for 2 units but the source location contains 20 units, this module allows to extend the reservation to the 20 units @@ -397,7 +397,7 @@

Bug Tracker

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

+feedback.

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

@@ -425,7 +425,7 @@

Maintainers

promote its widespread use.

Current maintainer:

mt-software-de

-

This module is part of the OCA/wms project on GitHub.

+

This module is part of the OCA/wms project on GitHub.

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

diff --git a/stock_full_location_reservation/tests/common.py b/stock_full_location_reservation/tests/common.py index a6412661e26..ede76445b32 100644 --- a/stock_full_location_reservation/tests/common.py +++ b/stock_full_location_reservation/tests/common.py @@ -68,7 +68,7 @@ def _create_picking(self, location, location_dest, picking_type, moves): return picking def _check_move_line_len(self, pick, length, filter_func=None): - moves = pick.move_lines + moves = pick.move_ids if filter_func: moves = moves.filtered(filter_func) diff --git a/stock_full_location_reservation/tests/test_full_location_reservation.py b/stock_full_location_reservation/tests/test_full_location_reservation.py index 2683c109cc2..dd43b8a9713 100644 --- a/stock_full_location_reservation/tests/test_full_location_reservation.py +++ b/stock_full_location_reservation/tests/test_full_location_reservation.py @@ -43,7 +43,7 @@ def test_full_location_reservation(self): self._check_move_line_len(picking, 3) self._check_move_line_len(picking, 2, self._filter_func) - moves = picking.move_lines.filtered(self._filter_func) + moves = picking.move_ids.filtered(self._filter_func) self.assertEqual(moves.location_id, self.location_rack_child) picking.undo_full_location_reservation() @@ -104,7 +104,7 @@ def test_package_only(self): self.assertEqual(picking.move_line_ids.package_id, package) self._check_move_line_len(picking, 2) - picking.move_lines._full_location_reservation(package_only=True) + picking.move_ids._full_location_reservation(package_only=True) self._check_move_line_len(picking, 3) self.assertEqual(picking.move_line_ids.package_id, package) - self.assertEqual(sum(picking.move_line_ids.mapped("product_qty")), 11) + self.assertEqual(sum(picking.move_line_ids.mapped("reserved_qty")), 11) From 28a3efce7aadba9d7f198ac7361cd6fcb25f213f Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Tue, 12 Dec 2023 13:34:22 +0100 Subject: [PATCH 004/357] [IMP] stock_full_location_reservation: Be able to merge the new movement for the whole quantity --- .../models/stock_move.py | 13 ++++++- .../models/stock_picking_type.py | 6 ++++ .../tests/test_full_location_reservation.py | 35 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/stock_full_location_reservation/models/stock_move.py b/stock_full_location_reservation/models/stock_move.py index 20a9cc62796..d5f2e5ac8f1 100644 --- a/stock_full_location_reservation/models/stock_move.py +++ b/stock_full_location_reservation/models/stock_move.py @@ -67,11 +67,22 @@ def _full_location_reservation_prepare_move_vals( def _full_location_reservation_create_move( self, product, qty, location, package=None ): - return self.create( + new_move = self.create( self._full_location_reservation_prepare_move_vals( product, qty, location, package ) ) + if self.picking_type_id.merge_move_for_full_location_reservation: + # To be able to be merged, the new move should use the same source location as + # the original one. + new_move._action_confirm() + new_move.location_id = self.location_id + new_move = ( + (new_move | self) + .with_context(skip_undo_full_location_reservation=True) + ._merge_moves(merge_into=self) + ) + return new_move def _full_location_reservation(self, package_only=None): return self.move_line_ids._full_location_reservation(package_only) diff --git a/stock_full_location_reservation/models/stock_picking_type.py b/stock_full_location_reservation/models/stock_picking_type.py index b434ea2c651..4667544d643 100644 --- a/stock_full_location_reservation/models/stock_picking_type.py +++ b/stock_full_location_reservation/models/stock_picking_type.py @@ -11,3 +11,9 @@ class StockPickingType(models.Model): "Is full location reservation visible", help="""If this is checked, the full reservation of a the picking is visible""", ) + merge_move_for_full_location_reservation = fields.Boolean( + help="""If this is checked, the full reservation of a the picking will be done + resulting of only one move (original one + full reservation one). + WARNING: If checked, it will be impossible to get the original move back. + """, + ) diff --git a/stock_full_location_reservation/tests/test_full_location_reservation.py b/stock_full_location_reservation/tests/test_full_location_reservation.py index dd43b8a9713..8bb0267e375 100644 --- a/stock_full_location_reservation/tests/test_full_location_reservation.py +++ b/stock_full_location_reservation/tests/test_full_location_reservation.py @@ -108,3 +108,38 @@ def test_package_only(self): self._check_move_line_len(picking, 3) self.assertEqual(picking.move_line_ids.package_id, package) self.assertEqual(sum(picking.move_line_ids.mapped("reserved_qty")), 11) + + def test_full_location_reservation_merge(self): + """ + Activate the merge for new quantity move. + Create a picking and confirm it (quantity: 5). + Set product A in rack location (qauntity : 10). + Confirm the picking. + Do the full reservation. + The whole quantity should be assigned in one move. + + """ + self.picking_type.merge_move_for_full_location_reservation = True + picking = self._create_picking( + self.location_rack, + self.customer_location, + self.picking_type, + [[self.productA, 5]], + ) + + picking.action_confirm() + self._check_move_line_len(picking, 1) + + self._create_quants( + [ + (self.productA, self.location_rack_child, 10.0), + ] + ) + + picking.action_assign() + + picking.do_full_location_reservation() + + self._check_move_line_len(picking, 1) + self.assertEqual(10.0, picking.move_ids.product_uom_qty) + self.assertEqual(10.0, picking.move_ids.reserved_availability) From 5b335f84ac703d8910b5c280d128d2c546d8611b Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 13 Dec 2023 08:43:17 +0100 Subject: [PATCH 005/357] [IMP] stock_full_location_reservation: Prevent first confirmation to merge As the _action_confirm() will do merges and as new moves are confirmed now, this can lead to current move unlink. So, don't merge on new move confirmation, unreserve current move, then process to merge. --- stock_full_location_reservation/models/stock_move.py | 8 +++++--- .../models/stock_move_line.py | 11 +++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/stock_full_location_reservation/models/stock_move.py b/stock_full_location_reservation/models/stock_move.py index d5f2e5ac8f1..cdc0fae7f7d 100644 --- a/stock_full_location_reservation/models/stock_move.py +++ b/stock_full_location_reservation/models/stock_move.py @@ -67,16 +67,18 @@ def _full_location_reservation_prepare_move_vals( def _full_location_reservation_create_move( self, product, qty, location, package=None ): - new_move = self.create( - self._full_location_reservation_prepare_move_vals( + new_move = self.copy( + default=self._full_location_reservation_prepare_move_vals( product, qty, location, package ) ) if self.picking_type_id.merge_move_for_full_location_reservation: # To be able to be merged, the new move should use the same source location as # the original one. - new_move._action_confirm() new_move.location_id = self.location_id + self._do_unreserve() + # Don't merge at confirm + new_move._action_confirm(merge=False) new_move = ( (new_move | self) .with_context(skip_undo_full_location_reservation=True) diff --git a/stock_full_location_reservation/models/stock_move_line.py b/stock_full_location_reservation/models/stock_move_line.py index dba21efe243..4802e988f9e 100644 --- a/stock_full_location_reservation/models/stock_move_line.py +++ b/stock_full_location_reservation/models/stock_move_line.py @@ -46,17 +46,20 @@ def _full_location_reservation(self, package_only=None): reservable_qties = self._get_full_location_reservable_qties(package_only) moves_to_assign_ids = [] for line in self: - qties = reservable_qties.get(line.location_id, {}).get(line.package_id, {}) + # Copy location and package as move line could be deleted if merge occurs + location = line.location_id + package = line.package_id + qties = reservable_qties.get(location, {}).get(package, {}) if not qties: continue for product, qty in qties.items(): moves_to_assign_ids.append( line.move_id._full_location_reservation_create_move( - product, qty, line.location_id, line.package_id + product, qty, location, package ).id ) - reservable_qties[line.location_id].pop(line.package_id) - moves_to_assign = self.move_id.browse(moves_to_assign_ids) + reservable_qties[location].pop(package) + moves_to_assign = self.env["stock.move"].browse(moves_to_assign_ids) if moves_to_assign: moves_to_assign._action_confirm() moves_to_assign._action_assign() From 76f2ed3e0d6425a2523193f27ed4fc19fbeb9b41 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 13 Dec 2023 11:24:56 +0100 Subject: [PATCH 006/357] [IMP] stock_full_location_reservation: Improve README --- stock_full_location_reservation/README.rst | 6 ++- .../readme/CONFIGURE.rst | 3 ++ .../readme/CONTRIBUTORS.rst | 1 + .../static/description/index.html | 41 ++++++++++--------- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/stock_full_location_reservation/README.rst b/stock_full_location_reservation/README.rst index 29cd28941bf..96b3fbe0d02 100644 --- a/stock_full_location_reservation/README.rst +++ b/stock_full_location_reservation/README.rst @@ -7,7 +7,7 @@ Stock full location reservation !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:408dfd3f2912eb7cc8496e999d7038726421103919c456f25465ff52e8ef3312 + !! source digest: sha256:a0ab49571364d4e982429166e3f0a9f7f961ebbd856f1c86fc93b67dbd95b1bb !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -46,6 +46,9 @@ Configuration On the operation type, configure if the full reservation button action is visible on related transfers +You can also configure the option 'Merge Move For Full Location Reservation' if you +want only one move at the end. WARNING: The original move will be lost. + Bug Tracker =========== @@ -70,6 +73,7 @@ Contributors * Michael Tietz (MT Software) * Jacques-Etienne Baudoux (BCIM) +* Denis Roussel Maintainers ~~~~~~~~~~~ diff --git a/stock_full_location_reservation/readme/CONFIGURE.rst b/stock_full_location_reservation/readme/CONFIGURE.rst index 2e4391267a2..43ce3dac8a5 100644 --- a/stock_full_location_reservation/readme/CONFIGURE.rst +++ b/stock_full_location_reservation/readme/CONFIGURE.rst @@ -1 +1,4 @@ On the operation type, configure if the full reservation button action is visible on related transfers + +You can also configure the option 'Merge Move For Full Location Reservation' if you +want only one move at the end. WARNING: The original move will be lost. diff --git a/stock_full_location_reservation/readme/CONTRIBUTORS.rst b/stock_full_location_reservation/readme/CONTRIBUTORS.rst index 03c3145a2be..866de0e85cb 100644 --- a/stock_full_location_reservation/readme/CONTRIBUTORS.rst +++ b/stock_full_location_reservation/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Michael Tietz (MT Software) * Jacques-Etienne Baudoux (BCIM) +* Denis Roussel diff --git a/stock_full_location_reservation/static/description/index.html b/stock_full_location_reservation/static/description/index.html index 19e884b9b50..c0ddf66dce5 100644 --- a/stock_full_location_reservation/static/description/index.html +++ b/stock_full_location_reservation/static/description/index.html @@ -1,20 +1,20 @@ - + - + Stock full location reservation -
-

Stock Warehouse Flow

- - -

Alpha License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

-

This module introduces the concept of routing flows in order to manage -different delivery routes for a warehouse.

-

The default behavior of Odoo allows you to have only one delivery route per -warehouse (with one, two or three steps). -With this module, you are now able to manage multiple delivery routes (having -their own rules and operation types), the right one being selected automatically -based on some criterias, like the carrier and any attribute of the stock move -to process.

-

This allows you to define a delivery route based on the type of goods to ship, -for instance:

-
    -
  • whole pallet (pick + ship)
  • -
  • cold chain goods
  • -
  • dangerous goods
  • -
-https://raw.githubusercontent.com/OCA/wms/14.0/stock_warehouse_flow/static/description/flow.png -
-

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

- -
-

Configuration

-

Got to “Inventory > Settings > Routing Flows”.

-

A routing flow can be seen as a helper to generate a delivery route (like the -warehouse is doing automatically). The new route will get its own rules and -operation types that doesn’t overlap with the default ones of the warehouse.

-

A routing flow is responsible to change the warehouse delivery route of a move -by another one depending on some criterias:

-
    -
  • the initial outgoing operation type (usually the default one)
  • -
  • the carrier
  • -
  • a custom domain (applied on the move)
  • -
-

This way you are able to change the route a move will take depending on its -carrier and, for instance, the type or the packaging of the product -you want to ship.

-https://raw.githubusercontent.com/OCA/wms/14.0/stock_warehouse_flow/static/description/config.png -
-
-

Usage

-

When a stock move is confirmed, if a flow is matching all the criteria then -the new delivery route will be automatically applied.

-
-
-

Known issues / Roadmap

-

Currently, the module supports only delivery routes, but it could improved to -support reception routes as well.

-
-
-

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 to smash it by providing a detailed and welcomed -feedback.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • Camptocamp
  • -
  • BCIM
  • -
-
-
-

Contributors

- -
-
-

Maintainers

-

This module is maintained by the OCA.

-Odoo Community Association -

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

-

This module is part of the OCA/wms project on GitHub.

-

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

-
-
+
+ + +
diff --git a/stock_warehouse_flow/tests/test_warehouse_flow.py b/stock_warehouse_flow/tests/test_warehouse_flow.py index 2c5e3ad80c3..a2e1edae8c7 100644 --- a/stock_warehouse_flow/tests/test_warehouse_flow.py +++ b/stock_warehouse_flow/tests/test_warehouse_flow.py @@ -90,6 +90,17 @@ def test_flow_pick_ship(self): self.assertEqual(move_ship.state, "assigned") self._validate_picking(move_ship.picking_id) + def test_disable_flow_at_move_confirm(self): + flow = self._get_flow("pick_ship") + # It is False by default + flow.impacted_route_ids.apply_flow_on = False + moves_before = self.env["stock.move"].search([]) + self._run_procurement(self.product, 10, flow.carrier_ids) + moves = self.env["stock.move"].search([("id", "not in", moves_before.ids)]) + move_ship = moves.filtered(lambda m: m.picking_type_id.code == "outgoing") + # ensure new move doesn't have flow.to_picking_type_id as picking type + self.assertNotEqual(move_ship.picking_type_id, flow.to_picking_type_id) + def test_no_rule_found_on_delivery_route(self): flow = self._get_flow("pick_ship") # Remove the rule diff --git a/stock_warehouse_flow/views/stock_route.xml b/stock_warehouse_flow/views/stock_route.xml index f2802dc7866..3be9e0e66c5 100644 --- a/stock_warehouse_flow/views/stock_route.xml +++ b/stock_warehouse_flow/views/stock_route.xml @@ -14,4 +14,15 @@ + + stock.route.form.inherit + stock.route + + + + + + + + From 4bf55b3b3e7bbb164e25cdd78131a11b0e0deee3 Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Wed, 12 Mar 2025 18:27:19 +0100 Subject: [PATCH 014/357] stock_warehouse_flow_release: Make apply at release optional --- stock_warehouse_flow_release/README.rst | 86 ------------------- stock_warehouse_flow_release/__manifest__.py | 3 +- .../migrations/16.0.1.1.0/post-migrate.py | 25 ++++++ .../models/__init__.py | 1 + .../models/stock_move.py | 10 +-- .../models/stock_route.py | 12 +++ .../readme/DESCRIPTION.rst | 2 +- .../tests/test_warehouse_flow_release.py | 21 ++++- 8 files changed, 64 insertions(+), 96 deletions(-) create mode 100644 stock_warehouse_flow_release/migrations/16.0.1.1.0/post-migrate.py create mode 100644 stock_warehouse_flow_release/models/stock_route.py diff --git a/stock_warehouse_flow_release/README.rst b/stock_warehouse_flow_release/README.rst index f85fff8b830..e69de29bb2d 100644 --- a/stock_warehouse_flow_release/README.rst +++ b/stock_warehouse_flow_release/README.rst @@ -1,86 +0,0 @@ -========================================== -Stock Warehouse Flow (release integration) -========================================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:d715d0b96733f62db800de351ef5f56c41e8847d4b1d4e07062731036b96e53c - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :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 -.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github - :target: https://github.com/OCA/wms/tree/16.0/stock_warehouse_flow_release - :alt: OCA/wms -.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow_release - :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 - :alt: Try me on Runboat - -|badge1| |badge2| |badge3| |badge4| |badge5| - -Integrate the **Stock Warehouse Flow** module with -**Stock Available to Promise Release**, so the flow is applied -when a move is released (not anymore when it is confirmed). - -.. 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:: - :local: - -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 to smash it by providing a detailed and welcomed -`feedback `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* Camptocamp -* BCIM - -Contributors -~~~~~~~~~~~~ - -* Sébastien Alix -* Jacques-Etienne Baudoux -* Michael Tietz (MT Software) - -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/wms `_ project on GitHub. - -You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_warehouse_flow_release/__manifest__.py b/stock_warehouse_flow_release/__manifest__.py index e07d031f812..2b071b0dc3b 100644 --- a/stock_warehouse_flow_release/__manifest__.py +++ b/stock_warehouse_flow_release/__manifest__.py @@ -6,7 +6,7 @@ "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "16.0.1.0.0", + "version": "16.0.1.1.0", "license": "AGPL-3", "depends": [ # OCA/wms @@ -14,7 +14,6 @@ "stock_available_to_promise_release", ], "data": [], - "auto_install": True, "installable": True, "development_status": "Alpha", } diff --git a/stock_warehouse_flow_release/migrations/16.0.1.1.0/post-migrate.py b/stock_warehouse_flow_release/migrations/16.0.1.1.0/post-migrate.py new file mode 100644 index 00000000000..ca58f3756b0 --- /dev/null +++ b/stock_warehouse_flow_release/migrations/16.0.1.1.0/post-migrate.py @@ -0,0 +1,25 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +import logging + +from odoo import SUPERUSER_ID, api + +_logger = logging.getLogger(__name__) + + +def migrate(cr, version): + if not version: + return + env = api.Environment(cr, SUPERUSER_ID, {}) + outgoing_rules = env["stock.rule"].search( + [("picking_type_id.code", "=", "outgoing")] + ) + routes_to_update = env["stock.route"].search( + [ + ("available_to_promise_defer_pull", "=", True), + ("rule_ids", "in", outgoing_rules.ids), + ] + ) + _logger.info(f"disabling flow at confirm on {len(routes_to_update)} routes") + routes_to_update.apply_flow_on = "on_release" diff --git a/stock_warehouse_flow_release/models/__init__.py b/stock_warehouse_flow_release/models/__init__.py index 6bda2d2428e..6ea87dcbcef 100644 --- a/stock_warehouse_flow_release/models/__init__.py +++ b/stock_warehouse_flow_release/models/__init__.py @@ -1 +1,2 @@ from . import stock_move +from . import stock_route diff --git a/stock_warehouse_flow_release/models/stock_move.py b/stock_warehouse_flow_release/models/stock_move.py index 153eb00da91..3a9d54231bf 100644 --- a/stock_warehouse_flow_release/models/stock_move.py +++ b/stock_warehouse_flow_release/models/stock_move.py @@ -8,12 +8,10 @@ class StockMove(models.Model): _inherit = "stock.move" - def _apply_flow_on_action_confirm(self): - # Override to not apply the flow configuration on moves to release. - # The flow will be applied on the release, not before. - if self.rule_id.route_id.available_to_promise_defer_pull: + def _apply_flow_on_release(self): + if self.rule_id.route_id.apply_flow_on != "on_release": return False - return super()._apply_flow_on_action_confirm() + return self.picking_type_id.code == "outgoing" def _before_release(self): # Apply the flow when releasing the move @@ -21,6 +19,8 @@ def _before_release(self): FLOW = self.env["stock.warehouse.flow"] move_ids_to_release = [] for move in self: + if not move._apply_flow_on_release(): + continue _move_ids_to_release = FLOW._search_and_apply_for_move(move).ids _move_ids_to_release.remove(move.id) move_ids_to_release += _move_ids_to_release diff --git a/stock_warehouse_flow_release/models/stock_route.py b/stock_warehouse_flow_release/models/stock_route.py new file mode 100644 index 00000000000..a67ff6952c4 --- /dev/null +++ b/stock_warehouse_flow_release/models/stock_route.py @@ -0,0 +1,12 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields, models + + +class StockRoute(models.Model): + _inherit = "stock.route" + + apply_flow_on = fields.Selection( + selection_add=[("on_release", "When move is released")] + ) diff --git a/stock_warehouse_flow_release/readme/DESCRIPTION.rst b/stock_warehouse_flow_release/readme/DESCRIPTION.rst index 3af6a51009a..120c7affd6e 100644 --- a/stock_warehouse_flow_release/readme/DESCRIPTION.rst +++ b/stock_warehouse_flow_release/readme/DESCRIPTION.rst @@ -1,3 +1,3 @@ Integrate the **Stock Warehouse Flow** module with **Stock Available to Promise Release**, so the flow is applied -when a move is released (not anymore when it is confirmed). +when a move is released. diff --git a/stock_warehouse_flow_release/tests/test_warehouse_flow_release.py b/stock_warehouse_flow_release/tests/test_warehouse_flow_release.py index 11d38fb5981..0a3d2062a38 100644 --- a/stock_warehouse_flow_release/tests/test_warehouse_flow_release.py +++ b/stock_warehouse_flow_release/tests/test_warehouse_flow_release.py @@ -12,8 +12,25 @@ def setUpClass(cls): # Set the default delivery route as pick+ship to make releasing working # (there is no need to release a 'ship_only' move) cls.wh.delivery_steps = "pick_ship" - # Enable the operation release on the default delivery route - cls.wh.delivery_route_id.available_to_promise_defer_pull = True + cls.out_rules = cls.env["stock.rule"].search( + [("picking_type_id.code", "=", "outgoing")] + ) + cls.out_rules.route_id.available_to_promise_defer_pull = True + cls.out_rules.route_id.apply_flow_on = "on_release" + + def test_flow_pick_ship_flow_at_confirm(self): + self.out_rules.route_id.apply_flow_on = "on_confirm" + # enable flow assigning at confirm + flow = self._get_flow("pick_ship") + to_picking_type = flow.to_picking_type_id + # NOTE: use the recorder when migrating to 15.0 to catch created moves + moves_before = self.env["stock.move"].search([]) + self._run_procurement(self.product, 10, flow.carrier_ids) + moves_after = self.env["stock.move"].search([]) + move = moves_after - moves_before + self.assertEqual(len(move), 1) + self.assertTrue(move.need_release) + self.assertEqual(move.picking_type_id, to_picking_type) def test_flow_pick_ship_on_release(self): """Replace the initial 'ship_only' move by pick+ship chained moves. From ad1c777105083fe310bde49c63979c2aa4e274cb Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Fri, 7 Mar 2025 16:48:58 +0100 Subject: [PATCH 015/357] Add stock_warehouse_flow_delivery_refresh --- .../stock_warehouse_flow_delivery_refresh | 1 + .../setup.py | 6 + .../README.rst | 0 .../__init__.py | 1 + .../__manifest__.py | 15 + .../models/__init__.py | 2 + .../models/stock_move.py | 15 + .../models/stock_picking.py | 17 + .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 3 + .../static/description/index.html | 368 ++++++++++++++++++ .../tests/__init__.py | 1 + .../tests/test_reapply_flow.py | 52 +++ 13 files changed, 483 insertions(+) create mode 120000 setup/stock_warehouse_flow_delivery_refresh/odoo/addons/stock_warehouse_flow_delivery_refresh create mode 100644 setup/stock_warehouse_flow_delivery_refresh/setup.py create mode 100644 stock_warehouse_flow_delivery_refresh/README.rst create mode 100644 stock_warehouse_flow_delivery_refresh/__init__.py create mode 100644 stock_warehouse_flow_delivery_refresh/__manifest__.py create mode 100644 stock_warehouse_flow_delivery_refresh/models/__init__.py create mode 100644 stock_warehouse_flow_delivery_refresh/models/stock_move.py create mode 100644 stock_warehouse_flow_delivery_refresh/models/stock_picking.py create mode 100644 stock_warehouse_flow_delivery_refresh/readme/CONTRIBUTORS.rst create mode 100644 stock_warehouse_flow_delivery_refresh/readme/DESCRIPTION.rst create mode 100644 stock_warehouse_flow_delivery_refresh/static/description/index.html create mode 100644 stock_warehouse_flow_delivery_refresh/tests/__init__.py create mode 100644 stock_warehouse_flow_delivery_refresh/tests/test_reapply_flow.py diff --git a/setup/stock_warehouse_flow_delivery_refresh/odoo/addons/stock_warehouse_flow_delivery_refresh b/setup/stock_warehouse_flow_delivery_refresh/odoo/addons/stock_warehouse_flow_delivery_refresh new file mode 120000 index 00000000000..80e56b952b5 --- /dev/null +++ b/setup/stock_warehouse_flow_delivery_refresh/odoo/addons/stock_warehouse_flow_delivery_refresh @@ -0,0 +1 @@ +../../../../stock_warehouse_flow_delivery_refresh \ No newline at end of file diff --git a/setup/stock_warehouse_flow_delivery_refresh/setup.py b/setup/stock_warehouse_flow_delivery_refresh/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/stock_warehouse_flow_delivery_refresh/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_warehouse_flow_delivery_refresh/README.rst b/stock_warehouse_flow_delivery_refresh/README.rst new file mode 100644 index 00000000000..e69de29bb2d diff --git a/stock_warehouse_flow_delivery_refresh/__init__.py b/stock_warehouse_flow_delivery_refresh/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_warehouse_flow_delivery_refresh/__manifest__.py b/stock_warehouse_flow_delivery_refresh/__manifest__.py new file mode 100644 index 00000000000..a054ac48181 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/__manifest__.py @@ -0,0 +1,15 @@ +{ + "name": "Stock Warehouse Flow Delivery Refresh", + "summary": "Allow to refresh delivery flow when carrier changes", + "version": "16.0.1.0.0", + "category": "Warehouse Management", + "website": "https://github.com/OCA/wms", + "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "depends": [ + "stock_warehouse_flow", + "stock_available_to_promise_release", + ], + "development_status": "Alpha", +} diff --git a/stock_warehouse_flow_delivery_refresh/models/__init__.py b/stock_warehouse_flow_delivery_refresh/models/__init__.py new file mode 100644 index 00000000000..a33bde1e878 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/models/__init__.py @@ -0,0 +1,2 @@ +from . import stock_move +from . import stock_picking diff --git a/stock_warehouse_flow_delivery_refresh/models/stock_move.py b/stock_warehouse_flow_delivery_refresh/models/stock_move.py new file mode 100644 index 00000000000..ac9c2944bb8 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/models/stock_move.py @@ -0,0 +1,15 @@ +# Copyright 2025 Camptocamp SA, BCIM +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import models + + +class StockMove(models.Model): + _inherit = "stock.move" + + def _refresh_warehouse_flow(self): + flow_model = self.env["stock.warehouse.flow"] + for move in self: + if not move.need_release: + continue + flow_model._search_and_apply_for_move(move, assign_picking=True) diff --git a/stock_warehouse_flow_delivery_refresh/models/stock_picking.py b/stock_warehouse_flow_delivery_refresh/models/stock_picking.py new file mode 100644 index 00000000000..075bacc06fa --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/models/stock_picking.py @@ -0,0 +1,17 @@ +# Copyright 2025 Camptocamp SA, BCIM +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import models + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + def write(self, values): + picking_carrier_mapping = {p.id: p.carrier_id for p in self} + res = super().write(values) + pickings_to_update = self.filtered( + lambda p: picking_carrier_mapping.get(p.id) != p.carrier_id + ) + pickings_to_update.move_ids._refresh_warehouse_flow() + return res diff --git a/stock_warehouse_flow_delivery_refresh/readme/CONTRIBUTORS.rst b/stock_warehouse_flow_delivery_refresh/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..c37569c4e3b --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Jacques-Etienne Baudoux +* Matthieu Méquignon diff --git a/stock_warehouse_flow_delivery_refresh/readme/DESCRIPTION.rst b/stock_warehouse_flow_delivery_refresh/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..f411e9e27f7 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +This is a glue module between Stock Warehouse Flow and Stock Available On Premise Release. + +This module applies a new Stock Warehouse Flow on Stock Moves waiting for release when carrier changes on a Stock Picking diff --git a/stock_warehouse_flow_delivery_refresh/static/description/index.html b/stock_warehouse_flow_delivery_refresh/static/description/index.html new file mode 100644 index 00000000000..04faf101c48 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/static/description/index.html @@ -0,0 +1,368 @@ + + + + + +README.rst + + + +
+ + + +
+ + diff --git a/stock_warehouse_flow_delivery_refresh/tests/__init__.py b/stock_warehouse_flow_delivery_refresh/tests/__init__.py new file mode 100644 index 00000000000..6be097995a5 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/tests/__init__.py @@ -0,0 +1 @@ +from . import test_reapply_flow diff --git a/stock_warehouse_flow_delivery_refresh/tests/test_reapply_flow.py b/stock_warehouse_flow_delivery_refresh/tests/test_reapply_flow.py new file mode 100644 index 00000000000..53cee536627 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/tests/test_reapply_flow.py @@ -0,0 +1,52 @@ +# Copyright 2025 Camptocamp SA, BCIM +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo.tests import tagged +from odoo.tests.common import Form + +from odoo.addons.stock_warehouse_flow.tests.common import CommonFlow + + +@tagged("-at_install", "post_install") +class TestDeliveryRefresh(CommonFlow): + @classmethod + def setUpClass(cls): + super().setUpClass() + # Set outgoing rules as + out_rules = cls.env["stock.rule"].search( + [("picking_type_id.code", "=", "outgoing")] + ) + out_rules.route_id.available_to_promise_defer_pull = True + cls.customer = cls.env["res.partner"].create({"name": "Bob the customer"}) + + @classmethod + def create_sale_order(cls, product_qty, carrier=None): + with Form(cls.env["sale.order"]) as sale_form: + sale_form.partner_id = cls.customer + for product, qty in product_qty: + with sale_form.order_line.new() as line: + line.product_id = product + line.product_uom_qty = qty + order = sale_form.save() + if carrier: + cls.update_carrier_on_order(order, carrier) + return order + + @classmethod + def update_carrier_on_order(cls, order, carrier): + order.set_delivery_line(carrier, 1) + + def test_flow_refresh_after_delivery_change(self): + self.env.ref("stock.stock_location_stock") + post_carrier_flow = self._get_flow("pick_ship") + normal_carrier_flow = self._get_flow("pick_pack_ship") + order = self.create_sale_order( + [(self.product, 10)], carrier=post_carrier_flow.carrier_ids + ) + order.action_confirm() + picking = order.picking_ids + move = picking.move_ids + self.assertEqual(move.picking_type_id, post_carrier_flow.to_picking_type_id) + # # Updating the carrier on the order should update flow used by moves + self.update_carrier_on_order(order, normal_carrier_flow.carrier_ids) + self.assertEqual(move.picking_type_id, normal_carrier_flow.to_picking_type_id) From 867381a1a487a6e87a32179d81f233188a50d10a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 25 Apr 2025 10:17:27 +0000 Subject: [PATCH 016/357] [BOT] post-merge updates --- README.md | 2 +- stock_release_channel/README.rst | 2 +- stock_release_channel/__manifest__.py | 2 +- stock_release_channel/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ca20853bc1a..71c65ba45ec 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ addon | version | maintainers | summary [stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.1.0.0 | [![lmignon](https://github.com/lmignon.png?size=30px)](https://github.com/lmignon) | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type -[stock_release_channel](stock_release_channel/) | 16.0.2.18.4 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![mt-software-de](https://github.com/mt-software-de.png?size=30px)](https://github.com/mt-software-de) | Manage workload in WMS with release channels +[stock_release_channel](stock_release_channel/) | 16.0.2.19.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![mt-software-de](https://github.com/mt-software-de.png?size=30px)](https://github.com/mt-software-de) | Manage workload in WMS with release channels [stock_release_channel_auto_release](stock_release_channel_auto_release/) | 16.0.1.1.0 | | Add an automatic release mode to the release channel [stock_release_channel_batch_mode_commercial_partner](stock_release_channel_batch_mode_commercial_partner/) | 16.0.1.0.2 | | Release pickings into channels by batch of same commercial entity [stock_release_channel_cutoff](stock_release_channel_cutoff/) | 16.0.1.0.2 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add the cutoff time to the release channel diff --git a/stock_release_channel/README.rst b/stock_release_channel/README.rst index 26a753f6929..1a78cd74007 100644 --- a/stock_release_channel/README.rst +++ b/stock_release_channel/README.rst @@ -7,7 +7,7 @@ Stock Release Channels !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:ac44a0ebd239ea0288201d0ee262ca120ffd246b3ac82a260ad0a0d6d18a9edc + !! source digest: sha256:01faeddc577b5d42e1ae117ebfe33bfe0990199904d5f038671d2fe58db87ca5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel/__manifest__.py b/stock_release_channel/__manifest__.py index 9739be00503..73947be0dc1 100644 --- a/stock_release_channel/__manifest__.py +++ b/stock_release_channel/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Stock Release Channels", "summary": "Manage workload in WMS with release channels", - "version": "16.0.2.18.4", + "version": "16.0.2.19.0", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, ACSONE SA/NV, Odoo Community Association (OCA)", diff --git a/stock_release_channel/static/description/index.html b/stock_release_channel/static/description/index.html index 8aaa6ce21d4..0692c438f54 100644 --- a/stock_release_channel/static/description/index.html +++ b/stock_release_channel/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channels

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:ac44a0ebd239ea0288201d0ee262ca120ffd246b3ac82a260ad0a0d6d18a9edc +!! source digest: sha256:01faeddc577b5d42e1ae117ebfe33bfe0990199904d5f038671d2fe58db87ca5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Release channels are:

From 0660f2c7a8362055a999391d80e1e7f4a96defa5 Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Tue, 14 Jan 2025 10:16:32 +0100 Subject: [PATCH 017/357] shopfloor delivery: better error when cancelled picking is scanned --- shopfloor/actions/message.py | 9 +++++++++ shopfloor/services/delivery.py | 15 ++++++++++++--- shopfloor/services/service.py | 2 ++ shopfloor/tests/test_delivery_scan_deliver.py | 9 +++++++++ .../tests/test_delivery_set_qty_done_line.py | 2 +- .../tests/test_delivery_set_qty_done_pack.py | 2 +- 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/shopfloor/actions/message.py b/shopfloor/actions/message.py index aa63b36824c..d28ad538b53 100644 --- a/shopfloor/actions/message.py +++ b/shopfloor/actions/message.py @@ -214,6 +214,15 @@ def confirm_pack_moved(self): def already_done(self): return {"message_type": "info", "body": _("Operation already processed.")} + def transfer_canceled(self): + return { + "message_type": "info", + "body": _( + "Transfer has been canceled. " + "This cannot be processed using this scenario" + ), + } + def move_already_done(self): return {"message_type": "warning", "body": _("Move already processed.")} diff --git a/shopfloor/services/delivery.py b/shopfloor/services/delivery.py index 9de2aaa98c3..4340514edb7 100644 --- a/shopfloor/services/delivery.py +++ b/shopfloor/services/delivery.py @@ -255,11 +255,20 @@ def _deliver_package(self, picking, package, location): return self._response_for_deliver(picking=new_picking, location=location) def _lines_base_domain(self, no_qty_done=True): + # we added auto_join for this, otherwise, the ORM would search all pickings + # in the picking type, and then use IN (ids) domain = [ - # we added auto_join for this, otherwise, the ORM would search all pickings - # in the picking type, and then use IN (ids) + # Accepting return_picking_types in order to display meaningful + # messages when trying to process a return move. + # Those returns are blocked later in `_check_picking_status` + "|", ("picking_id.picking_type_id", "in", self.picking_types.ids), - ("picking_id.state", "not in", ("done", "cancel")), + ( + "picking_id.picking_type_id", + "in", + self.picking_types.return_picking_type_id.ids, + ), + ("picking_id.state", "not in", ("done",)), ] if no_qty_done: domain.append(("qty_done", "=", 0)) diff --git a/shopfloor/services/service.py b/shopfloor/services/service.py index 0c98e23ae03..9f0d5844be7 100644 --- a/shopfloor/services/service.py +++ b/shopfloor/services/service.py @@ -83,6 +83,8 @@ def _check_picking_status(self, pickings, states=("assigned",)): return self.msg_store.stock_picking_not_found() if picking.state == "done": return self.msg_store.already_done() + if picking.state == "cancel": + return self.msg_store.transfer_cancelled() if picking.state not in states: # the picking must be ready return self.msg_store.stock_picking_not_available(picking) if picking.picking_type_id not in self.picking_types: diff --git a/shopfloor/tests/test_delivery_scan_deliver.py b/shopfloor/tests/test_delivery_scan_deliver.py index 32c7976065e..bae03f79cd9 100644 --- a/shopfloor/tests/test_delivery_scan_deliver.py +++ b/shopfloor/tests/test_delivery_scan_deliver.py @@ -447,6 +447,15 @@ def test_scan_deliver_scan_product_alone_in_package_qty_one(self): move_lines = pick.move_ids.mapped("move_line_ids") self._test_scan_set_done_ok(move_lines, self.product_c.barcode, [1]) + def test_scan_deliver_picking_canceled(self): + self.picking.action_cancel() + params = {"barcode": self.picking.name} + response = self.service.dispatch("scan_deliver", params=params) + self.assert_response_deliver( + response, + message=self.service.msg_store.transfer_canceled(), + ) + def test_scan_deliver_picking_done(self): # Set qty done for all lines (packages/raw product/lot...), picking is # automatically set to done when the last line is completed diff --git a/shopfloor/tests/test_delivery_set_qty_done_line.py b/shopfloor/tests/test_delivery_set_qty_done_line.py index 56a38e1cf06..696edc2f070 100644 --- a/shopfloor/tests/test_delivery_set_qty_done_line.py +++ b/shopfloor/tests/test_delivery_set_qty_done_line.py @@ -52,7 +52,7 @@ def test_set_qty_done_line_picking_canceled(self): ) self.assert_response_deliver( response, - message=self.service.msg_store.stock_picking_not_available(self.picking), + message=self.service.msg_store.transfer_canceled(), ) def test_set_qty_done_line_line_not_found(self): diff --git a/shopfloor/tests/test_delivery_set_qty_done_pack.py b/shopfloor/tests/test_delivery_set_qty_done_pack.py index bd7df5ad3f5..366950d4c25 100644 --- a/shopfloor/tests/test_delivery_set_qty_done_pack.py +++ b/shopfloor/tests/test_delivery_set_qty_done_pack.py @@ -67,7 +67,7 @@ def test_set_qty_done_pack_picking_canceled(self): ) self.assert_response_deliver( response, - message=self.service.msg_store.stock_picking_not_available(self.picking), + message=self.service.msg_store.transfer_canceled(), ) def test_set_qty_done_pack_package_not_found(self): From c892772e6cb04aba7db35abe88b20bb6a6fe4f9a Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Fri, 25 Apr 2025 17:52:44 +0200 Subject: [PATCH 018/357] [FIX] shopfloor_reception_mobile: Make product info works on picking detail --- .../static/src/scenario/reception.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/shopfloor_reception_mobile/static/src/scenario/reception.js b/shopfloor_reception_mobile/static/src/scenario/reception.js index f921e21a358..6a743658734 100644 --- a/shopfloor_reception_mobile/static/src/scenario/reception.js +++ b/shopfloor_reception_mobile/static/src/scenario/reception.js @@ -346,14 +346,18 @@ const Reception = { ], }; }, - picking_detail_options_for_select_move: function (move) { + picking_detail_options_for_select_move: function () { return { show_title: true, showActions: false, list_item_options: { loud_title: true, title_action_field: { - action_val_path: "name", + action_val_path: function (record, field) { + return record.product.barcode + ? "product.barcode" + : "product.default_code"; + }, }, list_item_klass_maker: this.move_card_color, key_title: "product.display_name", From 81b3b947ed780f923c959cff1e662257c1d6416e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 28 Apr 2025 09:23:45 +0000 Subject: [PATCH 019/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception_mobile/README.rst | 2 +- shopfloor_reception_mobile/__manifest__.py | 2 +- shopfloor_reception_mobile/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 71c65ba45ec..e6a6de90ba2 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ addon | version | maintainers | summary [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app [shopfloor_reception](shopfloor_reception/) | 16.0.1.0.0 | [![mmequignon](https://github.com/mmequignon.png?size=30px)](https://github.com/mmequignon) [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Reception scenario for shopfloor -[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.0 | [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Scenario for receiving products +[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Scenario for receiving products [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation diff --git a/shopfloor_reception_mobile/README.rst b/shopfloor_reception_mobile/README.rst index 91ff4b9b8f2..9e3eae11480 100644 --- a/shopfloor_reception_mobile/README.rst +++ b/shopfloor_reception_mobile/README.rst @@ -7,7 +7,7 @@ Shopfloor reception mobile !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:53481754aeb6f45f2bc05fa4eaf8aaf55552d1ada7b26c1e7f065d60faa2adbb + !! source digest: sha256:160fe3ea1390fd4c12a76fba12c0f662dcb164d2e39fd9455d08e1e0bf2b4b94 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception_mobile/__manifest__.py b/shopfloor_reception_mobile/__manifest__.py index a4f9bda4503..c95cac6d191 100644 --- a/shopfloor_reception_mobile/__manifest__.py +++ b/shopfloor_reception_mobile/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Shopfloor reception mobile", "summary": "Scenario for receiving products", - "version": "16.0.1.0.0", + "version": "16.0.1.0.1", "development_status": "Beta", "depends": ["shopfloor_mobile_base", "shopfloor_reception"], "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/shopfloor_reception_mobile/static/description/index.html b/shopfloor_reception_mobile/static/description/index.html index 5839f8cd1c5..88ec49d8a34 100644 --- a/shopfloor_reception_mobile/static/description/index.html +++ b/shopfloor_reception_mobile/static/description/index.html @@ -367,7 +367,7 @@

Shopfloor reception mobile

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:53481754aeb6f45f2bc05fa4eaf8aaf55552d1ada7b26c1e7f065d60faa2adbb +!! source digest: sha256:160fe3ea1390fd4c12a76fba12c0f662dcb164d2e39fd9455d08e1e0bf2b4b94 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Frontend for the reception scenario in shopfloor. From c5e1292161a70fcb5ccf5c0e0510b99f1e7e0a8b Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Tue, 14 Jan 2025 10:16:48 +0100 Subject: [PATCH 020/357] shopfloor delivery: better error when return picking is scanned --- shopfloor/actions/message.py | 10 ++ shopfloor/services/service.py | 2 + shopfloor/tests/test_delivery_scan_deliver.py | 134 ++++++++++++++++++ 3 files changed, 146 insertions(+) diff --git a/shopfloor/actions/message.py b/shopfloor/actions/message.py index d28ad538b53..97b733d3674 100644 --- a/shopfloor/actions/message.py +++ b/shopfloor/actions/message.py @@ -991,3 +991,13 @@ def lot_change_no_line_found(self): "message_type": "error", "body": _("Unable to find a line with the same product but different lot."), } + + def reserved_for_other_picking_type(self, picking): + body = _("Reserved for %(picking_type)s %(picking_name)s") % { + "picking_type": picking.picking_type_id.name, + "picking_name": picking.name, + } + return { + "message_type": "error", + "body": body, + } diff --git a/shopfloor/services/service.py b/shopfloor/services/service.py index 9f0d5844be7..8e48df0fa08 100644 --- a/shopfloor/services/service.py +++ b/shopfloor/services/service.py @@ -87,6 +87,8 @@ def _check_picking_status(self, pickings, states=("assigned",)): return self.msg_store.transfer_cancelled() if picking.state not in states: # the picking must be ready return self.msg_store.stock_picking_not_available(picking) + if picking.picking_type_id in self.picking_types.return_picking_type_id: + return self.msg_store.picking_type_is_return() if picking.picking_type_id not in self.picking_types: return self.msg_store.cannot_move_something_in_picking_type() diff --git a/shopfloor/tests/test_delivery_scan_deliver.py b/shopfloor/tests/test_delivery_scan_deliver.py index bae03f79cd9..15056e9b0bd 100644 --- a/shopfloor/tests/test_delivery_scan_deliver.py +++ b/shopfloor/tests/test_delivery_scan_deliver.py @@ -12,6 +12,20 @@ class DeliveryScanDeliverCase(DeliveryCommonCase): @classmethod def setUpClassBaseData(cls): super().setUpClassBaseData() + cls.out_location = cls.env.ref("stock.stock_location_output") + cls.cleanup_type = ( + cls.env["stock.picking.type"] + .sudo() + .create( + { + "name": "Cancel Cleanup", + "default_location_src_id": cls.out_location.id, + "default_location_dest_id": cls.stock_location.id, + "sequence_code": "CCP", + "code": "internal", + } + ) + ) cls.product_e.tracking = "lot" cls.picking = picking = cls._create_picking( lines=[ @@ -456,6 +470,126 @@ def test_scan_deliver_picking_canceled(self): message=self.service.msg_store.transfer_canceled(), ) + def test_scan_deliver_return_partial_package(self): + move_a = self.picking.move_ids.filtered( + lambda m: m.product_id == self.product_a + ) + move_a._action_cancel() + cleanup_picking = self._create_picking( + picking_type=self.cleanup_type, lines=[(self.product_a, 1)] + ) + package_vals = [(self.product_a, 1, None)] + cleanup_package = self._create_package_in_location( + cleanup_picking.location_id, package_vals + ) + cleanup_package.name = "CLEANUP_PACKAGE" + cleanup_picking.action_assign() + cleanup_picking.move_line_ids.package_id = cleanup_package + params = {"barcode": "CLEANUP_PACKAGE"} + response = self.service.dispatch("scan_deliver", params=params) + type_name = cleanup_picking.picking_type_id.name + pick_name = cleanup_picking.name + expected_body = f"Reserved for {type_name} {pick_name}" + self.assertEqual(response.get("message").get("body"), expected_body) + + def test_scan_deliver_return_package(self): + self.picking.action_cancel() + cleanup_picking = self._create_picking( + picking_type=self.cleanup_type, lines=[(self.product_a, 1)] + ) + package_vals = [(self.product_a, 1, None)] + cleanup_package = self._create_package_in_location( + cleanup_picking.location_id, package_vals + ) + cleanup_package.name = "CLEANUP_PACKAGE" + cleanup_picking.action_assign() + cleanup_picking.move_line_ids.package_id = cleanup_package + params = {"barcode": "CLEANUP_PACKAGE"} + response = self.service.dispatch("scan_deliver", params=params) + expected_body = ( + f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" + ) + self.assertEqual(response.get("message").get("body"), expected_body) + + def test_scan_deliver_return_product(self): + self.picking.action_cancel() + cleanup_picking = self._create_picking( + picking_type=self.cleanup_type, lines=[(self.product_a, 1)] + ) + cleanup_picking.action_assign() + params = {"barcode": self.product_a.barcode} + response = self.service.dispatch("scan_deliver", params=params) + expected_body = ( + f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" + ) + self.assertEqual(response.get("message").get("body"), expected_body) + + def test_scan_deliver_return_packaging(self): + self.picking.action_cancel() + cleanup_picking = self._create_picking( + picking_type=self.cleanup_type, lines=[(self.product_a, 1)], + ) + cleanup_picking.action_assign() + packaging = ( + self.env["product.packaging"] + .sudo() + .create( + { + "name": "CLEANUP PACKAGING", + "product_id": self.product_a.id, + "qty": 1, + "product_uom_id": self.product_a.id, + "barcode": "CLEANUP_PACKAGING", + } + ) + ) + params = {"barcode": "CLEANUP_PACKAGING"} + response = self.service.dispatch("scan_deliver", params=params) + expected_body = ( + f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" + ) + self.assertEqual(response.get("message").get("body"), expected_body) + + def test_scan_deliver_return_lot(self): + self.picking.action_cancel() + cleanup_picking = self._create_picking( + picking_type=self.cleanup_type, lines=[(self.product_a, 1)] + ) + # Create move lines and set lot + cleanup_picking.action_assign() + cleanup_lot = self.env["stock.lot"].create( + { + "product_id": self.product_a.id, + "company_id": self.env.company.id, + "name": "CLEANUP_LOT", + "ref": "CLEANUP_LOT", + } + ) + # Re-force qty to 1, as setting the lot resets qty to 0 + cleanup_picking.move_line_ids.lot_id = cleanup_lot + cleanup_picking.move_line_ids.reserved_uom_qty = 1.0 + params = {"barcode": "CLEANUP_LOT"} + response = self.service.dispatch("scan_deliver", params=params) + expected_body = ( + f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" + ) + self.assertEqual(response.get("message").get("body"), expected_body) + + def test_scan_delivery_return_picking(self): + self.picking.action_cancel() + cleanup_picking = self._create_picking( + picking_type=self.cleanup_type, lines=[(self.product_c, 1)] + ) + cleanup_picking.action_assign() + params = {"barcode": cleanup_picking.name} + response = self.service.dispatch("scan_deliver", params=params) + self.assert_response_deliver( + response, + message=self.service.msg_store.reserved_for_other_picking_type( + cleanup_picking + ), + ) + def test_scan_deliver_picking_done(self): # Set qty done for all lines (packages/raw product/lot...), picking is # automatically set to done when the last line is completed From 5e1412a5e5b792f0f6f4f4e63c7851292a7c32d2 Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Tue, 14 Jan 2025 15:27:00 +0100 Subject: [PATCH 021/357] shopfloor delivery: scan_delivery: use handlers --- shopfloor/services/delivery.py | 81 ++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/shopfloor/services/delivery.py b/shopfloor/services/delivery.py index 4340514edb7..768710162c1 100644 --- a/shopfloor/services/delivery.py +++ b/shopfloor/services/delivery.py @@ -147,47 +147,54 @@ def scan_deliver(self, barcode, picking_id=None, location_id=None): if picking_id: picking = self.env["stock.picking"].browse(picking_id) - # Validate picking anyway if not barcode_valid: - package = search.package_from_scan(barcode) - if package: - return self._deliver_package(picking, package, location) - - if not barcode_valid: - product = search.product_from_scan(barcode) - if product: - return self._deliver_product( - picking, product, product_qty=1, location=location - ) - - if not barcode_valid: - packaging = search.packaging_from_scan(barcode) - if packaging: - # By scanning a packaging, we want to process - # the full quantity of the packaging - packaging_qty = packaging.product_uom_id._compute_quantity( - packaging.qty, packaging.product_id.uom_id - ) - return self._deliver_product( - picking, - packaging.product_id, - product_qty=packaging_qty, - location=location, - ) + handlers_by_type = { + "package": self._scan_deliver__by_package, + "product": self._scan_deliver__by_product, + "packaging": self._scan_deliver__by_packaging, + "lot": self._scan_deliver__by_lot, + "location": self._scan_deliver__by_location, + } + search_result = search.find(barcode, handlers_by_type.keys()) + handler = handlers_by_type.get(search_result.type) + if handler: + result = handler(search_result.record, picking, location) + if result: + return result + return self._scan_deliver__fallback(picking, location, barcode_valid) + + def _scan_deliver__by_package(self, package, picking, location): + return self._deliver_package(picking, package, location) + + def _scan_deliver__by_product(self, product, picking, location): + return self._deliver_product(picking, product, product_qty=1, location=location) + + def _scan_deliver__by_packaging(self, packaging, picking, location): + # By scanning a packaging, we want to process + # the full quantity of the packaging + packaging_qty = packaging.product_uom_id._compute_quantity( + packaging.qty, packaging.product_id.uom_id + ) + return self._deliver_product( + picking, + packaging.product_id, + product_qty=packaging_qty, + location=location, + ) - if not barcode_valid: - lot = search.lot_from_scan(barcode) - if lot: - return self._deliver_lot(picking, lot, product_qty=1, location=location) + def _scan_deliver__by_lot(self, lot, picking, location): + return self._deliver_lot(picking, lot, product_qty=1, location=location) - if not barcode_valid: - sublocation = search.location_from_scan(barcode) - if sublocation and sublocation.is_sublocation_of( - self.picking_types.mapped("default_location_src_id") - ): - message = self.msg_store.location_src_set_to_sublocation(sublocation) - return self._response_for_deliver(location=sublocation, message=message) + def _scan_deliver__by_location(self, scanned_location, picking, location): + if scanned_location.is_sublocation_of( + self.picking_types.mapped("default_location_src_id") + ): + message = self.msg_store.location_src_set_to_sublocation(scanned_location) + return self._response_for_deliver( + location=scanned_location, message=message + ) + def _scan_deliver__fallback(self, picking, location, barcode_valid): message = self.msg_store.barcode_not_found() if not barcode_valid else None return self._response_for_deliver( picking=picking, location=location, message=message From 837dbb5166e98e53064bc25efdd1bd4278df238a Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Tue, 28 Jan 2025 14:01:02 +0100 Subject: [PATCH 022/357] shopfloor: Refactor _check_picking_status --- shopfloor/services/checkout.py | 34 ++++---- shopfloor/services/delivery.py | 77 +++++++++++-------- shopfloor/services/service.py | 54 ++++++++----- shopfloor/tests/test_checkout_select.py | 4 +- shopfloor/tests/test_delivery_scan_deliver.py | 51 ++++++------ shopfloor_reception/services/reception.py | 28 +++---- 6 files changed, 137 insertions(+), 111 deletions(-) diff --git a/shopfloor/services/checkout.py b/shopfloor/services/checkout.py index 232e1e96613..1f143c62faf 100644 --- a/shopfloor/services/checkout.py +++ b/shopfloor/services/checkout.py @@ -402,7 +402,7 @@ def select(self, picking_id): lines """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_manual_selection(message=message) return self._select_picking(picking, "manual_selection") @@ -451,7 +451,7 @@ def scan_line(self, picking_id, barcode, confirm_pack_all=False, confirm_lot=Non screen to change the qty done and destination pack if needed """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) @@ -774,7 +774,7 @@ def select_line(self, picking_id, package_id=None, move_line_id=None): assert package_id or move_line_id picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) @@ -793,7 +793,7 @@ def _change_line_qty( self, picking_id, selected_line_ids, move_line_ids, quantity_func ): picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) @@ -1031,7 +1031,7 @@ def scan_package_action(self, picking_id, selected_line_ids, barcode): to close the stock picking """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) @@ -1186,7 +1186,7 @@ def list_delivery_packaging(self, picking_id, selected_line_ids): * select_package: when no delivery packaging is available """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) selected_lines = self.env["stock.move.line"].browse(selected_line_ids).exists() @@ -1216,7 +1216,7 @@ def new_package(self, picking_id, selected_line_ids, package_type_id=None): * select_line: goes back to selection of lines to work on next lines """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) packaging = None @@ -1238,7 +1238,7 @@ def no_package(self, picking_id, selected_line_ids): if self.options.get("checkout__disable_no_package"): raise BadRequest("`checkout.no_package` endpoint is not enabled") picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) selected_lines = self.env["stock.move.line"].browse(selected_line_ids).exists() @@ -1270,7 +1270,7 @@ def list_dest_package(self, picking_id, selected_line_ids): * select_package: when no package is available """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) lines = self.env["stock.move.line"].browse(selected_line_ids).exists() @@ -1320,7 +1320,7 @@ def scan_dest_package(self, picking_id, selected_line_ids, barcode): * summary: all lines are put in packages """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) lines = self.env["stock.move.line"].browse(selected_line_ids).exists() @@ -1347,7 +1347,7 @@ def set_dest_package(self, picking_id, selected_line_ids, package_id): * summary: all lines are put in packages """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) lines = self.env["stock.move.line"].browse(selected_line_ids).exists() @@ -1374,7 +1374,7 @@ def summary(self, picking_id): * summary """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) return self._response_for_summary(picking) @@ -1393,7 +1393,7 @@ def list_packaging(self, picking_id, package_id): * summary: if the package_id no longer exists """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) package = self.env["stock.quant.package"].browse(package_id).exists() @@ -1408,7 +1408,7 @@ def set_packaging(self, picking_id, package_id, package_type_id): * summary """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) @@ -1445,7 +1445,7 @@ def cancel_line(self, picking_id, package_id=None, line_id=None): * select_line: when package or line has been canceled """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) @@ -1490,7 +1490,7 @@ def done(self, picking_id, confirmation=False): * select_child_location: there are child destination locations """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) lines = picking.move_line_ids @@ -1533,7 +1533,7 @@ def scan_dest_location(self, picking_id, barcode): * select_child_location: in case of error """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_document(message=message) search = self._actions_for("search") diff --git a/shopfloor/services/delivery.py b/shopfloor/services/delivery.py index 768710162c1..09ea2d9e04b 100644 --- a/shopfloor/services/delivery.py +++ b/shopfloor/services/delivery.py @@ -140,7 +140,7 @@ def scan_deliver(self, barcode, picking_id=None, location_id=None): barcode_valid = bool(picking) if picking: - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_deliver(location=location, message=message) @@ -235,6 +235,12 @@ def _deliver_package(self, picking, package, location): lines = package.move_line_ids.filtered( lambda l: l.state in ("assigned", "partially_available") ) + if not lines: + return self._response_for_deliver( + picking=picking, + location=location, + message=self.msg_store.cannot_move_something_in_picking_type(), + ) # State of the picking might change while we reach this point: check again! message = self._check_picking_status(lines.mapped("picking_id")) if message: @@ -247,12 +253,9 @@ def _deliver_package(self, picking, package, location): ] ) return self._response_for_deliver(location=location, message=message) - if not lines: - return self._response_for_deliver( - picking=picking, - location=location, - message=self.msg_store.cannot_move_something_in_picking_type(), - ) + message = self._check_picking_type(lines.mapped("picking_id")) + if message: + return self._response_for_deliver(location=location, message=message) # TODO add a message if any of the lines already had a qty_done > 0 new_picking = fields.first(lines.mapped("picking_id")) if self._set_lines_done(lines): @@ -264,19 +267,7 @@ def _deliver_package(self, picking, package, location): def _lines_base_domain(self, no_qty_done=True): # we added auto_join for this, otherwise, the ORM would search all pickings # in the picking type, and then use IN (ids) - domain = [ - # Accepting return_picking_types in order to display meaningful - # messages when trying to process a return move. - # Those returns are blocked later in `_check_picking_status` - "|", - ("picking_id.picking_type_id", "in", self.picking_types.ids), - ( - "picking_id.picking_type_id", - "in", - self.picking_types.return_picking_type_id.ids, - ), - ("picking_id.state", "not in", ("done",)), - ] + domain = [] if no_qty_done: domain.append(("qty_done", "=", 0)) return domain @@ -313,6 +304,16 @@ def _lines_from_product_domain( ) if location: domain.extend([("location_id", "=", location.id)]) + else: + domain.extend( + [ + ( + "location_id", + "child_of", + self.picking_types.default_location_src_id.ids, + ) + ] + ) if product_qty: domain.extend( [ @@ -367,6 +368,12 @@ def _deliver_product(self, picking, product, product_qty=None, location=None): message=self.msg_store.product_in_multiple_sublocation(product), ) + message = self._check_picking_type(lines.mapped("picking_id")) + if message: + return self._response_for_deliver(location=location, message=message) + lines = lines.filtered( + lambda l: l.move_id.picking_type_id in self.picking_types + ) # State of the picking might change while we reach this point: check again! message = self._check_picking_status(lines.mapped("picking_id")) if message: @@ -429,15 +436,14 @@ def _deliver_product(self, picking, product, product_qty=None, location=None): return self._response_for_deliver(new_picking, location=location) def _deliver_lot(self, picking, lot, product_qty=None, location=None): - lines = self.env["stock.move.line"].search( - self._lines_from_lot_domain( - lot, - no_qty_done=False, - product_qty=product_qty, - location=location, - picking=picking, - ) + domain = self._lines_from_lot_domain( + lot, + no_qty_done=False, + product_qty=product_qty, + location=location, + picking=picking, ) + lines = self.env["stock.move.line"].search(domain) if not lines: return self._response_for_deliver( picking, @@ -455,6 +461,9 @@ def _deliver_lot(self, picking, lot, product_qty=None, location=None): message=self.msg_store.lot_in_multiple_sublocation(lot), ) + message = self._check_picking_type(lines.mapped("picking_id")) + if message: + return self._response_for_deliver(location=location, message=message) # State of the picking might change while we reach this point: check again! message = self._check_picking_status(lines.mapped("picking_id")) if message: @@ -565,7 +574,7 @@ def select(self, picking_id): * deliver: with information about the stock.picking """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self.list_stock_picking(message=message) if picking: @@ -582,7 +591,7 @@ def set_qty_done_pack(self, picking_id, package_id, location_id=None): * deliver: always return here with updated data """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_deliver(message=message) package = self.env["stock.quant.package"].browse(package_id).exists() @@ -607,7 +616,7 @@ def set_qty_done_line(self, picking_id, move_line_id): * deliver: always return here with updated data """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_deliver(message=message) line = self.env["stock.move.line"].browse(move_line_id).exists() @@ -634,7 +643,7 @@ def reset_qty_done_pack(self, picking_id, package_id): * deliver: always return here with updated data """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_deliver(message=message) package = self.env["stock.quant.package"].browse(package_id).exists() @@ -667,7 +676,7 @@ def reset_qty_done_line(self, picking_id, move_line_id): * deliver: always return here with updated data """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_deliver(message=message) line = self.env["stock.move.line"].browse(move_line_id).exists() @@ -697,7 +706,7 @@ def done(self, picking_id, confirm=False): * confirm_done: when not all lines of the stock.picking are done """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_deliver(message=message) if self._action_picking_done(picking): diff --git a/shopfloor/services/service.py b/shopfloor/services/service.py index 8e48df0fa08..f55ab076407 100644 --- a/shopfloor/services/service.py +++ b/shopfloor/services/service.py @@ -2,7 +2,7 @@ # Copyright 2020 Akretion (http://www.akretion.com) # Copyright 2020-2021 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import _, exceptions +from odoo import _, exceptions, fields from odoo.addons.component.core import AbstractComponent @@ -72,25 +72,41 @@ def search_move_line(self): sort_order_custom_code=self.sort_order_custom_code, ) - def _check_picking_status(self, pickings, states=("assigned",)): - """Check if given pickings can be processed. + def _check_picking_consistency(self, pickings): + if not pickings.exists(): + return self.msg_store.stock_picking_not_found() + + def _check_picking_type(self, pickings): + """Check if the pickings have the right expected type.""" + if not any( + picking.picking_type_id in self.picking_types for picking in pickings + ): + return self.msg_store.reserved_for_other_picking_type( + fields.first(pickings) + ) - If the picking is already done, canceled or didn't belong to the - expected picking type, a message is returned. - """ - for picking in pickings: - if not picking.exists(): - return self.msg_store.stock_picking_not_found() - if picking.state == "done": - return self.msg_store.already_done() - if picking.state == "cancel": - return self.msg_store.transfer_cancelled() - if picking.state not in states: # the picking must be ready - return self.msg_store.stock_picking_not_available(picking) - if picking.picking_type_id in self.picking_types.return_picking_type_id: - return self.msg_store.picking_type_is_return() - if picking.picking_type_id not in self.picking_types: - return self.msg_store.cannot_move_something_in_picking_type() + def _check_picking_status(self, pickings, states=("assigned",)): + """Checks if the picking exists, is already done or canceled.""" + if not any(picking.state != "done" for picking in pickings): + return self.msg_store.already_done() + if not any(picking.state != "cancel" for picking in pickings): + return self.msg_store.transfer_canceled() + if not any( + picking.state in states for picking in pickings + ): # the picking must be ready + return self.msg_store.stock_picking_not_available(fields.first(pickings)) + + def _check_picking_processible(self, pickings, states=("assigned",)): + """Check if given pickings can be processed""" + message = self._check_picking_consistency(pickings) + if message: + return message + message = self._check_picking_type(pickings) + if message: + return message + message = self._check_picking_status(pickings, states=states) + if message: + return message def is_src_location_valid(self, location): """Check the source location is valid for given process. diff --git a/shopfloor/tests/test_checkout_select.py b/shopfloor/tests/test_checkout_select.py index 173b0aaf108..546da5e4a0a 100644 --- a/shopfloor/tests/test_checkout_select.py +++ b/shopfloor/tests/test_checkout_select.py @@ -68,7 +68,9 @@ def test_select_error_not_available(self): ) def test_select_error_not_allowed(self): + # Trying to pick a picking with wrong picking type picking = self._create_picking(picking_type=self.wh.pick_type_id) self._fill_stock_for_moves(picking.move_ids, in_package=True) picking.action_assign() - self._test_error(picking, "You cannot move this using this menu.") + expected_message = f"Reserved for {picking.picking_type_id.name} {picking.name}" + self._test_error(picking, expected_message) diff --git a/shopfloor/tests/test_delivery_scan_deliver.py b/shopfloor/tests/test_delivery_scan_deliver.py index 15056e9b0bd..e9cd1dcafba 100644 --- a/shopfloor/tests/test_delivery_scan_deliver.py +++ b/shopfloor/tests/test_delivery_scan_deliver.py @@ -506,9 +506,9 @@ def test_scan_deliver_return_package(self): cleanup_picking.move_line_ids.package_id = cleanup_package params = {"barcode": "CLEANUP_PACKAGE"} response = self.service.dispatch("scan_deliver", params=params) - expected_body = ( - f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" - ) + type_name = cleanup_picking.picking_type_id.name + pick_name = cleanup_picking.name + expected_body = f"Reserved for {type_name} {pick_name}" self.assertEqual(response.get("message").get("body"), expected_body) def test_scan_deliver_return_product(self): @@ -519,35 +519,34 @@ def test_scan_deliver_return_product(self): cleanup_picking.action_assign() params = {"barcode": self.product_a.barcode} response = self.service.dispatch("scan_deliver", params=params) - expected_body = ( - f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" - ) + type_name = cleanup_picking.picking_type_id.name + pick_name = cleanup_picking.name + expected_body = f"Reserved for {type_name} {pick_name}" self.assertEqual(response.get("message").get("body"), expected_body) def test_scan_deliver_return_packaging(self): self.picking.action_cancel() cleanup_picking = self._create_picking( - picking_type=self.cleanup_type, lines=[(self.product_a, 1)], + picking_type=self.cleanup_type, + lines=[(self.product_a, 1)], ) cleanup_picking.action_assign() - packaging = ( - self.env["product.packaging"] - .sudo() - .create( - { - "name": "CLEANUP PACKAGING", - "product_id": self.product_a.id, - "qty": 1, - "product_uom_id": self.product_a.id, - "barcode": "CLEANUP_PACKAGING", - } - ) + + packaging_model = self.env["product.packaging"].sudo() + packaging_model.create( + { + "name": "CLEANUP PACKAGING", + "product_id": self.product_a.id, + "qty": 1, + "product_uom_id": self.product_a.id, + "barcode": "CLEANUP_PACKAGING", + } ) params = {"barcode": "CLEANUP_PACKAGING"} response = self.service.dispatch("scan_deliver", params=params) - expected_body = ( - f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" - ) + type_name = cleanup_picking.picking_type_id.name + pick_name = cleanup_picking.name + expected_body = f"Reserved for {type_name} {pick_name}" self.assertEqual(response.get("message").get("body"), expected_body) def test_scan_deliver_return_lot(self): @@ -570,9 +569,9 @@ def test_scan_deliver_return_lot(self): cleanup_picking.move_line_ids.reserved_uom_qty = 1.0 params = {"barcode": "CLEANUP_LOT"} response = self.service.dispatch("scan_deliver", params=params) - expected_body = ( - f"Reserved for {cleanup_picking.picking_type_id.name} {cleanup_picking.name}" - ) + type_name = cleanup_picking.picking_type_id.name + pick_name = cleanup_picking.name + expected_body = f"Reserved for {type_name} {pick_name}" self.assertEqual(response.get("message").get("body"), expected_body) def test_scan_delivery_return_picking(self): @@ -668,7 +667,7 @@ def test_scan_deliver_error_picking_wrong_type(self): response, message={ "message_type": "error", - "body": "You cannot move this using this menu.", + "body": f"Reserved for {picking.picking_type_id.name} {picking.name}", }, ) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 212711d5e08..06359a09fa8 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -48,13 +48,13 @@ class Reception(Component): _usage = "reception" _description = __doc__ - def _check_picking_status(self, pickings): + def _check_picking_processible(self, pickings): # When returns are allowed, # the created picking might be empty and cannot be assigned. states = ["assigned"] if self.work.menu.allow_return: states.append("draft") - return super()._check_picking_status(pickings, states=states) + return super()._check_picking_processible(pickings, states=states) def _move_line_by_product(self, product): return self.env["stock.move.line"].search( @@ -328,7 +328,7 @@ def _scan_document__by_picking(self, pickings, barcode): message=self.msg_store.cannot_move_something_in_picking_type() ) if reception_pickings: - message = self._check_picking_status(reception_pickings) + message = self._check_picking_processible(reception_pickings) if message: return self._response_for_select_document( pickings=reception_pickings, message=message @@ -939,7 +939,7 @@ def scan_line(self, picking_id, barcode): - set_quantity: Packaging / Product has been scanned. Not tracked product """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_move(picking, message=message) handlers_by_type = { @@ -973,7 +973,7 @@ def done_action(self, picking_id, confirmation=False): - select_document: Mark as done """ picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_move(picking, message=message) if all(line.qty_done == 0 for line in picking.move_line_ids): @@ -1029,7 +1029,7 @@ def set_lot( """ picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_set_lot(picking, selected_line, message=message) if not selected_line.exists(): @@ -1060,7 +1060,7 @@ def _create_lot_values(self, product, lot_name): def set_lot_confirm_action(self, picking_id, selected_line_id): picking = self.env["stock.picking"].browse(picking_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) selected_line = self.env["stock.move.line"].browse(selected_line_id) if message: return self._response_for_set_lot(picking, selected_line, message=message) @@ -1145,7 +1145,7 @@ def set_quantity( """ picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_set_quantity( picking, selected_line, message=message @@ -1174,7 +1174,7 @@ def set_quantity( def set_quantity__cancel_action(self, picking_id, selected_line_id): picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_set_quantity( picking, selected_line, message=message @@ -1212,7 +1212,7 @@ def _set_quantity__process__set_qty_and_split(self, picking, line, quantity): def process_with_existing_pack(self, picking_id, selected_line_id, quantity): picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_set_quantity( picking, selected_line, message=message @@ -1227,7 +1227,7 @@ def process_with_existing_pack(self, picking_id, selected_line_id, quantity): def process_with_new_pack(self, picking_id, selected_line_id, quantity): picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_set_quantity( picking, selected_line, message=message @@ -1243,7 +1243,7 @@ def process_with_new_pack(self, picking_id, selected_line_id, quantity): def process_without_pack(self, picking_id, selected_line_id, quantity): picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_set_quantity( picking, selected_line, message=message @@ -1337,7 +1337,7 @@ def set_destination( """ picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_set_destination( picking, selected_line, message=message @@ -1399,7 +1399,7 @@ def select_dest_package( """ picking = self.env["stock.picking"].browse(picking_id) selected_line = self.env["stock.move.line"].browse(selected_line_id) - message = self._check_picking_status(picking) + message = self._check_picking_processible(picking) if message: return self._response_for_select_dest_package( picking, selected_line, message=message From 1b65d2374f9b50e58bc2a0914fba638748abcfb3 Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Tue, 4 Feb 2025 13:56:28 +0100 Subject: [PATCH 023/357] shopfloor checkout: scan document better messages --- shopfloor/actions/message.py | 24 ++++++ shopfloor/services/checkout.py | 107 +++++++++++++++----------- shopfloor/tests/test_checkout_scan.py | 14 +++- 3 files changed, 95 insertions(+), 50 deletions(-) diff --git a/shopfloor/actions/message.py b/shopfloor/actions/message.py index 97b733d3674..bda812a2841 100644 --- a/shopfloor/actions/message.py +++ b/shopfloor/actions/message.py @@ -467,6 +467,30 @@ def product_not_found_in_pickings(self): "body": _("No transfer found for this product."), } + def transfer_not_found_for_barcode(self, barcode): + body = _("No transfer found for barcode %s", barcode) + return { + "message_type": "error", + "body": body, + } + + def transfer_not_found_for_record(self, record): + model_mapping = { + "product.product": "product", + "stock.picking": "transfer", + "stock.quant.package": "package", + "product.packaging": "packaging", + "stock.location": "location", + "stock.lot": "lot", + "stock.move": "move", + } + model_name = model_mapping.get(record._name) + body = _("No transfer found for %s %s", model_name, record.name) + return { + "message_type": "error", + "body": body, + } + def product_not_found_in_location_or_transfer(self, product, location, picking): return { "message_type": "error", diff --git a/shopfloor/services/checkout.py b/shopfloor/services/checkout.py index 1f143c62faf..862ec082ece 100644 --- a/shopfloor/services/checkout.py +++ b/shopfloor/services/checkout.py @@ -214,25 +214,29 @@ def scan_document(self, barcode): * summary: stock.picking is selected and all its lines have a destination pack set """ - search_result = self._scan_document_find(barcode) - result_handler = getattr(self, "_select_document_from_" + search_result.type) - return result_handler(search_result.record) + handlers = { + "picking": self._select_document_from_picking, + "location": self._select_document_from_location, + "package": self._select_document_from_package, + "packaging": self._select_document_from_packaging, + "product": self._select_document_from_product, + "none": self._select_document_from_none, + } + if self.work.menu.scan_location_or_pack_first: + handlers.pop("product") + search_result = self._scan_document_find(barcode, handlers.keys()) + # Keep track of what has been initially scan, and forward it through kwargs + kwargs = { + "barcode": barcode, + "current_state": "select_document", + "scanned_record": search_result.record, + } + handler = handlers.get(search_result.type, self._select_document_from_none) + return handler(search_result.record, **kwargs) - def _scan_document_find(self, barcode, search_types=None): + def _scan_document_find(self, barcode, search_types): search = self._actions_for("search") - search_types = ( - "picking", - "location", - "package", - "packaging", - ) + (("product",) if not self.work.menu.scan_location_or_pack_first else ()) - return search.find( - barcode, - types=search_types, - ) - - def _select_document_from_picking(self, picking, **kw): - return self._select_picking(picking, "select_document") + return search.find(barcode, types=search_types) def _select_document_from_location(self, location, **kw): if not self.is_src_location_valid(location): @@ -251,7 +255,9 @@ def _select_document_from_location(self, location, **kw): ), } ) - return self._select_picking(pickings, "select_document") + # Keep track of what has been initially scan, and forward it through kwargs + kwargs = {**kw, "current_state": "select_document"} + return self._select_document_from_picking(pickings, **kwargs) def _select_document_from_package(self, package, **kw): pickings = package.move_line_ids.filtered( @@ -260,14 +266,15 @@ def _select_document_from_package(self, package, **kw): if len(pickings) > 1: # Filter only if we find several pickings to narrow the # selection to one of the good type. If we have one picking - # of the wrong type, it will be caught in _select_picking + # of the wrong type, it will be caught in _select_document_from_picking # with the proper error message. # Side note: rather unlikely to have several transfers ready # and moving the same things pickings = pickings.filtered( lambda p: p.picking_type_id in self.picking_types ) - return self._select_picking(fields.first(pickings), "select_document") + kwargs = {**kw, "current_state": "select_document"} + return self._select_document_from_picking(fields.first(pickings), **kwargs) def _select_document_from_product(self, product, line_domain=None, **kw): line_domain = line_domain or [] @@ -287,7 +294,8 @@ def _select_document_from_product(self, product, line_domain=None, **kw): order="priority desc, scheduled_date asc, id desc", limit=1, ) - return self._select_picking(picking, "select_document") + kwargs = {**kw, "current_state": "select_document"} + return self._select_document_from_picking(picking, **kwargs) def _select_document_from_packaging(self, packaging, **kw): # And retrieve its product @@ -298,35 +306,33 @@ def _select_document_from_packaging(self, packaging, **kw): line_domain = [("reserved_uom_qty", ">=", packaging.qty)] return self._select_document_from_product(product, line_domain=line_domain) - def _select_document_from_none(self, picking, **kw): + def _select_document_from_none(self, *args, barcode=None, **kwargs): """Handle result when no record is found.""" - return self._select_picking(picking, "select_document") + return self._response_for_select_document( + message=self.msg_store.transfer_not_found_for_barcode(barcode) + ) - def _select_picking(self, picking, state_for_error): + def _select_document_from_picking( + self, picking, current_state=None, barcode=None, **kwargs + ): + # Get origin record to give more context to the user when raising an error + # as we got picking from product/package/packaging/... + scanned_record = kwargs.get("scanned_record") if not picking: - if state_for_error == "manual_selection": - return self._response_for_manual_selection( - message=self.msg_store.stock_picking_not_found() - ) - return self._response_for_select_document( - message=self.msg_store.barcode_not_found() - ) + message = self.msg_store.transfer_not_found_for_record(scanned_record) + if current_state == "manual_selection": + return self._response_for_manual_selection(message=message) + return self._response_for_select_document(message=message) if picking.picking_type_id not in self.picking_types: - if state_for_error == "manual_selection": - return self._response_for_manual_selection( - message=self.msg_store.cannot_move_something_in_picking_type() - ) - return self._response_for_select_document( - message=self.msg_store.cannot_move_something_in_picking_type() - ) + message = self.msg_store.reserved_for_other_picking_type(picking) + if current_state == "manual_selection": + return self._response_for_manual_selection(message=message) + return self._response_for_select_document(message=message) if picking.state != "assigned": - if state_for_error == "manual_selection": - return self._response_for_manual_selection( - message=self.msg_store.stock_picking_not_available(picking) - ) - return self._response_for_select_document( - message=self.msg_store.stock_picking_not_available(picking) - ) + message = self.msg_store.stock_picking_not_available(picking) + if current_state == "manual_selection": + return self._response_for_manual_selection(message=message) + return self._response_for_select_document(message=message) return self._response_for_select_line(picking) def _data_for_move_lines(self, lines, **kw): @@ -405,7 +411,14 @@ def select(self, picking_id): message = self._check_picking_processible(picking) if message: return self._response_for_manual_selection(message=message) - return self._select_picking(picking, "manual_selection") + # Because _select_document_from_picking expects some context + # to give meaningful infos to the user, add some here. + kwargs = { + "current_state": "manual_selection", + "barcode": picking.name, + "scanned_record": picking, + } + return self._select_document_from_picking(picking, **kwargs) def _select_lines(self, lines, prefill_qty=0, related_lines=None): for i, line in enumerate(lines): @@ -1049,7 +1062,7 @@ def scan_package_action(self, picking_id, selected_line_ids, barcode): ) return result_handler(picking, selected_lines, search_result.record) - def _scan_package_find(self, picking, barcode, search_types=None): + def _scan_package_find(self, picking, barcode, search_types): search = self._actions_for("search") search_types = ( "package", diff --git a/shopfloor/tests/test_checkout_scan.py b/shopfloor/tests/test_checkout_scan.py index c980814ca58..fcc17fadfa1 100644 --- a/shopfloor/tests/test_checkout_scan.py +++ b/shopfloor/tests/test_checkout_scan.py @@ -41,7 +41,10 @@ def test_scan_document_with_option_product_not_ok(self): self.assert_response( response, next_state="select_document", - message={"message_type": "error", "body": "Barcode not found"}, + message={ + "message_type": "error", + "body": "No transfer found for barcode A", + }, data={"restrict_scan_first": True}, ) @@ -56,7 +59,10 @@ def test_scan_document_error_not_found(self): self.assert_response( response, next_state="select_document", - message={"message_type": "error", "body": "Barcode not found"}, + message={ + "message_type": "error", + "body": "No transfer found for barcode NOPE", + }, data={"restrict_scan_first": False}, ) @@ -117,12 +123,14 @@ def _test_scan_document_error_different_picking_type(self, barcode_func): picking.action_assign() barcode = barcode_func(picking) response = self.service.dispatch("scan_document", params={"barcode": barcode}) + picking_name = picking.name + type_name = picking.picking_type_id.name self.assert_response( response, next_state="select_document", message={ "message_type": "error", - "body": "You cannot move this using this menu.", + "body": f"Reserved for {type_name} {picking_name}", }, data={"restrict_scan_first": False}, ) From 215346d452c0ac1d368b7e58a9b4eeec5af7ba81 Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Fri, 14 Feb 2025 15:32:16 +0100 Subject: [PATCH 024/357] shopfloor checkout: scan line better messages --- shopfloor/actions/message.py | 14 +-- shopfloor/services/checkout.py | 93 +++++++++++-------- shopfloor/services/service.py | 17 ++++ shopfloor/tests/test_checkout_scan_line.py | 39 +++++++- shopfloor_reception/services/reception.py | 2 +- .../tests/test_return_scan_line.py | 2 +- 6 files changed, 114 insertions(+), 53 deletions(-) diff --git a/shopfloor/actions/message.py b/shopfloor/actions/message.py index bda812a2841..f2c15040026 100644 --- a/shopfloor/actions/message.py +++ b/shopfloor/actions/message.py @@ -485,7 +485,11 @@ def transfer_not_found_for_record(self, record): "stock.move": "move", } model_name = model_mapping.get(record._name) - body = _("No transfer found for %s %s", model_name, record.name) + body = _( + "No transfer found for %(model_name)s %(record_name)s", + model_name=model_name, + record_name=record.name, + ) return { "message_type": "error", "body": body, @@ -559,11 +563,9 @@ def place_in_location_ask_confirmation(self, location_name): "body": _("Place it in {}?").format(location_name), } - def product_not_found_in_current_picking(self): - return { - "message_type": "error", - "body": _("Product is not in the current transfer."), - } + def product_not_found_in_current_picking(self, product): + body = _("Product %s is not in the current transfer.", product.name) + return {"message_type": "error", "body": body} def lot_mixed_package_scan_package(self): return { diff --git a/shopfloor/services/checkout.py b/shopfloor/services/checkout.py index 862ec082ece..3266260c1a6 100644 --- a/shopfloor/services/checkout.py +++ b/shopfloor/services/checkout.py @@ -473,21 +473,31 @@ def scan_line(self, picking_id, barcode, confirm_pack_all=False, confirm_lot=Non return self._response_for_summary(picking) # Search of the destination package - search_result = self._scan_line_find(picking, barcode) - result_handler = getattr(self, "_select_lines_from_" + search_result.type) - kw = {"confirm_pack_all": confirm_pack_all, "confirm_lot": confirm_lot} - return result_handler(picking, selection_lines, search_result.record, **kw) + handlers = { + "package": self._select_lines_from_package, + "product": self._select_lines_from_product, + "packaging": self._select_lines_from_packaging, + "lot": self._select_lines_from_lot, + "serial": self._select_lines_from_serial, + "delivery_packaging": self._select_lines_from_delivery_packaging, + "none": self._select_lines_from_none, + } + search_result = self._scan_line_find(picking, barcode, handlers.keys()) + # setting scanned record as kwarg in order to make better logs. + # The reason for this is that from a product we might select various records + # and lose track of what was initially scanned. This forces us to display + # standard messages that might have no meaning for the user. + kwargs = { + "confirm_pack_all": confirm_pack_all, + "confirm_lot": confirm_lot, + "scanned_record": search_result.record, + "barcode": barcode, + } + handler = handlers.get(search_result.type, self._select_lines_from_none) + return handler(picking, selection_lines, search_result.record, **kwargs) - def _scan_line_find(self, picking, barcode, search_types=None): + def _scan_line_find(self, picking, barcode, search_types): search = self._actions_for("search") - search_types = ( - "package", - "product", - "packaging", - "lot", - "serial", - "delivery_packaging", - ) return search.find( barcode, types=search_types, @@ -510,15 +520,14 @@ def _select_lines_from_package( lambda l: l.package_id == package and not l.shopfloor_checkout_done ) if not lines: - return self._response_for_select_line( - picking, - message={ - "message_type": "error", - "body": _("Package {} is not in the current transfer.").format( - package.name - ), - }, - ) + # No line for scanned package in selected picking + # Check if there's any picking reserving this product. + return_picking = self._get_pickings_for_package(package, limit=1) + if return_picking: + message = self.msg_store.reserved_for_other_picking_type(return_picking) + else: + message = self.msg_store.package_not_found_in_picking(package, picking) + return self._response_for_select_line(picking, message=message) self._select_lines(lines, prefill_qty=prefill_qty) if self.work.menu.no_prefill_qty: lines = picking.move_line_ids @@ -535,9 +544,12 @@ def _select_lines_from_product( lines = selection_lines.filtered(lambda l: l.product_id == product) if not lines: - return self._response_for_select_line( - picking, message=self.msg_store.product_not_found_in_current_picking() - ) + return_picking = self._get_pickings_for_product(product, limit=1) + if return_picking: + message = self.msg_store.reserved_for_other_picking_type(return_picking) + else: + message = self.msg_store.product_not_found_in_current_picking(product) + return self._response_for_select_line(picking, message=message) # When products are as units outside of packages, we can select them for # packing, but if they are in a package, we want the user to scan the packages. @@ -1049,18 +1061,21 @@ def scan_package_action(self, picking_id, selected_line_ids, barcode): return self._response_for_select_document(message=message) selected_lines = self.env["stock.move.line"].browse(selected_line_ids).exists() - search_result = self._scan_package_find(picking, barcode) - message = self._check_scan_package_find(picking, search_result) - if message: - return self._response_for_select_package( - picking, - selected_lines, - message=message, - ) - result_handler = getattr( - self, "_scan_package_action_from_" + search_result.type - ) - return result_handler(picking, selected_lines, search_result.record) + handlers = { + "package": self._scan_package_action_from_package, + "product": self._scan_package_action_from_product, + "packaging": self._scan_package_action_from_packaging, + "lot": self._scan_package_action_from_lot, + "serial": self._scan_package_action_from_serial, + "delivery_packaging": self._scan_package_action_from_delivery_packaging, + } + search_result = self._scan_package_find(picking, barcode, handlers.keys()) + handler = handlers.get(search_result.type, self._scan_package_action_from_none) + kwargs = { + "barcode": barcode, + "scanned_record": search_result.record, + } + return handler(picking, selected_lines, search_result.record, **kwargs) def _scan_package_find(self, picking, barcode, search_types): search = self._actions_for("search") @@ -1081,10 +1096,6 @@ def _scan_package_find(self, picking, barcode, search_types): ), ) - def _check_scan_package_find(self, picking, search_result): - # Used by inheriting modules - return False - def _find_line_to_increment(self, product_lines): """Find which line should have its qty incremented. diff --git a/shopfloor/services/service.py b/shopfloor/services/service.py index f55ab076407..eb3d0592014 100644 --- a/shopfloor/services/service.py +++ b/shopfloor/services/service.py @@ -3,6 +3,7 @@ # Copyright 2020-2021 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, exceptions, fields +from odoo.osv.expression import AND from odoo.addons.component.core import AbstractComponent @@ -34,6 +35,22 @@ def _get_process_picking_types(self): """Return picking types for the menu""" return self.work.menu.picking_type_ids + def _get_pickings_base_domain(self): + return [ + ("state", "not in", ("done", "cancel")), + ("location_id", "child_of", self.picking_types.default_location_src_id.ids), + ] + + def _get_pickings_for_package(self, package, **kwargs): + domain = self._get_pickings_base_domain() + package_domain = [("move_line_ids.package_id", "=", package.id)] + return self.env["stock.picking"].search(AND([domain, package_domain]), **kwargs) + + def _get_pickings_for_product(self, product, **kwargs): + domain = self._get_pickings_base_domain() + product_domain = [("move_line_ids.product_id", "=", product.id)] + return self.env["stock.picking"].search(AND([domain, product_domain]), **kwargs) + @property def picking_types(self): if not hasattr(self.work, "picking_types"): diff --git a/shopfloor/tests/test_checkout_scan_line.py b/shopfloor/tests/test_checkout_scan_line.py index 42e4f67ab8f..8aa12933bd4 100644 --- a/shopfloor/tests/test_checkout_scan_line.py +++ b/shopfloor/tests/test_checkout_scan_line.py @@ -164,6 +164,24 @@ def test_scan_line_error_barcode_not_found(self): ) def test_scan_line_error_package_not_in_picking(self): + picking = self._create_picking(lines=[(self.product_a, 10)]) + self._fill_stock_for_moves(picking.move_ids, in_package=True) + picking.action_assign() + # Create a package for product_a + package = self._create_package_in_location( + picking.location_id, [(self.product_a, 10, None)] + ) + # we work with picking, but we scan another package (not in a pick) + self._test_scan_line_error( + picking, + package.name, + { + "message_type": "error", + "body": f"Package {package.name} not found in transfer {picking.name}", + }, + ) + + def test_scan_line_error_package_reserved_by_another_picking(self): picking = self._create_picking(lines=[(self.product_a, 10)]) self._fill_stock_for_moves(picking.move_ids, in_package=True) picking2 = self._create_picking(lines=[(self.product_a, 10)]) @@ -176,9 +194,7 @@ def test_scan_line_error_package_not_in_picking(self): package.name, { "message_type": "error", - "body": "Package {} is not in the current transfer.".format( - package.name - ), + "body": f"Reserved for Checkout {picking2.name}", }, ) @@ -247,7 +263,22 @@ def test_scan_line_error_product_not_in_picking(self): self.product_b.barcode, { "message_type": "error", - "body": "Product is not in the current transfer.", + "body": "Product Product B is not in the current transfer.", + }, + ) + + def test_scan_line_error_product_in_another_picking(self): + picking = self._create_picking(lines=[(self.product_a, 10)]) + self._fill_stock_for_moves(picking.move_ids, in_package=True) + picking2 = self._create_picking(lines=[(self.product_b, 10)]) + self._fill_stock_for_moves(picking2.move_ids, in_package=True) + (picking | picking2).action_assign() + self._test_scan_line_error( + picking, + self.product_b.barcode, + { + "message_type": "error", + "body": f"Reserved for Checkout {picking2.name}", }, ) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 06359a09fa8..8eab102accd 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -412,7 +412,7 @@ def _scan_line__by_product__return(self, picking, product): # If we have an origin picking but no origin move, then user # scanned a wrong product. Warn him about this. if origin_moves and not origin_moves_for_product: - message = self.msg_store.product_not_found_in_current_picking() + message = self.msg_store.product_not_found_in_current_picking(product) return self._response_for_select_move(picking, message=message) if origin_moves_for_product: return_move = self._scan_line__create_return_move( diff --git a/shopfloor_reception/tests/test_return_scan_line.py b/shopfloor_reception/tests/test_return_scan_line.py index 9575ebdbf1d..76aa9c538f6 100644 --- a/shopfloor_reception/tests/test_return_scan_line.py +++ b/shopfloor_reception/tests/test_return_scan_line.py @@ -22,7 +22,7 @@ def test_scan_product_not_in_delivery(self): data={"picking": self._data_for_picking_with_moves(return_picking)}, message={ "message_type": "error", - "body": "Product is not in the current transfer.", + "body": f"Product {wrong_product.name} is not in the current transfer.", }, ) From a42a8f7c7f7a0783eb2c0be4f4a5dc55a5c42536 Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Mon, 17 Mar 2025 15:40:43 +0100 Subject: [PATCH 025/357] shopfloor: location_content_transfer: Better messages --- shopfloor/actions/stock_unreserve.py | 15 ++++-- .../services/location_content_transfer.py | 52 ++++++++++++------- .../test_location_content_transfer_start.py | 25 ++++++++- 3 files changed, 69 insertions(+), 23 deletions(-) diff --git a/shopfloor/actions/stock_unreserve.py b/shopfloor/actions/stock_unreserve.py index b279a5d9082..a86c0c917f1 100644 --- a/shopfloor/actions/stock_unreserve.py +++ b/shopfloor/actions/stock_unreserve.py @@ -10,7 +10,9 @@ class StockUnreserve(Component): _inherit = "shopfloor.process.action" _usage = "stock.unreserve" - def check_unreserve(self, location, move_lines, product=None, lot=None): + def check_unreserve( + self, location, move_lines, product=None, lot=None, allowed_types=None + ): """Return a message if there is an ongoing operation in the location. It could be a move line with some qty already processed or another @@ -20,12 +22,17 @@ def check_unreserve(self, location, move_lines, product=None, lot=None): :param move_lines: move lines to unreserve :param product: optional product to limit the scope in the location """ + if not allowed_types: + allowed_types = self.env["stock.picking.type"] location_move_lines = self._find_location_all_move_lines(location, product, lot) extra_move_lines = location_move_lines - move_lines if extra_move_lines: - return self.msg_store.picking_already_started_in_location( - extra_move_lines.picking_id - ) + extra_pickings = extra_move_lines.picking_id + if allowed_types: + for picking in extra_pickings: + if picking.picking_type_id not in allowed_types: + return self.msg_store.reserved_for_other_picking_type(picking) + return self.msg_store.picking_already_started_in_location(extra_pickings) def unreserve_moves(self, move_lines, picking_types): """Unreserve moves from `move_lines'. diff --git a/shopfloor/services/location_content_transfer.py b/shopfloor/services/location_content_transfer.py index 9f5408bfde1..2983d084075 100644 --- a/shopfloor/services/location_content_transfer.py +++ b/shopfloor/services/location_content_transfer.py @@ -342,7 +342,9 @@ def scan_location(self, barcode): # noqa: C901 unreserved_moves = self.env["stock.move"].browse() if self.work.menu.allow_unreserve_other_moves: - message = unreserve.check_unreserve(location, move_lines) + message = unreserve.check_unreserve( + location, move_lines, allowed_types=self.picking_types + ) if message: return self._response_for_start(message=message) move_lines, unreserved_moves = unreserve.unreserve_moves( @@ -602,20 +604,31 @@ def scan_line(self, location_id, move_line_id, barcode): ) search = self._actions_for("search") + handlers = { + "package": self._scan_line__by_package, + "product": self._scan_line__by_product, + "packaging": self._scan_line__by_packaging, + "lot": self._scan_line__by_lot, + "none": self._scan_line__fallback, + } + search_result = search.find(barcode, types=handlers.keys()) + handler = handlers.get(search_result.type, self._scan_line__fallback) + # handler might've been called but returned no response. + # I.E. package is scanned but doesn't matches move_line's package. + # Call explicitely fallback in such case + response = handler(search_result.record, move_line, location) + return response or self._scan_line__fallback( + search_result.record, move_line, location + ) - package = search.package_from_scan(barcode) - if package and move_line.package_id == package: + def _scan_line__by_package(self, package, move_line, location): + if move_line.package_id == package: # In case we have a source package but no package level because if # we have a package level, we would use "scan_package". return self._response_for_scan_destination(location, move_line) - product = search.product_from_scan(barcode) - if not product: - packaging = search.packaging_from_scan(barcode) - if packaging: - product = packaging.product_id - - if product and product == move_line.product_id: + def _scan_line__by_product(self, product, move_line, location): + if product == move_line.product_id: if product.tracking in ("lot", "serial"): move_lines = self._find_transfer_move_lines(location) return self._response_for_start_single( @@ -625,18 +638,21 @@ def scan_line(self, location_id, move_line_id, barcode): else: return self._response_for_scan_destination(location, move_line) - lot = search.lot_from_scan(barcode, products=move_line.product_id) - if lot and lot == move_line.lot_id: + def _scan_line__by_packaging(self, packaging, move_line, location): + return self._scan_line__by_product(packaging.product_id, move_line, location) + + def _scan_line__by_lot(self, lot, move_line, location): + if lot == move_line.lot_id: return self._response_for_scan_destination(location, move_line) + def _scan_line__fallback(self, record, move_line, location): # Nothing matches what is expected from the move line. move_lines = self._find_transfer_move_lines(location) - for rec in (package, product, lot): - if rec: - return self._response_for_start_single( - move_lines.mapped("picking_id"), - message=self.msg_store.wrong_record(rec), - ) + if record: + return self._response_for_start_single( + move_lines.mapped("picking_id"), + message=self.msg_store.wrong_record(record), + ) return self._response_for_start_single( move_lines.mapped("picking_id"), message=self.msg_store.barcode_not_found() ) diff --git a/shopfloor/tests/test_location_content_transfer_start.py b/shopfloor/tests/test_location_content_transfer_start.py index d51597ee981..62bc1fcd6a2 100644 --- a/shopfloor/tests/test_location_content_transfer_start.py +++ b/shopfloor/tests/test_location_content_transfer_start.py @@ -275,6 +275,29 @@ def test_scan_location_wrong_picking_type_allow_unreserve_empty(self): message=self.service.msg_store.location_empty(self.content_loc), ) + def test_scan_location_picking_already_started(self): + self.menu.sudo().allow_unreserve_other_moves = True + picking = self._create_picking( + picking_type=self.menu.picking_type_ids, + lines=[(self.product_a, 10), (self.product_b, 10)], + ) + self._fill_stock_for_moves( + picking.move_ids, in_package=True, location=self.content_loc + ) + picking.action_assign() + picking.move_line_ids[0].qty_done = 10 + response = self.service.dispatch( + "scan_location", params={"barcode": self.content_loc.barcode} + ) + self.assert_response_start( + response, + message=self.service.msg_store.picking_already_started_in_location(picking), + ) + # check that the original moves are still assigned + self.assertRecordValues( + picking.move_ids, [{"state": "assigned"}, {"state": "assigned"}] + ) + def test_scan_location_wrong_picking_type_allow_unreserve_error(self): """Content has different picking type than menu, option to unreserve @@ -298,7 +321,7 @@ def test_scan_location_wrong_picking_type_allow_unreserve_error(self): ) self.assert_response_start( response, - message=self.service.msg_store.picking_already_started_in_location(picking), + message=self.service.msg_store.reserved_for_other_picking_type(picking), ) # check that the original moves are still assigned self.assertRecordValues( From f1a593fd65528a696dbae7c46445059548feab0e Mon Sep 17 00:00:00 2001 From: Mmequignon Date: Mon, 13 Jan 2025 14:09:23 +0100 Subject: [PATCH 026/357] stock_available_to_promise_release: Allow unrelease processed qties --- .../models/stock_move.py | 198 ++++++++++++--- .../models/stock_route.py | 10 + .../models/stock_rule.py | 4 + .../tests/__init__.py | 1 + .../tests/common.py | 16 +- .../tests/test_unrelease_cancel.py | 238 ++++++++++++++++++ .../views/stock_route_views.xml | 1 + 7 files changed, 435 insertions(+), 33 deletions(-) create mode 100644 stock_available_to_promise_release/tests/test_unrelease_cancel.py diff --git a/stock_available_to_promise_release/models/stock_move.py b/stock_available_to_promise_release/models/stock_move.py index 946593abe47..102fd5649ae 100644 --- a/stock_available_to_promise_release/models/stock_move.py +++ b/stock_available_to_promise_release/models/stock_move.py @@ -5,11 +5,12 @@ import itertools import logging import operator as py_operator +from collections import defaultdict from odoo import _, api, fields, models from odoo.exceptions import UserError from odoo.osv import expression -from odoo.tools import date_utils, float_compare, float_round, groupby +from odoo.tools import date_utils, float_compare, float_is_zero, float_round, groupby from odoo.addons.stock.models.stock_move import StockMove as StockMoveBase @@ -87,35 +88,42 @@ def _is_unreleaseable(self): and self.rule_id.available_to_promise_defer_pull ) + def _has_unreleasable_state(self): + self.ensure_one() + if self.rule_id.allow_unrelease_return_done_move: + blocking_states = ("cancel",) + else: + blocking_states = ("done", "cancel") + return self.state not in blocking_states + def _in_progress_for_unrelease(self) -> StockMoveBase: """ - This method will return the moves not done or canceled that : + This method will return the moves with unreleasable state that : - have their picking printed - - have a quantity done != 0 - + - have a quantity done set if allow_unrelease_return_done_move """ - moves = self.filtered(lambda m: m.state not in ("done", "cancel")) - if not moves: - return moves - moves_printed = moves.filtered("picking_id.printed") - if moves_printed: - return moves_printed - moves_done = moves.filtered("quantity_done") - if moves_done: - return moves_done - return moves.browse() + unreleasable_moves = self.filtered(lambda m: m._has_unreleasable_state()) + if not unreleasable_moves: + return unreleasable_moves + printed_pickings = unreleasable_moves.filtered("picking_id.printed") + if printed_pickings: + return printed_pickings + return unreleasable_moves.filtered( + lambda m: not m.rule_id.allow_unrelease_return_done_move and m.quantity_done + ) def _is_unrelease_allowed_on_origin_moves(self, origin_moves): """We check that the origin moves are in a state that allows the unrelease of the current move. At this stage, a move can't be unreleased if - * a picking is already printed. (The work on the picking is planned and - we don't want to change it) - * a quantity done is recorded - * the processed origin moves is not consumed by the dest moves. + the processed origin moves is not consumed by the dest moves. """ self.ensure_one() origin_done_moves = origin_moves.filtered(lambda m: m.state == "done") + if self.rule_id.allow_unrelease_return_done_move: + origin_done_moves = origin_done_moves.filtered( + lambda m: not m.picking_type_id.return_picking_type_id + ) origin_qty_done = sum( m.product_uom._compute_quantity( m.quantity_done, @@ -672,6 +680,81 @@ def _get_chained_moves_iterator(self, chain_field): visited_moves += moves moves = moves.mapped(chain_field) - visited_moves + def _return_quantity_in_stock(self, qty_to_return_per_move): + """Return a quantity from a list of moves. + + The quantity to return is in the product uom""" + moves_to_return = self.browse([m_id for m_id in qty_to_return_per_move.keys()]) + moves_per_type = groupby(moves_to_return, lambda m: m.picking_type_id) + for picking_type, moves_list in moves_per_type: + moves = self.browse().union(*moves_list) + pickings = moves.picking_id + if not pickings: + continue + return_type = picking_type.return_picking_type_id + wiz_values = { + "picking_id": fields.first(pickings).id, + "location_id": return_type.default_location_dest_id.id, + } + product_return_moves = [] + if not return_type: + message = _( + "The operation %(picking_names)s is done and cannot be returned", + picking_names=", ".join(pickings.mapped("name")), + ) + raise UserError(message) + for move in moves: + # Cannot return an unprocessed move + if move.state != "done": + continue + product = move.product_id + uom = product.uom_id + qty_to_return = qty_to_return_per_move.get(move.id, 0) + # Cannot return 0 qty + if float_is_zero(qty_to_return, precision_rounding=uom.rounding): + continue + return_move_vals = { + "product_id": product.id, + "quantity": qty_to_return, + "uom_id": uom.id, + "move_id": move.id, + } + product_return_moves.append((0, 0, return_move_vals)) + if product_return_moves: + wiz_values["product_return_moves"] = product_return_moves + return_wiz = self.env["stock.return.picking"].create(wiz_values) + return_wiz.create_returns() + return True + + def _unrelease_set_returnable_qty_per_move( + self, qty_to_return, qty_to_return_per_move + ): + returnable_qty = 0 + for move in self: + rounding = move.product_id.uom_id.rounding + # As a move might have multiple dest ids, we might have + # already planned to return a few units already. + # Get it, and deduce it from the returnable qty + move_qty_planned = qty_to_return_per_move.get(move.id, 0) + # A move might already have return moves linked to it, deduce their quantity + move_returned_qty = sum( + move.returned_move_ids.filtered(lambda m: m.state != "cancel").mapped( + "product_qty" + ) + ) + move_returnable_qty = min( + qty_to_return, move.product_qty - move_returned_qty - move_qty_planned + ) + if float_is_zero(move_returnable_qty, precision_rounding=rounding): + continue + # Update the quantity + qty_to_return_per_move[move.id] += move_returnable_qty + qty_to_return -= move_returnable_qty + returnable_qty += move_returnable_qty + if float_is_zero(qty_to_return, precision_rounding=rounding): + break + return returnable_qty + def unrelease(self, safe_unrelease=False): """Unrelease unreleasable moves @@ -685,29 +768,83 @@ def unrelease(self, safe_unrelease=False): if forbidden_moves: forbidden_moves._unrelease_not_allowed_error() moves_to_unrelease.write({"need_release": True}) - impacted_picking_ids = set() + qty_to_return_per_move = defaultdict(float) for move in moves_to_unrelease: + rounding = move.product_id.uom_id.rounding + # When a move is returned, it is going straight to WH/Stock, + # skipping all intermediate zones (pick/pack). + # That is why we need to keep track of qty returned along the way. + # We do not want to return the same goods at each step. + # At a given step (pick/pack/ship), qty to return is + # move.product_uom_qty - cancelled_qty_at_step - already returned qties + qty_to_unrelease = move.product_qty + qty_returned_for_move = 0 iterator = move._get_chained_moves_iterator("move_orig_ids") - moves_to_cancel = self.env["stock.move"] + moves_to_cancel_for_move = self.env["stock.move"] # backup procure_method as when you don't propagate cancel, the # destination move is forced to make_to_stock procure_method = move.procure_method next(iterator) # skip the current move for origin_moves in iterator: - origin_moves = origin_moves.filtered( + qty_to_cancel = qty_to_unrelease - qty_returned_for_move + if float_is_zero(qty_to_cancel, precision_rounding=rounding): + break + todo_origin_moves = origin_moves.filtered( lambda m: m.state not in ("done", "cancel") ) - if origin_moves: - origin_moves = move._split_origins(origin_moves) - impacted_picking_ids.update(origin_moves.mapped("picking_id").ids) + qty_canceled = 0 + if todo_origin_moves: + moves_to_cancel = move._split_origins( + todo_origin_moves, qty=qty_to_cancel + ) # avoid to propagate cancel to the original move - origin_moves.write({"propagate_cancel": False}) - # origin_moves._action_cancel() - moves_to_cancel |= origin_moves - moves_to_cancel._action_cancel() + moves_to_cancel.write({"propagate_cancel": False}) + moves_to_cancel_for_move |= moves_to_cancel + qty_canceled = sum(moves_to_cancel.mapped("product_qty")) + # checking that for the current step (pick/pack/ship) + # move.product_uom_qty == step.cancelled_qty + move.returned_quanty + # If not the case, we have to move back goods in stock. + qty_to_return = qty_to_cancel - qty_canceled + done_moves = origin_moves.filtered(lambda m: m.state == "done") + # in case of canceled origin_moves, the quantity to return must + # be limited to the quantity not consumed + done_dest_moves = done_moves.move_dest_ids.filtered( + lambda m: m.state == "done" + ) + returnable_qty = sum(done_moves.mapped("product_qty")) - sum( + done_dest_moves.mapped("product_qty") + ) + qty_to_return = min(qty_to_return, returnable_qty) + if float_compare(qty_to_return, 0, precision_rounding=rounding) <= 0: + continue + if not move.rule_id.allow_unrelease_return_done_move: + # Without allow_unrelease_return_done_move enabled, + # only moves that aren't done can be unreleased. + msg_args = { + "move_name": move.name, + "done_move_names": ", ".join(done_moves.mapped("name")), + } + message = _( + ( + "You cannot unrelease the move %(move_name)s " + "because some origin moves %(done_move_names)s are done" + ), + **msg_args + ) + raise UserError(message) + # Multiple pickings can satisfy a move + # -> len(move.move_orig_ids.picking_id) > 1 + # Group done_moves per picking, and create returns + returnable_qty = done_moves._unrelease_set_returnable_qty_per_move( + qty_to_return, qty_to_return_per_move + ) + qty_returned_for_move += returnable_qty + + moves_to_cancel_for_move._action_cancel() # restore the procure_method overwritten by _action_cancel() move.procure_method = procure_method + self._return_quantity_in_stock(qty_to_return_per_move) moves_to_unrelease.write({"need_release": True}) for picking, moves in itertools.groupby( moves_to_unrelease, lambda m: m.picking_id @@ -721,14 +858,15 @@ def unrelease(self, safe_unrelease=False): ) picking.message_post(body=body) - def _split_origins(self, origins): + def _split_origins(self, origins, qty=None): """Split the origins of the move according to the quantity into the move and the quantity in the origin moves. Return the origins for the move's quantity. """ self.ensure_one() - qty = self.product_qty + if not qty: + qty = self.product_qty # Unreserve goods before the split origins._do_unreserve() rounding = self.product_uom.rounding diff --git a/stock_available_to_promise_release/models/stock_route.py b/stock_available_to_promise_release/models/stock_route.py index 7c91e368b37..b7d32ea9e93 100644 --- a/stock_available_to_promise_release/models/stock_route.py +++ b/stock_available_to_promise_release/models/stock_route.py @@ -7,6 +7,16 @@ class StockRoute(models.Model): _inherit = "stock.route" + allow_unrelease_return_done_move = fields.Boolean( + string="Reverse done transfer on cancellation", + default=False, + help=( + "If checked, unreleasing the delivery may create a new inverse " + "internal operation on the last done pulled transfer. " + "Otherwise, you won't be able to unrelease as soon as one of " + "the pulled transfer is done" + ), + ) available_to_promise_defer_pull = fields.Boolean( string="Release based on Available to Promise", default=False, diff --git a/stock_available_to_promise_release/models/stock_rule.py b/stock_available_to_promise_release/models/stock_rule.py index 7c893df5eab..be7c2516761 100644 --- a/stock_available_to_promise_release/models/stock_rule.py +++ b/stock_available_to_promise_release/models/stock_rule.py @@ -14,6 +14,10 @@ class StockRule(models.Model): related="route_id.available_to_promise_defer_pull", store=True ) + allow_unrelease_return_done_move = fields.Boolean( + related="route_id.allow_unrelease_return_done_move", store=True + ) + no_backorder_at_release = fields.Boolean( related="route_id.no_backorder_at_release", store=True ) diff --git a/stock_available_to_promise_release/tests/__init__.py b/stock_available_to_promise_release/tests/__init__.py index 35a813d9a28..41181f76399 100644 --- a/stock_available_to_promise_release/tests/__init__.py +++ b/stock_available_to_promise_release/tests/__init__.py @@ -4,3 +4,4 @@ from . import test_unrelease_2steps from . import test_unrelease_3steps from . import test_unrelease_merged_moves +from . import test_unrelease_cancel diff --git a/stock_available_to_promise_release/tests/common.py b/stock_available_to_promise_release/tests/common.py index 6fd56df73af..c0a47307756 100644 --- a/stock_available_to_promise_release/tests/common.py +++ b/stock_available_to_promise_release/tests/common.py @@ -132,8 +132,18 @@ def _out_picking(cls, pickings): return pickings.filtered(lambda r: r.picking_type_code == "outgoing") @classmethod - def _deliver(cls, picking): + def _get_backorder_for_pickings(cls, pickings): + return cls.env["stock.picking"].search([("backorder_id", "in", pickings.ids)]) + + @classmethod + def _deliver(cls, picking, product_qty=None): picking.action_assign() - for line in picking.mapped("move_ids.move_line_ids"): - line.qty_done = line.reserved_qty + if product_qty: + lines = picking.move_ids.move_line_ids + for product, qty in product_qty: + line = lines.filtered(lambda m: m.product_id == product) + line.qty_done = qty + else: + for line in picking.mapped("move_ids.move_line_ids"): + line.qty_done = line.reserved_qty picking._action_done() diff --git a/stock_available_to_promise_release/tests/test_unrelease_cancel.py b/stock_available_to_promise_release/tests/test_unrelease_cancel.py new file mode 100644 index 00000000000..b3dc36fe5cd --- /dev/null +++ b/stock_available_to_promise_release/tests/test_unrelease_cancel.py @@ -0,0 +1,238 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from datetime import datetime + +from .common import PromiseReleaseCommonCase + + +class TestAvailableToPromiseReleaseCancel(PromiseReleaseCommonCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.wh.delivery_steps = "pick_pack_ship" + cls._update_qty_in_location(cls.loc_bin1, cls.product1, 50.0) + cls._update_qty_in_location(cls.loc_bin1, cls.product2, 50.0) + + delivery_route = cls.wh.delivery_route_id + ship_rule = delivery_route.rule_ids.filtered( + lambda r: r.location_dest_id == cls.loc_customer + ) + cls.loc_output = ship_rule.location_src_id + pack_rule = delivery_route.rule_ids.filtered( + lambda r: r.location_dest_id == cls.loc_output + ) + cls.loc_pack = pack_rule.location_src_id + pick_rule = delivery_route.rule_ids.filtered( + lambda r: r.location_dest_id == cls.loc_pack + ) + cls.pick_type = pick_rule.picking_type_id + cls.pack_type = pack_rule.picking_type_id + + cls.picking_chain = cls._create_picking_chain( + cls.wh, [(cls.product1, 10)], date=datetime(2019, 9, 2, 16, 0) + ) + cls.ship_picking = cls._out_picking(cls.picking_chain) + cls.pack_picking = cls._prev_picking(cls.ship_picking) + cls.pick_picking = cls._prev_picking(cls.pack_picking) + + # Why is this not working when creating picking after enabling this setting? + delivery_route.write( + { + "available_to_promise_defer_pull": True, + "allow_unrelease_return_done_move": True, + } + ) + cls.ship_picking.release_available_to_promise() + cls.cleanup_type = cls.env["stock.picking.type"].create( + { + "name": "Cancel Cleanup", + "default_location_dest_id": cls.loc_stock.id, + "sequence_code": "CCP", + "code": "internal", + } + ) + cls.pick_type.return_picking_type_id = cls.cleanup_type + cls.pack_type.return_picking_type_id = cls.cleanup_type + + @classmethod + def _get_cleanup_picking(cls): + return cls.env["stock.picking"].search( + [("picking_type_id", "=", cls.cleanup_type.id)] + ) + + def test_unrelease_picked(self): + # In this case, we should get 1 return picking from + # WH/PACK to WH/STOCK + self._deliver(self.pick_picking) + self.ship_picking.unrelease() + self.assertTrue(self.ship_picking.need_release) + self.assertEqual(self.pack_picking.state, "cancel") + self.assertEqual(self.pick_picking.state, "done") + cancel_picking = self._get_cleanup_picking() + self.assertEqual(len(cancel_picking), 1) + self.assertEqual(cancel_picking.location_id, self.loc_pack) + self.assertEqual(cancel_picking.location_dest_id, self.loc_stock) + + def test_unrelease_packed(self): + # In this case, we should get 1 return picking from + # WH/OUT to WH/STOCK + self._deliver(self.pick_picking) + self._deliver(self.pack_picking) + self.ship_picking.unrelease() + self.assertTrue(self.ship_picking.need_release) + self.assertEqual(self.pack_picking.state, "done") + self.assertEqual(self.pick_picking.state, "done") + cancel_picking = self._get_cleanup_picking() + self.assertEqual(len(cancel_picking), 1) + self.assertEqual(cancel_picking.location_id, self.loc_output) + self.assertEqual(cancel_picking.location_dest_id, self.loc_stock) + + def test_unrelease_picked_partial(self): + qty_picked = [(self.product1, 5.0)] + self._deliver(self.pick_picking, product_qty=qty_picked) + pick_backorder = self._get_backorder_for_pickings(self.pick_picking) + self.assertTrue(pick_backorder) + self.ship_picking.unrelease() + self.assertTrue(self.ship_picking.need_release) + self.assertEqual(self.pack_picking.state, "cancel") + self.assertEqual(self.pick_picking.state, "done") + cancel_picking = self._get_cleanup_picking() + # In the end, we cancelled 5 units for the pick backorder, and returned + # 5 units from pack -> stock + self.assertEqual(pick_backorder.state, "cancel") + self.assertEqual(cancel_picking.location_id, self.loc_pack) + self.assertEqual(cancel_picking.location_dest_id, self.loc_stock) + self.assertEqual(cancel_picking.move_ids.product_uom_qty, 5.0) + + def test_unrelease_packed_partial(self): + self._deliver(self.pick_picking) + qty_packed = [(self.product1, 5.0)] + self._deliver(self.pack_picking, product_qty=qty_packed) + pack_backorder = self._get_backorder_for_pickings(self.pack_picking) + self.assertTrue(pack_backorder) + self.ship_picking.unrelease() + self.assertTrue(self.ship_picking.need_release) + self.assertEqual(self.pack_picking.state, "done") + self.assertEqual(self.pick_picking.state, "done") + cancel_pickings = self._get_cleanup_picking() + self.assertEqual(len(cancel_pickings), 2) + # In the end, we cancelled 5 units for the pack backorder, returned + # 5 units from pack -> stock, and 5 units from output -> stock + pack_cancel = cancel_pickings.filtered(lambda p: p.location_id == self.loc_pack) + ship_cancel = cancel_pickings.filtered( + lambda p: p.location_id == self.loc_output + ) + self.assertEqual(pack_cancel.move_ids.product_uom_qty, 5.0) + self.assertEqual(ship_cancel.move_ids.product_uom_qty, 5.0) + + @classmethod + def put_in_pack(cls, move): + # is it necessary to create stock moves? + move._action_assign() + pack = cls.env["stock.quant.package"].create({"name": move.product_id.name}) + move.move_line_ids.result_package_id = pack + return pack + + def test_unrelease_multiple_moves_same_product(self): + # Create a picking with twice the same move + product_qty = [ + (self.product1, 20), + ] + picking_chain = self._create_picking_chain(self.wh, products=product_qty) + ship_picking = self._out_picking(picking_chain) + ship_picking.release_available_to_promise() + # Creating a second move. Both moves thave the same origin (pack.move_line) + self.env["stock.move"].create(ship_picking.move_ids._split(4)) + pack_picking = self._prev_picking(ship_picking) + pick_picking = self._prev_picking(pack_picking) + self._deliver(pick_picking) + self._deliver(pack_picking) + ship_picking.unrelease() + cancel_pickings = self._get_cleanup_picking() + self.assertEqual(cancel_pickings.move_ids.product_qty, 20) + + def test_unrelease_packed_multi(self): + # Pick and pack 2 pickings, unrelease both before shipping + # Both have same picking types, goods should be returned + # to stock in the same picking + ship_no_pack = self.ship_picking + pack_no_pack = self.pack_picking + pick_no_pack = self.pick_picking + # The new picking chain will have packages + product_qty = [(self.product1, 10), (self.product2, 10)] + picking_chain = self._create_picking_chain(self.wh, products=product_qty) + ship_with_pack = self._out_picking(picking_chain) + ship_with_pack.release_available_to_promise() + pack_with_pack = self._prev_picking(ship_with_pack) + pick_with_pack = self._prev_picking(pack_with_pack) + # Process pick pickings + self._deliver(pick_with_pack) + self._deliver(pick_no_pack) + # put pack moves in packages on pack_with_pack, + pack_moves = pack_with_pack.move_ids + pack_move1 = pack_moves.filtered(lambda m: m.product_id == self.product1) + pack_move2 = pack_moves.filtered(lambda m: m.product_id == self.product2) + self.put_in_pack(pack_move1) + self.put_in_pack(pack_move2) + # Process pack pickings + self._deliver(pack_with_pack) + self._deliver(pack_no_pack) + # unrelease both ship pickings at once + (ship_with_pack | ship_no_pack).unrelease() + cancel_pickings = self._get_cleanup_picking() + # We should have 1 return picking only + self.assertEqual(len(cancel_pickings), 1) + # We should have 3 moves + cancel_moves = cancel_pickings.move_ids + self.assertEqual(len(cancel_moves), 3) + # We should have: + # - 1 move for product1 without pack + # - 1 move for product1 with pack + # - 1 move for product2 with pack + cancel_move1_no_pack = cancel_moves.filtered( + lambda m: m.product_id == self.product1 and not m.move_line_ids.package_id + ) + cancel_move1_with_pack = cancel_moves.filtered( + lambda m: m.product_id == self.product1 and m.move_line_ids.package_id + ) + cancel_move2_with_pack = cancel_moves.filtered( + lambda m: m.product_id == self.product2 and m.move_line_ids.package_id + ) + self.assertTrue(cancel_move1_no_pack) + self.assertEqual(cancel_move1_no_pack.product_qty, 10) + self.assertTrue(cancel_move1_with_pack) + self.assertEqual(cancel_move1_with_pack.product_qty, 10) + self.assertTrue(cancel_move2_with_pack) + self.assertEqual(cancel_move2_with_pack.product_qty, 10) + + def test_return_quantity_in_stock(self): + move_model = self.env["stock.move"] + pack_move = self.pack_picking.move_ids + # process pick and pack, so pack is done and returnable + self._deliver(self.pick_picking) + self._deliver(self.pack_picking) + # Using empty_recordsets doesn't raises an exception and doesn't create + # a return picking + empty_args = {} + move_model._return_quantity_in_stock(empty_args) + self.assertFalse(self._get_cleanup_picking()) + # Adding a move with no quantity + empty_args = {pack_move.id: 0} + move_model._return_quantity_in_stock(empty_args) + self.assertFalse(self._get_cleanup_picking()) + # Adding a quantity should create a return picking + valid_args = {pack_move.id: 5} + move_model._return_quantity_in_stock(valid_args) + return_picking = self._get_cleanup_picking() + self.assertEqual(return_picking.move_ids.product_qty, 5) + + def test_unrelease_shipped(self): + self._deliver(self.pick_picking) + self._deliver(self.pack_picking) + self._deliver(self.ship_picking) + self.ship_picking.unrelease() + # Did nothing + self.assertEqual(self.ship_picking.state, "done") + self.assertEqual(self.pack_picking.state, "done") + self.assertEqual(self.pick_picking.state, "done") diff --git a/stock_available_to_promise_release/views/stock_route_views.xml b/stock_available_to_promise_release/views/stock_route_views.xml index 514953fee7f..8861bb75968 100644 --- a/stock_available_to_promise_release/views/stock_route_views.xml +++ b/stock_available_to_promise_release/views/stock_route_views.xml @@ -7,6 +7,7 @@ + From 3e673133633a66a469002db6dbbb9ab30203eca6 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Wed, 23 Apr 2025 14:44:16 +0200 Subject: [PATCH 027/357] stock_available_to_promise_release: fix test picking priority --- .../tests/test_reservation.py | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/stock_available_to_promise_release/tests/test_reservation.py b/stock_available_to_promise_release/tests/test_reservation.py index 11891f61dba..85c378f9fbc 100644 --- a/stock_available_to_promise_release/tests/test_reservation.py +++ b/stock_available_to_promise_release/tests/test_reservation.py @@ -1131,13 +1131,14 @@ def test_mto_picking(self): # TODO: test w/ multiple orders by priority def test_picking_priority(self): - self.wh.delivery_steps = "pick_pack_ship" + self.wh.delivery_steps = "pick_ship" self.wh.delivery_route_id.write({"available_to_promise_defer_pull": True}) self._update_qty_in_location(self.loc_bin1, self.product1, 20.0) pick = self._create_picking_chain(self.wh, [(self.product1, 20)]) pick.priority = "1" pick.action_confirm() pick.release_available_to_promise() + self.assertEqual(pick.priority, "1") self.assertEqual(pick.move_ids.move_orig_ids.picking_id.priority, "1") # from here we simulate a special processing flow where a priority @@ -1148,23 +1149,20 @@ def test_picking_priority(self): # partially process the picking pick_pick = pick.move_ids.move_orig_ids.picking_id pick_pick.move_ids.quantity_done = 3.0 - pick_pick._action_done() + pick_pick.with_context( + skip_immediate=True, skip_backorder=True + ).button_validate() # process and validate the picking to create a backorder pick.move_ids.quantity_done = 3.0 - pick.unrelease() - pick._action_done() - - # force priority on the initial picks to simulate an inconsistency - # this case should not happen but we observe it in real life without - # knowing how it happens - pick.priority = "1" - pick_pick.priority = "1" + pick.picking_type_id.unrelease_on_backorder = True + pick.with_context(skip_immediate=True, skip_backorder=True).button_validate() backorder = pick.backorder_ids + self.assertEqual(backorder.move_ids.need_release, True) + # the backorder should have kept the initial priority + self.assertEqual(backorder.priority, "1") # change the priority on the backorder and release it backorder.priority = "0" - backorder.action_confirm() - # force need release to True for the test - backorder.move_ids.need_release = True + self.assertEqual(pick.move_ids.priority, "0") backorder.release_available_to_promise() # the backorder should keep the new priority self.assertEqual(backorder.priority, "0") From c76669e511b0836bbea34953cdb405aa262b5620 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Mon, 28 Apr 2025 16:01:16 +0000 Subject: [PATCH 028/357] [UPD] Update stock_available_to_promise_release.pot --- .../stock_available_to_promise_release.pot | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot b/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot index d94b4663f21..493952fe07c 100644 --- a/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot +++ b/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot @@ -154,6 +154,15 @@ msgid "" "new moves will be added to a new delivery." msgstr "" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "" +"If checked, unreleasing the delivery may create a new inverse internal " +"operation on the last done pulled transfer. Otherwise, you won't be able to " +"unrelease as soon as one of the pulled transfer is done" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_picking_type__unrelease_on_backorder msgid "" @@ -315,6 +324,12 @@ msgstr "" msgid "Release based on Available to Promise" msgstr "" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "Reverse done transfer on cancellation" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model,name:stock_available_to_promise_release.model_stock_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form @@ -366,6 +381,13 @@ msgid "" "%(move_names)s" msgstr "" +#. module: stock_available_to_promise_release +#. odoo-python +#: code:addons/stock_available_to_promise_release/models/stock_move.py:0 +#, python-format +msgid "The operation %(picking_names)s is done and cannot be returned" +msgstr "" + #. module: stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form msgid "The selected records will be released." From 08171953c599f334f93005ca3c33dfd112aee1a7 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 28 Apr 2025 16:12:31 +0000 Subject: [PATCH 029/357] [BOT] post-merge updates --- README.md | 2 +- stock_available_to_promise_release/README.rst | 2 +- stock_available_to_promise_release/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e6a6de90ba2..8f8d712b033 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ addon | version | maintainers | summary [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation -[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.6.2 | | Release Operations based on available to promise +[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.7.0 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves diff --git a/stock_available_to_promise_release/README.rst b/stock_available_to_promise_release/README.rst index bc3c5b06be5..a25557b3030 100644 --- a/stock_available_to_promise_release/README.rst +++ b/stock_available_to_promise_release/README.rst @@ -7,7 +7,7 @@ Stock Available to Promise Release !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:7dbd35643eddc66766843961912a08ae586df66939dbdc9472d365d36da415b8 + !! source digest: sha256:a1337e83c6332c7cfddb1c2c787bcc88bf6bb309e9c45ff10492d36ff8c74fe3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_available_to_promise_release/__manifest__.py b/stock_available_to_promise_release/__manifest__.py index 9371b2e0cd0..75f42be939a 100644 --- a/stock_available_to_promise_release/__manifest__.py +++ b/stock_available_to_promise_release/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Available to Promise Release", - "version": "16.0.3.6.2", + "version": "16.0.3.7.0", "summary": "Release Operations based on available to promise", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_available_to_promise_release/static/description/index.html b/stock_available_to_promise_release/static/description/index.html index 74ba04c6572..a4a8e43214b 100644 --- a/stock_available_to_promise_release/static/description/index.html +++ b/stock_available_to_promise_release/static/description/index.html @@ -367,7 +367,7 @@

Stock Available to Promise Release

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:7dbd35643eddc66766843961912a08ae586df66939dbdc9472d365d36da415b8 +!! source digest: sha256:a1337e83c6332c7cfddb1c2c787bcc88bf6bb309e9c45ff10492d36ff8c74fe3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Currently the reservation is performed by adding reserved quantities on quants, From 4d718210357b9a6fa168c3da6e6d2c4758ad85d3 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 28 Apr 2025 16:12:40 +0000 Subject: [PATCH 030/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_available_to_promise_release Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_available_to_promise_release/ --- stock_available_to_promise_release/i18n/es.po | 22 +++++++++++++++++++ .../i18n/es_AR.po | 22 +++++++++++++++++++ stock_available_to_promise_release/i18n/fr.po | 22 +++++++++++++++++++ stock_available_to_promise_release/i18n/hr.po | 22 +++++++++++++++++++ stock_available_to_promise_release/i18n/it.po | 22 +++++++++++++++++++ 5 files changed, 110 insertions(+) diff --git a/stock_available_to_promise_release/i18n/es.po b/stock_available_to_promise_release/i18n/es.po index a2309506b01..027efd538a7 100644 --- a/stock_available_to_promise_release/i18n/es.po +++ b/stock_available_to_promise_release/i18n/es.po @@ -175,6 +175,15 @@ msgstr "" "más movimientos. Por ejemplo, si se añaden líneas en el pedido de cliente de " "origen, los nuevos movimientos se añadirán a una nueva entrega." +#. module: stock_available_to_promise_release +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "" +"If checked, unreleasing the delivery may create a new inverse internal " +"operation on the last done pulled transfer. Otherwise, you won't be able to " +"unrelease as soon as one of the pulled transfer is done" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_picking_type__unrelease_on_backorder msgid "" @@ -344,6 +353,12 @@ msgstr "Liberar asignaciones de transferencias" msgid "Release based on Available to Promise" msgstr "Lanzamiento basado en disponibilidad para prometer" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "Reverse done transfer on cancellation" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model,name:stock_available_to_promise_release.model_stock_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form @@ -399,6 +414,13 @@ msgstr "" "Los siguientes movimientos no se han publicado:\n" "%(move_names)s" +#. module: stock_available_to_promise_release +#. odoo-python +#: code:addons/stock_available_to_promise_release/models/stock_move.py:0 +#, python-format +msgid "The operation %(picking_names)s is done and cannot be returned" +msgstr "" + #. module: stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form msgid "The selected records will be released." diff --git a/stock_available_to_promise_release/i18n/es_AR.po b/stock_available_to_promise_release/i18n/es_AR.po index 7dfe4413025..a74583bdb21 100644 --- a/stock_available_to_promise_release/i18n/es_AR.po +++ b/stock_available_to_promise_release/i18n/es_AR.po @@ -174,6 +174,15 @@ msgid "" "new moves will be added to a new delivery." msgstr "" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "" +"If checked, unreleasing the delivery may create a new inverse internal " +"operation on the last done pulled transfer. Otherwise, you won't be able to " +"unrelease as soon as one of the pulled transfer is done" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_picking_type__unrelease_on_backorder msgid "" @@ -337,6 +346,12 @@ msgstr "Liberar Asignaciones de Transferencias" msgid "Release based on Available to Promise" msgstr "Liberación basada en Disponibilidad a Prometer" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "Reverse done transfer on cancellation" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model,name:stock_available_to_promise_release.model_stock_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form @@ -388,6 +403,13 @@ msgid "" "%(move_names)s" msgstr "" +#. module: stock_available_to_promise_release +#. odoo-python +#: code:addons/stock_available_to_promise_release/models/stock_move.py:0 +#, python-format +msgid "The operation %(picking_names)s is done and cannot be returned" +msgstr "" + #. module: stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form msgid "The selected records will be released." diff --git a/stock_available_to_promise_release/i18n/fr.po b/stock_available_to_promise_release/i18n/fr.po index f36bf4d5727..ec36be7baa5 100644 --- a/stock_available_to_promise_release/i18n/fr.po +++ b/stock_available_to_promise_release/i18n/fr.po @@ -175,6 +175,15 @@ msgstr "" "des lignes dans la commande de vente d'origine, les nouveaux mouvements " "seront ajoutés à une nouvelle livraison." +#. module: stock_available_to_promise_release +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "" +"If checked, unreleasing the delivery may create a new inverse internal " +"operation on the last done pulled transfer. Otherwise, you won't be able to " +"unrelease as soon as one of the pulled transfer is done" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_picking_type__unrelease_on_backorder msgid "" @@ -343,6 +352,12 @@ msgstr "" msgid "Release based on Available to Promise" msgstr "" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "Reverse done transfer on cancellation" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model,name:stock_available_to_promise_release.model_stock_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form @@ -398,6 +413,13 @@ msgstr "" "Les mouvements suivants ont été remis en attente de libération : \n" "%(move_names)s" +#. module: stock_available_to_promise_release +#. odoo-python +#: code:addons/stock_available_to_promise_release/models/stock_move.py:0 +#, python-format +msgid "The operation %(picking_names)s is done and cannot be returned" +msgstr "" + #. module: stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form msgid "The selected records will be released." diff --git a/stock_available_to_promise_release/i18n/hr.po b/stock_available_to_promise_release/i18n/hr.po index 6f011d613ce..910342ec56f 100644 --- a/stock_available_to_promise_release/i18n/hr.po +++ b/stock_available_to_promise_release/i18n/hr.po @@ -166,6 +166,15 @@ msgid "" "new moves will be added to a new delivery." msgstr "" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "" +"If checked, unreleasing the delivery may create a new inverse internal " +"operation on the last done pulled transfer. Otherwise, you won't be able to " +"unrelease as soon as one of the pulled transfer is done" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_picking_type__unrelease_on_backorder msgid "" @@ -329,6 +338,12 @@ msgstr "Otpusti alokacije prijenosa" msgid "Release based on Available to Promise" msgstr "Otpusti bazirano na raspoloživom za obećati" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "Reverse done transfer on cancellation" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model,name:stock_available_to_promise_release.model_stock_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form @@ -382,6 +397,13 @@ msgid "" "%(move_names)s" msgstr "" +#. module: stock_available_to_promise_release +#. odoo-python +#: code:addons/stock_available_to_promise_release/models/stock_move.py:0 +#, python-format +msgid "The operation %(picking_names)s is done and cannot be returned" +msgstr "" + #. module: stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form msgid "The selected records will be released." diff --git a/stock_available_to_promise_release/i18n/it.po b/stock_available_to_promise_release/i18n/it.po index cff64aef092..fccc6ec5f44 100644 --- a/stock_available_to_promise_release/i18n/it.po +++ b/stock_available_to_promise_release/i18n/it.po @@ -175,6 +175,15 @@ msgstr "" "nell'ordine di vendita originale, i nuovi movimenti verranno aggiunti a una " "nuova consegna." +#. module: stock_available_to_promise_release +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "" +"If checked, unreleasing the delivery may create a new inverse internal " +"operation on the last done pulled transfer. Otherwise, you won't be able to " +"unrelease as soon as one of the pulled transfer is done" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_picking_type__unrelease_on_backorder msgid "" @@ -345,6 +354,12 @@ msgstr "Rilascio assegnazioni trasferimenti" msgid "Release based on Available to Promise" msgstr "Rilascio in base alla disponibilità alle promesse" +#. module: stock_available_to_promise_release +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move +#: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move +msgid "Reverse done transfer on cancellation" +msgstr "" + #. module: stock_available_to_promise_release #: model:ir.model,name:stock_available_to_promise_release.model_stock_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form @@ -400,6 +415,13 @@ msgstr "" "I segenti movimenti sono stati trattenuti: \n" "%(move_names)s" +#. module: stock_available_to_promise_release +#. odoo-python +#: code:addons/stock_available_to_promise_release/models/stock_move.py:0 +#, python-format +msgid "The operation %(picking_names)s is done and cannot be returned" +msgstr "" + #. module: stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form msgid "The selected records will be released." From fd41b01d86ea88b34e2f0259fa27723edf4f1237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Thu, 17 Apr 2025 17:25:10 +0200 Subject: [PATCH 031/357] stock_storage_type: define 'Allow New Product' rules with conditions The 'Allow New Product' rules that were defined on storage capacity lines have been moved to a new data model `stock.storage.category.allow_new_product`. On these rules, conditions are set, and all of them have to be `True` in order to set the expected 'Allow New Product' value. The conditions are defined in another new data model (`stock.storage.category.allow_new_product.cond`), so they can be reused by different 'Allow New Product' rules. A condition can use different inputs to do its evaluation (product, package type, quant...), allowing a more advanced configuration than before. A `stock.storage.condition.mixin` has been added so both the new data model `stock.storage.category.allow_new_product.cond` and `stock.storage.location.sequence.cond` inherit from it. --- stock_storage_type/__manifest__.py | 5 +- .../demo/stock_storage_category.xml | 13 ++ ...torage_category_allow_new_product_cond.xml | 20 +++ .../demo/stock_storage_category_capacity.xml | 1 - .../migrations/16.0.2.0.0/post-migrate.py | 63 ++++++++ stock_storage_type/models/__init__.py | 4 +- stock_storage_type/models/stock_location.py | 117 ++++++-------- .../models/stock_package_type.py | 8 +- stock_storage_type/models/stock_quant.py | 149 ++++++++---------- .../models/stock_quant_package.py | 6 +- .../models/stock_storage_category.py | 120 +++++++++++++- ...tock_storage_category_allow_new_product.py | 31 ++++ ...storage_category_allow_new_product_cond.py | 138 ++++++++++++++++ .../models/stock_storage_category_capacity.py | 111 ------------- .../models/stock_storage_condition_mixin.py | 65 ++++++++ .../models/stock_storage_location_sequence.py | 15 +- .../stock_storage_location_sequence_cond.py | 45 +----- stock_storage_type/readme/CONFIGURATION.rst | 18 +-- stock_storage_type/readme/DESCRIPTION.rst | 46 ++---- .../security/ir.model.access.csv | 4 + stock_storage_type/tests/__init__.py | 1 + .../tests/test_auto_assign_storage_type.py | 2 +- .../tests/test_stock_location.py | 11 +- ...test_storage_category_allow_new_product.py | 111 +++++++++++++ stock_storage_type/tests/test_storage_type.py | 21 +-- .../tests/test_storage_type_move.py | 25 ++- .../test_storage_type_putaway_strategy.py | 27 +++- .../views/stock_package_type.xml | 6 - .../views/stock_storage_category.xml | 24 ++- ...torage_category_allow_new_product_cond.xml | 54 +++++++ .../views/stock_storage_category_capacity.xml | 18 --- .../views/storage_type_menus.xml | 7 + 32 files changed, 866 insertions(+), 420 deletions(-) create mode 100644 stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml create mode 100644 stock_storage_type/migrations/16.0.2.0.0/post-migrate.py create mode 100644 stock_storage_type/models/stock_storage_category_allow_new_product.py create mode 100644 stock_storage_type/models/stock_storage_category_allow_new_product_cond.py delete mode 100644 stock_storage_type/models/stock_storage_category_capacity.py create mode 100644 stock_storage_type/models/stock_storage_condition_mixin.py create mode 100644 stock_storage_type/tests/test_storage_category_allow_new_product.py create mode 100644 stock_storage_type/views/stock_storage_category_allow_new_product_cond.xml delete mode 100644 stock_storage_type/views/stock_storage_category_capacity.xml diff --git a/stock_storage_type/__manifest__.py b/stock_storage_type/__manifest__.py index 48b4a0e18ae..4e1510bfa12 100644 --- a/stock_storage_type/__manifest__.py +++ b/stock_storage_type/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Stock Storage Type", "summary": "Manage packages and locations storage types", - "version": "16.0.1.1.0", + "version": "16.0.2.0.0", "development_status": "Beta", "category": "Warehouse Management", "website": "https://github.com/OCA/wms", @@ -24,7 +24,7 @@ "views/product_template.xml", "views/stock_location.xml", "views/stock_storage_category.xml", - "views/stock_storage_category_capacity.xml", + "views/stock_storage_category_allow_new_product_cond.xml", "views/stock_package_level.xml", "views/stock_package_type.xml", "views/stock_storage_location_sequence.xml", @@ -33,6 +33,7 @@ ], "demo": [ "demo/stock_package_type.xml", + "demo/stock_storage_category_allow_new_product_cond.xml", "demo/stock_storage_category.xml", "demo/stock_storage_category_capacity.xml", "demo/product_packaging.xml", diff --git a/stock_storage_type/demo/stock_storage_category.xml b/stock_storage_type/demo/stock_storage_category.xml index 174b1166c17..503e24ce0ab 100644 --- a/stock_storage_type/demo/stock_storage_category.xml +++ b/stock_storage_type/demo/stock_storage_category.xml @@ -5,6 +5,19 @@ Pallets + + + + + empty + + Cardboxes diff --git a/stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml b/stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml new file mode 100644 index 00000000000..33fec54528d --- /dev/null +++ b/stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml @@ -0,0 +1,20 @@ + + + + + Package type is 'Pallets' + + + + + + diff --git a/stock_storage_type/demo/stock_storage_category_capacity.xml b/stock_storage_type/demo/stock_storage_category_capacity.xml index 5a3a536582f..f2fdaeee0b5 100644 --- a/stock_storage_type/demo/stock_storage_category_capacity.xml +++ b/stock_storage_type/demo/stock_storage_category_capacity.xml @@ -4,7 +4,6 @@ - empty .allow_new_product' values to " + "category allow_new_product rules..." + ) + query = """ + SELECT sscc.id, storage_category_id, sscc.allow_new_product, package_type_id + FROM stock_storage_category_capacity sscc + LEFT JOIN stock_storage_category ssc + ON sscc.storage_category_id = ssc.id + WHERE sscc.allow_new_product != ssc.allow_new_product; + """ + env.cr.execute(query) + capacities = env.cr.dictfetchall() + condition_model = env["stock.storage.category.allow_new_product.cond"] + for capacity in capacities: + _logger.info("row = %s", capacity) + package_type = env["stock.package.type"].browse(capacity["package_type_id"]) + package_type_name = package_type.name if package_type else "Any package type" + condition_name = f"[MIG] {package_type_name}" + condition = condition_model.search([("name", "=", condition_name)], limit=1) + if not condition: + if package_type: + code_snippet = f""" +result = False +if package_type and package_type.id == {package_type.id}: + result = True + """ + else: + code_snippet = """ +result = False +if not package_type: + result = True + """ + vals = { + "name": condition_name, + "code_snippet": code_snippet, + } + condition = condition_model.create(vals) + # Bind the condition with the category through a allow_new_product rule + category = env["stock.storage.category"].browse(capacity["storage_category_id"]) + vals = { + "allow_new_product": capacity["allow_new_product"], + "condition_ids": [fields.Command.link(condition.id)], + } + category.write({"allow_new_product_ids": [fields.Command.create(vals)]}) diff --git a/stock_storage_type/models/__init__.py b/stock_storage_type/models/__init__.py index ef4b4162a17..2c5f31919dd 100644 --- a/stock_storage_type/models/__init__.py +++ b/stock_storage_type/models/__init__.py @@ -5,8 +5,10 @@ stock_package_type, stock_quant, stock_quant_package, + stock_storage_condition_mixin, stock_storage_category, - stock_storage_category_capacity, + stock_storage_category_allow_new_product, + stock_storage_category_allow_new_product_cond, stock_storage_location_sequence, stock_storage_location_sequence_cond, ) diff --git a/stock_storage_type/models/stock_location.py b/stock_storage_type/models/stock_location.py index 9672dcce608..72d2de071cd 100644 --- a/stock_storage_type/models/stock_location.py +++ b/stock_storage_type/models/stock_location.py @@ -46,7 +46,7 @@ class StockLocation(models.Model): "Ordered Children Locations: when moved to this " "location, a suitable location will be searched in its children " "locations according to the restrictions defined on their " - "respective location storage types.", + "respective storage category.", ) package_type_putaway_sequence = fields.Integer( string="Putaway Sequence", @@ -64,7 +64,7 @@ class StockLocation(models.Model): help="technical field: True if the location is empty " "and there is no pending incoming products in the location. " " Computed only if the location needs to check for emptiness " - '(has an "only empty" location storage type).', + '(has an "only empty" policy).', recursive=True, ) # TODO: Maybe renaming these fields as there are already such fields @@ -158,7 +158,7 @@ def init(self): # pylint: disable=missing-return @api.depends( "usage", "computed_storage_category_id.allow_new_product", - "computed_storage_category_id.capacity_ids.allow_new_product", + "computed_storage_category_id.allow_new_product_ids.allow_new_product", ) def _compute_do_not_mix_lots(self): """ @@ -167,18 +167,16 @@ def _compute_do_not_mix_lots(self): - one of its Storage Capacities value """ for rec in self: + rules = rec.computed_storage_category_id.allow_new_product_ids rec.do_not_mix_lots = rec.usage == "internal" and ( - any( - storage_type.allow_new_product == "same_lot" - for storage_type in rec.computed_storage_category_id.capacity_ids - ) + any(rule.allow_new_product == "same_lot" for rule in rules) or rec.computed_storage_category_id.allow_new_product == "same_lot" ) @api.depends( "usage", "computed_storage_category_id.allow_new_product", - "computed_storage_category_id.capacity_ids.allow_new_product", + "computed_storage_category_id.allow_new_product_ids.allow_new_product", ) def _compute_only_empty(self): """ @@ -187,18 +185,16 @@ def _compute_only_empty(self): - one of its Storage Capacities value """ for rec in self: + rules = rec.computed_storage_category_id.allow_new_product_ids rec.only_empty = rec.usage == "internal" and ( - any( - storage_type.allow_new_product == "empty" - for storage_type in rec.computed_storage_category_id.capacity_ids - ) + any(rule.allow_new_product == "empty" for rule in rules) or rec.computed_storage_category_id.allow_new_product == "empty" ) @api.depends( "usage", "computed_storage_category_id.allow_new_product", - "computed_storage_category_id.capacity_ids.allow_new_product", + "computed_storage_category_id.allow_new_product_ids.allow_new_product", ) def _compute_do_not_mix_products(self): """ @@ -207,11 +203,9 @@ def _compute_do_not_mix_products(self): - one of its Storage Capacities value """ for rec in self: + rules = rec.computed_storage_category_id.allow_new_product_ids rec.do_not_mix_products = rec.usage == "internal" and ( - any( - storage_type.allow_new_product in ("same", "same_lot") - for storage_type in rec.computed_storage_category_id.capacity_ids - ) + any(rule.allow_new_product in ("same", "same_lot") for rule in rules) or rec.computed_storage_category_id.allow_new_product in ("same", "same_lot") ) @@ -513,30 +507,29 @@ def select_first_allowed_location(self, package_type, quants, products): allowed = self.select_allowed_locations(package_type, quants, products, limit=1) return allowed - def _domain_location_storage_type_constraints(self, package_type, quants, products): - """Compute the domain for the location storage type which match the package - storage type + def _domain_storage_category_constraints(self, package_type, quants, products): + """Compute the domain for the storage category which matches the package type. - This method also checks the "capacity" constraints (height and weight) + This method also checks the category constraints (height and weight) """ - # There can be multiple location storage types for a given + # There can be multiple storage capacities for a given # location, so we need to filter on the ones relative to the package # we consider. - Capacity = self.env["stock.storage.category.capacity"] - compatible_location_storage_types = Capacity.search( + Category = self.env["stock.storage.category"] + compatible_categories = Category.search( [("computed_location_ids", "in", self.ids)] ) - pertinent_loc_storagetype_domain = [ - ("id", "in", compatible_location_storage_types.ids), - ("package_type_id", "=", package_type.id), + pertinent_category_domain = [ + ("id", "in", compatible_categories.ids), + ("capacity_ids.package_type_id", "=", package_type.id), ] if quants.package_id.height: - pertinent_loc_storagetype_domain += [ + pertinent_category_domain += [ "|", - ("storage_category_id.max_height_in_m", "=", 0), + ("max_height_in_m", "=", 0), ( - "storage_category_id.max_height_in_m", + "max_height_in_m", ">=", quants.package_id.height_in_m, ), @@ -546,23 +539,23 @@ def _domain_location_storage_type_constraints(self, package_type, quants, produc or quants.package_id.estimated_pack_weight_kg ) if package_weight_kg: - pertinent_loc_storagetype_domain += [ + pertinent_category_domain += [ "|", - ("storage_category_id.max_weight_in_kg", "=", 0), - ("storage_category_id.max_weight_in_kg", ">=", package_weight_kg), + ("max_weight_in_kg", "=", 0), + ("max_weight_in_kg", ">=", package_weight_kg), ] _logger.debug( - "pertinent storage type domain: %s", pertinent_loc_storagetype_domain + "pertinent storage category domain: %s", pertinent_category_domain ) - return pertinent_loc_storagetype_domain + return pertinent_category_domain - def _allowed_locations_for_location_storage_types( - self, location_storage_types, quants, products + def _allowed_locations_for_storage_categories( + self, categories, quants, products, package_type ): valid_location_ids = set() - for loc_storage_type in location_storage_types: - location_domain = loc_storage_type._domain_location_storage_type( - self, quants, products + for category in categories: + location_domain = category._domain_location_storage_category( + self, quants, products, package_type ) _logger.debug("pertinent location domain: %s", location_domain) locations = self.search(location_domain) @@ -581,7 +574,7 @@ def _select_final_valid_putaway_locations(self, limit=None): return self[:limit] def select_allowed_locations(self, package_type, quants, products, limit=None): - """Filter allowed locations for a storage type + """Filter allowed locations for a package type. ``self`` contains locations already ordered according to the putaway strategy, so beware of the return that must keep the @@ -589,45 +582,31 @@ def select_allowed_locations(self, package_type, quants, products, limit=None): """ # We have package who may be placed in a stock.location # - # 1. On the stock.location there are location_storage_type and on the - # packages there are package_storage_type. Between both, there's a m2m - # who says which package ST can be placed in which location ST + # 1. On the location there is a storage category that defines which + # package type is allowed. This is given by the storage capacities. # - # 2. On a location_ST there are some additional restrictions: a - - # capacity (volume / height / weight) and b - properties (boolean + # 2. On a storage category there are some additional restrictions: + # a - capacity (volume / height / weight) and b - properties (boolean # flags: only empty, don't mix lots, don't mix products) - Capacity = self.env["stock.storage.category.capacity"] _logger.debug( - "select allowed location for package storage type %s (q=%s, p=%s)", + "select allowed location for package type %s (q=%s, p=%s)", package_type.name, quants, products.mapped("name"), ) - # 1: filter locations on compatible storage type - compatible_locations = self.search( - [ - ("id", "in", self.ids), - ( - "computed_storage_category_id.capacity_ids", - "in", - package_type.storage_category_capacity_ids.ids, - ), - ] - ) - pertinent_loc_s_t_domain = ( - compatible_locations._domain_location_storage_type_constraints( - package_type, quants, products - ) + # 1: filter pertinent storage categories + pertinent_category_domain = self._domain_storage_category_constraints( + package_type, quants, products ) - pertinent_loc_storage_types = Capacity.search(pertinent_loc_s_t_domain) + pertinent_categories = self.env["stock.storage.category"].search( + pertinent_category_domain + ) - # now loop over the pertinent location storage types (there should be + # now loop over the pertinent categories (there should be # few of them) and check for properties to find suitable locations - valid_locations = ( - compatible_locations._allowed_locations_for_location_storage_types( - pertinent_loc_storage_types, quants, products - ) + valid_locations = self._allowed_locations_for_storage_categories( + pertinent_categories, quants, products, package_type ) valid_locations = self._order_allowed_locations(valid_locations) diff --git a/stock_storage_type/models/stock_package_type.py b/stock_storage_type/models/stock_package_type.py index ab93b299c33..d099958cd71 100644 --- a/stock_storage_type/models/stock_package_type.py +++ b/stock_storage_type/models/stock_package_type.py @@ -16,7 +16,7 @@ class StockPackageType(models.Model): storage_type_message = fields.Html(compute="_compute_storage_type_message") height_required = fields.Boolean( string="Height required for packages", - help=("Height is mandatory for packages configured with this storage type."), + help=("Height is mandatory for packages configured with this package type."), default=False, ) barcode = fields.Char(copy=False) @@ -36,10 +36,10 @@ def _compute_storage_type_message(self): if sl == storage_locations[-1]: last = True formatted_storage_locations_msgs.append( - sl._format_package_storage_type_message(last=last) + sl._format_package_type_message(last=last) ) msg = _( - "When a package with storage type {name} is put away, the " + "When a package with type {name} is put away, the " "strategy will look for an allowed location in the " "following locations:

" "{message}

" @@ -56,7 +56,7 @@ def _compute_storage_type_message(self): msg = _( 'The "Put-Away sequence" ' "must be defined in order to put away packages using " - "this package storage type ({storage})." + "this package type ({storage})." ).format(storage=package_type.name) package_type.storage_type_message = msg diff --git a/stock_storage_type/models/stock_quant.py b/stock_storage_type/models/stock_quant.py index ce08ee4ef23..effebd99c38 100644 --- a/stock_storage_type/models/stock_quant.py +++ b/stock_storage_type/models/stock_quant.py @@ -30,7 +30,6 @@ def _check_storage_capacities(self): "Location {location}" ).format(storage=package_type.name, location=location.name) ) - allowed = False package_weight_kg = ( quant.package_id.pack_weight_in_kg or quant.package_id.estimated_pack_weight_kg @@ -47,94 +46,80 @@ def _check_storage_capacities(self): ) products_in_location = other_quants_in_location.mapped("product_id") lots_in_location = other_quants_in_location.mapped("lot_id") - capacity_fails = [] - for capacity in allowed_capacities: - # Check content constraints - if capacity.allow_new_product == "empty" and other_quants_in_location: - capacity_fails.append( - _( - "Storage Capacity {storage_capacity} is flagged " - "'only empty'" - " with other quants in location." - ).format(storage_capacity=capacity.display_name) - ) - continue - if capacity.allow_new_product == "same" and ( - len(package_products) > 1 - or len(products_in_location) >= 1 - and package_products != products_in_location - ): - capacity_fails.append( - _( - "Storage Capacity {storage_capacity} is flagged 'do not mix" - " products' but there are other products in " - "location." - ).format(storage_capacity=capacity.display_name) - ) - continue - if capacity.allow_new_product == "same_lot" and ( - len(package_lots) > 1 - or len(lots_in_location) >= 1 - and package_lots != lots_in_location - ): - capacity_fails.append( - _( - "Storage Capacity {storage_capacity} is flagged 'do not mix" - " lots' but there are other lots in " - "location." - ).format(storage_capacity=capacity.display_name) - ) - continue - # Check size constraint - if ( - capacity.storage_category_id.max_height_in_m - and quant.package_id.height_in_m - > capacity.storage_category_id.max_height_in_m - ): - capacity_fails.append( - _( - "Storage Category {storage_category} defines " - "max height of {max_h} but the package is bigger: " - "{height}." - ).format( - storage_category=capacity.storage_category_id.display_name, - max_h=capacity.storage_category_id.max_height_in_m, - height=quant.package_id.height_in_m, - ) - ) - continue - if ( - capacity.storage_category_id.max_weight_in_kg - and package_weight_kg - > capacity.storage_category_id.max_weight_in_kg - ): - capacity_fails.append( - _( - "Storage Category {storage_category} defines " - "max weight of {max_w} but the package is heavier: " - "{weight_kg}." - ).format( - storage_category=capacity.storage_category_id.display_name, - max_w=capacity.storage_category_id.max_weight_in_kg, - weight_kg=package_weight_kg, - ) - ) - continue - # If we get here, it means there is a location storage type - # allowing the package into the location - allowed = True - break - if not allowed: + error = None + category = location.computed_storage_category_id + allow_new_product = category.get_allow_new_product( + product=quant.product_id, + package_type=package_type, + package=quant.package_id, + quants=quant, + ) + # Check content constraints + if allow_new_product == "empty" and other_quants_in_location: + error = _( + "Storage Category {category} is flagged " + "'only empty' with other quants in location." + ).format(category=category.display_name) + elif allow_new_product == "same" and ( + len(package_products) > 1 + or len(products_in_location) >= 1 + and package_products != products_in_location + ): + error = _( + "Storage Category {category} is flagged 'do not mix" + " products' but there are other products in " + "location." + ).format(category=category.display_name) + elif allow_new_product == "same_lot" and ( + len(package_lots) > 1 + or len(lots_in_location) >= 1 + and package_lots != lots_in_location + ): + error = _( + "Storage Category {category} is flagged 'do not mix" + " lots' but there are other lots in " + "location." + ).format(category=category.display_name) + # Check size constraint + elif ( + category.max_height_in_m + and quant.package_id.height_in_m > category.max_height_in_m + ): + error = _( + "Storage Category {category} defines " + "max height of {max_h} but the package is bigger: " + "{height}." + ).format( + category=category.display_name, + max_h=category.max_height_in_m, + height=quant.package_id.height_in_m, + ) + elif ( + category.max_weight_in_kg + and package_weight_kg > category.max_weight_in_kg + ): + error = _( + "Storage Category {category} defines " + "max weight of {max_w} but the package is heavier: " + "{weight_kg}." + ).format( + category=category.display_name, + max_w=category.max_weight_in_kg, + weight_kg=package_weight_kg, + ) + # If we get here, it means there is a storage category + # allowing the package into the location + if error: raise ValidationError( _( "Package {package} is not allowed into location {location}," - " because there isn't any storage capacity that allows" - " package type {type} into it:\n\n{fails}" + " because there isn't any rules that allows" + " package type {type} into it:\n\n{error}" ).format( package=quant.package_id.name, location=location.complete_name, type=package_type.name, - fails="\n".join(capacity_fails), + error=error, ) ) diff --git a/stock_storage_type/models/stock_quant_package.py b/stock_storage_type/models/stock_quant_package.py index 3967e8ef59a..f7b642c7fad 100644 --- a/stock_storage_type/models/stock_quant_package.py +++ b/stock_storage_type/models/stock_quant_package.py @@ -51,8 +51,8 @@ def auto_assign_packaging(self): res = super().auto_assign_packaging() for package in self: if not package.package_type_id: - # if no storage type could be set by auto assign, - # fallback on the default product's storage type (if any) + # if no package type could be set by auto assign, + # fallback on the default product's package type (if any) package._sync_package_type_from_single_product() return res @@ -71,7 +71,7 @@ def write(self, vals): def _sync_package_type_from_packaging(self): for package in self: if package.package_type_id: - # Do not set package storage type for delivery packages + # Do not set package type for delivery packages # to not trigger constraint like height requirement # (we are delivering them, not storing them) continue diff --git a/stock_storage_type/models/stock_storage_category.py b/stock_storage_type/models/stock_storage_category.py index 63b794c38f5..cb69e592a60 100644 --- a/stock_storage_type/models/stock_storage_category.py +++ b/stock_storage_type/models/stock_storage_category.py @@ -15,6 +15,11 @@ class StockStorageCategory(models.Model): computed_location_ids = fields.One2many( comodel_name="stock.location", inverse_name="computed_storage_category_id" ) + allow_new_product_ids = fields.One2many( + comodel_name="stock.storage.category.allow_new_product", + inverse_name="storage_category_id", + string="Allow New Product Rules", + ) # TODO: Move these fields in another module ? max_height = fields.Float( @@ -51,7 +56,6 @@ class StockStorageCategory(models.Model): compute="_compute_max_weight_in_kg", store=True, ) - length_uom_id = fields.Many2one( # Same as product.packing "uom.uom", @@ -64,6 +68,10 @@ class StockStorageCategory(models.Model): "product.template" ]._get_length_uom_id_from_ir_config_parameter(), ) + has_restrictions = fields.Boolean( + compute="_compute_has_restrictions", + help="Technical: This is used to check if we need to display warning message", + ) _sql_constraints = [ ( @@ -92,3 +100,113 @@ def _compute_max_weight_in_kg(self): to_unit=uom_kg, round=False, ) + + @api.depends( + "allow_new_product", + "allow_new_product_ids.allow_new_product", + "max_height", + "max_weight", + ) + def _compute_has_restrictions(self): + """ + A storage category has restrictions when it: + - does not accept mixed products + - or does not accept mixed lots + - or do have a maximum height set on its category + - or do have a maximum weight set on its category + """ + for rec in self: + rec.has_restrictions = any( + [ + rec.allow_new_product != "mixed", + any( + rule.allow_new_product != "mixed" + for rule in rec.allow_new_product_ids + ), + rec.max_height, + rec.max_weight, + ] + ) + + def _get_product_location_domain(self, products): + """ + Helper to get products location domain + """ + return [ + "|", + # Ideally, we would like a domain which is a strict comparison: + # if we do not mix products, we should be able to filter on == + # product.id. Here, if we can create a move for product B and + # set it's destination in a location already used by product A, + # then all the new moves for product B will be allowed in the + # location. + ("location_will_contain_product_ids", "in", products.ids), + ("location_will_contain_product_ids", "=", False), + ] + + def _domain_location_storage_category( + self, candidate_locations, quants, products, package_type + ): + """ + Compute a domain which applies the constraint of the + Stock Storage Category to select locations among candidate locations. + """ + self.ensure_one() + location_domain = [ + ("id", "in", candidate_locations.ids), + ("computed_storage_category_id", "in", self.ids), + ] + # Build the domain using the 'allow_new_product' field + allow_new_product = self.get_allow_new_product( + product=products, + package_type=package_type, + package=quants.package_id, + quants=quants, + ) + if allow_new_product == "empty": + location_domain.append(("location_is_empty", "=", True)) + elif allow_new_product == "same": + location_domain += self._get_product_location_domain(products) + elif allow_new_product == "same_lot": + lots = quants.mapped("lot_id") + # As same lot should filter also on same product + location_domain += self._get_product_location_domain(products) + location_domain += [ + "|", + # same comment as for the products + ("location_will_contain_lot_ids", "in", lots.ids), + ("location_will_contain_lot_ids", "=", False), + ] + return location_domain + + def get_allow_new_product( + self, + product, + package_type=None, + package=None, + quants=None, + ): + """Return the `allow_new_product` option value. + + It first evaluates the conditions based on different criteria, and if no + value can be found among them it fallbacks on the category option value. + """ + self.ensure_one() + for rule in self.allow_new_product_ids: + res = True + for condition in rule.condition_ids: + res = condition.evaluate( + self, + product, + package_type, + package, + quants, + ) + if not res: + # Fallback on category option value + return self.allow_new_product + # All conditions are matching + if res: + return rule.allow_new_product + # Fallback on category option value + return self.allow_new_product diff --git a/stock_storage_type/models/stock_storage_category_allow_new_product.py b/stock_storage_type/models/stock_storage_category_allow_new_product.py new file mode 100644 index 00000000000..fa2f1ac004f --- /dev/null +++ b/stock_storage_type/models/stock_storage_category_allow_new_product.py @@ -0,0 +1,31 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields, models + + +class StockStorageCategoryAllowNewProduct(models.Model): + _name = "stock.storage.category.allow_new_product" + _description = "Storage Category Allow New Product Rule" + _order = "storage_category_id, sequence" + + def _selection_allow_new_product(self): + return self.env["stock.storage.category"]._fields["allow_new_product"].selection + + storage_category_id = fields.Many2one( + comodel_name="stock.storage.category", + ondelete="cascade", + required=True, + index=True, + ) + condition_ids = fields.Many2many( + comodel_name="stock.storage.category.allow_new_product.cond", + relation="stock_storage_category_allow_new_product_cond_rel", + string="Conditions", + required=True, + help="All conditions have to match to apply the Allow New Product policy.", + ) + allow_new_product = fields.Selection( + selection=_selection_allow_new_product, default="mixed", required=True + ) + sequence = fields.Integer(index=True) diff --git a/stock_storage_type/models/stock_storage_category_allow_new_product_cond.py b/stock_storage_type/models/stock_storage_category_allow_new_product_cond.py new file mode 100644 index 00000000000..50a105c9b1e --- /dev/null +++ b/stock_storage_type/models/stock_storage_category_allow_new_product_cond.py @@ -0,0 +1,138 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +import logging + +from odoo import _, exceptions, models +from odoo.tools import safe_eval + +_logger = logging.getLogger(__name__) + + +class StockStorageCategoryAllowNewProductCond(models.Model): + _inherit = "stock.storage.condition.mixin" + _name = "stock.storage.category.allow_new_product.cond" + _description = "Stock Storage Category Allow New Product Condition" + + _sql_constraints = [ + ( + "name", + "EXCLUDE (name WITH =) WHERE (active = True)", + "Storage Category Allow New Product Condition name must be unique", + ) + ] + + def _default_code_snippet_docs(self): + return """ + Available vars: + * condition (recordset) + * storage_category (recordset) + * product (recordset) + * package_type (recordset) + * package (recordset) + * quants (recordset) + * env + * datetime + * dateutil + * time + * user + * exceptions + + Must initialize a boolean 'result' variable set to True when condition is met + + """ + + def _get_code_snippet_eval_context( + self, + storage_category, + product, + package_type, + package, + quants, + ): + """Prepare the context used when evaluating python code + + :returns: dict -- evaluation context given to safe_eval + """ + self.ensure_one() + return { + "env": self.env, + "user": self.env.user, + "condition": self, + "storage_category": storage_category, + "product": product, + "package_type": package_type, + "package": package, + "quants": quants, + "datetime": safe_eval.datetime, + "dateutil": safe_eval.dateutil, + "time": safe_eval.time, + "exceptions": safe_eval.wrap_module( + exceptions, ["UserError", "ValidationError"] + ), + } + + def _exec_code( + self, + storage_category, + product, + package_type, + package, + quants, + ): + self.ensure_one() + if not self._code_snippet_valued(): + return False + eval_ctx = self._get_code_snippet_eval_context( + storage_category, + product, + package_type, + package, + quants, + ) + snippet = self.code_snippet + safe_eval.safe_eval(snippet, eval_ctx, mode="exec", nocopy=True) + result = eval_ctx.get("result") + if not isinstance(result, bool): + raise exceptions.UserError( + _("code_snippet should return boolean value into `result` variable.") + ) + if not result: + _logger.debug( + "Condition %s not met:\n" + "* storage_category: %s\n" + "* product: %s\n" + "* package_type: %s\n" + "* package: %s\n" + "* quants: %s\n" + % ( + self.name, + storage_category.ids, + package_type and package_type.id or None, + package and package.id or None, + product.id, + quants and quants.ids or None, + ) + ) + return result + + def evaluate( + self, + storage_category, + product, + package_type, + package, + quants, + ): + self.ensure_one() + if self.condition_type == "code": + return self._exec_code( + storage_category, + product, + package_type, + package, + quants, + ) + condition_type = self.condition_type + raise exceptions.UserError( + _(f"Not able to evaluate condition of type {condition_type}") + ) diff --git a/stock_storage_type/models/stock_storage_category_capacity.py b/stock_storage_type/models/stock_storage_category_capacity.py deleted file mode 100644 index e007d398bf1..00000000000 --- a/stock_storage_type/models/stock_storage_category_capacity.py +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright 2022 ACSONE SA -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -from odoo import _, api, fields, models - - -class StorageCategoryProductCapacity(models.Model): - - _inherit = "stock.storage.category.capacity" - - allow_new_product = fields.Selection( - selection=[ - ("empty", "If the location is empty"), - ("same", "If all products are same"), - ("mixed", "Allow mixed products"), - ("same_lot", "If all lots are the same"), - ], - default="mixed", - required=True, - ) - computed_location_ids = fields.One2many( - comodel_name="stock.location", - related="storage_category_id.computed_location_ids", - ) - has_restrictions = fields.Boolean( - compute="_compute_has_restrictions", - help="Technical: This is used to check if we need to display warning message", - ) - - @api.model - def _get_display_name_attributes(self): - """ - Adds the storage capacity attributes to compose the display name - """ - attributes = super()._get_display_name_attributes() - value = self._fields["allow_new_product"].convert_to_export( - self.allow_new_product, self - ) - attributes.append(_("Allow New Product: ") + value) - return attributes - - @api.model - def _compute_display_name_depends(self): - depends = super()._compute_display_name_depends() - depends.append("allow_new_product") - return depends - - @api.depends( - "allow_new_product", - "storage_category_id.max_height", - "storage_category_id.max_weight", - ) - def _compute_has_restrictions(self): - """ - A storage capacity has restrictions when it: - - does not accept mixed products - - or does not accept mixed lots - - or do have a maximum height set on its category - - or do have a maximum weight set on its category - """ - for capacity in self: - capacity.has_restrictions = any( - [ - capacity.allow_new_product != "mixed", - capacity.storage_category_id.max_height, - capacity.storage_category_id.max_weight, - ] - ) - - def _get_product_location_domain(self, products): - """ - Helper to get products location domain - """ - return [ - "|", - # Ideally, we would like a domain which is a strict comparison: - # if we do not mix products, we should be able to filter on == - # product.id. Here, if we can create a move for product B and - # set it's destination in a location already used by product A, - # then all the new moves for product B will be allowed in the - # location. - ("location_will_contain_product_ids", "in", products.ids), - ("location_will_contain_product_ids", "=", False), - ] - - def _domain_location_storage_type(self, candidate_locations, quants, products): - """ - Compute a domain which applies the constraint of the - Stock Storage Category Capacities to select locations among candidate - locations. - """ - self.ensure_one() - location_domain = [ - ("id", "in", candidate_locations.ids), - ("computed_storage_category_id.capacity_ids", "in", self.ids), - ] - # Build the domain using the 'allow_new_product' field - if self.allow_new_product == "empty": - location_domain.append(("location_is_empty", "=", True)) - elif self.allow_new_product == "same": - location_domain += self._get_product_location_domain(products) - elif self.allow_new_product == "same_lot": - lots = quants.mapped("lot_id") - # As same lot should filter also on same product - location_domain += self._get_product_location_domain(products) - location_domain += [ - "|", - # same comment as for the products - ("location_will_contain_lot_ids", "in", lots.ids), - ("location_will_contain_lot_ids", "=", False), - ] - return location_domain diff --git a/stock_storage_type/models/stock_storage_condition_mixin.py b/stock_storage_type/models/stock_storage_condition_mixin.py new file mode 100644 index 00000000000..aa7b7d11e3c --- /dev/null +++ b/stock_storage_type/models/stock_storage_condition_mixin.py @@ -0,0 +1,65 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +import textwrap + +from odoo import _, api, exceptions, fields, models + + +class StockStorageConditionMixin(models.AbstractModel): + _name = "stock.storage.condition.mixin" + _description = "Mixin to implement storage condition." + + name = fields.Char(required=True) + condition_type = fields.Selection( + selection=[("code", "Execute code")], default="code", required=True + ) + code_snippet = fields.Text(required=True) + code_snippet_docs = fields.Text( + compute="_compute_code_snippet_docs", + default=lambda self: self._default_code_snippet_docs(), + ) + active = fields.Boolean(default=True) + + @api.constrains("condition_type", "code_snippet") + def _check_condition_type_code(self): + for rec in self.filtered(lambda c: c.condition_type == "code"): + if not rec._code_snippet_valued(): + raise exceptions.UserError( + _( + "Condition type is set to `Code`: you must provide a piece of code" + ) + ) + + def _code_snippet_valued(self): + self.ensure_one() + snippet = self.code_snippet or "" + return bool( + [ + not line.startswith("#") + for line in (snippet.splitlines()) + if line.strip("") + ] + ) + + def _compute_code_snippet_docs(self): + for rec in self: + rec.code_snippet_docs = textwrap.dedent(rec._default_code_snippet_docs()) + + def _default_code_snippet_docs(self): + """Return the documentation (e.g. available variables) for `code_snippet`.""" + raise NotImplementedError + + def _get_code_snippet_eval_context(self, *args, **kwargs): + """Prepare the context used when evaluating python code + + :returns: dict -- evaluation context given to safe_eval + """ + raise NotImplementedError + + def _exec_code(self, *args, **kwargs): + raise NotImplementedError + + def evaluate(self, *args, **kwargs): + """Evaluate and return the result of the condition.""" + raise NotImplementedError diff --git a/stock_storage_type/models/stock_storage_location_sequence.py b/stock_storage_type/models/stock_storage_location_sequence.py index f789317c1f8..1dabc98d14a 100644 --- a/stock_storage_type/models/stock_storage_location_sequence.py +++ b/stock_storage_type/models/stock_storage_location_sequence.py @@ -6,7 +6,7 @@ class StockStorageLocationSequence(models.Model): _name = "stock.storage.location.sequence" - _description = "Sequence of locations to put-away the package storage type" + _description = "Sequence of locations to put-away the package type" _order = "sequence" package_type_id = fields.Many2one("stock.package.type", required=True) @@ -22,9 +22,10 @@ class StockStorageLocationSequence(models.Model): string="Conditions", comodel_name="stock.storage.location.sequence.cond", relation="stock_location_sequence_cond_rel", + help="All conditions have to match to apply the put-away strategy.", ) - def _format_package_storage_type_message(self, last=False): + def _format_package_type_message(self, last=False): self.ensure_one() # TODO improve ugly code type_matching_locations = self.location_id.get_storage_locations().filtered( @@ -47,25 +48,25 @@ def _format_package_storage_type_message(self, last=False): ) if last: # If last, we want to check if restrictions are defined on - # location storage types accepting this package storage type + # capacities accepting this package type # TODO improve ugly code capacities = type_matching_locations.mapped( "computed_storage_category_id.capacity_ids" ).filtered( lambda lst, package_type=self.package_type_id: package_type == lst.package_type_id - and not lst.has_restrictions + and not lst.storage_category_id.has_restrictions ) if not capacities: msg = _( ' * {location} (WARNING: ' - "restrictions are active on location storage types " - "matching this package storage type)" + "restrictions are active on storage categories " + "matching this package type)" ).format(location=self.location_id.name) else: msg = _( ' * {location} ' - "(WARNING: no suitable location matching storage type)" + "(WARNING: no suitable location matching package type)" ).format(location=self.location_id.name) return msg diff --git a/stock_storage_type/models/stock_storage_location_sequence_cond.py b/stock_storage_type/models/stock_storage_location_sequence_cond.py index 4a66115f119..f155c2048db 100644 --- a/stock_storage_type/models/stock_storage_location_sequence_cond.py +++ b/stock_storage_type/models/stock_storage_location_sequence_cond.py @@ -1,34 +1,18 @@ # Copyright 2022 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging -import textwrap -from odoo import _, api, exceptions, fields, models +from odoo import _, exceptions, models from odoo.tools import safe_eval _logger = logging.getLogger(__name__) class StockStorageLocationSequenceCond(models.Model): - + _inherit = "stock.storage.condition.mixin" _name = "stock.storage.location.sequence.cond" _description = "Stock Storage Location Sequence Condition" - name = fields.Char(required=True) - - condition_type = fields.Selection( - selection=[("code", "Execute code")], default="code", required=True - ) - code_snippet = fields.Text(required=True) - code_snippet_docs = fields.Text( - compute="_compute_code_snippet_docs", - default=lambda self: self._default_code_snippet_docs(), - ) - - active = fields.Boolean( - default=True, - ) - _sql_constraints = [ ( "name", @@ -37,20 +21,6 @@ class StockStorageLocationSequenceCond(models.Model): ) ] - def _compute_code_snippet_docs(self): - for rec in self: - rec.code_snippet_docs = textwrap.dedent(rec._default_code_snippet_docs()) - - @api.constrains("condition_type", "code_snippet") - def _check_condition_type_code(self): - for rec in self.filtered(lambda c: c.condition_type == "code"): - if not rec._code_snippet_valued(): - raise exceptions.UserError( - _( - "Condition type is set to `Code`: you must provide a piece of code" - ) - ) - def _default_code_snippet_docs(self): return """ Available vars: @@ -124,17 +94,6 @@ def _exec_code(self, storage_location_sequence, putaway_location, quant, product ) return result - def _code_snippet_valued(self): - self.ensure_one() - snippet = self.code_snippet or "" - return bool( - [ - not line.startswith("#") - for line in (snippet.splitlines()) - if line.strip("") - ] - ) - def evaluate(self, storage_location_sequence, putaway_location, quant, product): self.ensure_one() if self.condition_type == "code": diff --git a/stock_storage_type/readme/CONFIGURATION.rst b/stock_storage_type/readme/CONFIGURATION.rst index 00a0c3f399c..b16e7a780fd 100644 --- a/stock_storage_type/readme/CONFIGURATION.rst +++ b/stock_storage_type/readme/CONFIGURATION.rst @@ -1,11 +1,11 @@ -Got to "Inventory > Settings > Storage Types", to define Package Storage Types -and Location Storage Types. +Go to "Inventory > Settings > Package Types" and +"Inventory > Settings > Storage Categories", to define Package Types and Storage +Categories. -Package Storage Type can be defined on Product Packaging form view from the -product form view. +Package Type can be set on Product and Product Packaging. -Location Storage Type can be added to any stock location and will be computed -automatically as Allowed Locations Storage Types on said stock location's +Storage Category can be added to any stock location and will be computed +automatically as Allowed Storage Category on said stock location's children location. @@ -13,16 +13,16 @@ children location. On stock locations, you can define a "Pack put-away strategy" as "Ordered bins", so that any move, having this locations as its destination, will be put-away -on a children location, according to the restrictions from storage types. +on a children location, according to the restrictions from package types. - Put-away sequence -For any package storage types, you must define a Put-away sequence (i.e. stock +For any package types, you must define a Put-away sequence (i.e. stock location to search) where such a package is allowed to be put-away. Locations will be processed sequentially and the first one having an allowed child location (according to restrictions) will be used to put away. -A good practice here, is to set a location accepting this storage type without +A good practice here, is to set a location accepting this package type without any restriction as the last location in the sequence, to act as a fallback if no other location could be found before. diff --git a/stock_storage_type/readme/DESCRIPTION.rst b/stock_storage_type/readme/DESCRIPTION.rst index bd8d800bb2a..ecd00d730a4 100644 --- a/stock_storage_type/readme/DESCRIPTION.rst +++ b/stock_storage_type/readme/DESCRIPTION.rst @@ -1,51 +1,33 @@ -This module introduces two new models in order to manage stock moves with - packages according to the packaging and stock location properties. +This module extends package types Odoo feature in order to better manage stock +moves with packages according to the packaging and stock location properties +(like height, weight or any customized conditions). -* Stock package storage type (`stock.package.storage.type`) +Moreover, this module implements "package type put-away strategy" in order to +compute a put-away location using package types. - This model is linked to product.packaging and defines the type of storage - related to a specific packaging. - -* Stock location storage type (`stock.location.storage.type`) - - This models is linked to stock.location and defines the types of storage - that are allowed for a specific location. - -Therefore a Stock location storage type can include different Stock package -storage type in order to validate the destination of a move with package into a -stock location. -Moreover Stock location storage type can include product, size or lot -restrictions for the stock locations it's defined on, so that a move with -package will only be allowed if it doesn't violate the restrictions defined -(cf stock_location_storage_type_strategy). - -Moreover, this module implements "storage type put-away strategy" in order to compute a -put-away location using storage types. - -The standard put-away strategy is applied *before* the storage type put-away +The standard put-away strategy is applied *before* the package type put-away strategy as the former relies on product or product category and the latter relies on stock packages. -In other words, when a move is assigned, Odoo standard put-away strategy will be +In other words, when a move is reserved, Odoo standard put-away strategy will be applied to compute a new destination on the stock move lines, according to the product. -After this first "put-away computation", the "storage type" put-away strategy -is applied, if the reserved quant is linked to a package defining a package -storage type. +After this first "put-away computation", the "package type" put-away strategy +is applied, if the reserved quant is linked to a package defining a package type. -Storage locations linked to the package storage are processed sequentially, if +Storage locations linked to the package type are processed sequentially, if said storage location is a child of the move line's destination location (i.e either the put-away location or the move's destination location). -For each location, their packs storage strategy is applied as well as the -restrictions defined on the stock location storage types. +For each location, their package type strategy is applied as well as the +restrictions defined on the storage category. If no suitable location is found, the next location in the sequence will be searched and so on. -For the packs putaway strategy "none", the location is considered as is. For +For the package type putaway strategy "None", the location is considered as is. For the "ordered children" strategy, children locations are sorted by first by max height which is a physical constraint to respect, then pack putaway sequence which allow to favor for example some level or corridor, and finally by name. At the end, if found location is not the same as the original destination location, -the putaway strategies are applied (e.g.: A "none" pack putaway strategy is set on +the putaway strategies are applied (e.g.: A "None" pack putaway strategy is set on computed location and a putaway rule exists on that one). diff --git a/stock_storage_type/security/ir.model.access.csv b/stock_storage_type/security/ir.model.access.csv index ed6a03817a1..7fa2b5e7312 100644 --- a/stock_storage_type/security/ir.model.access.csv +++ b/stock_storage_type/security/ir.model.access.csv @@ -3,3 +3,7 @@ access_stock_storage_location_sequence_user,access_stock_storage_location_sequen access_stock_storage_location_sequence_manager,access_stock_storage_location_sequence_manager,model_stock_storage_location_sequence,stock.group_stock_manager,1,1,1,1 access_stock_storage_location_sequence_cond_user,access_stock_storage_location_sequence_cond_user,model_stock_storage_location_sequence_cond,base.group_user,1,0,0,0 access_stock_storage_location_sequence_cond_manager,access_stock_storage_location_sequence_cond_manager,model_stock_storage_location_sequence_cond,stock.group_stock_manager,1,1,1,1 +access_stock_storage_category_allow_new_product_user,access_stock_storage_category_allow_new_product_user,model_stock_storage_category_allow_new_product,base.group_user,1,0,0,0 +access_stock_storage_category_allow_new_product_manager,access_stock_storage_category_allow_new_product_manager,model_stock_storage_category_allow_new_product,stock.group_stock_manager,1,1,1,1 +access_stock_storage_category_allow_new_product_cond_user,access_stock_storage_category_allow_new_product_cond_user,model_stock_storage_category_allow_new_product_cond,base.group_user,1,0,0,0 +access_stock_storage_category_allow_new_product_cond_manager,access_stock_storage_category_allow_new_product_cond_manager,model_stock_storage_category_allow_new_product_cond,stock.group_stock_manager,1,1,1,1 diff --git a/stock_storage_type/tests/__init__.py b/stock_storage_type/tests/__init__.py index 06655c55be3..ba7aa132776 100644 --- a/stock_storage_type/tests/__init__.py +++ b/stock_storage_type/tests/__init__.py @@ -6,4 +6,5 @@ test_storage_type, test_storage_type_move, test_storage_type_putaway_strategy, + test_storage_category_allow_new_product, ) diff --git a/stock_storage_type/tests/test_auto_assign_storage_type.py b/stock_storage_type/tests/test_auto_assign_storage_type.py index bd83034e14a..f80562ca2af 100644 --- a/stock_storage_type/tests/test_auto_assign_storage_type.py +++ b/stock_storage_type/tests/test_auto_assign_storage_type.py @@ -19,7 +19,7 @@ def setUpClass(cls): def test_auto_assign_package_storage_type_without_packaging_id(self): """Packages without `packaging_id` are internal packages and they are intended to be stored in the warehouse. - On such packages storage type is automatically defined. + On such packages, a package type is automatically defined. """ package = self.env["stock.quant.package"].create( {"name": "TEST", "product_packaging_id": self.product_packaging.id} diff --git a/stock_storage_type/tests/test_stock_location.py b/stock_storage_type/tests/test_stock_location.py index 370f3295d95..6381ee18195 100644 --- a/stock_storage_type/tests/test_stock_location.py +++ b/stock_storage_type/tests/test_stock_location.py @@ -50,7 +50,7 @@ def test_get_ordered_leaf_locations(self): | self.pallets_reserve_bin_4_location ).ids, ) - # Set the max_height on pallets storage type higher than the others + # Set the max_height on pallets storage category higher than the others self.pallets_location_storage_type.storage_category_id.max_height = 2 self.cardboxes_location_storage_type.storage_category_id.max_height = 1 ordered_locations = sublocation.get_storage_locations(self.product) @@ -71,7 +71,7 @@ def test_get_ordered_leaf_locations(self): | self.pallets_reserve_bin_4_location ).ids, ) - # Set the max_height on cardboxes storage type higher than the others + # Set the max_height on cardboxes storage category higher than the others self.pallets_location_storage_type.storage_category_id.max_height = 1 self.cardboxes_location_storage_type.storage_category_id.max_height = 2 ordered_locations = sublocation.get_storage_locations(self.product) @@ -283,11 +283,12 @@ def test_location_is_empty(self): self._update_qty_in_location(location, self.product, 10) self.assertFalse(location.location_is_empty) - # When the location has no "only_empty" storage type, we don't + # When the location has no "only_empty" rule, we don't # care about if it is empty or not, we keep it as True so we # can always put things inside. Not computing it prevents # useless race conditions on concurrent writes. - location.computed_storage_category_id.capacity_ids.filtered( - lambda c: c.allow_new_product == "empty" + category = location.computed_storage_category_id + category.allow_new_product_ids.filtered( + lambda rule: rule.allow_new_product == "empty" ).allow_new_product = "mixed" self.assertTrue(location.location_is_empty) diff --git a/stock_storage_type/tests/test_storage_category_allow_new_product.py b/stock_storage_type/tests/test_storage_category_allow_new_product.py new file mode 100644 index 00000000000..6a890113783 --- /dev/null +++ b/stock_storage_type/tests/test_storage_category_allow_new_product.py @@ -0,0 +1,111 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from .common import TestStorageTypeCommon + + +class TestStorageCategoryAllowNewProduct(TestStorageTypeCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.areas.write({"pack_putaway_strategy": "ordered_locations"}) + cls.category = cls.pallets_location_storage_type.storage_category_id + # Configure the rule matching Pallets to allow the same product on locations + cls.category.allow_new_product_ids.allow_new_product = "same" + + def test_storage_category_allow_new_product(self): + self.category.allow_new_product = "empty" + self.assertEqual(self.category.get_allow_new_product(self.product), "empty") + self.category.allow_new_product = "same_lot" + self.assertEqual(self.category.get_allow_new_product(self.product), "same_lot") + # Create a quant with a package of type Pallet to check the + # allow_new_product rule result + package_type_pallets = self.env.ref( + "stock_storage_type.package_storage_type_pallets" + ) + package = self.env["stock.quant.package"].create( + { + "name": "TEST PKG", + "package_type_id": package_type_pallets.id, + } + ) + self.env["stock.quant"]._update_available_quantity( + self.product, + self.pallets_bin_2_location, + 1.0, + package_id=package, + ) + quant = self.env["stock.quant"].search( + [ + ("location_id", "=", self.pallets_bin_2_location.id), + ("product_id", "=", self.product.id), + ("package_id", "=", package.id), + ] + ) + self.assertEqual( + self.category.get_allow_new_product( + self.product, + quants=quant, + package_type=package_type_pallets, + package=package, + ), + "same", + ) + + def test_storage_strategy_with_allow_new_product_rule(self): + # Set pallets location type as only empty, while it also has a rule + # that will force the 'allow_new_product' to 'same' + self.pallets_location_storage_type.storage_category_id.write( + {"allow_new_product": "empty"} + ) + # Create picking + in_picking = self.env["stock.picking"].create( + { + "picking_type_id": self.receipts_picking_type.id, + "location_id": self.suppliers_location.id, + "location_dest_id": self.input_location.id, + "move_ids": [ + ( + 0, + 0, + { + "name": self.product.name, + "location_id": self.suppliers_location.id, + "location_dest_id": self.input_location.id, + "product_id": self.product.id, + "product_uom_qty": 96.0, + "product_uom": self.product.uom_id.id, + }, + ) + ], + } + ) + # Mark as todo + in_picking.action_confirm() + # Put in pack + in_picking.move_line_ids.qty_done = 48.0 + first_package = in_picking.action_put_in_pack() + # Ensure packaging is set properly on pack + first_package.product_packaging_id = self.product_pallet_product_packaging + # Put in pack again + ml_without_package = in_picking.move_line_ids.filtered( + lambda ml: not ml.result_package_id + ) + ml_without_package.qty_done = 48.0 + second_pack = in_picking.action_put_in_pack() + # Ensure packaging is set properly on pack + second_pack.product_packaging_id = self.product_pallet_product_packaging + + # Validate picking + in_picking.button_validate() + # Assign internal picking + int_picking = in_picking.move_ids.move_dest_ids.picking_id + int_picking.action_assign() + self.assertEqual(int_picking.location_dest_id, self.stock_location) + self.assertEqual( + int_picking.move_ids.mapped("location_dest_id"), self.stock_location + ) + # First & second move lines goes into pallets bin 1, as forced by the rule + self.assertEqual( + int_picking.move_line_ids.mapped("location_dest_id"), + self.pallets_bin_1_location, + ) diff --git a/stock_storage_type/tests/test_storage_type.py b/stock_storage_type/tests/test_storage_type.py index a7747c71eda..aa6be654e5e 100644 --- a/stock_storage_type/tests/test_storage_type.py +++ b/stock_storage_type/tests/test_storage_type.py @@ -37,7 +37,7 @@ def setUpClass(cls): ) def test_location_allowed_storage_types(self): - # As cardboxes location storage type is defined on parent stock + # As cardboxes capacity is defined on parent stock # location_storage_type_ids self.assertEqual( self.cardboxes_stock.computed_storage_category_id.capacity_ids, @@ -89,7 +89,7 @@ def test_location_allowed_storage_types(self): self.cardboxes_location_storage_type, ) # If I create a child bin on cardboxes bin 1, it will use the first - # parent's storage type + # parent's capacity bin_1_child = self.env["stock.location"].create( {"name": "Carboxes bin 1 child", "location_id": self.cardboxes_bin_1.id} ) @@ -163,16 +163,23 @@ def test_package_message(self): Test for the message displayed on Stock Package Type forms """ pallets = self.env.ref("stock_storage_type.package_storage_type_pallets") - message = "When a package with storage type Pallets is put away, the " + category = pallets.storage_category_capacity_ids.storage_category_id + message = "When a package with type Pallets is put away, the " message += "strategy will look for an allowed location in the " message += "following locations:" self.assertIn(message, pallets.storage_type_message) + category.allow_new_product_ids.allow_new_product = "empty" + pallets._compute_storage_type_message() message = ( "Pallets reserve storage area (WARNING: restrictions are active on " - "location storage types matching this package storage type)" + "storage categories matching this package type)" ) + self.assertIn(message, pallets.storage_type_message) + category.allow_new_product_ids.allow_new_product = "mixed" + pallets._compute_storage_type_message() + message = "Pallets reserve storage area (Ordered Children Locations)" self.assertIn(message, pallets.storage_type_message) def test_sequence_to_location_menu(self): @@ -185,9 +192,3 @@ def test_sequence_to_location_menu(self): ), action["domain"], ) - - def test_storage_capacity_display(self): - self.assertEqual( - self.cardboxes_stock.computed_storage_category_id.capacity_ids.display_name, - "Cardboxes x 1.0 (Package: Cardboxes - Allow New Product: Allow mixed products)", - ) diff --git a/stock_storage_type/tests/test_storage_type_move.py b/stock_storage_type/tests/test_storage_type_move.py index 86e5d1aa7b7..1915122a3a6 100644 --- a/stock_storage_type/tests/test_storage_type_move.py +++ b/stock_storage_type/tests/test_storage_type_move.py @@ -38,28 +38,33 @@ def _test_confirmed_move(self, product=None): return move_to_assign def test_not_only_empty_confirmed_move(self): - self.pallets_location_storage_type.write({"allow_new_product": "mixed"}) + category = self.pallets_location_storage_type.storage_category_id + category.allow_new_product_ids.allow_new_product = "mixed" move = self._test_confirmed_move() self.assertEqual( move.move_line_ids.location_dest_id, self.pallets_bin_1_location ) def test_only_empty_confirmed_move(self): - self.pallets_location_storage_type.write({"allow_new_product": "empty"}) + category = self.pallets_location_storage_type.storage_category_id + category.allow_new_product_ids.allow_new_product = "empty" move = self._test_confirmed_move() self.assertNotEqual( move.move_line_ids.location_dest_id, self.pallets_bin_1_location ) def test_do_not_mix_products_confirmed_move_ok(self): - self.pallets_location_storage_type.write({"allow_new_product": "same"}) + category = self.pallets_location_storage_type.storage_category_id + category.allow_new_product_ids.allow_new_product = "same" move = self._test_confirmed_move() self.assertEqual( move.move_line_ids.location_dest_id, self.pallets_bin_1_location ) def test_do_not_mix_products_confirmed_move_nok(self): - self.pallets_location_storage_type.write({"allow_new_product": "same"}) + self.pallets_location_storage_type.storage_category_id.write( + {"allow_new_product": "same"} + ) move_other_product = self._test_confirmed_move( self.env.ref("product.product_product_10") ) @@ -70,7 +75,9 @@ def test_do_not_mix_products_confirmed_move_nok(self): def test_package_level_location_dest_domain_only_empty(self): # Set pallets location type as only empty - self.pallets_location_storage_type.write({"allow_new_product": "empty"}) + self.pallets_location_storage_type.storage_category_id.write( + {"allow_new_product": "empty"} + ) # Create picking in_picking = self.env["stock.picking"].create( { @@ -202,7 +209,9 @@ def test_package_level_location_dest_domain_mixed(self): # Mark picking to allow creation and use of existing lots in order # to register two times the same lot in different packages self.receipts_picking_type.use_existing_lots = True - self.cardboxes_location_storage_type.write({"allow_new_product": "same_lot"}) + self.cardboxes_location_storage_type.storage_category_id.write( + {"allow_new_product": "same_lot"} + ) # Create picking in_picking = self.env["stock.picking"].create( { @@ -381,7 +390,9 @@ def test_stock_move_no_package(self): Check that lot restriction is well applied """ # Constrain Cardbox Capacity to accept same lots only - self.cardboxes_location_storage_type.write({"allow_new_product": "same_lot"}) + self.cardboxes_location_storage_type.storage_category_id.write( + {"allow_new_product": "same_lot"} + ) # Set a quantity in cardbox bin 2 to make sure constraint is applied self.env["stock.quant"]._update_available_quantity( self.env.ref("product.product_product_10"), diff --git a/stock_storage_type/tests/test_storage_type_putaway_strategy.py b/stock_storage_type/tests/test_storage_type_putaway_strategy.py index 3f2956576c6..a2e2f82b120 100644 --- a/stock_storage_type/tests/test_storage_type_putaway_strategy.py +++ b/stock_storage_type/tests/test_storage_type_putaway_strategy.py @@ -81,7 +81,9 @@ def test_storage_strategy_ordered_locations_cardboxes(self): def test_storage_strategy_only_empty_ordered_locations_pallets(self): # Set pallets location type as only empty - self.pallets_location_storage_type.write({"allow_new_product": "empty"}) + self.pallets_location_storage_type.storage_category_id.write( + {"allow_new_product": "empty"} + ) # Set a quantity in pallet bin 2 to make sure constraint is applied self.env["stock.quant"]._update_available_quantity( self.product, self.pallets_bin_2_location, 1.0 @@ -142,14 +144,25 @@ def test_storage_strategy_only_empty_ordered_locations_pallets(self): ) def test_storage_strategy_max_weight_ordered_locations_pallets(self): + """Test pallet max weight constraint on a location. + + Configure 'Pallets storage area/Pallets Bin 2' with a max weight to 50kg. + Reception of two pallets of 60kg suggests to put them into Bin 1 and 3, + skipping Bin 2 that doesn't match anymore. + """ + self.pallets_location.storage_category_id.allow_new_product = "empty" # Add a category for max_weight 50 category_50 = self.env["stock.storage.category"].create( - {"name": "Pallets max 50 kg", "max_weight": 50} + { + "name": "Pallets max 50 kg", + "max_weight": 50, + "allow_new_product": "empty", + } ) # Define new pallets location type with a max weight on bin 2 light_location_storage_type = self.pallets_location_storage_type.copy( - {"allow_new_product": "empty", "storage_category_id": category_50.id} + {"storage_category_id": category_50.id} ) self.pallets_bin_2_location.write({"storage_category_id": category_50.id}) self.assertEqual( @@ -215,7 +228,9 @@ def test_storage_strategy_max_weight_ordered_locations_pallets(self): ) def test_storage_strategy_no_products_lots_mix_ordered_locations_cardboxes(self): - self.cardboxes_location_storage_type.write({"allow_new_product": "same_lot"}) + self.cardboxes_location_storage_type.storage_category_id.write( + {"allow_new_product": "same_lot"} + ) # Set a quantity in cardbox bin 2 to make sure constraint is applied self.env["stock.quant"]._update_available_quantity( self.env.ref("product.product_product_10"), @@ -398,7 +413,9 @@ def test_storage_strategy_do_not_mix_products_reuse_location(self): (less qty first). """ StockLocation = self.env["stock.location"] - self.cardboxes_location_storage_type.write({"allow_new_product": "same"}) + self.cardboxes_location_storage_type.storage_category_id.write( + {"allow_new_product": "same"} + ) product = self.product packaging = self.product_cardbox_product_packaging dest_location = self.cardboxes_location diff --git a/stock_storage_type/views/stock_package_type.xml b/stock_storage_type/views/stock_package_type.xml index 7fc87b9c726..e688068d398 100644 --- a/stock_storage_type/views/stock_package_type.xml +++ b/stock_storage_type/views/stock_package_type.xml @@ -32,12 +32,6 @@ - - -
diff --git a/stock_storage_type/views/stock_storage_category.xml b/stock_storage_type/views/stock_storage_category.xml index 4665528732a..f0ee3bb7e6e 100644 --- a/stock_storage_type/views/stock_storage_category.xml +++ b/stock_storage_type/views/stock_storage_category.xml @@ -1,5 +1,6 @@ @@ -7,9 +8,26 @@ stock.storage.category - - - + + + + + + + + + + + + + diff --git a/stock_storage_type/views/stock_storage_category_allow_new_product_cond.xml b/stock_storage_type/views/stock_storage_category_allow_new_product_cond.xml new file mode 100644 index 00000000000..b67aba6b640 --- /dev/null +++ b/stock_storage_type/views/stock_storage_category_allow_new_product_cond.xml @@ -0,0 +1,54 @@ + + + + + + stock.storage.category.allow_new_product.cond.form + stock.storage.category.allow_new_product.cond + +

+ + + +
+
+ + + + + +
+ +
+ + + + Storage Category Allow New Product Conditions + stock.storage.category.allow_new_product.cond + tree,form + + + diff --git a/stock_storage_type/views/stock_storage_category_capacity.xml b/stock_storage_type/views/stock_storage_category_capacity.xml deleted file mode 100644 index e7db3cead26..00000000000 --- a/stock_storage_type/views/stock_storage_category_capacity.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - stock.storage.category.capacity.tree (in stock_storage_type) - stock.storage.category.capacity - - - - - - - - - diff --git a/stock_storage_type/views/storage_type_menus.xml b/stock_storage_type/views/storage_type_menus.xml index 8300eef602f..6ec04679ee5 100644 --- a/stock_storage_type/views/storage_type_menus.xml +++ b/stock_storage_type/views/storage_type_menus.xml @@ -7,6 +7,13 @@ sequence="9" groups="stock.group_adv_location" /> + Date: Tue, 29 Apr 2025 16:13:27 +0000 Subject: [PATCH 032/357] [UPD] Update shopfloor.pot --- shopfloor/i18n/shopfloor.pot | 48 ++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/shopfloor/i18n/shopfloor.pot b/shopfloor/i18n/shopfloor.pot index 2b73bb4472d..bc978c4c04b 100644 --- a/shopfloor/i18n/shopfloor.pot +++ b/shopfloor/i18n/shopfloor.pot @@ -839,6 +839,20 @@ msgstr "" msgid "No quantity has been processed, unable to complete the transfer." msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for %(model_name)s %(record_name)s" +msgstr "" + +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for barcode %s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1047,13 +1061,6 @@ msgstr "" msgid "Package {} is not empty." msgstr "" -#. module: shopfloor -#. odoo-python -#: code:addons/shopfloor/services/checkout.py:0 -#, python-format -msgid "Package {} is not in the current transfer." -msgstr "" - #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_quant_package msgid "Packages" @@ -1209,16 +1216,16 @@ msgid "" " %(picking_name)s." msgstr "" -#. module: shopfloor -#: model:ir.model,name:shopfloor.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "" - #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Product is not in the current transfer." +msgid "Product %s is not in the current transfer." +msgstr "" + +#. module: shopfloor +#: model:ir.model,name:shopfloor.model_stock_move_line +msgid "Product Moves (Stock Move Line)" msgstr "" #. module: shopfloor @@ -1289,6 +1296,13 @@ msgstr "" msgid "Reserved Move Line" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "Reserved for %(picking_type)s %(picking_name)s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1890,6 +1904,14 @@ msgstr "" msgid "Transfer" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "" +"Transfer has been canceled. This cannot be processed using this scenario" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 From 5996d83aefbe7f219b74b9a02049b8fc1b291e24 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 29 Apr 2025 16:25:55 +0000 Subject: [PATCH 033/357] [BOT] post-merge updates --- README.md | 4 ++-- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8f8d712b033..39f3721c41b 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,13 @@ addon | version | maintainers | summary [sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.0.0 | | Block release of deliveries from sales orders. [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.6.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.7.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.1.1 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.0.0 | [![mmequignon](https://github.com/mmequignon.png?size=30px)](https://github.com/mmequignon) [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.1.0 | [![mmequignon](https://github.com/mmequignon.png?size=30px)](https://github.com/mmequignon) [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Scenario for receiving products [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners diff --git a/shopfloor/README.rst b/shopfloor/README.rst index 1b7ca9b1d6e..9363266b807 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -7,7 +7,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:15590a835f281c13f0eae031c50d19d04ab77e94ee95b697d5eabd04373c21ce + !! source digest: sha256:986a6c228f6ee438330907a4be64b74f7291bb1acfc6498a2617ed5e69777d9e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index de5ce464254..6354f5151f9 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.6.0", + "version": "16.0.2.7.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index a1160934b74..2e90526f077 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -367,7 +367,7 @@

Shopfloor

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:15590a835f281c13f0eae031c50d19d04ab77e94ee95b697d5eabd04373c21ce +!! source digest: sha256:986a6c228f6ee438330907a4be64b74f7291bb1acfc6498a2617ed5e69777d9e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 2bc3044e8fb..a467458adef 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -7,7 +7,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:41faa7df7bdb71ba8f5be9c536daff42f29bea13d2ae79892e084f5259c2d1ce + !! source digest: sha256:91d600cf02ccddb57cc28496eef052a0d5a9179b984e2acb651fbab29a5e3586 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index afbe051d4f4..9a594c71d6f 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.0.0", + "version": "16.0.1.1.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 578483fd8d6..9a0d185d39a 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -367,7 +367,7 @@

Shopfloor Reception

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:41faa7df7bdb71ba8f5be9c536daff42f29bea13d2ae79892e084f5259c2d1ce +!! source digest: sha256:91d600cf02ccddb57cc28496eef052a0d5a9179b984e2acb651fbab29a5e3586 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor implementation of the reception scenario. From 193d530907af245b4021356f59bad63709fd464e Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 29 Apr 2025 16:25:49 +0000 Subject: [PATCH 034/357] Translated using Weblate (Italian) Currently translated at 100.0% (83 of 83 strings) Translation: wms-16.0/wms-16.0-stock_available_to_promise_release Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_available_to_promise_release/it/ --- stock_available_to_promise_release/i18n/it.po | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/stock_available_to_promise_release/i18n/it.po b/stock_available_to_promise_release/i18n/it.po index fccc6ec5f44..0e57f9b86e2 100644 --- a/stock_available_to_promise_release/i18n/it.po +++ b/stock_available_to_promise_release/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-01-15 15:06+0000\n" +"PO-Revision-Date: 2025-04-29 16:26+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.6.2\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_available_to_promise_release #: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_picking__release_ready_count @@ -183,6 +183,10 @@ msgid "" "operation on the last done pulled transfer. Otherwise, you won't be able to " "unrelease as soon as one of the pulled transfer is done" msgstr "" +"Se selezionata, l'annullamento del rilascio della consegna potrebbe creare " +"una nuova operazione interna inversa sull'ultimo trasferimento prelevato " +"eseguito. In caso contrario, non sarà possibile annullare il rilascio non " +"appena uno dei trasferimenti prelevati viene completato" #. module: stock_available_to_promise_release #: model:ir.model.fields,help:stock_available_to_promise_release.field_stock_picking_type__unrelease_on_backorder @@ -358,7 +362,7 @@ msgstr "Rilascio in base alla disponibilità alle promesse" #: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_route__allow_unrelease_return_done_move #: model:ir.model.fields,field_description:stock_available_to_promise_release.field_stock_rule__allow_unrelease_return_done_move msgid "Reverse done transfer on cancellation" -msgstr "" +msgstr "Inverti trasferimento eseguito all'annullamento" #. module: stock_available_to_promise_release #: model:ir.model,name:stock_available_to_promise_release.model_stock_release @@ -420,7 +424,7 @@ msgstr "" #: code:addons/stock_available_to_promise_release/models/stock_move.py:0 #, python-format msgid "The operation %(picking_names)s is done and cannot be returned" -msgstr "" +msgstr "L'operazione %(picking_names)s è conclusa e non può essere resa" #. module: stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release.view_stock_release_form From 8d0264fe15558963feb655dc9b550d08fb2b9a1a Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 29 Apr 2025 16:26:08 +0000 Subject: [PATCH 035/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/ --- shopfloor/i18n/ca.po | 48 +++++++++++++++++++++++++--------- shopfloor/i18n/de.po | 48 +++++++++++++++++++++++++--------- shopfloor/i18n/es_AR.po | 58 +++++++++++++++++++++++++++++++---------- shopfloor/i18n/it.po | 58 +++++++++++++++++++++++++++++++---------- shopfloor/i18n/pt_BR.po | 48 +++++++++++++++++++++++++--------- 5 files changed, 193 insertions(+), 67 deletions(-) diff --git a/shopfloor/i18n/ca.po b/shopfloor/i18n/ca.po index 71e40111cfd..b48d5e8516a 100644 --- a/shopfloor/i18n/ca.po +++ b/shopfloor/i18n/ca.po @@ -847,6 +847,20 @@ msgstr "" msgid "No quantity has been processed, unable to complete the transfer." msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for %(model_name)s %(record_name)s" +msgstr "" + +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for barcode %s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1054,13 +1068,6 @@ msgstr "" msgid "Package {} is not empty." msgstr "" -#. module: shopfloor -#. odoo-python -#: code:addons/shopfloor/services/checkout.py:0 -#, python-format -msgid "Package {} is not in the current transfer." -msgstr "" - #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_quant_package msgid "Packages" @@ -1216,16 +1223,16 @@ msgid "" "%(picking_name)s." msgstr "" -#. module: shopfloor -#: model:ir.model,name:shopfloor.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "" - #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Product is not in the current transfer." +msgid "Product %s is not in the current transfer." +msgstr "" + +#. module: shopfloor +#: model:ir.model,name:shopfloor.model_stock_move_line +msgid "Product Moves (Stock Move Line)" msgstr "" #. module: shopfloor @@ -1296,6 +1303,13 @@ msgstr "" msgid "Reserved Move Line" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "Reserved for %(picking_type)s %(picking_name)s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1895,6 +1909,14 @@ msgstr "" msgid "Transfer" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "" +"Transfer has been canceled. This cannot be processed using this scenario" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 diff --git a/shopfloor/i18n/de.po b/shopfloor/i18n/de.po index 749de96c952..97abe7b564a 100644 --- a/shopfloor/i18n/de.po +++ b/shopfloor/i18n/de.po @@ -843,6 +843,20 @@ msgstr "" msgid "No quantity has been processed, unable to complete the transfer." msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for %(model_name)s %(record_name)s" +msgstr "" + +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for barcode %s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1050,13 +1064,6 @@ msgstr "" msgid "Package {} is not empty." msgstr "" -#. module: shopfloor -#. odoo-python -#: code:addons/shopfloor/services/checkout.py:0 -#, python-format -msgid "Package {} is not in the current transfer." -msgstr "" - #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_quant_package msgid "Packages" @@ -1212,16 +1219,16 @@ msgid "" "%(picking_name)s." msgstr "" -#. module: shopfloor -#: model:ir.model,name:shopfloor.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "" - #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Product is not in the current transfer." +msgid "Product %s is not in the current transfer." +msgstr "" + +#. module: shopfloor +#: model:ir.model,name:shopfloor.model_stock_move_line +msgid "Product Moves (Stock Move Line)" msgstr "" #. module: shopfloor @@ -1292,6 +1299,13 @@ msgstr "" msgid "Reserved Move Line" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "Reserved for %(picking_type)s %(picking_name)s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1891,6 +1905,14 @@ msgstr "" msgid "Transfer" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "" +"Transfer has been canceled. This cannot be processed using this scenario" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 diff --git a/shopfloor/i18n/es_AR.po b/shopfloor/i18n/es_AR.po index 629a786662a..5ec807de624 100644 --- a/shopfloor/i18n/es_AR.po +++ b/shopfloor/i18n/es_AR.po @@ -894,6 +894,20 @@ msgstr "" "No se ha procesado ninguna cantidad, no se ha podido completar la " "transferencia." +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for %(model_name)s %(record_name)s" +msgstr "" + +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for barcode %s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1111,13 +1125,6 @@ msgstr "El Paquete {} está usado." msgid "Package {} is not empty." msgstr "El Paquete {} no está vacío." -#. module: shopfloor -#. odoo-python -#: code:addons/shopfloor/services/checkout.py:0 -#, python-format -msgid "Package {} is not in the current transfer." -msgstr "El Paquete {} no está en la transferencia actual." - #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_quant_package msgid "Packages" @@ -1279,17 +1286,17 @@ msgid "" "%(picking_name)s." msgstr "" -#. module: shopfloor -#: model:ir.model,name:shopfloor.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "Movimientos de Producto (Stock Move Line)" - #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Product is not in the current transfer." -msgstr "El Producto no está en la transferencia actual." +msgid "Product %s is not in the current transfer." +msgstr "" + +#. module: shopfloor +#: model:ir.model,name:shopfloor.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Movimientos de Producto (Stock Move Line)" #. module: shopfloor #. odoo-python @@ -1362,6 +1369,13 @@ msgstr "" msgid "Reserved Move Line" msgstr "Movimiento de Línea Reservado" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "Reserved for %(picking_type)s %(picking_name)s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1993,6 +2007,14 @@ msgstr "Peso Total" msgid "Transfer" msgstr "Transferencia" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "" +"Transfer has been canceled. This cannot be processed using this scenario" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -2272,6 +2294,14 @@ msgstr "" msgid "{} is not a valid destination package." msgstr "{} no es un paquete de destino válido." +#, python-format +#~ msgid "Package {} is not in the current transfer." +#~ msgstr "El Paquete {} no está en la transferencia actual." + +#, python-format +#~ msgid "Product is not in the current transfer." +#~ msgstr "El Producto no está en la transferencia actual." + #, python-format #~ msgid "Lot is not in the current transfer." #~ msgstr "El Lote no está en la transferencia actual." diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index 2042831b499..2b4b4aa1984 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -929,6 +929,20 @@ msgstr "Nessuna destinazion di inoltro disponibile." msgid "No quantity has been processed, unable to complete the transfer." msgstr "Nessuna quantità elaborata, impossibile completare il trasferimento." +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for %(model_name)s %(record_name)s" +msgstr "" + +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for barcode %s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1152,13 +1166,6 @@ msgstr "Il collo {} è già in uso." msgid "Package {} is not empty." msgstr "Il collo {} non è vuoto." -#. module: shopfloor -#. odoo-python -#: code:addons/shopfloor/services/checkout.py:0 -#, python-format -msgid "Package {} is not in the current transfer." -msgstr "Il collo {} non è nel trasferimento attuale." - #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_quant_package msgid "Packages" @@ -1322,17 +1329,17 @@ msgstr "" "Prodotto %(product_name)s non trovato nell'ubicazione %(location_name)s o " "trasferimento %(picking_name)s." -#. module: shopfloor -#: model:ir.model,name:shopfloor.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "Movimenti prodotto (riga movimento di magazzino)" - #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Product is not in the current transfer." -msgstr "Il prodotto non è nel trasferimento attuale." +msgid "Product %s is not in the current transfer." +msgstr "" + +#. module: shopfloor +#: model:ir.model,name:shopfloor.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Movimenti prodotto (riga movimento di magazzino)" #. module: shopfloor #. odoo-python @@ -1403,6 +1410,13 @@ msgstr "È possibile richiedere il collo di destinazione" msgid "Reserved Move Line" msgstr "Riga movimento prenotata" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "Reserved for %(picking_type)s %(picking_name)s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -2039,6 +2053,14 @@ msgstr "Peso totale" msgid "Transfer" msgstr "Trasferimento" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "" +"Transfer has been canceled. This cannot be processed using this scenario" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -2336,6 +2358,14 @@ msgstr "" msgid "{} is not a valid destination package." msgstr "{} non è un collo destinazione valido." +#, python-format +#~ msgid "Package {} is not in the current transfer." +#~ msgstr "Il collo {} non è nel trasferimento attuale." + +#, python-format +#~ msgid "Product is not in the current transfer." +#~ msgstr "Il prodotto non è nel trasferimento attuale." + #, python-format #~ msgid "Lot is not in the current transfer." #~ msgstr "Il lotto non è nel trasferimento attuale." diff --git a/shopfloor/i18n/pt_BR.po b/shopfloor/i18n/pt_BR.po index 9f928a07f3b..483ce9a4845 100644 --- a/shopfloor/i18n/pt_BR.po +++ b/shopfloor/i18n/pt_BR.po @@ -843,6 +843,20 @@ msgstr "" msgid "No quantity has been processed, unable to complete the transfer." msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for %(model_name)s %(record_name)s" +msgstr "" + +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "No transfer found for barcode %s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1050,13 +1064,6 @@ msgstr "" msgid "Package {} is not empty." msgstr "" -#. module: shopfloor -#. odoo-python -#: code:addons/shopfloor/services/checkout.py:0 -#, python-format -msgid "Package {} is not in the current transfer." -msgstr "" - #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_quant_package msgid "Packages" @@ -1212,16 +1219,16 @@ msgid "" "%(picking_name)s." msgstr "" -#. module: shopfloor -#: model:ir.model,name:shopfloor.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "" - #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Product is not in the current transfer." +msgid "Product %s is not in the current transfer." +msgstr "" + +#. module: shopfloor +#: model:ir.model,name:shopfloor.model_stock_move_line +msgid "Product Moves (Stock Move Line)" msgstr "" #. module: shopfloor @@ -1292,6 +1299,13 @@ msgstr "" msgid "Reserved Move Line" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "Reserved for %(picking_type)s %(picking_name)s" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 @@ -1891,6 +1905,14 @@ msgstr "" msgid "Transfer" msgstr "" +#. module: shopfloor +#. odoo-python +#: code:addons/shopfloor/actions/message.py:0 +#, python-format +msgid "" +"Transfer has been canceled. This cannot be processed using this scenario" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 From 9f3b9ca6be0ca3e3d779e1d6f39c3123bfeba8db Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 30 Apr 2025 08:58:52 +0000 Subject: [PATCH 036/357] [UPD] Update stock_warehouse_flow.pot --- .../i18n/stock_warehouse_flow.pot | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/stock_warehouse_flow/i18n/stock_warehouse_flow.pot b/stock_warehouse_flow/i18n/stock_warehouse_flow.pot index f151a64490d..35710954779 100644 --- a/stock_warehouse_flow/i18n/stock_warehouse_flow.pot +++ b/stock_warehouse_flow/i18n/stock_warehouse_flow.pot @@ -33,6 +33,11 @@ msgstr "" msgid "Applicable Flows" msgstr "" +#. module: stock_warehouse_flow +#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_route__apply_flow_on +msgid "Apply Flow On" +msgstr "" + #. module: stock_warehouse_flow #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_form #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_search @@ -59,6 +64,11 @@ msgstr "" msgid "Created on" msgstr "" +#. module: stock_warehouse_flow +#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_move__default_picking_type_id +msgid "Default Picking Type" +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_warehouse_flow__delivery_steps__ship_only msgid "Deliver goods directly (1 step)" @@ -380,6 +390,13 @@ msgstr "" msgid "Uom" msgstr "" +#. module: stock_warehouse_flow +#: model:ir.model.fields,help:stock_warehouse_flow.field_stock_move__default_picking_type_id +msgid "" +"Used as a backup to save picking type set by odoo, before a new flow is " +"applied." +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields,help:stock_warehouse_flow.field_stock_warehouse_flow__sequence_prefix msgid "" @@ -404,6 +421,11 @@ msgstr "" msgid "Warning" msgstr "" +#. module: stock_warehouse_flow +#: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_route__apply_flow_on__on_confirm +msgid "When move is confirmed" +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_warehouse_flow__carrier_ids msgid "With carriers" From 42008514bf7a9ec678eac502bb04a153892136b9 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 30 Apr 2025 08:58:52 +0000 Subject: [PATCH 037/357] [UPD] Update stock_warehouse_flow_delivery_refresh.pot --- .../stock_warehouse_flow_delivery_refresh.pot | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 stock_warehouse_flow_delivery_refresh/i18n/stock_warehouse_flow_delivery_refresh.pot diff --git a/stock_warehouse_flow_delivery_refresh/i18n/stock_warehouse_flow_delivery_refresh.pot b/stock_warehouse_flow_delivery_refresh/i18n/stock_warehouse_flow_delivery_refresh.pot new file mode 100644 index 00000000000..c57f505fff8 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/i18n/stock_warehouse_flow_delivery_refresh.pot @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_warehouse_flow_delivery_refresh +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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_warehouse_flow_delivery_refresh +#: model:ir.model,name:stock_warehouse_flow_delivery_refresh.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: stock_warehouse_flow_delivery_refresh +#: model:ir.model,name:stock_warehouse_flow_delivery_refresh.model_stock_picking +msgid "Transfer" +msgstr "" From c3224a13c77b4f24e1b73626a473dc1ae5164c04 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 30 Apr 2025 08:58:53 +0000 Subject: [PATCH 038/357] [UPD] Update stock_warehouse_flow_release.pot --- .../i18n/stock_warehouse_flow_release.pot | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/stock_warehouse_flow_release/i18n/stock_warehouse_flow_release.pot b/stock_warehouse_flow_release/i18n/stock_warehouse_flow_release.pot index a1c307ca235..57fdfc3854f 100644 --- a/stock_warehouse_flow_release/i18n/stock_warehouse_flow_release.pot +++ b/stock_warehouse_flow_release/i18n/stock_warehouse_flow_release.pot @@ -13,7 +13,22 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: stock_warehouse_flow_release +#: model:ir.model.fields,field_description:stock_warehouse_flow_release.field_stock_route__apply_flow_on +msgid "Apply Flow On" +msgstr "" + +#. module: stock_warehouse_flow_release +#: model:ir.model,name:stock_warehouse_flow_release.model_stock_route +msgid "Inventory Routes" +msgstr "" + #. module: stock_warehouse_flow_release #: model:ir.model,name:stock_warehouse_flow_release.model_stock_move msgid "Stock Move" msgstr "" + +#. module: stock_warehouse_flow_release +#: model:ir.model.fields.selection,name:stock_warehouse_flow_release.selection__stock_route__apply_flow_on__on_release +msgid "When move is released" +msgstr "" From a729b8f1f5f38532e1ea58fd286cef1adec50f67 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 30 Apr 2025 09:09:49 +0000 Subject: [PATCH 039/357] [BOT] post-merge updates --- README.md | 5 +- setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + stock_warehouse_flow/README.rst | 135 ++++++++++++++++++ .../README.rst | 85 +++++++++++ .../static/description/icon.png | Bin 0 -> 10254 bytes stock_warehouse_flow_release/README.rst | 86 +++++++++++ 7 files changed, 311 insertions(+), 3 deletions(-) create mode 100644 stock_warehouse_flow_delivery_refresh/static/description/icon.png diff --git a/README.md b/README.md index 39f3721c41b..c1238767c87 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,9 @@ addon | version | maintainers | summary [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels [stock_storage_type](stock_storage_type/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) | Manage packages and locations storage types [stock_storage_type_putaway_abc](stock_storage_type_putaway_abc/) | 16.0.1.0.0 | | Advanced storage strategy ABC for WMS -[stock_warehouse_flow](stock_warehouse_flow/) | 16.0.1.0.2 | | Configure routing flow for stock moves -[stock_warehouse_flow_release](stock_warehouse_flow_release/) | 16.0.1.0.0 | | Warehouse flows integrated with Operation Release +[stock_warehouse_flow](stock_warehouse_flow/) | 16.0.1.1.0 | | Configure routing flow for stock moves +[stock_warehouse_flow_delivery_refresh](stock_warehouse_flow_delivery_refresh/) | 16.0.1.0.0 | | Allow to refresh delivery flow when carrier changes +[stock_warehouse_flow_release](stock_warehouse_flow_release/) | 16.0.1.1.0 | | Warehouse flows integrated with Operation Release [//]: # (end addons) diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 6c7082808aa..22db282e855 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250423.0 \ No newline at end of file +16.0.20250430.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index 4a8e3c0d4e1..3ce8f568c8c 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -55,6 +55,7 @@ 'odoo-addon-stock_storage_type>=16.0dev,<16.1dev', 'odoo-addon-stock_storage_type_putaway_abc>=16.0dev,<16.1dev', 'odoo-addon-stock_warehouse_flow>=16.0dev,<16.1dev', + 'odoo-addon-stock_warehouse_flow_delivery_refresh>=16.0dev,<16.1dev', 'odoo-addon-stock_warehouse_flow_release>=16.0dev,<16.1dev', ], classifiers=[ diff --git a/stock_warehouse_flow/README.rst b/stock_warehouse_flow/README.rst index e69de29bb2d..693493df2f2 100644 --- a/stock_warehouse_flow/README.rst +++ b/stock_warehouse_flow/README.rst @@ -0,0 +1,135 @@ +==================== +Stock Warehouse Flow +==================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c82fff4e498effcb90a8f7a92adccc461a6ada468f5a82079759bc844272f3c1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :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 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/stock_warehouse_flow + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module introduces the concept of routing flows in order to manage +different delivery routes for a warehouse. + +The default behavior of Odoo allows you to have only one delivery route per +warehouse (with one, two or three steps). +With this module, you are now able to manage multiple delivery routes (having +their own rules and operation types), the right one being selected automatically +based on some criterias, like the carrier and any attribute of the stock move +to process. + +This allows you to define a delivery route based on the type of goods to ship, +for instance: + +* whole pallet (pick + ship) +* cold chain goods +* dangerous goods + +.. image:: https://raw.githubusercontent.com/OCA/wms/14.0/stock_warehouse_flow/static/description/flow.png + +.. 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:: + :local: + +Configuration +============= + +Got to "Inventory > Settings > Routing Flows". + +A routing flow can be seen as a helper to generate a delivery route (like the +warehouse is doing automatically). The new route will get its own rules and +operation types that doesn't overlap with the default ones of the warehouse. + +A routing flow is responsible to change the warehouse delivery route of a move +by another one depending on some criterias: + +* the initial outgoing operation type (usually the default one) +* the carrier +* a custom domain (applied on the move) + +This way you are able to change the route a move will take depending on its +carrier and, for instance, the type or the packaging of the product +you want to ship. + +.. image:: https://raw.githubusercontent.com/OCA/wms/14.0/stock_warehouse_flow/static/description/config.png + +Usage +===== + +When a stock move is confirmed, if a flow is matching all the criteria then +the new delivery route will be automatically applied. + +Known issues / Roadmap +====================== + +Currently, the module supports only delivery routes, but it could improved to +support reception routes as well. + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp +* BCIM + +Contributors +~~~~~~~~~~~~ + +* Sébastien Alix +* Jacques-Etienne Baudoux +* Michael Tietz (MT Software) + +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/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_warehouse_flow_delivery_refresh/README.rst b/stock_warehouse_flow_delivery_refresh/README.rst index e69de29bb2d..131d52c7eaa 100644 --- a/stock_warehouse_flow_delivery_refresh/README.rst +++ b/stock_warehouse_flow_delivery_refresh/README.rst @@ -0,0 +1,85 @@ +===================================== +Stock Warehouse Flow Delivery Refresh +===================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:2391de51e04af41e8c5acfcd570c0a8d2ccfeef45975cb932f12686e45873281 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :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 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/stock_warehouse_flow_delivery_refresh + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow_delivery_refresh + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This is a glue module between Stock Warehouse Flow and Stock Available On Premise Release. + +This module applies a new Stock Warehouse Flow on Stock Moves waiting for release when carrier changes on a Stock Picking + +.. 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:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp +* BCIM + +Contributors +~~~~~~~~~~~~ + +* Jacques-Etienne Baudoux +* Matthieu Méquignon + +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/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_warehouse_flow_delivery_refresh/static/description/icon.png b/stock_warehouse_flow_delivery_refresh/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp +* BCIM + +Contributors +~~~~~~~~~~~~ + +* Sébastien Alix +* Jacques-Etienne Baudoux +* Michael Tietz (MT Software) + +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/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. From 744a460d74065edec8e44b6ba7ebd9378a940217 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 30 Apr 2025 09:10:04 +0000 Subject: [PATCH 040/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_warehouse_flow_release Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow_release/ --- stock_warehouse_flow_release/i18n/it.po | 31 ++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/stock_warehouse_flow_release/i18n/it.po b/stock_warehouse_flow_release/i18n/it.po index d73f5d6efcf..b4f8a7f969b 100644 --- a/stock_warehouse_flow_release/i18n/it.po +++ b/stock_warehouse_flow_release/i18n/it.po @@ -17,21 +17,30 @@ msgstr "" "X-Generator: Weblate 4.17\n" #. module: stock_warehouse_flow_release -#: model:ir.model.fields,field_description:stock_warehouse_flow_release.field_stock_move__display_name -msgid "Display Name" -msgstr "Nome visualizzato" - -#. module: stock_warehouse_flow_release -#: model:ir.model.fields,field_description:stock_warehouse_flow_release.field_stock_move__id -msgid "ID" -msgstr "ID" +#: model:ir.model.fields,field_description:stock_warehouse_flow_release.field_stock_route__apply_flow_on +msgid "Apply Flow On" +msgstr "" #. module: stock_warehouse_flow_release -#: model:ir.model.fields,field_description:stock_warehouse_flow_release.field_stock_move____last_update -msgid "Last Modified on" -msgstr "Ultima modifica il" +#: model:ir.model,name:stock_warehouse_flow_release.model_stock_route +msgid "Inventory Routes" +msgstr "" #. module: stock_warehouse_flow_release #: model:ir.model,name:stock_warehouse_flow_release.model_stock_move msgid "Stock Move" msgstr "Movimento di magazzino" + +#. module: stock_warehouse_flow_release +#: model:ir.model.fields.selection,name:stock_warehouse_flow_release.selection__stock_route__apply_flow_on__on_release +msgid "When move is released" +msgstr "" + +#~ msgid "Display Name" +#~ msgstr "Nome visualizzato" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" From 4ebc6d0ae94218a9384a4a6964fce857ad340104 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 30 Apr 2025 09:10:04 +0000 Subject: [PATCH 041/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_warehouse_flow Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow/ --- stock_warehouse_flow/i18n/es.po | 22 ++++++++++++++++++++++ stock_warehouse_flow/i18n/it.po | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/stock_warehouse_flow/i18n/es.po b/stock_warehouse_flow/i18n/es.po index 8b26769f442..8b668222c02 100644 --- a/stock_warehouse_flow/i18n/es.po +++ b/stock_warehouse_flow/i18n/es.po @@ -36,6 +36,11 @@ msgstr "Activo" msgid "Applicable Flows" msgstr "Flujos aplicables" +#. module: stock_warehouse_flow +#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_route__apply_flow_on +msgid "Apply Flow On" +msgstr "" + #. module: stock_warehouse_flow #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_form #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_search @@ -62,6 +67,11 @@ msgstr "Creado por" msgid "Created on" msgstr "Creado el" +#. module: stock_warehouse_flow +#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_move__default_picking_type_id +msgid "Default Picking Type" +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_warehouse_flow__delivery_steps__ship_only msgid "Deliver goods directly (1 step)" @@ -400,6 +410,13 @@ msgstr "A ubicación de salida" msgid "Uom" msgstr "UdM" +#. module: stock_warehouse_flow +#: model:ir.model.fields,help:stock_warehouse_flow.field_stock_move__default_picking_type_id +msgid "" +"Used as a backup to save picking type set by odoo, before a new flow is " +"applied." +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields,help:stock_warehouse_flow.field_stock_warehouse_flow__sequence_prefix msgid "" @@ -426,6 +443,11 @@ msgstr "Flujo de Almacén" msgid "Warning" msgstr "Aviso" +#. module: stock_warehouse_flow +#: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_route__apply_flow_on__on_confirm +msgid "When move is confirmed" +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_warehouse_flow__carrier_ids msgid "With carriers" diff --git a/stock_warehouse_flow/i18n/it.po b/stock_warehouse_flow/i18n/it.po index 9141300982b..7dd73ad9e84 100644 --- a/stock_warehouse_flow/i18n/it.po +++ b/stock_warehouse_flow/i18n/it.po @@ -36,6 +36,11 @@ msgstr "Attivo" msgid "Applicable Flows" msgstr "Flussi applicabili" +#. module: stock_warehouse_flow +#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_route__apply_flow_on +msgid "Apply Flow On" +msgstr "" + #. module: stock_warehouse_flow #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_form #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_search @@ -62,6 +67,11 @@ msgstr "Creato da" msgid "Created on" msgstr "Creato il" +#. module: stock_warehouse_flow +#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_move__default_picking_type_id +msgid "Default Picking Type" +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_warehouse_flow__delivery_steps__ship_only msgid "Deliver goods directly (1 step)" @@ -398,6 +408,13 @@ msgstr "A ubicazione uscita" msgid "Uom" msgstr "UdM" +#. module: stock_warehouse_flow +#: model:ir.model.fields,help:stock_warehouse_flow.field_stock_move__default_picking_type_id +msgid "" +"Used as a backup to save picking type set by odoo, before a new flow is " +"applied." +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields,help:stock_warehouse_flow.field_stock_warehouse_flow__sequence_prefix msgid "" @@ -424,6 +441,11 @@ msgstr "Flusso di magazzino" msgid "Warning" msgstr "Attenzione" +#. module: stock_warehouse_flow +#: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_route__apply_flow_on__on_confirm +msgid "When move is confirmed" +msgstr "" + #. module: stock_warehouse_flow #: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_warehouse_flow__carrier_ids msgid "With carriers" From dfa5a87630721efcb85c8c1639cccb023ece5206 Mon Sep 17 00:00:00 2001 From: mymage Date: Sat, 3 May 2025 14:21:12 +0000 Subject: [PATCH 042/357] Translated using Weblate (Italian) Currently translated at 100.0% (4 of 4 strings) Translation: wms-16.0/wms-16.0-stock_warehouse_flow_release Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow_release/it/ --- stock_warehouse_flow_release/i18n/it.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stock_warehouse_flow_release/i18n/it.po b/stock_warehouse_flow_release/i18n/it.po index b4f8a7f969b..f7bd4256c5e 100644 --- a/stock_warehouse_flow_release/i18n/it.po +++ b/stock_warehouse_flow_release/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-09-20 04:45+0000\n" +"PO-Revision-Date: 2025-05-03 14:48+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,17 +14,17 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_warehouse_flow_release #: model:ir.model.fields,field_description:stock_warehouse_flow_release.field_stock_route__apply_flow_on msgid "Apply Flow On" -msgstr "" +msgstr "Applica flusso a" #. module: stock_warehouse_flow_release #: model:ir.model,name:stock_warehouse_flow_release.model_stock_route msgid "Inventory Routes" -msgstr "" +msgstr "Percorsi di inventario" #. module: stock_warehouse_flow_release #: model:ir.model,name:stock_warehouse_flow_release.model_stock_move @@ -34,7 +34,7 @@ msgstr "Movimento di magazzino" #. module: stock_warehouse_flow_release #: model:ir.model.fields.selection,name:stock_warehouse_flow_release.selection__stock_route__apply_flow_on__on_release msgid "When move is released" -msgstr "" +msgstr "Quando il movimento è rilasciato" #~ msgid "Display Name" #~ msgstr "Nome visualizzato" From 3d0f1cbdba57486a5ad64bd83c13441b6d173e65 Mon Sep 17 00:00:00 2001 From: mymage Date: Sat, 3 May 2025 14:23:42 +0000 Subject: [PATCH 043/357] Translated using Weblate (Italian) Currently translated at 100.0% (328 of 328 strings) Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/it/ --- shopfloor/i18n/it.po | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index 2b4b4aa1984..4ea35ebb14e 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-01-31 20:06+0000\n" +"PO-Revision-Date: 2025-05-03 14:48+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.6.2\n" +"X-Generator: Weblate 5.10.4\n" #. module: shopfloor #: model:ir.model.fields,help:shopfloor.field_shopfloor_menu__pick_pack_same_time @@ -934,14 +934,14 @@ msgstr "Nessuna quantità elaborata, impossibile completare il trasferimento." #: code:addons/shopfloor/actions/message.py:0 #, python-format msgid "No transfer found for %(model_name)s %(record_name)s" -msgstr "" +msgstr "Nessun trasferimento trovato per %(model_name)s %(record_name)s" #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format msgid "No transfer found for barcode %s" -msgstr "" +msgstr "Nessun trasferimento trovato per il codice a barre %s" #. module: shopfloor #. odoo-python @@ -1334,7 +1334,7 @@ msgstr "" #: code:addons/shopfloor/actions/message.py:0 #, python-format msgid "Product %s is not in the current transfer." -msgstr "" +msgstr "Il prodotto %s non è nel trasferimento attuale." #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_move_line @@ -1415,7 +1415,7 @@ msgstr "Riga movimento prenotata" #: code:addons/shopfloor/actions/message.py:0 #, python-format msgid "Reserved for %(picking_type)s %(picking_name)s" -msgstr "" +msgstr "Prenotato per %(picking_type)s %(picking_name)s" #. module: shopfloor #. odoo-python @@ -2060,6 +2060,8 @@ msgstr "Trasferimento" msgid "" "Transfer has been canceled. This cannot be processed using this scenario" msgstr "" +"Il trasferimento è stato annullato. Non può essere elaborato usando questo " +"scenario" #. module: shopfloor #. odoo-python From eb53f0633b6162b35dfc1f3350f0450eec5d3975 Mon Sep 17 00:00:00 2001 From: mymage Date: Sat, 3 May 2025 14:22:50 +0000 Subject: [PATCH 044/357] Translated using Weblate (Italian) Currently translated at 100.0% (77 of 77 strings) Translation: wms-16.0/wms-16.0-stock_warehouse_flow Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow/it/ --- stock_warehouse_flow/i18n/it.po | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/stock_warehouse_flow/i18n/it.po b/stock_warehouse_flow/i18n/it.po index 7dd73ad9e84..3c903b6ed83 100644 --- a/stock_warehouse_flow/i18n/it.po +++ b/stock_warehouse_flow/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-12-24 18:43+0000\n" +"PO-Revision-Date: 2025-05-03 14:48+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_warehouse_flow #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_form @@ -39,7 +39,7 @@ msgstr "Flussi applicabili" #. module: stock_warehouse_flow #: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_route__apply_flow_on msgid "Apply Flow On" -msgstr "" +msgstr "Applica flusso a" #. module: stock_warehouse_flow #: model_terms:ir.ui.view,arch_db:stock_warehouse_flow.stock_warehouse_flow_view_form @@ -70,7 +70,7 @@ msgstr "Creato il" #. module: stock_warehouse_flow #: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_move__default_picking_type_id msgid "Default Picking Type" -msgstr "" +msgstr "Tipo predefinito prelievo" #. module: stock_warehouse_flow #: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_warehouse_flow__delivery_steps__ship_only @@ -414,6 +414,8 @@ msgid "" "Used as a backup to save picking type set by odoo, before a new flow is " "applied." msgstr "" +"Utilizzato come backup per salvare il tipo prelievo impostato da Odoo, prima " +"che sia applicato un nuovo flusso." #. module: stock_warehouse_flow #: model:ir.model.fields,help:stock_warehouse_flow.field_stock_warehouse_flow__sequence_prefix @@ -444,7 +446,7 @@ msgstr "Attenzione" #. module: stock_warehouse_flow #: model:ir.model.fields.selection,name:stock_warehouse_flow.selection__stock_route__apply_flow_on__on_confirm msgid "When move is confirmed" -msgstr "" +msgstr "Quando il movimento è confermato" #. module: stock_warehouse_flow #: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_warehouse_flow__carrier_ids From 84eba9743e2833d0c44b9cd64d592c47e795fa36 Mon Sep 17 00:00:00 2001 From: mymage Date: Sat, 3 May 2025 14:48:39 +0000 Subject: [PATCH 045/357] Added translation using Weblate (Italian) --- .../i18n/it.po | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 stock_warehouse_flow_delivery_refresh/i18n/it.po diff --git a/stock_warehouse_flow_delivery_refresh/i18n/it.po b/stock_warehouse_flow_delivery_refresh/i18n/it.po new file mode 100644 index 00000000000..eae056e54e8 --- /dev/null +++ b/stock_warehouse_flow_delivery_refresh/i18n/it.po @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_warehouse_flow_delivery_refresh +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: stock_warehouse_flow_delivery_refresh +#: model:ir.model,name:stock_warehouse_flow_delivery_refresh.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: stock_warehouse_flow_delivery_refresh +#: model:ir.model,name:stock_warehouse_flow_delivery_refresh.model_stock_picking +msgid "Transfer" +msgstr "" From 77fecebcdb593eff79697f7666fe5f13fa1d4632 Mon Sep 17 00:00:00 2001 From: mymage Date: Sat, 3 May 2025 14:48:47 +0000 Subject: [PATCH 046/357] Translated using Weblate (Italian) Currently translated at 100.0% (2 of 2 strings) Translation: wms-16.0/wms-16.0-stock_warehouse_flow_delivery_refresh Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_warehouse_flow_delivery_refresh/it/ --- stock_warehouse_flow_delivery_refresh/i18n/it.po | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/stock_warehouse_flow_delivery_refresh/i18n/it.po b/stock_warehouse_flow_delivery_refresh/i18n/it.po index eae056e54e8..f4e7cc63246 100644 --- a/stock_warehouse_flow_delivery_refresh/i18n/it.po +++ b/stock_warehouse_flow_delivery_refresh/i18n/it.po @@ -6,20 +6,22 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-05-03 17:24+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_warehouse_flow_delivery_refresh #: model:ir.model,name:stock_warehouse_flow_delivery_refresh.model_stock_move msgid "Stock Move" -msgstr "" +msgstr "Movimento di magazzino" #. module: stock_warehouse_flow_delivery_refresh #: model:ir.model,name:stock_warehouse_flow_delivery_refresh.model_stock_picking msgid "Transfer" -msgstr "" +msgstr "Trasferimento" From 76eae324273430d958236668571ad0669e616577 Mon Sep 17 00:00:00 2001 From: Telmo Santos Date: Thu, 4 Jul 2024 08:44:44 +0200 Subject: [PATCH 047/357] [ADD] stock_release_channel_depot --- .../odoo/addons/stock_release_channel_depot | 1 + setup/stock_release_channel_depot/setup.py | 6 + stock_release_channel_depot/README.rst | 74 +++ stock_release_channel_depot/__init__.py | 1 + stock_release_channel_depot/__manifest__.py | 16 + stock_release_channel_depot/l18n/fr.po | 22 + .../l18n/stock_release_channel_depot.pot | 32 ++ .../models/__init__.py | 2 + .../models/release_channel.py | 10 + .../models/stock_picking.py | 10 + .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 1 + .../static/description/index.html | 420 ++++++++++++++++++ .../views/stock_picking.xml | 24 + .../views/stock_release_channel_views.xml | 22 + 15 files changed, 643 insertions(+) create mode 120000 setup/stock_release_channel_depot/odoo/addons/stock_release_channel_depot create mode 100644 setup/stock_release_channel_depot/setup.py create mode 100644 stock_release_channel_depot/README.rst create mode 100644 stock_release_channel_depot/__init__.py create mode 100644 stock_release_channel_depot/__manifest__.py create mode 100644 stock_release_channel_depot/l18n/fr.po create mode 100644 stock_release_channel_depot/l18n/stock_release_channel_depot.pot create mode 100644 stock_release_channel_depot/models/__init__.py create mode 100644 stock_release_channel_depot/models/release_channel.py create mode 100644 stock_release_channel_depot/models/stock_picking.py create mode 100644 stock_release_channel_depot/readme/CONTRIBUTORS.rst create mode 100644 stock_release_channel_depot/readme/DESCRIPTION.rst create mode 100644 stock_release_channel_depot/static/description/index.html create mode 100644 stock_release_channel_depot/views/stock_picking.xml create mode 100644 stock_release_channel_depot/views/stock_release_channel_views.xml diff --git a/setup/stock_release_channel_depot/odoo/addons/stock_release_channel_depot b/setup/stock_release_channel_depot/odoo/addons/stock_release_channel_depot new file mode 120000 index 00000000000..6aabdb91c33 --- /dev/null +++ b/setup/stock_release_channel_depot/odoo/addons/stock_release_channel_depot @@ -0,0 +1 @@ +../../../../stock_release_channel_depot \ No newline at end of file diff --git a/setup/stock_release_channel_depot/setup.py b/setup/stock_release_channel_depot/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/stock_release_channel_depot/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_release_channel_depot/README.rst b/stock_release_channel_depot/README.rst new file mode 100644 index 00000000000..bd1e070daa5 --- /dev/null +++ b/stock_release_channel_depot/README.rst @@ -0,0 +1,74 @@ +=========================== +Stock Release Channel Depot +=========================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! 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%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/stock_release_channel_depot + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_depot + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Add partner depot to stock release channel + +**Table of contents** + +.. contents:: + :local: + +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 + +Contributors +~~~~~~~~~~~~ + +* Telmo Santos +* Jacques-Etienne Baudoux + +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/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_release_channel_depot/__init__.py b/stock_release_channel_depot/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/stock_release_channel_depot/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_release_channel_depot/__manifest__.py b/stock_release_channel_depot/__manifest__.py new file mode 100644 index 00000000000..3f62523fd02 --- /dev/null +++ b/stock_release_channel_depot/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Stock Release Channel Depot", + "summary": """This module allows users to add partner depot to stock release channel.""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Camptocamp, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/wms", + "depends": ["stock_depot", "stock_release_channel"], + "data": [ + "views/stock_release_channel_views.xml", + "views/stock_picking.xml", + ], +} diff --git a/stock_release_channel_depot/l18n/fr.po b/stock_release_channel_depot/l18n/fr.po new file mode 100644 index 00000000000..540913f044e --- /dev/null +++ b/stock_release_channel_depot/l18n/fr.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_release_channel_depot +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-04 06:13+0000\n" +"PO-Revision-Date: 2024-07-04 06:13+0000\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_release_channel_depot +#: model:ir.model.fields,field_description:stock_release_channel_depot.field_stock_picking__depot_id +#: model:ir.model.fields,field_description:stock_release_channel_depot.field_stock_release_channel__depot_id +msgid "Depot" +msgstr "Dépôt" diff --git a/stock_release_channel_depot/l18n/stock_release_channel_depot.pot b/stock_release_channel_depot/l18n/stock_release_channel_depot.pot new file mode 100644 index 00000000000..e3f20cbb747 --- /dev/null +++ b/stock_release_channel_depot/l18n/stock_release_channel_depot.pot @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_release_channel_depot +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-04 06:13+0000\n" +"PO-Revision-Date: 2024-07-04 06:13+0000\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_release_channel_depot +#: model:ir.model.fields,field_description:stock_release_channel_depot.field_stock_picking__depot_id +#: model:ir.model.fields,field_description:stock_release_channel_depot.field_stock_release_channel__depot_id +msgid "Depot" +msgstr "" + +#. module: stock_release_channel_depot +#: model:ir.model,name:stock_release_channel_depot.model_stock_picking +msgid "Stock Picking" +msgstr "" + +#. module: stock_release_channel_depot +#: model:ir.model,name:stock_release_channel_depot.model_stock_release_channel +msgid "Stock Release Channels" +msgstr "" diff --git a/stock_release_channel_depot/models/__init__.py b/stock_release_channel_depot/models/__init__.py new file mode 100644 index 00000000000..56916daf065 --- /dev/null +++ b/stock_release_channel_depot/models/__init__.py @@ -0,0 +1,2 @@ +from . import release_channel +from . import stock_picking diff --git a/stock_release_channel_depot/models/release_channel.py b/stock_release_channel_depot/models/release_channel.py new file mode 100644 index 00000000000..a04bbd67d3b --- /dev/null +++ b/stock_release_channel_depot/models/release_channel.py @@ -0,0 +1,10 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class StockReleaseChannel(models.Model): + _inherit = "stock.release.channel" + + depot_id = fields.Many2one("stock.depot") diff --git a/stock_release_channel_depot/models/stock_picking.py b/stock_release_channel_depot/models/stock_picking.py new file mode 100644 index 00000000000..71633832c8b --- /dev/null +++ b/stock_release_channel_depot/models/stock_picking.py @@ -0,0 +1,10 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + depot_id = fields.Many2one(related="release_channel_id.depot_id", store=True) diff --git a/stock_release_channel_depot/readme/CONTRIBUTORS.rst b/stock_release_channel_depot/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..22612a25009 --- /dev/null +++ b/stock_release_channel_depot/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Telmo Santos +* Jacques-Etienne Baudoux diff --git a/stock_release_channel_depot/readme/DESCRIPTION.rst b/stock_release_channel_depot/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..1e578ec7e02 --- /dev/null +++ b/stock_release_channel_depot/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Add partner depot to stock release channel diff --git a/stock_release_channel_depot/static/description/index.html b/stock_release_channel_depot/static/description/index.html new file mode 100644 index 00000000000..74933910611 --- /dev/null +++ b/stock_release_channel_depot/static/description/index.html @@ -0,0 +1,420 @@ + + + + + + +Stock Release Channel Depot + + + +

+

Stock Release Channel Depot

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Add partner depot to stock release channel

+

Table of contents

+ +
+

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
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_release_channel_depot/views/stock_picking.xml b/stock_release_channel_depot/views/stock_picking.xml new file mode 100644 index 00000000000..8f632c18c21 --- /dev/null +++ b/stock_release_channel_depot/views/stock_picking.xml @@ -0,0 +1,24 @@ + + + + stock.picking.form (in stock_release_channel_depot) + stock.picking + + + + + + + + + + stock.picking.delivery.tree + stock.picking + + + + + + + + diff --git a/stock_release_channel_depot/views/stock_release_channel_views.xml b/stock_release_channel_depot/views/stock_release_channel_views.xml new file mode 100644 index 00000000000..3d9086f244e --- /dev/null +++ b/stock_release_channel_depot/views/stock_release_channel_views.xml @@ -0,0 +1,22 @@ + + + + + stock.release.channel.form (in stock_release_channel_depot) + stock.release.channel + + + + + + + + + + + From 670cf02e95ae3b499555d8b3e6937320b525191d Mon Sep 17 00:00:00 2001 From: oca-ci Date: Mon, 5 May 2025 06:12:26 +0000 Subject: [PATCH 048/357] [UPD] Update stock_release_channel_depot.pot --- .../i18n/stock_release_channel_depot.pot | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 stock_release_channel_depot/i18n/stock_release_channel_depot.pot diff --git a/stock_release_channel_depot/i18n/stock_release_channel_depot.pot b/stock_release_channel_depot/i18n/stock_release_channel_depot.pot new file mode 100644 index 00000000000..b7e1546fbc0 --- /dev/null +++ b/stock_release_channel_depot/i18n/stock_release_channel_depot.pot @@ -0,0 +1,30 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_release_channel_depot +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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_release_channel_depot +#: model:ir.model.fields,field_description:stock_release_channel_depot.field_stock_picking__depot_id +#: model:ir.model.fields,field_description:stock_release_channel_depot.field_stock_release_channel__depot_id +msgid "Depot" +msgstr "" + +#. module: stock_release_channel_depot +#: model:ir.model,name:stock_release_channel_depot.model_stock_release_channel +msgid "Stock Release Channels" +msgstr "" + +#. module: stock_release_channel_depot +#: model:ir.model,name:stock_release_channel_depot.model_stock_picking +msgid "Transfer" +msgstr "" From 7cfdcd519240a8f60a48f0321b7f9b7696904da0 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 5 May 2025 06:23:45 +0000 Subject: [PATCH 049/357] [BOT] post-merge updates --- README.md | 1 + setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + stock_release_channel_depot/README.rst | 11 +++-- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 42 ++++++++++-------- 6 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 stock_release_channel_depot/static/description/icon.png diff --git a/README.md b/README.md index c1238767c87..5fd2fcdf0b1 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ addon | version | maintainers | summary [stock_release_channel_batch_mode_commercial_partner](stock_release_channel_batch_mode_commercial_partner/) | 16.0.1.0.2 | | Release pickings into channels by batch of same commercial entity [stock_release_channel_cutoff](stock_release_channel_cutoff/) | 16.0.1.0.2 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add the cutoff time to the release channel [stock_release_channel_delivery](stock_release_channel_delivery/) | 16.0.2.1.0 | | Add a carrier selection criteria on the release channel +[stock_release_channel_depot](stock_release_channel_depot/) | 16.0.1.0.0 | | This module allows users to add partner depot to stock release channel. [stock_release_channel_geoengine](stock_release_channel_geoengine/) | 16.0.1.1.0 | | Release channel based on geo-localization [stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.1.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates [stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.1.0.1 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 22db282e855..a22e3e0895a 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250430.0 \ No newline at end of file +16.0.20250505.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index 3ce8f568c8c..9bf92308092 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -36,6 +36,7 @@ 'odoo-addon-stock_release_channel_batch_mode_commercial_partner>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_cutoff>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_delivery>=16.0dev,<16.1dev', + 'odoo-addon-stock_release_channel_depot>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_geoengine>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_by_date>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_delivery_window>=16.0dev,<16.1dev', diff --git a/stock_release_channel_depot/README.rst b/stock_release_channel_depot/README.rst index bd1e070daa5..2592c70064f 100644 --- a/stock_release_channel_depot/README.rst +++ b/stock_release_channel_depot/README.rst @@ -2,10 +2,13 @@ Stock Release Channel Depot =========================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:0a56a1bb41eebdd7b8566fadc36e5057eccab67da1131086b4c42c193b330523 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -20,10 +23,10 @@ Stock Release Channel Depot :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_depot :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/wms&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| Add partner depot to stock release channel @@ -37,7 +40,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed +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. diff --git a/stock_release_channel_depot/static/description/icon.png b/stock_release_channel_depot/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 - + Stock Release Channel Depot + + +
+

Glue Stock Release Channels for Delivery Dates and Public holidays

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Test module between Stock Release Channels for Delivery Dates and Public holiday

+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • BCIM
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

Current maintainer:

+

jbaudoux

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_release_channel_partner_by_date_public_holidays/tests/__init__.py b/stock_release_channel_partner_by_date_public_holidays/tests/__init__.py new file mode 100644 index 00000000000..3e28dc125ca --- /dev/null +++ b/stock_release_channel_partner_by_date_public_holidays/tests/__init__.py @@ -0,0 +1 @@ +from . import test_release_channel_partner_date diff --git a/stock_release_channel_partner_by_date_public_holidays/tests/test_release_channel_partner_date.py b/stock_release_channel_partner_by_date_public_holidays/tests/test_release_channel_partner_date.py new file mode 100644 index 00000000000..0ddb6215208 --- /dev/null +++ b/stock_release_channel_partner_by_date_public_holidays/tests/test_release_channel_partner_date.py @@ -0,0 +1,31 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields + +from odoo.addons.stock_release_channel_partner_by_date.tests.common import ( + ReleaseChannelPartnerDateCommon, +) + + +class TestReleaseChannelPartnerDate(ReleaseChannelPartnerDateCommon): + def test_release_channel_on_specific_date_not_available(self): + """Test that when no release channel is available to satisfy + a specific partner date, no fallback release channel is + proposed.""" + scheduled_date = fields.Datetime.now() + + # Create holiday + this_year = scheduled_date.year + holiday_year = self.env["hr.holidays.public"].create({"year": this_year}) + self.env["hr.holidays.public.line"].create( + {"name": "holiday 1", "date": scheduled_date, "year_id": holiday_year.id} + ) + self._create_channel_partner_date( + self.delivery_date_channel, + self.partner, + scheduled_date, + ) + self.move.picking_id.scheduled_date = scheduled_date + self.move.picking_id.assign_release_channel() + self.assertFalse(self.move.picking_id.release_channel_id) From e388671a0348aa6808b434471e7d262508a363a5 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Wed, 14 May 2025 14:18:02 +0200 Subject: [PATCH 069/357] [IMP] stock_release_channel_partner_public_holidays Move filtering to existing domain method --- .../models/stock_picking.py | 37 +++++++++++++++---- .../models/stock_release_channel.py | 30 --------------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/stock_release_channel_partner_public_holidays/models/stock_picking.py b/stock_release_channel_partner_public_holidays/models/stock_picking.py index 071dc674a77..d67ee441c2f 100644 --- a/stock_release_channel_partner_public_holidays/models/stock_picking.py +++ b/stock_release_channel_partner_public_holidays/models/stock_picking.py @@ -1,15 +1,36 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import models + +from datetime import timedelta + +from odoo import fields, models +from odoo.osv import expression class StockPicking(models.Model): _inherit = "stock.picking" - def _find_release_channel_possible_candidate(self): - """Filter channels: make sure shipment date is not a public holiday of Partner - :return: release channels - """ - channels = super()._find_release_channel_possible_candidate() - channels = channels.filter_release_channel(self.partner_id) - return channels + def _get_release_channel_possible_candidate_domain_partner_public_holidays(self): + now = fields.Datetime.now() + all_holidays = self.env["hr.holidays.public"].get_holidays_list( + start_dt=now, + end_dt=now + timedelta(365), + partner_id=self.partner_id.id, + ) + if not all_holidays: + return [] + return [ + "|", + ("exclude_public_holidays", "=", False), + ("shipment_date", "not in", all_holidays.mapped("date")), + ] + + def _get_release_channel_possible_candidate_domain_channel(self): + domain = super()._get_release_channel_possible_candidate_domain_channel() + return expression.AND( + [ + domain, + self._get_release_channel_possible_candidate_domain_partner_public_holidays(), + ] + ) diff --git a/stock_release_channel_partner_public_holidays/models/stock_release_channel.py b/stock_release_channel_partner_public_holidays/models/stock_release_channel.py index 99fecdefc51..d244d52e9f8 100644 --- a/stock_release_channel_partner_public_holidays/models/stock_release_channel.py +++ b/stock_release_channel_partner_public_holidays/models/stock_release_channel.py @@ -7,33 +7,3 @@ class StockReleaseChannel(models.Model): _inherit = "stock.release.channel" exclude_public_holidays = fields.Boolean() - - def filter_release_channel(self, partner): - channels = self - for channel in self: - if not channel.exclude_public_holidays: - continue - if channel._is_shipment_date_a_public_holiday(partner): - channels -= channel - return channels - - def _is_shipment_date_a_public_holiday(self, partner): - """ - Returns True if shipment_date is a public holiday - :return: bool - """ - self.ensure_one() - res = False - shipment_date = self.shipment_date - if not shipment_date: - return res - domain = [ - ("year_id.country_id", "in", (False, partner.country_id.id)), - "|", - ("state_ids", "=", False), - ("state_ids", "=", partner.state_id.id), - ("date", "=", shipment_date), - ] - hhplo = self.env["hr.holidays.public.line"] - holidays_line = hhplo.search(domain, limit=1, order="id") - return bool(holidays_line) From 6260b6f9b1ae9b61c04937bb5bbe55de00382073 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 May 2025 14:45:15 +0200 Subject: [PATCH 070/357] [FIX] stock_release_channel_partner_delivery_window Fix channel assignment computation --- .../__manifest__.py | 2 ++ .../models/stock_release_channel.py | 34 ++++++------------- .../readme/USAGE.rst | 0 .../tests/test_release_window.py | 5 +-- 4 files changed, 16 insertions(+), 25 deletions(-) delete mode 100644 stock_release_channel_partner_delivery_window/readme/USAGE.rst diff --git a/stock_release_channel_partner_delivery_window/__manifest__.py b/stock_release_channel_partner_delivery_window/__manifest__.py index 9d73aa55803..18d64ac7028 100644 --- a/stock_release_channel_partner_delivery_window/__manifest__.py +++ b/stock_release_channel_partner_delivery_window/__manifest__.py @@ -1,3 +1,4 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { @@ -11,6 +12,7 @@ "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "depends": [ + "sale", "stock_partner_delivery_window", "stock_release_channel_shipment_lead_time", ], diff --git a/stock_release_channel_partner_delivery_window/models/stock_release_channel.py b/stock_release_channel_partner_delivery_window/models/stock_release_channel.py index 33ed84b3e19..48871aa1181 100644 --- a/stock_release_channel_partner_delivery_window/models/stock_release_channel.py +++ b/stock_release_channel_partner_delivery_window/models/stock_release_channel.py @@ -1,3 +1,4 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import fields, models @@ -17,26 +18,13 @@ class StockReleaseChannel(models.Model): ) def filter_release_channel_partner_window(self, picking, partner): - channels = self - if ( - not partner.delivery_time_preference - or partner.delivery_time_preference == "anytime" - ): - return channels - - for channel in self: - if not channel.shipment_date: - continue - shipment_datetime = fields.Datetime.to_datetime(channel.shipment_date) - if channel.process_end_date: - shipment_datetime = shipment_datetime.replace( - hour=channel.process_end_date.hour, - minute=channel.process_end_date.minute, - ) - if ( - channel.respect_partner_delivery_time_windows - and not picking.sale_id.commitment_date - and not partner.is_in_delivery_window(shipment_datetime) - ): - channels -= channel - return channels + if picking.sale_id.commitment_date: + # Date is forced on SO, don't filter + return self + return self.filtered( + lambda channel: not channel.respect_partner_delivery_time_windows + or ( + channel.shipment_date + and channel.shipment_date.weekday() in partner.delivery_time_weekdays + ) + ) diff --git a/stock_release_channel_partner_delivery_window/readme/USAGE.rst b/stock_release_channel_partner_delivery_window/readme/USAGE.rst deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/stock_release_channel_partner_delivery_window/tests/test_release_window.py b/stock_release_channel_partner_delivery_window/tests/test_release_window.py index a06a73fb78e..d61d375ecb1 100644 --- a/stock_release_channel_partner_delivery_window/tests/test_release_window.py +++ b/stock_release_channel_partner_delivery_window/tests/test_release_window.py @@ -1,3 +1,4 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from datetime import timedelta @@ -28,8 +29,8 @@ def setUpClass(cls): 0, 0, { - "time_window_start": 0.00, - "time_window_end": 23.99, + "time_window_start": 8.00, + "time_window_end": 18.50, "time_window_weekday_ids": [ ( 6, From 60edcf6f8076ced7881bd4036e2c18dcfeec764f Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 15 May 2025 11:21:45 +0000 Subject: [PATCH 071/357] [UPD] Update stock_release_channel_partner_by_date_public_holidays.pot --- ...ease_channel_partner_by_date_public_holidays.pot | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 stock_release_channel_partner_by_date_public_holidays/i18n/stock_release_channel_partner_by_date_public_holidays.pot diff --git a/stock_release_channel_partner_by_date_public_holidays/i18n/stock_release_channel_partner_by_date_public_holidays.pot b/stock_release_channel_partner_by_date_public_holidays/i18n/stock_release_channel_partner_by_date_public_holidays.pot new file mode 100644 index 00000000000..78d58d53fe0 --- /dev/null +++ b/stock_release_channel_partner_by_date_public_holidays/i18n/stock_release_channel_partner_by_date_public_holidays.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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" From f663e66813175595a7a09135e498ddc80930fca7 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 15 May 2025 11:33:36 +0000 Subject: [PATCH 072/357] [BOT] post-merge updates --- README.md | 3 +- setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 2 +- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 46 +++++++++--------- 10 files changed, 33 insertions(+), 29 deletions(-) create mode 100644 stock_release_channel_partner_by_date_public_holidays/static/description/icon.png diff --git a/README.md b/README.md index 8d7a04877e5..0a184882929 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,9 @@ addon | version | maintainers | summary [stock_release_channel_depot](stock_release_channel_depot/) | 16.0.1.0.0 | | This module allows users to add partner depot to stock release channel. [stock_release_channel_geoengine](stock_release_channel_geoengine/) | 16.0.1.1.0 | | Release channel based on geo-localization [stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.1.1.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates +[stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Public holidays [stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.1.0.1 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings -[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel +[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel [stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Manage release channel preparation plan [stock_release_channel_plan_process_end_time](stock_release_channel_plan_process_end_time/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue module between release channel plan and process end time [stock_release_channel_plan_shipment_lead_time](stock_release_channel_plan_shipment_lead_time/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Stock release channel plan shipment lead time diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index a22e3e0895a..8afc86e729c 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250505.0 \ No newline at end of file +16.0.20250515.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index 9bf92308092..2941ac6385d 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -39,6 +39,7 @@ 'odoo-addon-stock_release_channel_depot>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_geoengine>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_by_date>=16.0dev,<16.1dev', + 'odoo-addon-stock_release_channel_partner_by_date_public_holidays>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_delivery_window>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_public_holidays>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_plan>=16.0dev,<16.1dev', diff --git a/stock_release_channel_partner_by_date_public_holidays/README.rst b/stock_release_channel_partner_by_date_public_holidays/README.rst index 291e4325acb..3412d3d206d 100644 --- a/stock_release_channel_partner_by_date_public_holidays/README.rst +++ b/stock_release_channel_partner_by_date_public_holidays/README.rst @@ -7,7 +7,7 @@ Glue Stock Release Channels for Delivery Dates and Public holidays !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:4fe43c888e6b54ec55a6bb5e690de63ba9cd2a27d726808eb1402a2918d10764 + !! source digest: sha256:aa4d97e3cc741b05247e275f883632318049bee6262fe854b240c6160a123d47 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_partner_by_date_public_holidays/__manifest__.py b/stock_release_channel_partner_by_date_public_holidays/__manifest__.py index 697dd31ff99..c69898d9dde 100644 --- a/stock_release_channel_partner_by_date_public_holidays/__manifest__.py +++ b/stock_release_channel_partner_by_date_public_holidays/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Glue Stock Release Channels for Delivery Dates and Public holidays", - "version": "16.0.1.0.0", + "version": "16.0.1.1.0", "development_status": "Beta", "license": "AGPL-3", "author": "BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_by_date_public_holidays/static/description/icon.png b/stock_release_channel_partner_by_date_public_holidays/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Stock Release Channels for Delivery Dates and Public holi !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:4fe43c888e6b54ec55a6bb5e690de63ba9cd2a27d726808eb1402a2918d10764 +!! source digest: sha256:aa4d97e3cc741b05247e275f883632318049bee6262fe854b240c6160a123d47 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Test module between Stock Release Channels for Delivery Dates and Public holiday

diff --git a/stock_release_channel_partner_public_holidays/README.rst b/stock_release_channel_partner_public_holidays/README.rst index fbfcf24e26d..cc089bb9db7 100644 --- a/stock_release_channel_partner_public_holidays/README.rst +++ b/stock_release_channel_partner_public_holidays/README.rst @@ -7,7 +7,7 @@ Stock Release Channel Partner Public Holidays !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:7da4c7a1a2899c4f5465d2194105ab0242c4ea9ed32212592dfbb9aed03aebbe + !! source digest: sha256:86674ca944b224b795ffd2f36412ebf7b68254539747e47d89680ea6ac41d5bd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_partner_public_holidays/__manifest__.py b/stock_release_channel_partner_public_holidays/__manifest__.py index 3a88823f9df..72b11382eda 100644 --- a/stock_release_channel_partner_public_holidays/__manifest__.py +++ b/stock_release_channel_partner_public_holidays/__manifest__.py @@ -4,7 +4,7 @@ "name": "Stock Release Channel Partner Public Holidays", "summary": """ Add an option to exclude the public holidays when assigning th release channel""", - "version": "16.0.1.0.0", + "version": "16.0.1.1.0", "license": "AGPL-3", "maintainers": ["jbaudoux"], "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_public_holidays/static/description/index.html b/stock_release_channel_partner_public_holidays/static/description/index.html index fc747ca0f12..a0725fc1181 100644 --- a/stock_release_channel_partner_public_holidays/static/description/index.html +++ b/stock_release_channel_partner_public_holidays/static/description/index.html @@ -1,20 +1,20 @@ - - + Stock Release Channel Partner Public Holidays + + +
+

Sales Stock Release Channel

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Do not apply extra domains for finding release channel candidates when there is +an SO commitment date.

+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • BCIM
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

Current maintainer:

+

jbaudoux

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/sale_stock_release_channel/tests/__init__.py b/sale_stock_release_channel/tests/__init__.py new file mode 100644 index 00000000000..53d40210de1 --- /dev/null +++ b/sale_stock_release_channel/tests/__init__.py @@ -0,0 +1 @@ +from . import test_release_channel diff --git a/sale_stock_release_channel/tests/common.py b/sale_stock_release_channel/tests/common.py new file mode 100644 index 00000000000..d488274fedf --- /dev/null +++ b/sale_stock_release_channel/tests/common.py @@ -0,0 +1,14 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests.common import Form, TransactionCase + + +class SaleStockReleaseChannelCommon(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.customer = cls.env.ref("base.res_partner_1") + sale_form = Form(cls.env["sale.order"]) + sale_form.partner_id = cls.customer + cls.so = sale_form.save() diff --git a/sale_stock_release_channel/tests/test_release_channel.py b/sale_stock_release_channel/tests/test_release_channel.py new file mode 100644 index 00000000000..63b88cc710e --- /dev/null +++ b/sale_stock_release_channel/tests/test_release_channel.py @@ -0,0 +1,11 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from .common import SaleStockReleaseChannelCommon + + +class TestSaleStockReleaseChannel(SaleStockReleaseChannelCommon): + def test_candidate_domain(self): + """Test domain returns a value""" + domain = self.so._release_channel_possible_candidate_domain_base + self.assertIsInstance(domain, list) diff --git a/setup/sale_stock_release_channel/odoo/addons/sale_stock_release_channel b/setup/sale_stock_release_channel/odoo/addons/sale_stock_release_channel new file mode 120000 index 00000000000..4ee365a5345 --- /dev/null +++ b/setup/sale_stock_release_channel/odoo/addons/sale_stock_release_channel @@ -0,0 +1 @@ +../../../../sale_stock_release_channel \ No newline at end of file diff --git a/setup/sale_stock_release_channel/setup.py b/setup/sale_stock_release_channel/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/sale_stock_release_channel/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 26024895b13a51b2b951469caffe1a56e7747e3c Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Sun, 18 May 2025 19:16:02 +0200 Subject: [PATCH 088/357] [ADD] sale_stock_release_channel_delivery --- .../README.rst | 85 ++++ .../__init__.py | 1 + .../__manifest__.py | 16 + .../models/__init__.py | 1 + .../models/sale_order.py | 31 ++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 2 + .../static/description/index.html | 426 ++++++++++++++++++ .../tests/__init__.py | 1 + .../tests/test_release_channel.py | 13 + .../sale_stock_release_channel_delivery | 1 + .../setup.py | 6 + 12 files changed, 584 insertions(+) create mode 100644 sale_stock_release_channel_delivery/README.rst create mode 100644 sale_stock_release_channel_delivery/__init__.py create mode 100644 sale_stock_release_channel_delivery/__manifest__.py create mode 100644 sale_stock_release_channel_delivery/models/__init__.py create mode 100644 sale_stock_release_channel_delivery/models/sale_order.py create mode 100644 sale_stock_release_channel_delivery/readme/CONTRIBUTORS.rst create mode 100644 sale_stock_release_channel_delivery/readme/DESCRIPTION.rst create mode 100644 sale_stock_release_channel_delivery/static/description/index.html create mode 100644 sale_stock_release_channel_delivery/tests/__init__.py create mode 100644 sale_stock_release_channel_delivery/tests/test_release_channel.py create mode 120000 setup/sale_stock_release_channel_delivery/odoo/addons/sale_stock_release_channel_delivery create mode 100644 setup/sale_stock_release_channel_delivery/setup.py diff --git a/sale_stock_release_channel_delivery/README.rst b/sale_stock_release_channel_delivery/README.rst new file mode 100644 index 00000000000..72982a72e22 --- /dev/null +++ b/sale_stock_release_channel_delivery/README.rst @@ -0,0 +1,85 @@ +==================================== +Sales Stock Release Channel Delivery +==================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:4f534f7308ae014934704708eade46e994c7c54ff3fb81f37951f5438b37a863 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/sale_stock_release_channel_delivery + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-sale_stock_release_channel_delivery + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Do not apply extra domains for finding release channel candidates when there is +an SO commitment date. + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* BCIM + +Contributors +~~~~~~~~~~~~ + +* Jacques-Etienne Baudoux (BCIM) + +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. + +.. |maintainer-jbaudoux| image:: https://github.com/jbaudoux.png?size=40px + :target: https://github.com/jbaudoux + :alt: jbaudoux + +Current `maintainer `__: + +|maintainer-jbaudoux| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_stock_release_channel_delivery/__init__.py b/sale_stock_release_channel_delivery/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/sale_stock_release_channel_delivery/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_stock_release_channel_delivery/__manifest__.py b/sale_stock_release_channel_delivery/__manifest__.py new file mode 100644 index 00000000000..40ca88ec676 --- /dev/null +++ b/sale_stock_release_channel_delivery/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Sales Stock Release Channel Delivery", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "maintainers": ["jbaudoux"], + "author": "BCIM, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/wms", + "depends": [ + "sale_stock_release_channel", + "stock_release_channel_delivery", + ], + "auto_install": True, +} diff --git a/sale_stock_release_channel_delivery/models/__init__.py b/sale_stock_release_channel_delivery/models/__init__.py new file mode 100644 index 00000000000..6aacb753131 --- /dev/null +++ b/sale_stock_release_channel_delivery/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order diff --git a/sale_stock_release_channel_delivery/models/sale_order.py b/sale_stock_release_channel_delivery/models/sale_order.py new file mode 100644 index 00000000000..426cdce35bd --- /dev/null +++ b/sale_stock_release_channel_delivery/models/sale_order.py @@ -0,0 +1,31 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models +from odoo.osv import expression + + +class SaleOrder(models.Model): + + _inherit = "sale.order" + + @property + def _release_channel_carrier_id(self): + """Return the SO carrier or planned carrier at confirm""" + return self.carrier_id + + @property + def _release_channel_possible_candidate_domain_base(self): + # Mimick the domain extension defined on stock.picking in + # stock_release_channel_delivery + domain = super()._release_channel_possible_candidate_domain_base + if self._release_channel_carrier_id: + domain_carrier = [ + "|", + ("carrier_ids", "=", False), + ("carrier_ids", "in", self._release_channel_carrier_id.id), + ] + else: + domain_carrier = [("carrier_ids", "=", False)] + domain = expression.AND([domain, domain_carrier]) + return domain diff --git a/sale_stock_release_channel_delivery/readme/CONTRIBUTORS.rst b/sale_stock_release_channel_delivery/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..3c6c5c696a8 --- /dev/null +++ b/sale_stock_release_channel_delivery/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Jacques-Etienne Baudoux (BCIM) diff --git a/sale_stock_release_channel_delivery/readme/DESCRIPTION.rst b/sale_stock_release_channel_delivery/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..3ee583f0f50 --- /dev/null +++ b/sale_stock_release_channel_delivery/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +Do not apply extra domains for finding release channel candidates when there is +an SO commitment date. diff --git a/sale_stock_release_channel_delivery/static/description/index.html b/sale_stock_release_channel_delivery/static/description/index.html new file mode 100644 index 00000000000..293a2a8c8b7 --- /dev/null +++ b/sale_stock_release_channel_delivery/static/description/index.html @@ -0,0 +1,426 @@ + + + + + +Sales Stock Release Channel Delivery + + + +
+

Sales Stock Release Channel Delivery

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Do not apply extra domains for finding release channel candidates when there is +an SO commitment date.

+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • BCIM
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

Current maintainer:

+

jbaudoux

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/sale_stock_release_channel_delivery/tests/__init__.py b/sale_stock_release_channel_delivery/tests/__init__.py new file mode 100644 index 00000000000..53d40210de1 --- /dev/null +++ b/sale_stock_release_channel_delivery/tests/__init__.py @@ -0,0 +1 @@ +from . import test_release_channel diff --git a/sale_stock_release_channel_delivery/tests/test_release_channel.py b/sale_stock_release_channel_delivery/tests/test_release_channel.py new file mode 100644 index 00000000000..a1ab9632508 --- /dev/null +++ b/sale_stock_release_channel_delivery/tests/test_release_channel.py @@ -0,0 +1,13 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.addons.sale_stock_release_channel.tests.common import ( + SaleStockReleaseChannelCommon, +) + + +class TestSaleStockReleaseChannel(SaleStockReleaseChannelCommon): + def test_candidate_domain(self): + """Test domain returns a value""" + domain = self.so._release_channel_possible_candidate_domain_base + self.assertIsInstance(domain, list) diff --git a/setup/sale_stock_release_channel_delivery/odoo/addons/sale_stock_release_channel_delivery b/setup/sale_stock_release_channel_delivery/odoo/addons/sale_stock_release_channel_delivery new file mode 120000 index 00000000000..59d2936211d --- /dev/null +++ b/setup/sale_stock_release_channel_delivery/odoo/addons/sale_stock_release_channel_delivery @@ -0,0 +1 @@ +../../../../sale_stock_release_channel_delivery \ No newline at end of file diff --git a/setup/sale_stock_release_channel_delivery/setup.py b/setup/sale_stock_release_channel_delivery/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/sale_stock_release_channel_delivery/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 0155b1d1becf8f6fa2c607af3c012f8f6ace7c65 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 20 May 2025 07:41:39 +0000 Subject: [PATCH 089/357] [UPD] Update stock_release_channel_geoengine.pot --- .../i18n/stock_release_channel_geoengine.pot | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stock_release_channel_geoengine/i18n/stock_release_channel_geoengine.pot b/stock_release_channel_geoengine/i18n/stock_release_channel_geoengine.pot index 76f51a4e088..8a91acf7ca3 100644 --- a/stock_release_channel_geoengine/i18n/stock_release_channel_geoengine.pot +++ b/stock_release_channel_geoengine/i18n/stock_release_channel_geoengine.pot @@ -97,11 +97,6 @@ msgstr "" msgid "To Release:" msgstr "" -#. module: stock_release_channel_geoengine -#: model:ir.model,name:stock_release_channel_geoengine.model_stock_picking -msgid "Transfer" -msgstr "" - #. module: stock_release_channel_geoengine #: model_terms:ir.ui.view,arch_db:stock_release_channel_geoengine.stock_release_channel_geoengine_view msgid "Waiting:" From 67c3edc8c39f0d264281ca1c59b39c6b83c49132 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 20 May 2025 07:41:40 +0000 Subject: [PATCH 090/357] [UPD] Update stock_release_channel_partner_delivery_window.pot --- .../i18n/stock_release_channel_partner_delivery_window.pot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stock_release_channel_partner_delivery_window/i18n/stock_release_channel_partner_delivery_window.pot b/stock_release_channel_partner_delivery_window/i18n/stock_release_channel_partner_delivery_window.pot index 305c4552c35..a22ca7cca9d 100644 --- a/stock_release_channel_partner_delivery_window/i18n/stock_release_channel_partner_delivery_window.pot +++ b/stock_release_channel_partner_delivery_window/i18n/stock_release_channel_partner_delivery_window.pot @@ -13,6 +13,11 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: stock_release_channel_partner_delivery_window +#: model:ir.model.fields,field_description:stock_release_channel_partner_delivery_window.field_stock_release_channel__delivery_date_weekday +msgid "Delivery Date Weekday" +msgstr "" + #. module: stock_release_channel_partner_delivery_window #: model:ir.model.fields,help:stock_release_channel_partner_delivery_window.field_stock_release_channel__respect_partner_delivery_time_windows msgid "" From b3f10c00a40acad6beba01bcf7875fb97c5abd4e Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 20 May 2025 07:41:43 +0000 Subject: [PATCH 091/357] [UPD] Update stock_release_channel_shipment_advice_deliver.pot --- .../i18n/stock_release_channel_shipment_advice_deliver.pot | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stock_release_channel_shipment_advice_deliver/i18n/stock_release_channel_shipment_advice_deliver.pot b/stock_release_channel_shipment_advice_deliver/i18n/stock_release_channel_shipment_advice_deliver.pot index d3f3034a8ef..92a3a8cfc95 100644 --- a/stock_release_channel_shipment_advice_deliver/i18n/stock_release_channel_shipment_advice_deliver.pot +++ b/stock_release_channel_shipment_advice_deliver/i18n/stock_release_channel_shipment_advice_deliver.pot @@ -261,11 +261,6 @@ msgid "" " Are you sure you want to proceed with the delivery?" msgstr "" -#. module: stock_release_channel_shipment_advice_deliver -#: model:ir.model,name:stock_release_channel_shipment_advice_deliver.model_stock_picking -msgid "Transfer" -msgstr "" - #. module: stock_release_channel_shipment_advice_deliver #: model:ir.model,name:stock_release_channel_shipment_advice_deliver.model_stock_release_channel_deliver_check_wizard msgid "stock release channel deliver check wizard" From b2863e150f98eb1fe6a1bfff499bb28ebd565644 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 20 May 2025 07:53:29 +0000 Subject: [PATCH 092/357] [BOT] post-merge updates --- README.md | 18 +++++++++--------- stock_release_channel/README.rst | 2 +- stock_release_channel/__manifest__.py | 2 +- .../static/description/index.html | 2 +- stock_release_channel_delivery/README.rst | 2 +- stock_release_channel_delivery/__manifest__.py | 2 +- .../static/description/index.html | 2 +- stock_release_channel_geoengine/README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- 28 files changed, 36 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 8f2a8a51c86..5a4c254fe41 100644 --- a/README.md +++ b/README.md @@ -44,27 +44,27 @@ addon | version | maintainers | summary [stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.1.0.0 | [![lmignon](https://github.com/lmignon.png?size=30px)](https://github.com/lmignon) | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type -[stock_release_channel](stock_release_channel/) | 16.0.2.19.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![mt-software-de](https://github.com/mt-software-de.png?size=30px)](https://github.com/mt-software-de) | Manage workload in WMS with release channels +[stock_release_channel](stock_release_channel/) | 16.0.3.0.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![mt-software-de](https://github.com/mt-software-de.png?size=30px)](https://github.com/mt-software-de) | Manage workload in WMS with release channels [stock_release_channel_auto_release](stock_release_channel_auto_release/) | 16.0.1.1.0 | | Add an automatic release mode to the release channel [stock_release_channel_batch_mode_commercial_partner](stock_release_channel_batch_mode_commercial_partner/) | 16.0.1.0.2 | | Release pickings into channels by batch of same commercial entity [stock_release_channel_cutoff](stock_release_channel_cutoff/) | 16.0.1.0.2 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add the cutoff time to the release channel -[stock_release_channel_delivery](stock_release_channel_delivery/) | 16.0.2.1.0 | | Add a carrier selection criteria on the release channel +[stock_release_channel_delivery](stock_release_channel_delivery/) | 16.0.3.0.0 | | Add a carrier selection criteria on the release channel [stock_release_channel_depot](stock_release_channel_depot/) | 16.0.1.0.0 | | This module allows users to add partner depot to stock release channel. -[stock_release_channel_geoengine](stock_release_channel_geoengine/) | 16.0.1.1.0 | | Release channel based on geo-localization -[stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.1.1.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates -[stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Public holidays -[stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings -[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel +[stock_release_channel_geoengine](stock_release_channel_geoengine/) | 16.0.2.0.0 | | Release channel based on geo-localization +[stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.2.0.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates +[stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Public holidays +[stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings +[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel [stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Manage release channel preparation plan [stock_release_channel_plan_process_end_time](stock_release_channel_plan_process_end_time/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue module between release channel plan and process end time [stock_release_channel_plan_shipment_lead_time](stock_release_channel_plan_shipment_lead_time/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Stock release channel plan shipment lead time [stock_release_channel_process_end_time](stock_release_channel_process_end_time/) | 16.0.1.7.0 | [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_propagate_channel_picking](stock_release_channel_propagate_channel_picking/) | 16.0.1.2.0 | | Allows to propagate the channel to every picking that is created from the original one. [stock_release_channel_shipment_advice](stock_release_channel_shipment_advice/) | 16.0.1.2.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Plan shipment advices for ready and released pickings -[stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.1.1.0 | | This module adds an action to the release channel to automate the delivery of its shippings. +[stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.0 | | This module adds an action to the release channel to automate the delivery of its shippings. [stock_release_channel_shipment_advice_process_end_time](stock_release_channel_shipment_advice_process_end_time/) | 16.0.1.0.0 | | This module allows to set a delay time (in minutes) between the release channel process end time and the shipment advice arrival to the dock time. [stock_release_channel_shipment_advice_toursolver](stock_release_channel_shipment_advice_toursolver/) | 16.0.1.0.1 | | Use TourSolver to plan shipment advices for ready and released pickings -[stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.1.3.1 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Release channel with shipment lead time +[stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Release channel with shipment lead time [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels [stock_storage_type](stock_storage_type/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) | Manage packages and locations storage types diff --git a/stock_release_channel/README.rst b/stock_release_channel/README.rst index 55a0e9ca081..219d6c85994 100644 --- a/stock_release_channel/README.rst +++ b/stock_release_channel/README.rst @@ -7,7 +7,7 @@ Stock Release Channels !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:6b5b036fae8830ee36b903acf9d9a8275defe86ac5cdb1236411be37d5743641 + !! source digest: sha256:d3e4a6ca33a07a0967c75174dc29fa2dc7cc413f659bcd0686dd3238396bd3a8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel/__manifest__.py b/stock_release_channel/__manifest__.py index 89c4aa9c9fc..726892df5b7 100644 --- a/stock_release_channel/__manifest__.py +++ b/stock_release_channel/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Stock Release Channels", "summary": "Manage workload in WMS with release channels", - "version": "16.0.2.19.1", + "version": "16.0.3.0.0", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, ACSONE SA/NV, Odoo Community Association (OCA)", diff --git a/stock_release_channel/static/description/index.html b/stock_release_channel/static/description/index.html index c0eea5d5dcf..3a5f2e338e7 100644 --- a/stock_release_channel/static/description/index.html +++ b/stock_release_channel/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channels

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:6b5b036fae8830ee36b903acf9d9a8275defe86ac5cdb1236411be37d5743641 +!! source digest: sha256:d3e4a6ca33a07a0967c75174dc29fa2dc7cc413f659bcd0686dd3238396bd3a8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Release channels are:

diff --git a/stock_release_channel_delivery/README.rst b/stock_release_channel_delivery/README.rst index 1869db3dc1c..f7536e7f17c 100644 --- a/stock_release_channel_delivery/README.rst +++ b/stock_release_channel_delivery/README.rst @@ -7,7 +7,7 @@ Stock Release Channel Delivery !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:cc77481670c48e1405bcdfe6831bc807e6f5e989075fbd6195a43e9a6992330c + !! source digest: sha256:d86dc233e0fdccccf51aee7ec5f966b26b901a04c888531fb06aea98074dcf62 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_delivery/__manifest__.py b/stock_release_channel_delivery/__manifest__.py index caf7ef53af3..fc733129860 100644 --- a/stock_release_channel_delivery/__manifest__.py +++ b/stock_release_channel_delivery/__manifest__.py @@ -5,7 +5,7 @@ "name": "Stock Release Channel Delivery", "summary": """ Add a carrier selection criteria on the release channel """, - "version": "16.0.2.1.0", + "version": "16.0.3.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV,BCIM,Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_release_channel_delivery/static/description/index.html b/stock_release_channel_delivery/static/description/index.html index 7404f31d78e..03ceb942d9d 100644 --- a/stock_release_channel_delivery/static/description/index.html +++ b/stock_release_channel_delivery/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channel Delivery

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:cc77481670c48e1405bcdfe6831bc807e6f5e989075fbd6195a43e9a6992330c +!! source digest: sha256:d86dc233e0fdccccf51aee7ec5f966b26b901a04c888531fb06aea98074dcf62 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This addon adds a selection criteria on the release channel based on the shipping diff --git a/stock_release_channel_geoengine/README.rst b/stock_release_channel_geoengine/README.rst index 621e5ea25b2..21ccc700371 100644 --- a/stock_release_channel_geoengine/README.rst +++ b/stock_release_channel_geoengine/README.rst @@ -7,7 +7,7 @@ Stock Release Channel Geoengine !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:4e6a0c62f90513e2c1a31fa1b4e5780862cb8e5182ee0dfa16b63fddca7e28f1 + !! source digest: sha256:f710239ba0afe50575605fba54d5b1041491ffb4b66caed10ca5027d745651eb !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_geoengine/__manifest__.py b/stock_release_channel_geoengine/__manifest__.py index da2ada5e04c..5d0c61218b0 100644 --- a/stock_release_channel_geoengine/__manifest__.py +++ b/stock_release_channel_geoengine/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Stock Release Channel Geoengine", "summary": """Release channel based on geo-localization""", - "version": "16.0.1.1.0", + "version": "16.0.2.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_release_channel_geoengine/static/description/index.html b/stock_release_channel_geoengine/static/description/index.html index d3438a4a9c8..da07aeb8c00 100644 --- a/stock_release_channel_geoengine/static/description/index.html +++ b/stock_release_channel_geoengine/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channel Geoengine

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:4e6a0c62f90513e2c1a31fa1b4e5780862cb8e5182ee0dfa16b63fddca7e28f1 +!! source digest: sha256:f710239ba0afe50575605fba54d5b1041491ffb4b66caed10ca5027d745651eb !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This module enhance release channels with the addition of diff --git a/stock_release_channel_partner_by_date/README.rst b/stock_release_channel_partner_by_date/README.rst index cfa28be517c..9b82d9a4ae5 100644 --- a/stock_release_channel_partner_by_date/README.rst +++ b/stock_release_channel_partner_by_date/README.rst @@ -7,7 +7,7 @@ Stock Release Channels for Delivery Dates !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:224c443456be835a2a77e7ad62bac6e4b1b7eb7d17486272cb7e8a29d87421e8 + !! source digest: sha256:16d1e9fa4cde82b51cd295a591fe8489504408753f6f9a677de3ab71dff53608 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_partner_by_date/__manifest__.py b/stock_release_channel_partner_by_date/__manifest__.py index a65e09850de..62e87e08087 100644 --- a/stock_release_channel_partner_by_date/__manifest__.py +++ b/stock_release_channel_partner_by_date/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Stock Release Channels for Delivery Dates", "summary": "Set release channels for specific delivery dates", - "version": "16.0.1.1.1", + "version": "16.0.2.0.0", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_by_date/static/description/index.html b/stock_release_channel_partner_by_date/static/description/index.html index 57686baec96..04d1c4080f6 100644 --- a/stock_release_channel_partner_by_date/static/description/index.html +++ b/stock_release_channel_partner_by_date/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channels for Delivery Dates

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:224c443456be835a2a77e7ad62bac6e4b1b7eb7d17486272cb7e8a29d87421e8 +!! source digest: sha256:16d1e9fa4cde82b51cd295a591fe8489504408753f6f9a677de3ab71dff53608 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Set release channels for specific delivery addresses and dates.

diff --git a/stock_release_channel_partner_by_date_public_holidays/README.rst b/stock_release_channel_partner_by_date_public_holidays/README.rst index 3412d3d206d..22034ae07ff 100644 --- a/stock_release_channel_partner_by_date_public_holidays/README.rst +++ b/stock_release_channel_partner_by_date_public_holidays/README.rst @@ -7,7 +7,7 @@ Glue Stock Release Channels for Delivery Dates and Public holidays !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:aa4d97e3cc741b05247e275f883632318049bee6262fe854b240c6160a123d47 + !! source digest: sha256:d97b4b0cd28c4b51d8d7d08d832b0caf31c2e966e3f4900ccd448a69c7969d4e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_partner_by_date_public_holidays/__manifest__.py b/stock_release_channel_partner_by_date_public_holidays/__manifest__.py index c69898d9dde..4408ece199d 100644 --- a/stock_release_channel_partner_by_date_public_holidays/__manifest__.py +++ b/stock_release_channel_partner_by_date_public_holidays/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Glue Stock Release Channels for Delivery Dates and Public holidays", - "version": "16.0.1.1.0", + "version": "16.0.2.0.0", "development_status": "Beta", "license": "AGPL-3", "author": "BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_by_date_public_holidays/static/description/index.html b/stock_release_channel_partner_by_date_public_holidays/static/description/index.html index d0f7cd424bc..24e499ed504 100644 --- a/stock_release_channel_partner_by_date_public_holidays/static/description/index.html +++ b/stock_release_channel_partner_by_date_public_holidays/static/description/index.html @@ -367,7 +367,7 @@

Glue Stock Release Channels for Delivery Dates and Public holi !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:aa4d97e3cc741b05247e275f883632318049bee6262fe854b240c6160a123d47 +!! source digest: sha256:d97b4b0cd28c4b51d8d7d08d832b0caf31c2e966e3f4900ccd448a69c7969d4e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Test module between Stock Release Channels for Delivery Dates and Public holiday

diff --git a/stock_release_channel_partner_delivery_window/README.rst b/stock_release_channel_partner_delivery_window/README.rst index 5e987f553e8..89ec119f731 100644 --- a/stock_release_channel_partner_delivery_window/README.rst +++ b/stock_release_channel_partner_delivery_window/README.rst @@ -7,7 +7,7 @@ Stock Release Channel Partner Delivery Window !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:a44098e5dc540d9b49424251b4d014f03f84169fce1a030afdaa2303be31313f + !! source digest: sha256:5883e42a1f877f4be3a892ba5719290292c453c87d886c95004d8859a6b76045 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_partner_delivery_window/__manifest__.py b/stock_release_channel_partner_delivery_window/__manifest__.py index bb96b2bb52a..d444cd3afbb 100644 --- a/stock_release_channel_partner_delivery_window/__manifest__.py +++ b/stock_release_channel_partner_delivery_window/__manifest__.py @@ -6,7 +6,7 @@ "summary": """ Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings""", - "version": "16.0.1.1.0", + "version": "16.0.2.0.0", "license": "AGPL-3", "maintainers": ["jbaudoux"], "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_delivery_window/static/description/index.html b/stock_release_channel_partner_delivery_window/static/description/index.html index 7258c045384..624ec1bc566 100644 --- a/stock_release_channel_partner_delivery_window/static/description/index.html +++ b/stock_release_channel_partner_delivery_window/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channel Partner Delivery Window

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:a44098e5dc540d9b49424251b4d014f03f84169fce1a030afdaa2303be31313f +!! source digest: sha256:5883e42a1f877f4be3a892ba5719290292c453c87d886c95004d8859a6b76045 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This module excludes the channel when its shipment date is not in Partner delivery window

diff --git a/stock_release_channel_partner_public_holidays/README.rst b/stock_release_channel_partner_public_holidays/README.rst index cc089bb9db7..b988d5298b3 100644 --- a/stock_release_channel_partner_public_holidays/README.rst +++ b/stock_release_channel_partner_public_holidays/README.rst @@ -7,7 +7,7 @@ Stock Release Channel Partner Public Holidays !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:86674ca944b224b795ffd2f36412ebf7b68254539747e47d89680ea6ac41d5bd + !! source digest: sha256:f693a3d2112af69a449d66b8a67b3e64ee7c14c09368f96527b9035adc234a97 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_partner_public_holidays/__manifest__.py b/stock_release_channel_partner_public_holidays/__manifest__.py index 72b11382eda..1d3376f33b0 100644 --- a/stock_release_channel_partner_public_holidays/__manifest__.py +++ b/stock_release_channel_partner_public_holidays/__manifest__.py @@ -4,7 +4,7 @@ "name": "Stock Release Channel Partner Public Holidays", "summary": """ Add an option to exclude the public holidays when assigning th release channel""", - "version": "16.0.1.1.0", + "version": "16.0.2.0.0", "license": "AGPL-3", "maintainers": ["jbaudoux"], "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_public_holidays/static/description/index.html b/stock_release_channel_partner_public_holidays/static/description/index.html index a0725fc1181..6ccc5d8c6cd 100644 --- a/stock_release_channel_partner_public_holidays/static/description/index.html +++ b/stock_release_channel_partner_public_holidays/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channel Partner Public Holidays

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:86674ca944b224b795ffd2f36412ebf7b68254539747e47d89680ea6ac41d5bd +!! source digest: sha256:f693a3d2112af69a449d66b8a67b3e64ee7c14c09368f96527b9035adc234a97 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This module adds an option to exclude the channel when its shipment date is a public holiday

diff --git a/stock_release_channel_shipment_advice_deliver/README.rst b/stock_release_channel_shipment_advice_deliver/README.rst index 986a237056e..53f0c38e290 100644 --- a/stock_release_channel_shipment_advice_deliver/README.rst +++ b/stock_release_channel_shipment_advice_deliver/README.rst @@ -7,7 +7,7 @@ Stock Release Channel Shipment Advice Deliver !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:dc1500cd3d3aeb4cc935b248aebbb30988b012245111ed6a0685e9bce156503d + !! source digest: sha256:db140089539861042d53b0bd663c8a69a99e5d2da9609f9bec7a28556b4409d1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_shipment_advice_deliver/__manifest__.py b/stock_release_channel_shipment_advice_deliver/__manifest__.py index 074ba3c2bb9..c35abcc2e3e 100644 --- a/stock_release_channel_shipment_advice_deliver/__manifest__.py +++ b/stock_release_channel_shipment_advice_deliver/__manifest__.py @@ -8,7 +8,7 @@ "author": "ACSONE SA/NV, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "16.0.1.1.0", + "version": "16.0.2.0.0", "license": "AGPL-3", "depends": [ "stock_release_channel", diff --git a/stock_release_channel_shipment_advice_deliver/static/description/index.html b/stock_release_channel_shipment_advice_deliver/static/description/index.html index 21dbe7e8e90..feb704a6cf1 100644 --- a/stock_release_channel_shipment_advice_deliver/static/description/index.html +++ b/stock_release_channel_shipment_advice_deliver/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channel Shipment Advice Deliver

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:dc1500cd3d3aeb4cc935b248aebbb30988b012245111ed6a0685e9bce156503d +!! source digest: sha256:db140089539861042d53b0bd663c8a69a99e5d2da9609f9bec7a28556b4409d1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This module adds an action to the release channel to automate the delivery of diff --git a/stock_release_channel_shipment_lead_time/README.rst b/stock_release_channel_shipment_lead_time/README.rst index 303746f257a..f50ac6f922b 100644 --- a/stock_release_channel_shipment_lead_time/README.rst +++ b/stock_release_channel_shipment_lead_time/README.rst @@ -7,7 +7,7 @@ Release channel shipment lead time !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3e1fee71870e1f1e045032f7436306c846a1fd49a8121169a669e3d33c952a94 + !! source digest: sha256:c2158bf4a0b06dcc988a18ebdd178f8a8b1abeff288dfc1a4721dd6222d21135 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_shipment_lead_time/__manifest__.py b/stock_release_channel_shipment_lead_time/__manifest__.py index 010ffc3395a..f43eee19f4e 100644 --- a/stock_release_channel_shipment_lead_time/__manifest__.py +++ b/stock_release_channel_shipment_lead_time/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Release channel shipment lead time", "summary": "Release channel with shipment lead time", - "version": "16.0.1.3.1", + "version": "16.0.2.0.0", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_shipment_lead_time/static/description/index.html b/stock_release_channel_shipment_lead_time/static/description/index.html index f9ad3f2f03e..8f2cd353d2f 100644 --- a/stock_release_channel_shipment_lead_time/static/description/index.html +++ b/stock_release_channel_shipment_lead_time/static/description/index.html @@ -367,7 +367,7 @@

Release channel shipment lead time

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:3e1fee71870e1f1e045032f7436306c846a1fd49a8121169a669e3d33c952a94 +!! source digest: sha256:c2158bf4a0b06dcc988a18ebdd178f8a8b1abeff288dfc1a4721dd6222d21135 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Manage shipment date and delivery lead time on release channel. From 9b957565b675181ef1a6dca1a893ec1a311403e4 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 20 May 2025 07:53:57 +0000 Subject: [PATCH 093/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_release_channel_geoengine Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_geoengine/ --- stock_release_channel_geoengine/i18n/it.po | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/stock_release_channel_geoengine/i18n/it.po b/stock_release_channel_geoengine/i18n/it.po index 1e33d12dfb0..3e0f39f33ed 100644 --- a/stock_release_channel_geoengine/i18n/it.po +++ b/stock_release_channel_geoengine/i18n/it.po @@ -100,11 +100,6 @@ msgstr "Da fare:" msgid "To Release:" msgstr "Da rilasciare:" -#. module: stock_release_channel_geoengine -#: model:ir.model,name:stock_release_channel_geoengine.model_stock_picking -msgid "Transfer" -msgstr "Trasferimento" - #. module: stock_release_channel_geoengine #: model_terms:ir.ui.view,arch_db:stock_release_channel_geoengine.stock_release_channel_geoengine_view msgid "Waiting:" @@ -114,3 +109,6 @@ msgstr "In attesa:" #: model_terms:ir.ui.view,arch_db:stock_release_channel_geoengine.stock_release_channel_geoengine_view msgid "Warehouse:" msgstr "Magazzino:" + +#~ msgid "Transfer" +#~ msgstr "Trasferimento" From 13be512001946f73789faff09055e8f2e675f612 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 20 May 2025 07:53:57 +0000 Subject: [PATCH 094/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_release_channel_partner_delivery_window Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_partner_delivery_window/ --- stock_release_channel_partner_delivery_window/i18n/fr.po | 9 +++++++-- stock_release_channel_partner_delivery_window/i18n/it.po | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/stock_release_channel_partner_delivery_window/i18n/fr.po b/stock_release_channel_partner_delivery_window/i18n/fr.po index 5324fc8ef95..a05e259483a 100644 --- a/stock_release_channel_partner_delivery_window/i18n/fr.po +++ b/stock_release_channel_partner_delivery_window/i18n/fr.po @@ -16,12 +16,17 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.6.2\n" +#. module: stock_release_channel_partner_delivery_window +#: model:ir.model.fields,field_description:stock_release_channel_partner_delivery_window.field_stock_release_channel__delivery_date_weekday +msgid "Delivery Date Weekday" +msgstr "" + #. module: stock_release_channel_partner_delivery_window #: model:ir.model.fields,help:stock_release_channel_partner_delivery_window.field_stock_release_channel__respect_partner_delivery_time_windows msgid "" "If the delivery has moves linked to SO lines linked to SO that has a " -"commitment_date, then we never respect the partner time window (it is not an" -" exclusion selection criteria anymore)" +"commitment_date, then we never respect the partner time window (it is not an " +"exclusion selection criteria anymore)" msgstr "" #. module: stock_release_channel_partner_delivery_window diff --git a/stock_release_channel_partner_delivery_window/i18n/it.po b/stock_release_channel_partner_delivery_window/i18n/it.po index 9da4bf3cdba..f2ddfe913e1 100644 --- a/stock_release_channel_partner_delivery_window/i18n/it.po +++ b/stock_release_channel_partner_delivery_window/i18n/it.po @@ -16,12 +16,17 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17\n" +#. module: stock_release_channel_partner_delivery_window +#: model:ir.model.fields,field_description:stock_release_channel_partner_delivery_window.field_stock_release_channel__delivery_date_weekday +msgid "Delivery Date Weekday" +msgstr "" + #. module: stock_release_channel_partner_delivery_window #: model:ir.model.fields,help:stock_release_channel_partner_delivery_window.field_stock_release_channel__respect_partner_delivery_time_windows msgid "" "If the delivery has moves linked to SO lines linked to SO that has a " -"commitment_date, then we never respect the partner time window (it is not an" -" exclusion selection criteria anymore)" +"commitment_date, then we never respect the partner time window (it is not an " +"exclusion selection criteria anymore)" msgstr "" "Se la consegna ha movimenti collegati a righe dell'OV che ha una data " "impegno, allora non si rispetta mai l'intervallo tempoale del partner (non è " From 6b1f14ca0b1fcde57fbfd5984d7ae2427dba418c Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 20 May 2025 07:53:57 +0000 Subject: [PATCH 095/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_release_channel_shipment_advice_deliver Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_shipment_advice_deliver/ --- .../i18n/fr.po | 8 +++--- .../i18n/it.po | 26 +++++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/stock_release_channel_shipment_advice_deliver/i18n/fr.po b/stock_release_channel_shipment_advice_deliver/i18n/fr.po index 2a3bbf39c81..9f6cb8a76f7 100644 --- a/stock_release_channel_shipment_advice_deliver/i18n/fr.po +++ b/stock_release_channel_shipment_advice_deliver/i18n/fr.po @@ -303,12 +303,10 @@ msgstr "" "remises en non libérées.
\n" " Êtes-vous sûr de vouloir procéder à la livraison ?" -#. module: stock_release_channel_shipment_advice_deliver -#: model:ir.model,name:stock_release_channel_shipment_advice_deliver.model_stock_picking -msgid "Transfer" -msgstr "Transfert" - #. module: stock_release_channel_shipment_advice_deliver #: model:ir.model,name:stock_release_channel_shipment_advice_deliver.model_stock_release_channel_deliver_check_wizard msgid "stock release channel deliver check wizard" msgstr "" + +#~ msgid "Transfer" +#~ msgstr "Transfert" diff --git a/stock_release_channel_shipment_advice_deliver/i18n/it.po b/stock_release_channel_shipment_advice_deliver/i18n/it.po index 3e28f336306..98f67989500 100644 --- a/stock_release_channel_shipment_advice_deliver/i18n/it.po +++ b/stock_release_channel_shipment_advice_deliver/i18n/it.po @@ -195,7 +195,8 @@ msgstr "Nessun prelievo da consegnare per il canale %(name)s." #, python-format msgid "" "One of the delivery for channel %(name)s is waiting on another transfer. \n" -"Please finish it manually or cancel its start and done quantities to be able to deliver.\n" +"Please finish it manually or cancel its start and done quantities to be able " +"to deliver.\n" "%(pickings)s" msgstr "" "Una delle consegne per il canale %(name)s è in attesa di un altro " @@ -263,12 +264,16 @@ msgstr "" #: model:ir.model.fields,help:stock_release_channel_shipment_advice_deliver.field_stock_release_channel__state msgid "" "The state allows you to control the availability of the release channel.\n" -"* Open: Manual and automatic picking assignment to the release is effective and release operations are allowed.\n" -" * Locked: Release operations are forbidden. (Assignement processes are still working)\n" -"* Delivering: A background task is running to automatically deliver ready shipments\n" +"* Open: Manual and automatic picking assignment to the release is effective " +"and release operations are allowed.\n" +" * Locked: Release operations are forbidden. (Assignement processes are " +"still working)\n" +"* Delivering: A background task is running to automatically deliver ready " +"shipments\n" "* Delivering Error: An error occurred in the delivery background task\n" "* Delivered: Ready transfers are delivered\n" -"* Asleep: Assigned pickings not processed are unassigned from the release channel.\n" +"* Asleep: Assigned pickings not processed are unassigned from the release " +"channel.\n" msgstr "" "Lo stato consente di controllare la disponibilità del canale di rilascio.\n" "* Apri: l'assegnazione manuale e automatica di raccolta al rilascio è " @@ -287,7 +292,8 @@ msgstr "" #: model_terms:ir.ui.view,arch_db:stock_release_channel_shipment_advice_deliver.stock_release_channel_deliver_check_wizard_form_view msgid "" "There are some preparations that have not been completed.\n" -" If you choose to proceed, these preparations will be unreleased.
\n" +" If you choose to proceed, these preparations will be " +"unreleased.
\n" " Are you sure you want to proceed with the delivery?" msgstr "" "Ci sono alcuni preparativi che non sono stati completati.\n" @@ -295,12 +301,10 @@ msgstr "" "saranno pubblicati.
\n" " Si è sicuri di voler procedere con la consegna?" -#. module: stock_release_channel_shipment_advice_deliver -#: model:ir.model,name:stock_release_channel_shipment_advice_deliver.model_stock_picking -msgid "Transfer" -msgstr "Trasferimento" - #. module: stock_release_channel_shipment_advice_deliver #: model:ir.model,name:stock_release_channel_shipment_advice_deliver.model_stock_release_channel_deliver_check_wizard msgid "stock release channel deliver check wizard" msgstr "procedura guidata controllo consegna canale rilascio magazzino" + +#~ msgid "Transfer" +#~ msgstr "Trasferimento" From 7e90701a98677c0e5d3778c56fd0d6fbcc684fd1 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Sun, 18 May 2025 13:36:39 +0200 Subject: [PATCH 096/357] [ADD] stock_release_channel_partner_by_date_delivery_window: add tests --- ...se_channel_partner_by_date_delivery_window | 1 + .../setup.py | 6 + .../README.rst | 84 ++++ .../__init__.py | 0 .../__manifest__.py | 17 + .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 1 + .../static/description/index.html | 425 ++++++++++++++++++ .../tests/__init__.py | 1 + .../test_release_channel_partner_date.py | 67 +++ 10 files changed, 603 insertions(+) create mode 120000 setup/stock_release_channel_partner_by_date_delivery_window/odoo/addons/stock_release_channel_partner_by_date_delivery_window create mode 100644 setup/stock_release_channel_partner_by_date_delivery_window/setup.py create mode 100644 stock_release_channel_partner_by_date_delivery_window/README.rst create mode 100644 stock_release_channel_partner_by_date_delivery_window/__init__.py create mode 100644 stock_release_channel_partner_by_date_delivery_window/__manifest__.py create mode 100644 stock_release_channel_partner_by_date_delivery_window/readme/CONTRIBUTORS.rst create mode 100644 stock_release_channel_partner_by_date_delivery_window/readme/DESCRIPTION.rst create mode 100644 stock_release_channel_partner_by_date_delivery_window/static/description/index.html create mode 100644 stock_release_channel_partner_by_date_delivery_window/tests/__init__.py create mode 100644 stock_release_channel_partner_by_date_delivery_window/tests/test_release_channel_partner_date.py diff --git a/setup/stock_release_channel_partner_by_date_delivery_window/odoo/addons/stock_release_channel_partner_by_date_delivery_window b/setup/stock_release_channel_partner_by_date_delivery_window/odoo/addons/stock_release_channel_partner_by_date_delivery_window new file mode 120000 index 00000000000..aa9538eaf1e --- /dev/null +++ b/setup/stock_release_channel_partner_by_date_delivery_window/odoo/addons/stock_release_channel_partner_by_date_delivery_window @@ -0,0 +1 @@ +../../../../stock_release_channel_partner_by_date_delivery_window \ No newline at end of file diff --git a/setup/stock_release_channel_partner_by_date_delivery_window/setup.py b/setup/stock_release_channel_partner_by_date_delivery_window/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/stock_release_channel_partner_by_date_delivery_window/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_release_channel_partner_by_date_delivery_window/README.rst b/stock_release_channel_partner_by_date_delivery_window/README.rst new file mode 100644 index 00000000000..e19c4125a8f --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/README.rst @@ -0,0 +1,84 @@ +================================================================== +Glue Stock Release Channels for Delivery Dates and Delivery window +================================================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:41a3baa296f8da7e0b152b188a758550e7a15aaf22245e6263c48e009dbb82d6 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/stock_release_channel_partner_by_date_delivery_window + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_partner_by_date_delivery_window + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Test module between Stock Release Channels for Delivery Dates and Delivery window + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* BCIM + +Contributors +~~~~~~~~~~~~ + +* Jacques-Etienne Baudoux (BCIM) + +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. + +.. |maintainer-jbaudoux| image:: https://github.com/jbaudoux.png?size=40px + :target: https://github.com/jbaudoux + :alt: jbaudoux + +Current `maintainer `__: + +|maintainer-jbaudoux| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_release_channel_partner_by_date_delivery_window/__init__.py b/stock_release_channel_partner_by_date_delivery_window/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/stock_release_channel_partner_by_date_delivery_window/__manifest__.py b/stock_release_channel_partner_by_date_delivery_window/__manifest__.py new file mode 100644 index 00000000000..c44f11c7d7a --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{ + "name": "Glue Stock Release Channels for Delivery Dates and Delivery window", + "version": "16.0.1.0.0", + "development_status": "Beta", + "license": "AGPL-3", + "author": "BCIM, Odoo Community Association (OCA)", + "maintainers": ["jbaudoux"], + "website": "https://github.com/OCA/wms", + "depends": [ + "stock_release_channel_partner_by_date", + "stock_release_channel_partner_delivery_window", + ], + "auto_install": True, +} diff --git a/stock_release_channel_partner_by_date_delivery_window/readme/CONTRIBUTORS.rst b/stock_release_channel_partner_by_date_delivery_window/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..3c6c5c696a8 --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Jacques-Etienne Baudoux (BCIM) diff --git a/stock_release_channel_partner_by_date_delivery_window/readme/DESCRIPTION.rst b/stock_release_channel_partner_by_date_delivery_window/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..bcfa4a7f3c1 --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Test module between Stock Release Channels for Delivery Dates and Delivery window diff --git a/stock_release_channel_partner_by_date_delivery_window/static/description/index.html b/stock_release_channel_partner_by_date_delivery_window/static/description/index.html new file mode 100644 index 00000000000..32bdb5257f4 --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/static/description/index.html @@ -0,0 +1,425 @@ + + + + + +Glue Stock Release Channels for Delivery Dates and Delivery window + + + +

+

Glue Stock Release Channels for Delivery Dates and Delivery window

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Test module between Stock Release Channels for Delivery Dates and Delivery window

+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • BCIM
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

Current maintainer:

+

jbaudoux

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_release_channel_partner_by_date_delivery_window/tests/__init__.py b/stock_release_channel_partner_by_date_delivery_window/tests/__init__.py new file mode 100644 index 00000000000..3e28dc125ca --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/tests/__init__.py @@ -0,0 +1 @@ +from . import test_release_channel_partner_date diff --git a/stock_release_channel_partner_by_date_delivery_window/tests/test_release_channel_partner_date.py b/stock_release_channel_partner_by_date_delivery_window/tests/test_release_channel_partner_date.py new file mode 100644 index 00000000000..dfb9bc6ee8f --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/tests/test_release_channel_partner_date.py @@ -0,0 +1,67 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields +from odoo.fields import Command + +from odoo.addons.stock_release_channel_partner_by_date.tests.common import ( + ReleaseChannelPartnerDateCommon, +) + + +class TestReleaseChannelPartnerDate(ReleaseChannelPartnerDateCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.scheduled_date = fields.Datetime.now() + cls.move.picking_id.scheduled_date = cls.scheduled_date + cls.move.picking_id.date_deadline = cls.scheduled_date + + # Create partner delivery window on a date different from scheduled + weekday = (cls.scheduled_date.weekday() + 3) % 6 + time_weekday = cls.env["time.weekday"].search([("name", "=", str(weekday))]) + cls.partner.write( + { + "delivery_time_preference": "time_windows", + "delivery_time_window_ids": [ + Command.create( + { + "time_window_start": 8.00, + "time_window_end": 18.50, + "time_window_weekday_ids": [Command.link(time_weekday.id)], + } + ) + ], + } + ) + + # Create specific date channel for partner + cls._create_channel_partner_date( + cls.delivery_date_channel, + cls.partner, + cls.scheduled_date, + ) + + def test_release_channel_on_specific_date_available(self): + """Test when channel is open. + + Test that when the specific channel is available, it is assigned even + if it is not in the delivery window. + """ + self.delivery_date_channel.action_wake_up() + self.delivery_date_channel.shipment_date = self.scheduled_date + self.move.picking_id.assign_release_channel() + self.assertEqual( + self.move.picking_id.release_channel_id, self.delivery_date_channel + ) + + def test_release_channel_on_specific_date_not_available(self): + """Test when channel is asleep. + + Test that when no release channel is available to satisfy + a specific partner date, no fallback release channel is + proposed. + """ + self.move.picking_id.assign_release_channel() + self.assertFalse(self.move.picking_id.release_channel_id) From d6314adbda2521bda13be8d3470810552d362079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Mon, 13 Jan 2025 15:50:33 +0100 Subject: [PATCH 097/357] stock_release_channel_partner_by_date: display archived specific channels --- stock_release_channel_partner_by_date/models/res_partner.py | 1 + stock_release_channel_partner_by_date/views/res_partner.xml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/stock_release_channel_partner_by_date/models/res_partner.py b/stock_release_channel_partner_by_date/models/res_partner.py index f8054392211..067539d86e5 100644 --- a/stock_release_channel_partner_by_date/models/res_partner.py +++ b/stock_release_channel_partner_by_date/models/res_partner.py @@ -13,4 +13,5 @@ class ResPartner(models.Model): inverse_name="partner_id", string="Additional Release Channels", help="Additional release channels for a specific delivery date.", + context={"active_test": False}, ) diff --git a/stock_release_channel_partner_by_date/views/res_partner.xml b/stock_release_channel_partner_by_date/views/res_partner.xml index 529bff9a607..c31d0e726b0 100644 --- a/stock_release_channel_partner_by_date/views/res_partner.xml +++ b/stock_release_channel_partner_by_date/views/res_partner.xml @@ -15,7 +15,8 @@ colspan="2" /> - + + From 9fded309eb374ac1eb74b1e6474d4af867ece742 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 20 May 2025 08:55:48 +0000 Subject: [PATCH 098/357] [BOT] post-merge updates --- README.md | 2 +- stock_release_channel_partner_by_date/README.rst | 2 +- stock_release_channel_partner_by_date/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5a4c254fe41..790e240999f 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ addon | version | maintainers | summary [stock_release_channel_delivery](stock_release_channel_delivery/) | 16.0.3.0.0 | | Add a carrier selection criteria on the release channel [stock_release_channel_depot](stock_release_channel_depot/) | 16.0.1.0.0 | | This module allows users to add partner depot to stock release channel. [stock_release_channel_geoengine](stock_release_channel_geoengine/) | 16.0.2.0.0 | | Release channel based on geo-localization -[stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.2.0.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates +[stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.2.0.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates [stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Public holidays [stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel diff --git a/stock_release_channel_partner_by_date/README.rst b/stock_release_channel_partner_by_date/README.rst index 9b82d9a4ae5..8e110aa7150 100644 --- a/stock_release_channel_partner_by_date/README.rst +++ b/stock_release_channel_partner_by_date/README.rst @@ -7,7 +7,7 @@ Stock Release Channels for Delivery Dates !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:16d1e9fa4cde82b51cd295a591fe8489504408753f6f9a677de3ab71dff53608 + !! source digest: sha256:0ca449845c7440346880f1d856d8144be516dbeeb9e0376250d9d714926d60f1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_partner_by_date/__manifest__.py b/stock_release_channel_partner_by_date/__manifest__.py index 62e87e08087..856c29c9e30 100644 --- a/stock_release_channel_partner_by_date/__manifest__.py +++ b/stock_release_channel_partner_by_date/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Stock Release Channels for Delivery Dates", "summary": "Set release channels for specific delivery dates", - "version": "16.0.2.0.0", + "version": "16.0.2.0.1", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_by_date/static/description/index.html b/stock_release_channel_partner_by_date/static/description/index.html index 04d1c4080f6..fe722c73475 100644 --- a/stock_release_channel_partner_by_date/static/description/index.html +++ b/stock_release_channel_partner_by_date/static/description/index.html @@ -367,7 +367,7 @@

Stock Release Channels for Delivery Dates

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:16d1e9fa4cde82b51cd295a591fe8489504408753f6f9a677de3ab71dff53608 +!! source digest: sha256:0ca449845c7440346880f1d856d8144be516dbeeb9e0376250d9d714926d60f1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Set release channels for specific delivery addresses and dates.

From aec347d84e239cfe4dbf0ee3eb0c4002558e7bf4 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 20 May 2025 09:07:53 +0000 Subject: [PATCH 099/357] [UPD] Update stock_release_channel_partner_by_date_delivery_window.pot --- ...ease_channel_partner_by_date_delivery_window.pot | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 stock_release_channel_partner_by_date_delivery_window/i18n/stock_release_channel_partner_by_date_delivery_window.pot diff --git a/stock_release_channel_partner_by_date_delivery_window/i18n/stock_release_channel_partner_by_date_delivery_window.pot b/stock_release_channel_partner_by_date_delivery_window/i18n/stock_release_channel_partner_by_date_delivery_window.pot new file mode 100644 index 00000000000..78d58d53fe0 --- /dev/null +++ b/stock_release_channel_partner_by_date_delivery_window/i18n/stock_release_channel_partner_by_date_delivery_window.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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" From a0dfc9e025030f6e27a432ef37a4a78934f28b07 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 20 May 2025 09:18:51 +0000 Subject: [PATCH 100/357] [BOT] post-merge updates --- README.md | 1 + setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + .../static/description/icon.png | Bin 0 -> 10254 bytes 4 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 stock_release_channel_partner_by_date_delivery_window/static/description/icon.png diff --git a/README.md b/README.md index 790e240999f..a833b386850 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ addon | version | maintainers | summary [stock_release_channel_depot](stock_release_channel_depot/) | 16.0.1.0.0 | | This module allows users to add partner depot to stock release channel. [stock_release_channel_geoengine](stock_release_channel_geoengine/) | 16.0.2.0.0 | | Release channel based on geo-localization [stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.2.0.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates +[stock_release_channel_partner_by_date_delivery_window](stock_release_channel_partner_by_date_delivery_window/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Delivery window [stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Public holidays [stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 8afc86e729c..89ed48d7796 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250515.0 \ No newline at end of file +16.0.20250520.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index 2941ac6385d..c4203b164d5 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -39,6 +39,7 @@ 'odoo-addon-stock_release_channel_depot>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_geoengine>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_by_date>=16.0dev,<16.1dev', + 'odoo-addon-stock_release_channel_partner_by_date_delivery_window>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_by_date_public_holidays>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_delivery_window>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_public_holidays>=16.0dev,<16.1dev', diff --git a/stock_release_channel_partner_by_date_delivery_window/static/description/icon.png b/stock_release_channel_partner_by_date_delivery_window/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Date: Thu, 4 Jul 2024 09:04:56 +0200 Subject: [PATCH 101/357] [ADD] stock_release_channel_plan_depot --- .../addons/stock_release_channel_plan_depot | 1 + .../stock_release_channel_plan_depot/setup.py | 6 + stock_release_channel_plan_depot/README.rst | 74 +++ stock_release_channel_plan_depot/__init__.py | 1 + .../__manifest__.py | 16 + stock_release_channel_plan_depot/i18n/fr.po | 21 + .../i18n/stock_release_channel_plan_depot.pot | 26 ++ .../models/__init__.py | 1 + .../stock_release_channel_preparation_plan.py | 10 + .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 1 + .../static/description/index.html | 420 ++++++++++++++++++ ...stock_release_channel_preparation_plan.xml | 44 ++ 13 files changed, 623 insertions(+) create mode 120000 setup/stock_release_channel_plan_depot/odoo/addons/stock_release_channel_plan_depot create mode 100644 setup/stock_release_channel_plan_depot/setup.py create mode 100644 stock_release_channel_plan_depot/README.rst create mode 100644 stock_release_channel_plan_depot/__init__.py create mode 100644 stock_release_channel_plan_depot/__manifest__.py create mode 100644 stock_release_channel_plan_depot/i18n/fr.po create mode 100644 stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot create mode 100644 stock_release_channel_plan_depot/models/__init__.py create mode 100644 stock_release_channel_plan_depot/models/stock_release_channel_preparation_plan.py create mode 100644 stock_release_channel_plan_depot/readme/CONTRIBUTORS.rst create mode 100644 stock_release_channel_plan_depot/readme/DESCRIPTION.rst create mode 100644 stock_release_channel_plan_depot/static/description/index.html create mode 100644 stock_release_channel_plan_depot/views/stock_release_channel_preparation_plan.xml diff --git a/setup/stock_release_channel_plan_depot/odoo/addons/stock_release_channel_plan_depot b/setup/stock_release_channel_plan_depot/odoo/addons/stock_release_channel_plan_depot new file mode 120000 index 00000000000..a30aae60461 --- /dev/null +++ b/setup/stock_release_channel_plan_depot/odoo/addons/stock_release_channel_plan_depot @@ -0,0 +1 @@ +../../../../stock_release_channel_plan_depot \ No newline at end of file diff --git a/setup/stock_release_channel_plan_depot/setup.py b/setup/stock_release_channel_plan_depot/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/stock_release_channel_plan_depot/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_release_channel_plan_depot/README.rst b/stock_release_channel_plan_depot/README.rst new file mode 100644 index 00000000000..aeaf4468179 --- /dev/null +++ b/stock_release_channel_plan_depot/README.rst @@ -0,0 +1,74 @@ +================================ +Stock Release Channel Plan Depot +================================ + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! 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%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/stock_release_channel_plan_depot + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_plan_depot + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Add partner depot to stock release channel preparation plan + +**Table of contents** + +.. contents:: + :local: + +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 + +Contributors +~~~~~~~~~~~~ + +* Telmo Santos +* Jacques-Etienne Baudoux + +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/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_release_channel_plan_depot/__init__.py b/stock_release_channel_plan_depot/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/stock_release_channel_plan_depot/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_release_channel_plan_depot/__manifest__.py b/stock_release_channel_plan_depot/__manifest__.py new file mode 100644 index 00000000000..12945c0a1c2 --- /dev/null +++ b/stock_release_channel_plan_depot/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Stock Release Channel Plan Depot", + "summary": """This module allows users to set partner depot on + stock release channel preparation plan.""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Camptocamp, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/wms", + "depends": ["stock_depot", "stock_release_channel_plan"], + "data": [ + "views/stock_release_channel_preparation_plan.xml", + ], +} diff --git a/stock_release_channel_plan_depot/i18n/fr.po b/stock_release_channel_plan_depot/i18n/fr.po new file mode 100644 index 00000000000..9eabceef487 --- /dev/null +++ b/stock_release_channel_plan_depot/i18n/fr.po @@ -0,0 +1,21 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_release_channel_plan_depot +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-04 06:21+0000\n" +"PO-Revision-Date: 2024-07-04 06:21+0000\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_release_channel_plan_depot +#: model:ir.model.fields,field_description:stock_release_channel_plan_depot.field_stock_release_channel_preparation_plan__depot_id +msgid "Depot" +msgstr "Dépôt" diff --git a/stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot b/stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot new file mode 100644 index 00000000000..55517e5db42 --- /dev/null +++ b/stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_release_channel_plan_depot +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-04 06:21+0000\n" +"PO-Revision-Date: 2024-07-04 06:21+0000\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_release_channel_plan_depot +#: model:ir.model.fields,field_description:stock_release_channel_plan_depot.field_stock_release_channel_preparation_plan__depot_id +msgid "Depot" +msgstr "" + +#. module: stock_release_channel_plan_depot +#: model:ir.model,name:stock_release_channel_plan_depot.model_stock_release_channel_preparation_plan +msgid "Stock Release Channel Preparation Plan" +msgstr "" diff --git a/stock_release_channel_plan_depot/models/__init__.py b/stock_release_channel_plan_depot/models/__init__.py new file mode 100644 index 00000000000..57926ea54ca --- /dev/null +++ b/stock_release_channel_plan_depot/models/__init__.py @@ -0,0 +1 @@ +from . import stock_release_channel_preparation_plan diff --git a/stock_release_channel_plan_depot/models/stock_release_channel_preparation_plan.py b/stock_release_channel_plan_depot/models/stock_release_channel_preparation_plan.py new file mode 100644 index 00000000000..9a4e30b5fb7 --- /dev/null +++ b/stock_release_channel_plan_depot/models/stock_release_channel_preparation_plan.py @@ -0,0 +1,10 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class StockReleaseChannelPreparationPlan(models.Model): + _inherit = "stock.release.channel.preparation.plan" + + depot_id = fields.Many2one("stock.depot") diff --git a/stock_release_channel_plan_depot/readme/CONTRIBUTORS.rst b/stock_release_channel_plan_depot/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..22612a25009 --- /dev/null +++ b/stock_release_channel_plan_depot/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Telmo Santos +* Jacques-Etienne Baudoux diff --git a/stock_release_channel_plan_depot/readme/DESCRIPTION.rst b/stock_release_channel_plan_depot/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..99ae5360d35 --- /dev/null +++ b/stock_release_channel_plan_depot/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Add partner depot to stock release channel preparation plan diff --git a/stock_release_channel_plan_depot/static/description/index.html b/stock_release_channel_plan_depot/static/description/index.html new file mode 100644 index 00000000000..d880896dbae --- /dev/null +++ b/stock_release_channel_plan_depot/static/description/index.html @@ -0,0 +1,420 @@ + + + + + + +Stock Release Channel Plan Depot + + + +
+

Stock Release Channel Plan Depot

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Add partner depot to stock release channel preparation plan

+

Table of contents

+ +
+

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
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_release_channel_plan_depot/views/stock_release_channel_preparation_plan.xml b/stock_release_channel_plan_depot/views/stock_release_channel_preparation_plan.xml new file mode 100644 index 00000000000..d0133fee2f5 --- /dev/null +++ b/stock_release_channel_plan_depot/views/stock_release_channel_preparation_plan.xml @@ -0,0 +1,44 @@ + + + + + stock.release.channel.preparation.plan.form (in stock_release_channel_plan_depot) + stock.release.channel.preparation.plan + + + + + + + + + + + + + + + stock.release.channel.preparation.plan.tree (in stock_release_channel_plan_depot) + stock.release.channel.preparation.plan + + + + + + + + + From 33cc8333d158b8e3dc393f884918d9749cdbc927 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 20 May 2025 15:25:31 +0000 Subject: [PATCH 102/357] [UPD] Update sale_stock_available_to_promise_release_block.pot --- ...ock_available_to_promise_release_block.pot | 156 +++++++++++++++++- 1 file changed, 155 insertions(+), 1 deletion(-) diff --git a/sale_stock_available_to_promise_release_block/i18n/sale_stock_available_to_promise_release_block.pot b/sale_stock_available_to_promise_release_block/i18n/sale_stock_available_to_promise_release_block.pot index eba9fe1fc75..474e1afce15 100644 --- a/sale_stock_available_to_promise_release_block/i18n/sale_stock_available_to_promise_release_block.pot +++ b/sale_stock_available_to_promise_release_block/i18n/sale_stock_available_to_promise_release_block.pot @@ -13,6 +13,34 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,help:sale_stock_available_to_promise_release_block.field_unblock_release__option +msgid "" +"- Manual: schedule blocked deliveries at a given date;\n" +"- Automatic: schedule blocked deliveries as soon as possible;\n" +"- Based on current order: schedule blocked deliveries with the contextual sale order." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__available_move_to_unblock_count +msgid "Available Move To Unblock Count" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__available_move_to_unblock_ids +msgid "Available moves to unblock" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,help:sale_stock_available_to_promise_release_block.field_sale_order__available_move_to_unblock_ids +msgid "Available moves to unblock for this order." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_order_form +msgid "Backorders" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.actions.server,name:sale_stock_available_to_promise_release_block.action_sale_order_line_block_release #: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__block_release @@ -31,16 +59,106 @@ msgstr "" msgid "Blocked" msgstr "" +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "Cancel" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__create_uid +msgid "Created by" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__create_date +msgid "Created on" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__date_deadline +msgid "Date Deadline" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_order_form +msgid "Deliveries that could be unblocked at order confirmation." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_order_form +msgid "Deliveries that will be unblocked at order confirmation." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__move_ids +msgid "Delivery moves" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__display_name +msgid "Display Name" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order_line__is_release_blocked msgid "Has Blocked Delivery" msgstr "" +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__id +msgid "ID" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_sales_order_line_filter msgid "Is Release Blocked" msgstr "" +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release____last_update +msgid "Last Modified on" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__write_date +msgid "Last Updated on" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__move_to_unblock_count +msgid "Move To Unblock Count" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__move_to_unblock_ids +msgid "Moves To Unblock" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,help:sale_stock_available_to_promise_release_block.field_sale_order__move_to_unblock_ids +msgid "Moves to unblock when the current order is confirmed." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__option +msgid "Option" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__order_id +msgid "Order" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__order_line_ids +msgid "Order Lines" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order_line__release_blocked_label msgid "Release Blocked" @@ -61,6 +179,23 @@ msgstr "" msgid "Sales Order Lines having blocked deliveries" msgstr "" +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "Selected deliveries" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "" +"Selected delivery moves will be unblocked when the above order is confirmed.\n" +" Their delivery method, shipping policy and scheduled date will be aligned with the deliveries of the confirmed order." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model,name:sale_stock_available_to_promise_release_block.model_stock_move +msgid "Stock Move" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.model,name:sale_stock_available_to_promise_release_block.model_stock_rule msgid "Stock Rule" @@ -74,6 +209,25 @@ msgid "This operator is not supported" msgstr "" #. module: sale_stock_available_to_promise_release_block -#: model:ir.actions.server,name:sale_stock_available_to_promise_release_block.action_sale_order_line_unblock_release +#: model:ir.actions.act_window,name:sale_stock_available_to_promise_release_block.action_sale_order_line_unblock_release +#: model:ir.actions.act_window,name:sale_stock_available_to_promise_release_block.action_stock_move_unblock_release +#: model:ir.model,name:sale_stock_available_to_promise_release_block.model_unblock_release msgid "Unblock Release" msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_stock_move__unblocked_by_order_id +msgid "Unblocked by order" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "Validate" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#. odoo-python +#: code:addons/sale_stock_available_to_promise_release_block/wizards/unblock_release.py:0 +#, python-format +msgid "You cannot reschedule deliveries in the past." +msgstr "" From d98c8f1c568ccfaa685ec77d7609acd16e197aa1 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 20 May 2025 15:25:35 +0000 Subject: [PATCH 103/357] [UPD] Update stock_available_to_promise_release_block.pot --- .../i18n/stock_available_to_promise_release_block.pot | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stock_available_to_promise_release_block/i18n/stock_available_to_promise_release_block.pot b/stock_available_to_promise_release_block/i18n/stock_available_to_promise_release_block.pot index f3c80732f99..36e425f397a 100644 --- a/stock_available_to_promise_release_block/i18n/stock_available_to_promise_release_block.pot +++ b/stock_available_to_promise_release_block/i18n/stock_available_to_promise_release_block.pot @@ -88,11 +88,6 @@ msgstr "" msgid "Transfer" msgstr "" -#. module: stock_available_to_promise_release_block -#: model:ir.actions.server,name:stock_available_to_promise_release_block.action_stock_move_unblock_release -msgid "Unblock Release" -msgstr "" - #. module: stock_available_to_promise_release_block #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release_block.stock_picking_form_view msgid "Unblock release" From 70205255efac7958cc01234a9273649698a3ed6a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 20 May 2025 15:37:22 +0000 Subject: [PATCH 104/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 15 ++++++++++-- .../static/description/index.html | 23 ++++++++++++++----- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a833b386850..e77ae0d067c 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ addon | version | maintainers | summary --- | --- | --- | --- [delivery_carrier_warehouse](delivery_carrier_warehouse/) | 16.0.1.0.1 | | Get delivery method used in sales orders from warehouse [sale_stock_available_to_promise_release](sale_stock_available_to_promise_release/) | 16.0.1.1.2 | | Integration between Sales and Available to Promise Release -[sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.0.0 | | Block release of deliveries from sales orders. +[sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.1.0 | | Block release of deliveries from sales orders. [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Filters channels on sales based on selected carrier. [shopfloor](shopfloor/) | 16.0.2.7.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | manage warehouse operations with barcode scanners diff --git a/sale_stock_available_to_promise_release_block/README.rst b/sale_stock_available_to_promise_release_block/README.rst index 7d564cc2ede..3f5cbb05d1d 100644 --- a/sale_stock_available_to_promise_release_block/README.rst +++ b/sale_stock_available_to_promise_release_block/README.rst @@ -7,7 +7,7 @@ Stock Available to Promise Release - Block from Sales !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:a4fccfd767ff2327845ac9a41c82922424dd602e454da081ba2a9a565120f8ca + !! source digest: sha256:3d9773050fa015580ca1f200699c0df6bf9f3b377a4ae106a15c909f215c2847 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -28,7 +28,18 @@ Stock Available to Promise Release - Block from Sales |badge1| |badge2| |badge3| |badge4| |badge5| -Block release of deliveries from sale orders. +Block and unblock release of deliveries from sale orders. + +Release of deliveries can be blocked right after the sale order confirmation. + +When encoding a new order sharing the same delivery address, the user can +list the existing blocked deliveries (backorders) and plan to unblock them +when this new order is confirmed, making the existing deliveries and the new +ones sharing the same scheduled dates and deadlines. + +As a side-effect, this will leverage the module +`stock_picking_group_by_partner_by_carrier_by_date` if this one is installed, +by grouping all delivery lines within the same delivery order. **Table of contents** diff --git a/sale_stock_available_to_promise_release_block/static/description/index.html b/sale_stock_available_to_promise_release_block/static/description/index.html index a9c5d1ff93c..b2a57c1e549 100644 --- a/sale_stock_available_to_promise_release_block/static/description/index.html +++ b/sale_stock_available_to_promise_release_block/static/description/index.html @@ -8,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -274,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -300,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -366,10 +367,18 @@

Stock Available to Promise Release - Block from Sales

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:a4fccfd767ff2327845ac9a41c82922424dd602e454da081ba2a9a565120f8ca +!! source digest: sha256:3d9773050fa015580ca1f200699c0df6bf9f3b377a4ae106a15c909f215c2847 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

-

Block release of deliveries from sale orders.

+

Block and unblock release of deliveries from sale orders.

+

Release of deliveries can be blocked right after the sale order confirmation.

+

When encoding a new order sharing the same delivery address, the user can +list the existing blocked deliveries (backorders) and plan to unblock them +when this new order is confirmed, making the existing deliveries and the new +ones sharing the same scheduled dates and deadlines.

+

As a side-effect, this will leverage the module +stock_picking_group_by_partner_by_carrier_by_date if this one is installed, +by grouping all delivery lines within the same delivery order.

Table of contents

    @@ -419,7 +428,9 @@

    Contributors

    Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +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.

    From be60f8c07f1664139555d8a2ac927e9e409a7c65 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 20 May 2025 15:37:34 +0000 Subject: [PATCH 105/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_available_to_promise_release_block Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_available_to_promise_release_block/ --- stock_available_to_promise_release_block/i18n/it.po | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/stock_available_to_promise_release_block/i18n/it.po b/stock_available_to_promise_release_block/i18n/it.po index 34faea626cf..9f28d41a420 100644 --- a/stock_available_to_promise_release_block/i18n/it.po +++ b/stock_available_to_promise_release_block/i18n/it.po @@ -94,12 +94,10 @@ msgstr "" msgid "Transfer" msgstr "Trasferimento" -#. module: stock_available_to_promise_release_block -#: model:ir.actions.server,name:stock_available_to_promise_release_block.action_stock_move_unblock_release -msgid "Unblock Release" -msgstr "Sblocco rilascio" - #. module: stock_available_to_promise_release_block #: model_terms:ir.ui.view,arch_db:stock_available_to_promise_release_block.stock_picking_form_view msgid "Unblock release" msgstr "Sblocco rilascio" + +#~ msgid "Unblock Release" +#~ msgstr "Sblocco rilascio" From a278e8464bfc11e5822341ea804a1d7704c2123f Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 20 May 2025 15:37:34 +0000 Subject: [PATCH 106/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-sale_stock_available_to_promise_release_block Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-sale_stock_available_to_promise_release_block/ --- .../i18n/it.po | 159 +++++++++++++++++- 1 file changed, 158 insertions(+), 1 deletion(-) diff --git a/sale_stock_available_to_promise_release_block/i18n/it.po b/sale_stock_available_to_promise_release_block/i18n/it.po index 919b8032ddf..0900fd87bf1 100644 --- a/sale_stock_available_to_promise_release_block/i18n/it.po +++ b/sale_stock_available_to_promise_release_block/i18n/it.po @@ -16,6 +16,35 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17\n" +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,help:sale_stock_available_to_promise_release_block.field_unblock_release__option +msgid "" +"- Manual: schedule blocked deliveries at a given date;\n" +"- Automatic: schedule blocked deliveries as soon as possible;\n" +"- Based on current order: schedule blocked deliveries with the contextual " +"sale order." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__available_move_to_unblock_count +msgid "Available Move To Unblock Count" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__available_move_to_unblock_ids +msgid "Available moves to unblock" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,help:sale_stock_available_to_promise_release_block.field_sale_order__available_move_to_unblock_ids +msgid "Available moves to unblock for this order." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_order_form +msgid "Backorders" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.actions.server,name:sale_stock_available_to_promise_release_block.action_sale_order_line_block_release #: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__block_release @@ -34,16 +63,106 @@ msgstr "Blocca il rilascio delle consegne generate alla conferma ordine." msgid "Blocked" msgstr "Bloccata" +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "Cancel" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__create_uid +msgid "Created by" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__create_date +msgid "Created on" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__date_deadline +msgid "Date Deadline" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_order_form +msgid "Deliveries that could be unblocked at order confirmation." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_order_form +msgid "Deliveries that will be unblocked at order confirmation." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__move_ids +msgid "Delivery moves" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__display_name +msgid "Display Name" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order_line__is_release_blocked msgid "Has Blocked Delivery" msgstr "Ha consegne bloccate" +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__id +msgid "ID" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.view_sales_order_line_filter msgid "Is Release Blocked" msgstr "Il rilascio è bloccato" +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release____last_update +msgid "Last Modified on" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__write_date +msgid "Last Updated on" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__move_to_unblock_count +msgid "Move To Unblock Count" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order__move_to_unblock_ids +msgid "Moves To Unblock" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,help:sale_stock_available_to_promise_release_block.field_sale_order__move_to_unblock_ids +msgid "Moves to unblock when the current order is confirmed." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__option +msgid "Option" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__order_id +msgid "Order" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_unblock_release__order_line_ids +msgid "Order Lines" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_sale_order_line__release_blocked_label msgid "Release Blocked" @@ -64,6 +183,25 @@ msgstr "Riga ordine di vendita" msgid "Sales Order Lines having blocked deliveries" msgstr "Righe ordine di vendita con consegne bloccate" +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "Selected deliveries" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "" +"Selected delivery moves will be unblocked when the above order is " +"confirmed.\n" +" Their delivery method, shipping policy and scheduled date will " +"be aligned with the deliveries of the confirmed order." +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model,name:sale_stock_available_to_promise_release_block.model_stock_move +msgid "Stock Move" +msgstr "" + #. module: sale_stock_available_to_promise_release_block #: model:ir.model,name:sale_stock_available_to_promise_release_block.model_stock_rule msgid "Stock Rule" @@ -77,6 +215,25 @@ msgid "This operator is not supported" msgstr "Questo operatore non è supportato" #. module: sale_stock_available_to_promise_release_block -#: model:ir.actions.server,name:sale_stock_available_to_promise_release_block.action_sale_order_line_unblock_release +#: model:ir.actions.act_window,name:sale_stock_available_to_promise_release_block.action_sale_order_line_unblock_release +#: model:ir.actions.act_window,name:sale_stock_available_to_promise_release_block.action_stock_move_unblock_release +#: model:ir.model,name:sale_stock_available_to_promise_release_block.model_unblock_release msgid "Unblock Release" msgstr "Sblocco rilascio" + +#. module: sale_stock_available_to_promise_release_block +#: model:ir.model.fields,field_description:sale_stock_available_to_promise_release_block.field_stock_move__unblocked_by_order_id +msgid "Unblocked by order" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release_block.unblock_release_view_form +msgid "Validate" +msgstr "" + +#. module: sale_stock_available_to_promise_release_block +#. odoo-python +#: code:addons/sale_stock_available_to_promise_release_block/wizards/unblock_release.py:0 +#, python-format +msgid "You cannot reschedule deliveries in the past." +msgstr "" From ef961c8b15915eba3b0de488a70c674c3eb08bf5 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 20 May 2025 15:53:05 +0000 Subject: [PATCH 107/357] [UPD] Update stock_release_channel_plan_depot.pot --- .../i18n/stock_release_channel_plan_depot.pot | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot b/stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot index 55517e5db42..0e7b8a7e985 100644 --- a/stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot +++ b/stock_release_channel_plan_depot/i18n/stock_release_channel_plan_depot.pot @@ -4,10 +4,8 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 16.0+e\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-04 06:21+0000\n" -"PO-Revision-Date: 2024-07-04 06:21+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" From c876c0532ee61c4bccf0b3cf9091f839ff4c1963 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 20 May 2025 16:04:23 +0000 Subject: [PATCH 108/357] [BOT] post-merge updates --- README.md | 1 + setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + stock_release_channel_plan_depot/README.rst | 11 +++-- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 42 ++++++++++-------- 6 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 stock_release_channel_plan_depot/static/description/icon.png diff --git a/README.md b/README.md index e77ae0d067c..96d098b05f6 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ addon | version | maintainers | summary [stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel [stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Manage release channel preparation plan +[stock_release_channel_plan_depot](stock_release_channel_plan_depot/) | 16.0.1.0.0 | | This module allows users to set partner depot on stock release channel preparation plan. [stock_release_channel_plan_process_end_time](stock_release_channel_plan_process_end_time/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue module between release channel plan and process end time [stock_release_channel_plan_shipment_lead_time](stock_release_channel_plan_shipment_lead_time/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Stock release channel plan shipment lead time [stock_release_channel_process_end_time](stock_release_channel_process_end_time/) | 16.0.1.7.0 | [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 89ed48d7796..5165a867d58 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250520.0 \ No newline at end of file +16.0.20250520.1 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index c4203b164d5..3c955d9312a 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -44,6 +44,7 @@ 'odoo-addon-stock_release_channel_partner_delivery_window>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_partner_public_holidays>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_plan>=16.0dev,<16.1dev', + 'odoo-addon-stock_release_channel_plan_depot>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_plan_process_end_time>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_plan_shipment_lead_time>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_process_end_time>=16.0dev,<16.1dev', diff --git a/stock_release_channel_plan_depot/README.rst b/stock_release_channel_plan_depot/README.rst index aeaf4468179..ebd895a390c 100644 --- a/stock_release_channel_plan_depot/README.rst +++ b/stock_release_channel_plan_depot/README.rst @@ -2,10 +2,13 @@ Stock Release Channel Plan Depot ================================ -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:0f2f6cca378fe4e53df17bcfe21853e2fc2baf2bf6b0fccdab9f0d9ed54c92bf + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -20,10 +23,10 @@ Stock Release Channel Plan Depot :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_plan_depot :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/wms&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| Add partner depot to stock release channel preparation plan @@ -37,7 +40,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed +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. diff --git a/stock_release_channel_plan_depot/static/description/icon.png b/stock_release_channel_plan_depot/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 - + Stock Release Channel Plan Depot + + +
    +

    Sale Stock Release Channel Delivery Date

    + + +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Provide the SO expected date according to possible channels respecting SO +warehouse, carrier and shipping partner.

    +

    Table of contents

    + +
    +

    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 to smash it by providing a detailed and welcomed +feedback.

    +

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

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • BCIM
    • +
    • Camptocamp
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    + +Odoo Community Association + +

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

    +

    Current maintainer:

    +

    jbaudoux

    +

    This module is part of the OCA/wms project on GitHub.

    +

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

    +
    +
    +
    + + diff --git a/sale_stock_release_channel_delivery_date/tests/__init__.py b/sale_stock_release_channel_delivery_date/tests/__init__.py new file mode 100644 index 00000000000..19d3fb4a8a3 --- /dev/null +++ b/sale_stock_release_channel_delivery_date/tests/__init__.py @@ -0,0 +1 @@ +from . import test_delivery_date diff --git a/sale_stock_release_channel_delivery_date/tests/test_delivery_date.py b/sale_stock_release_channel_delivery_date/tests/test_delivery_date.py new file mode 100644 index 00000000000..836821b77af --- /dev/null +++ b/sale_stock_release_channel_delivery_date/tests/test_delivery_date.py @@ -0,0 +1,106 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) + +from datetime import timedelta + +from freezegun import freeze_time + +from odoo import fields +from odoo.fields import Command + +from odoo.addons.sale.tests.common import SaleCommon +from odoo.addons.stock_release_channel.tests.common import ( # noqa + StockReleaseChannelDeliveryDateCommon, +) + + +class TestSaleStockReleaseChannelDeliveryDate( + StockReleaseChannelDeliveryDateCommon, SaleCommon +): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.warehouse = cls.env.ref("stock.warehouse0") + cls.channel.warehouse_id = cls.warehouse + cls.channel.is_manual_assignment = False + + @freeze_time("2025-01-02 10:00:00") + def test_empty(self): + """Test empty SO + + Expected date is computed as if there will be stock lines""" + so = self.empty_order + dt = fields.Datetime.now() + timedelta(days=2) + # the order was created in setup outside freezegun + so.invalidate_recordset(["expected_date"]) + self.assertEqual(so.expected_date, dt) + + @freeze_time("2025-01-02 10:01:00") + def test_service(self): + """Test SO with service""" + so = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + "order_line": [ + Command.create( + { + "product_id": self.service_product.id, + "product_uom_qty": 22, + } + ) + ], + } + ) + dt = fields.Datetime.now() + # the order was created in setup outside freezegun + so.invalidate_recordset(["expected_date"]) + self.assertEqual(so.expected_date, dt) + + @freeze_time("2025-01-02 10:02:00") + def test_product(self): + """Test SO with 2 consumables""" + so = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + "order_line": [ + Command.create( + { + "product_id": self.consumable_product.id, + "product_uom_qty": 22, + } + ), + Command.create( + { + "product_id": self.consumable_product.id, + "product_uom_qty": 22, + } + ), + ], + } + ) + dt = fields.Datetime.now() + timedelta(days=2) + # the order was created in setup outside freezegun + so.invalidate_recordset(["expected_date"]) + self.assertEqual(so.expected_date, dt) + + @freeze_time("2025-01-02 10:03:00") + def test_product_customer_lead(self): + """Test SO with a customer lead time""" + so = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + "order_line": [ + Command.create( + { + "product_id": self.consumable_product.id, + "product_uom_qty": 22, + "customer_lead": 5, + } + ) + ], + } + ) + dt = fields.Datetime.now() + timedelta(days=7) + # the order was created in setup outside freezegun + so.invalidate_recordset(["expected_date"]) + self.assertEqual(so.expected_date, dt) diff --git a/setup/sale_stock_release_channel_delivery_date/odoo/addons/sale_stock_release_channel_delivery_date b/setup/sale_stock_release_channel_delivery_date/odoo/addons/sale_stock_release_channel_delivery_date new file mode 120000 index 00000000000..1e69c8df826 --- /dev/null +++ b/setup/sale_stock_release_channel_delivery_date/odoo/addons/sale_stock_release_channel_delivery_date @@ -0,0 +1 @@ +../../../../sale_stock_release_channel_delivery_date \ No newline at end of file diff --git a/setup/sale_stock_release_channel_delivery_date/setup.py b/setup/sale_stock_release_channel_delivery_date/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/sale_stock_release_channel_delivery_date/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 890054570e87d217fc3348639fd09ca72821f06a Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Mon, 26 May 2025 22:04:24 +0200 Subject: [PATCH 130/357] stock_release_channel: add test for extension modules --- .../tests/test_release_channel_delivery_date.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/stock_release_channel/tests/test_release_channel_delivery_date.py b/stock_release_channel/tests/test_release_channel_delivery_date.py index 36e582b9b05..48c527341ea 100644 --- a/stock_release_channel/tests/test_release_channel_delivery_date.py +++ b/stock_release_channel/tests/test_release_channel_delivery_date.py @@ -5,15 +5,26 @@ from odoo import fields -from .common import StockReleaseChannelDeliveryDateCommon +from .common import ReleaseChannelCase, StockReleaseChannelDeliveryDateCommon to_datetime = fields.Datetime.to_datetime -class TestStockReleaseChannelDeliverydate(StockReleaseChannelDeliveryDateCommon): +class TestReleaseChannelDeliveryDateFake(StockReleaseChannelDeliveryDateCommon): @freeze_time("2025-01-02 10:00:00") def test_delivery_date(self): """Test generator on channel object""" now = fields.Datetime.now() dt = self.channel._get_earliest_delivery_date(self.partner, now) self.assertEqual(dt, to_datetime("2025-01-04 10:00:00")) + + +class TestReleaseChannelDeliveryDate(ReleaseChannelCase): + def test_compute_delivery_date(self): + """Test delivery date computes with registered generators + + This test will run with other modules loaded. + """ + now = fields.Datetime.now() + partner = self.env.ref("base.main_partner") + self.default_channel._get_earliest_delivery_date(partner, now) From ff1edd313ca9ee1fad8c425b3f09901528c0c6ae Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 28 May 2025 16:08:52 +0000 Subject: [PATCH 131/357] [UPD] Update sale_stock_release_channel_delivery_date.pot --- ...le_stock_release_channel_delivery_date.pot | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 sale_stock_release_channel_delivery_date/i18n/sale_stock_release_channel_delivery_date.pot diff --git a/sale_stock_release_channel_delivery_date/i18n/sale_stock_release_channel_delivery_date.pot b/sale_stock_release_channel_delivery_date/i18n/sale_stock_release_channel_delivery_date.pot new file mode 100644 index 00000000000..07bd8148357 --- /dev/null +++ b/sale_stock_release_channel_delivery_date/i18n/sale_stock_release_channel_delivery_date.pot @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_stock_release_channel_delivery_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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: sale_stock_release_channel_delivery_date +#: model:ir.model,name:sale_stock_release_channel_delivery_date.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_stock_release_channel_delivery_date +#: model:ir.model,name:sale_stock_release_channel_delivery_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "" From 25d49440b1aef379de6859c78dc70dd8e4f03f17 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 28 May 2025 16:20:46 +0000 Subject: [PATCH 132/357] [BOT] post-merge updates --- README.md | 3 ++- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 2 +- setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + stock_release_channel/README.rst | 2 +- stock_release_channel/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 10 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 sale_stock_release_channel_delivery_date/static/description/icon.png diff --git a/README.md b/README.md index b4bba2ba843..0b4bbc51306 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ addon | version | maintainers | summary [sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.1.0 | | Block release of deliveries from sales orders. [sale_stock_release_channel](sale_stock_release_channel/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Sales Stock Release Channel [sale_stock_release_channel_delivery](sale_stock_release_channel_delivery/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Sales Stock Release Channel Delivery +[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Filters channels on sales based on selected carrier. [shopfloor](shopfloor/) | 16.0.2.8.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | manage warehouse operations with barcode scanners @@ -46,7 +47,7 @@ addon | version | maintainers | summary [stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.1.0.0 | [![lmignon](https://github.com/lmignon.png?size=30px)](https://github.com/lmignon) | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type -[stock_release_channel](stock_release_channel/) | 16.0.3.0.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![mt-software-de](https://github.com/mt-software-de.png?size=30px)](https://github.com/mt-software-de) | Manage workload in WMS with release channels +[stock_release_channel](stock_release_channel/) | 16.0.3.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![mt-software-de](https://github.com/mt-software-de.png?size=30px)](https://github.com/mt-software-de) | Manage workload in WMS with release channels [stock_release_channel_auto_release](stock_release_channel_auto_release/) | 16.0.1.1.0 | | Add an automatic release mode to the release channel [stock_release_channel_batch_mode_commercial_partner](stock_release_channel_batch_mode_commercial_partner/) | 16.0.1.0.2 | | Release pickings into channels by batch of same commercial entity [stock_release_channel_cutoff](stock_release_channel_cutoff/) | 16.0.1.0.2 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add the cutoff time to the release channel diff --git a/sale_stock_release_channel_delivery_date/README.rst b/sale_stock_release_channel_delivery_date/README.rst index 0ecef800435..e082b25a80d 100644 --- a/sale_stock_release_channel_delivery_date/README.rst +++ b/sale_stock_release_channel_delivery_date/README.rst @@ -7,7 +7,7 @@ Sale Stock Release Channel Delivery Date !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e1140d039404629758922df7eb5171da9e5e6443f4e3cd8ff12e989259a2bf5e + !! source digest: sha256:25ade9facd700085d5a846f91dba83b941e48f66a3caa8355679480daf6275d8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/sale_stock_release_channel_delivery_date/__manifest__.py b/sale_stock_release_channel_delivery_date/__manifest__.py index 33d91920670..9078c3f286c 100644 --- a/sale_stock_release_channel_delivery_date/__manifest__.py +++ b/sale_stock_release_channel_delivery_date/__manifest__.py @@ -5,7 +5,7 @@ "name": "Sale Stock Release Channel Delivery Date", "summary": """ Compute expected date based on available release channels """, - "version": "16.0.1.0.0", + "version": "16.0.1.1.0", "license": "AGPL-3", "author": "BCIM,Camptocamp,Odoo Community Association (OCA)", "maintainers": ["jbaudoux"], diff --git a/sale_stock_release_channel_delivery_date/static/description/icon.png b/sale_stock_release_channel_delivery_date/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Stock Release Channel Delivery Date !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:e1140d039404629758922df7eb5171da9e5e6443f4e3cd8ff12e989259a2bf5e +!! source digest: sha256:25ade9facd700085d5a846f91dba83b941e48f66a3caa8355679480daf6275d8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Provide the SO expected date according to possible channels respecting SO diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index bf037976292..28e8403b265 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250528.0 \ No newline at end of file +16.0.20250528.1 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index 2f4b92d2e3a..ca8630470d8 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -13,6 +13,7 @@ 'odoo-addon-sale_stock_available_to_promise_release_block>=16.0dev,<16.1dev', 'odoo-addon-sale_stock_release_channel>=16.0dev,<16.1dev', 'odoo-addon-sale_stock_release_channel_delivery>=16.0dev,<16.1dev', + 'odoo-addon-sale_stock_release_channel_delivery_date>=16.0dev,<16.1dev', 'odoo-addon-sale_stock_release_channel_partner_by_date>=16.0dev,<16.1dev', 'odoo-addon-sale_stock_release_channel_partner_by_date_delivery>=16.0dev,<16.1dev', 'odoo-addon-shopfloor>=16.0dev,<16.1dev', diff --git a/stock_release_channel/README.rst b/stock_release_channel/README.rst index 219d6c85994..a8c2b83541c 100644 --- a/stock_release_channel/README.rst +++ b/stock_release_channel/README.rst @@ -7,7 +7,7 @@ Stock Release Channels !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:d3e4a6ca33a07a0967c75174dc29fa2dc7cc413f659bcd0686dd3238396bd3a8 + !! source digest: sha256:2fad401dca0aa4a4f4b0e8ddcc83fd0010d54cdfe53ed66d8fc01049bdb6d273 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel/__manifest__.py b/stock_release_channel/__manifest__.py index 726892df5b7..4f9cde1b92a 100644 --- a/stock_release_channel/__manifest__.py +++ b/stock_release_channel/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Stock Release Channels", "summary": "Manage workload in WMS with release channels", - "version": "16.0.3.0.0", + "version": "16.0.3.1.0", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, ACSONE SA/NV, Odoo Community Association (OCA)", diff --git a/stock_release_channel/static/description/index.html b/stock_release_channel/static/description/index.html index 3a5f2e338e7..3ebd0ec010e 100644 --- a/stock_release_channel/static/description/index.html +++ b/stock_release_channel/static/description/index.html @@ -367,7 +367,7 @@

    Stock Release Channels

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:d3e4a6ca33a07a0967c75174dc29fa2dc7cc413f659bcd0686dd3238396bd3a8 +!! source digest: sha256:2fad401dca0aa4a4f4b0e8ddcc83fd0010d54cdfe53ed66d8fc01049bdb6d273 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Release channels are:

    From 76769e81670a64779bf4753718f5b481ab38ab9f Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 May 2025 17:30:08 +0200 Subject: [PATCH 133/357] [IMP] stock_release_channel_partner_public_holidays Add next delivery date generator --- .../models/stock_release_channel.py | 44 +++++++++++++++++++ .../readme/CONTRIBUTORS.rst | 1 + .../tests/test_release_on_holiday.py | 23 ++++++++++ 3 files changed, 68 insertions(+) diff --git a/stock_release_channel_partner_public_holidays/models/stock_release_channel.py b/stock_release_channel_partner_public_holidays/models/stock_release_channel.py index d244d52e9f8..a64f5e235ba 100644 --- a/stock_release_channel_partner_public_holidays/models/stock_release_channel.py +++ b/stock_release_channel_partner_public_holidays/models/stock_release_channel.py @@ -1,4 +1,8 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import timedelta + from odoo import fields, models @@ -7,3 +11,43 @@ class StockReleaseChannel(models.Model): _inherit = "stock.release.channel" exclude_public_holidays = fields.Boolean() + + @property + def _delivery_date_generators(self): + d = super()._delivery_date_generators + d["customer"].append(self._next_delivery_date_partner_public_holiday) + return d + + def _next_delivery_date_partner_public_holiday(self, delivery_date, partner): + """Get the next valid delivery date respecting cutoff. + + The delivery date must not be a public holiday otherwise it is + postponed to next open day. + + A delivery date generator needs to provide the earliest valid date + starting from the received date. It can be called multiple times with a + new date to validate. + """ + self.ensure_one() + partner.ensure_one() + + if not self.exclude_public_holidays: + while True: + delivery_date = yield delivery_date + + batch_delta = timedelta(days=61) + delivery_date_tz = self._localize(delivery_date, tz=partner.tz) + while True: + end_dt_tz = delivery_date_tz + batch_delta + all_holidays = self.env["hr.holidays.public"].get_holidays_list( + start_dt=delivery_date_tz, end_dt=end_dt_tz, partner_id=partner.id + ) + while delivery_date_tz <= end_dt_tz: + if delivery_date_tz.date() not in all_holidays.mapped("date"): + delivery_date = yield self._naive(delivery_date_tz) + delivery_date_tz = self._localize(delivery_date, tz=partner.tz) + else: + delivery_date_tz += timedelta(days=1) + delivery_date_tz = delivery_date_tz.replace( + hour=0, minute=0, second=0, microsecond=0 + ) diff --git a/stock_release_channel_partner_public_holidays/readme/CONTRIBUTORS.rst b/stock_release_channel_partner_public_holidays/readme/CONTRIBUTORS.rst index 9873004f883..2ac0f1f7ff3 100644 --- a/stock_release_channel_partner_public_holidays/readme/CONTRIBUTORS.rst +++ b/stock_release_channel_partner_public_holidays/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ +* Jacques-Etienne Baudoux (BCIM) * Nguyen Minh Chien diff --git a/stock_release_channel_partner_public_holidays/tests/test_release_on_holiday.py b/stock_release_channel_partner_public_holidays/tests/test_release_on_holiday.py index c4dcdff36de..d8aebf49b3f 100644 --- a/stock_release_channel_partner_public_holidays/tests/test_release_on_holiday.py +++ b/stock_release_channel_partner_public_holidays/tests/test_release_on_holiday.py @@ -1,3 +1,4 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from datetime import timedelta @@ -7,6 +8,8 @@ from odoo.addons.stock_release_channel.tests.common import ChannelReleaseCase +to_datetime = fields.Datetime.to_datetime + class ReleaseChannelEndDateCase(ChannelReleaseCase): @classmethod @@ -58,3 +61,23 @@ def test_assign_channel(self): self.picking.partner_id.state_id = self.env.ref("base.state_us_35") self._assign_picking(self.picking) self.assertNotEqual(self.channel, self.picking.release_channel_id) + + @freeze_time("2023-09-01") + def test_delivery_date_public_holiday(self): + partner = self.picking.partner_id + self.channel.exclude_public_holidays = True + partner.tz = "Europe/Brussels" + dt = to_datetime("2023-09-17 08:00:00") + gen = self.channel._next_delivery_date_partner_public_holiday(dt, partner) + # not an holiday + result = next(gen) + self.assertEqual(result, dt) + result = gen.send(dt) + self.assertEqual(result, dt) + # an holiday + dt = to_datetime("2023-09-18 08:00:00") + result = gen.send(dt) + next_day = to_datetime("2023-09-18 22:00:00") + self.assertEqual(result, next_day) + result = gen.send(dt) + self.assertEqual(result, next_day) From ba86f69df88e9b3ccb607df80a670925a4ea64bb Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 May 2025 15:34:38 +0200 Subject: [PATCH 134/357] [ADD] stock_release_channel_warehouse_calendar Add next delivery date generator --- .../stock_release_channel_warehouse_calendar | 1 + .../setup.py | 6 + .../README.rst | 85 ++++ .../__init__.py | 1 + .../__manifest__.py | 16 + .../models/__init__.py | 1 + .../models/stock_release_channel.py | 48 ++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 1 + .../static/description/index.html | 426 ++++++++++++++++++ .../tests/__init__.py | 1 + .../tests/test_channel_delivery_date.py | 69 +++ 12 files changed, 656 insertions(+) create mode 120000 setup/stock_release_channel_warehouse_calendar/odoo/addons/stock_release_channel_warehouse_calendar create mode 100644 setup/stock_release_channel_warehouse_calendar/setup.py create mode 100644 stock_release_channel_warehouse_calendar/README.rst create mode 100644 stock_release_channel_warehouse_calendar/__init__.py create mode 100644 stock_release_channel_warehouse_calendar/__manifest__.py create mode 100644 stock_release_channel_warehouse_calendar/models/__init__.py create mode 100644 stock_release_channel_warehouse_calendar/models/stock_release_channel.py create mode 100644 stock_release_channel_warehouse_calendar/readme/CONTRIBUTORS.rst create mode 100644 stock_release_channel_warehouse_calendar/readme/DESCRIPTION.rst create mode 100644 stock_release_channel_warehouse_calendar/static/description/index.html create mode 100644 stock_release_channel_warehouse_calendar/tests/__init__.py create mode 100644 stock_release_channel_warehouse_calendar/tests/test_channel_delivery_date.py diff --git a/setup/stock_release_channel_warehouse_calendar/odoo/addons/stock_release_channel_warehouse_calendar b/setup/stock_release_channel_warehouse_calendar/odoo/addons/stock_release_channel_warehouse_calendar new file mode 120000 index 00000000000..24c66fce05c --- /dev/null +++ b/setup/stock_release_channel_warehouse_calendar/odoo/addons/stock_release_channel_warehouse_calendar @@ -0,0 +1 @@ +../../../../stock_release_channel_warehouse_calendar \ No newline at end of file diff --git a/setup/stock_release_channel_warehouse_calendar/setup.py b/setup/stock_release_channel_warehouse_calendar/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/stock_release_channel_warehouse_calendar/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_release_channel_warehouse_calendar/README.rst b/stock_release_channel_warehouse_calendar/README.rst new file mode 100644 index 00000000000..a8df0fe1406 --- /dev/null +++ b/stock_release_channel_warehouse_calendar/README.rst @@ -0,0 +1,85 @@ +========================================= +Stock Release Channels Warehouse Calendar +========================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:b9a622b5638dc89f2fe5ef7bb17be429c4b646474cf18c9c81cdea6dd3d9e007 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/16.0/stock_release_channel_warehouse_calendar + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_warehouse_calendar + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module when a calendar can be set on the warehouse. + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* BCIM +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* Jacques-Etienne Baudoux (BCIM) + +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. + +.. |maintainer-jbaudoux| image:: https://github.com/jbaudoux.png?size=40px + :target: https://github.com/jbaudoux + :alt: jbaudoux + +Current `maintainer `__: + +|maintainer-jbaudoux| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_release_channel_warehouse_calendar/__init__.py b/stock_release_channel_warehouse_calendar/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/stock_release_channel_warehouse_calendar/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_release_channel_warehouse_calendar/__manifest__.py b/stock_release_channel_warehouse_calendar/__manifest__.py new file mode 100644 index 00000000000..40d776458fa --- /dev/null +++ b/stock_release_channel_warehouse_calendar/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) +{ + "name": "Stock Release Channels Warehouse Calendar", + "summary": "Glue module between release channel and warehouse calendar", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "BCIM, Camptocamp, Odoo Community Association (OCA)", + "maintainers": ["jbaudoux"], + "website": "https://github.com/OCA/wms", + "depends": [ + "stock_release_channel", + "stock_warehouse_calendar", # OCA/stock-logistics-warehouse + ], + "auto_install": True, +} diff --git a/stock_release_channel_warehouse_calendar/models/__init__.py b/stock_release_channel_warehouse_calendar/models/__init__.py new file mode 100644 index 00000000000..a0504e84078 --- /dev/null +++ b/stock_release_channel_warehouse_calendar/models/__init__.py @@ -0,0 +1 @@ +from . import stock_release_channel diff --git a/stock_release_channel_warehouse_calendar/models/stock_release_channel.py b/stock_release_channel_warehouse_calendar/models/stock_release_channel.py new file mode 100644 index 00000000000..38aeb64bf80 --- /dev/null +++ b/stock_release_channel_warehouse_calendar/models/stock_release_channel.py @@ -0,0 +1,48 @@ +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from datetime import timedelta + +import pytz + +from odoo import models + + +class StockReleaseChannel(models.Model): + _inherit = "stock.release.channel" + + @property + def _delivery_date_generators(self): + d = super()._delivery_date_generators + d["preparation"].append(self._next_delivery_date_warehouse_calendar) + return d + + def _next_delivery_date_warehouse_calendar(self, delivery_date, partner=None): + """Get the next valid delivery date respecting warehouse calendar + + The preparation date must be during warehouse working hours given by + the calendar on the warehouse. + + A delivery date generator needs to provide the earliest valid date + starting from the received date. It can be called multiple times with a + new date to validate. + """ + calendar = self.warehouse_id.calendar_id + if not calendar: + while True: + delivery_date = yield delivery_date + wh_tz = pytz.timezone(self.warehouse_id.partner_id.tz or "UTC") + batch_delta = timedelta(days=61) + while True: + delivery_date = delivery_date.astimezone(pytz.utc) + work_intervals = calendar._work_intervals_batch( + delivery_date, delivery_date + batch_delta, tz=wh_tz + )[False] + for begin_dt_tz, end_dt_tz, _attendance in work_intervals: + while delivery_date <= end_dt_tz: + if delivery_date < begin_dt_tz: + delivery_date = begin_dt_tz + delivery_date = yield delivery_date.astimezone(pytz.utc).replace( + tzinfo=None + ) + delivery_date = delivery_date.astimezone(pytz.utc) diff --git a/stock_release_channel_warehouse_calendar/readme/CONTRIBUTORS.rst b/stock_release_channel_warehouse_calendar/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..3c6c5c696a8 --- /dev/null +++ b/stock_release_channel_warehouse_calendar/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Jacques-Etienne Baudoux (BCIM) diff --git a/stock_release_channel_warehouse_calendar/readme/DESCRIPTION.rst b/stock_release_channel_warehouse_calendar/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..4ba96149a1c --- /dev/null +++ b/stock_release_channel_warehouse_calendar/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Glue module when a calendar can be set on the warehouse. diff --git a/stock_release_channel_warehouse_calendar/static/description/index.html b/stock_release_channel_warehouse_calendar/static/description/index.html new file mode 100644 index 00000000000..c41b6266225 --- /dev/null +++ b/stock_release_channel_warehouse_calendar/static/description/index.html @@ -0,0 +1,426 @@ + + + + + +Stock Release Channels Warehouse Calendar + + + +
    +

    Stock Release Channels Warehouse Calendar

    + + +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Glue module when a calendar can be set on the warehouse.

    +

    Table of contents

    + +
    +

    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 to smash it by providing a detailed and welcomed +feedback.

    +

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

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • BCIM
    • +
    • Camptocamp
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    + +Odoo Community Association + +

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

    +

    Current maintainer:

    +

    jbaudoux

    +

    This module is part of the OCA/wms project on GitHub.

    +

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

    +
    +
    +
    + + diff --git a/stock_release_channel_warehouse_calendar/tests/__init__.py b/stock_release_channel_warehouse_calendar/tests/__init__.py new file mode 100644 index 00000000000..52a6a32ce1c --- /dev/null +++ b/stock_release_channel_warehouse_calendar/tests/__init__.py @@ -0,0 +1 @@ +from . import test_channel_delivery_date diff --git a/stock_release_channel_warehouse_calendar/tests/test_channel_delivery_date.py b/stock_release_channel_warehouse_calendar/tests/test_channel_delivery_date.py new file mode 100644 index 00000000000..e18774a018e --- /dev/null +++ b/stock_release_channel_warehouse_calendar/tests/test_channel_delivery_date.py @@ -0,0 +1,69 @@ +# Copyright 2024 Jacques-Etienne Baudoux (BCIM) +# Copyright 2024 Camptocamp (https://www.camptocamp.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + + +from odoo import fields + +from odoo.addons.stock_release_channel.tests.common import ReleaseChannelCase + +to_datetime = fields.Datetime.to_datetime + + +class TestChannelDeliveryDate(ReleaseChannelCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # Mon-Fri 8:00-12:00 13:00-17:00 + cls.calendar = cls.env.ref("resource.resource_calendar_std") + cls.wh.partner_id.tz = "Europe/Brussels" + cls.channel = cls._create_channel( + name="partner channel", + warehouse_id=cls.wh.id, + ) + + def test_warehouse_calendar_no_calendar(self): + dt = to_datetime("2023-02-01 08:00:00") + gen = self.channel._next_delivery_date_warehouse_calendar(dt) + result = next(gen) + self.assertEqual(result, dt) + result = gen.send(dt) + self.assertEqual(result, dt) + + def test_warehouse_calendar_time_before_opening(self): + self.wh.calendar_id = self.calendar + dt = to_datetime("2025-01-06 06:30:00") # Monday 07:30 + gen = self.channel._next_delivery_date_warehouse_calendar(dt) + result = next(gen) + opening = to_datetime("2025-01-06 07:00:00") # Monday 08:00 + self.assertEqual(result, opening) + result = gen.send(dt) + self.assertEqual(result, opening) + + def test_warehouse_calendar_time_during_opening(self): + self.wh.calendar_id = self.calendar + dt = to_datetime("2025-01-06 07:30:00") # Monday 08:30 + gen = self.channel._next_delivery_date_warehouse_calendar(dt) + result = next(gen) + self.assertEqual(result, dt) + dt = to_datetime("2025-01-06 15:30:00") # Monday 16:30 + result = gen.send(dt) + self.assertEqual(result, dt) + + def test_warehouse_calendar_time_after_opening(self): + self.wh.calendar_id = self.calendar + dt = to_datetime("2025-01-06 16:30:00") # Monday 17:30 + gen = self.channel._next_delivery_date_warehouse_calendar(dt) + result = next(gen) + next_day = to_datetime("2025-01-07 07:00:00") # Tuesday 08:00 + self.assertEqual(result, next_day) + + def test_warehouse_calendar_day_before_opening(self): + self.wh.calendar_id = self.calendar + dt = to_datetime("2025-01-05 14:30:00") # Sunday 15:30 + gen = self.channel._next_delivery_date_warehouse_calendar(dt) + result = next(gen) + opening = to_datetime("2025-01-06 07:00:00") # Monday 08:00 + self.assertEqual(result, opening) + result = gen.send(dt) + self.assertEqual(result, opening) From db8b32be4ba8bd17a7b0d21cd5ceebd4fac6c1df Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 May 2025 08:31:56 +0000 Subject: [PATCH 135/357] Added translation using Weblate (Italian) --- .../i18n/it.po | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 sale_stock_release_channel_delivery_date/i18n/it.po diff --git a/sale_stock_release_channel_delivery_date/i18n/it.po b/sale_stock_release_channel_delivery_date/i18n/it.po new file mode 100644 index 00000000000..2ad225ac8de --- /dev/null +++ b/sale_stock_release_channel_delivery_date/i18n/it.po @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_stock_release_channel_delivery_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: sale_stock_release_channel_delivery_date +#: model:ir.model,name:sale_stock_release_channel_delivery_date.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_stock_release_channel_delivery_date +#: model:ir.model,name:sale_stock_release_channel_delivery_date.model_sale_order_line +msgid "Sales Order Line" +msgstr "" From d7db548a5eedb491e4a4f0c08b84f3c3c6c75841 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 May 2025 09:06:43 +0000 Subject: [PATCH 136/357] Added translation using Weblate (Italian) --- sale_stock_release_channel/i18n/it.po | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 sale_stock_release_channel/i18n/it.po diff --git a/sale_stock_release_channel/i18n/it.po b/sale_stock_release_channel/i18n/it.po new file mode 100644 index 00000000000..973ec32bc3a --- /dev/null +++ b/sale_stock_release_channel/i18n/it.po @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_stock_release_channel +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: sale_stock_release_channel +#: model:ir.model,name:sale_stock_release_channel.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_stock_release_channel +#: model:ir.model,name:sale_stock_release_channel.model_stock_picking +msgid "Transfer" +msgstr "" From a17d41642c18ca9955be6298780b50b0abc90939 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 May 2025 09:06:48 +0000 Subject: [PATCH 137/357] Added translation using Weblate (Italian) --- .../i18n/it.po | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 sale_stock_release_channel_delivery/i18n/it.po diff --git a/sale_stock_release_channel_delivery/i18n/it.po b/sale_stock_release_channel_delivery/i18n/it.po new file mode 100644 index 00000000000..b995ef4a80c --- /dev/null +++ b/sale_stock_release_channel_delivery/i18n/it.po @@ -0,0 +1,20 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_stock_release_channel_delivery +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: sale_stock_release_channel_delivery +#: model:ir.model,name:sale_stock_release_channel_delivery.model_sale_order +msgid "Sales Order" +msgstr "" From ed19a4a945fffc203056542b09398c2c74504ad4 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 May 2025 09:07:12 +0000 Subject: [PATCH 138/357] Translated using Weblate (Italian) Currently translated at 100.0% (1 of 1 strings) Translation: wms-16.0/wms-16.0-sale_stock_release_channel_delivery Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-sale_stock_release_channel_delivery/it/ --- sale_stock_release_channel_delivery/i18n/it.po | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sale_stock_release_channel_delivery/i18n/it.po b/sale_stock_release_channel_delivery/i18n/it.po index b995ef4a80c..9f3e1f0469f 100644 --- a/sale_stock_release_channel_delivery/i18n/it.po +++ b/sale_stock_release_channel_delivery/i18n/it.po @@ -6,15 +6,17 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-05-29 11:25+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: sale_stock_release_channel_delivery #: model:ir.model,name:sale_stock_release_channel_delivery.model_sale_order msgid "Sales Order" -msgstr "" +msgstr "Ordine di vendita" From dd84cc3940c85e27a864a067343fd1f235a74ff0 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 May 2025 09:06:56 +0000 Subject: [PATCH 139/357] Translated using Weblate (Italian) Currently translated at 100.0% (2 of 2 strings) Translation: wms-16.0/wms-16.0-sale_stock_release_channel Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-sale_stock_release_channel/it/ --- sale_stock_release_channel/i18n/it.po | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sale_stock_release_channel/i18n/it.po b/sale_stock_release_channel/i18n/it.po index 973ec32bc3a..2ed9566beb6 100644 --- a/sale_stock_release_channel/i18n/it.po +++ b/sale_stock_release_channel/i18n/it.po @@ -6,20 +6,22 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-05-29 11:25+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: sale_stock_release_channel #: model:ir.model,name:sale_stock_release_channel.model_sale_order msgid "Sales Order" -msgstr "" +msgstr "Ordine di vendita" #. module: sale_stock_release_channel #: model:ir.model,name:sale_stock_release_channel.model_stock_picking msgid "Transfer" -msgstr "" +msgstr "Trasferimento" From 2a93623fe629d8e5ffaedaa087951921fda73b88 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 May 2025 15:13:04 +0200 Subject: [PATCH 140/357] [IMP] stock_release_channel_cutoff Add next delivery date generator --- .../models/stock_release_channel.py | 60 ++++++++++++++++--- .../tests/test_compute_cutoff_time.py | 38 ++++++++++++ 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/stock_release_channel_cutoff/models/stock_release_channel.py b/stock_release_channel_cutoff/models/stock_release_channel.py index dc652650939..9f6dcd64e35 100644 --- a/stock_release_channel_cutoff/models/stock_release_channel.py +++ b/stock_release_channel_cutoff/models/stock_release_channel.py @@ -2,6 +2,10 @@ # Copyright 2024 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) +from datetime import datetime + +import pytz + from odoo import api, fields, models from odoo.addons.stock_release_channel_process_end_time.utils import ( @@ -20,18 +24,58 @@ class StockReleaseChannel(models.Model): # Technical field for warning on kanban view cutoff_warning = fields.Boolean(compute="_compute_cutoff_warning") + @property + def cutoff_datetime(self): + self.ensure_one() + if not self.cutoff_time: + return False + now = self.process_end_date if self.state == "open" else fields.Datetime.now() + return time_to_datetime( + float_to_time( + self.cutoff_time, + ), + now=now, + tz=self.process_end_time_tz, + ) + @api.depends("cutoff_time", "state", "process_end_date", "process_end_time_tz") def _compute_cutoff_warning(self): now = fields.Datetime.now() for channel in self: cutoff_warning = False if channel.state == "open" and channel.cutoff_time: - cutoff = time_to_datetime( - float_to_time( - channel.cutoff_time, - ), - now=channel.process_end_date, - tz=channel.process_end_time_tz, - ) - cutoff_warning = cutoff < now + cutoff_warning = channel.cutoff_datetime < now channel.cutoff_warning = cutoff_warning + + @property + def _delivery_date_generators(self): + d = super()._delivery_date_generators + d["preparation"].append(self._next_delivery_date_cutoff) + return d + + def _next_delivery_date_cutoff(self, delivery_date, partner=None): + """Get the next valid delivery date respecting cutoff. + + The preparation date must be before the cutoff time otherwise it is + postponed to next day. + + A delivery date generator needs to provide the earliest valid date + starting from the received date. It can be called multiple times with a + new date to validate. + """ + self.ensure_one() + cutoff = self.cutoff_datetime + if not cutoff: + # any date is valid + while True: + delivery_date = yield delivery_date + wh_tz = pytz.timezone(self.process_end_time_tz) + next_day = time_to_datetime( + datetime.min.time(), + now=fields.Datetime.add(cutoff, days=1), + tz=wh_tz, + ) + while True: + while delivery_date <= cutoff: + delivery_date = yield delivery_date + delivery_date = yield max(delivery_date, next_day) diff --git a/stock_release_channel_cutoff/tests/test_compute_cutoff_time.py b/stock_release_channel_cutoff/tests/test_compute_cutoff_time.py index 64663661fc3..8a5dcb246b8 100644 --- a/stock_release_channel_cutoff/tests/test_compute_cutoff_time.py +++ b/stock_release_channel_cutoff/tests/test_compute_cutoff_time.py @@ -6,8 +6,11 @@ from freezegun import freeze_time +from odoo import fields from odoo.tests.common import TransactionCase +to_datetime = fields.Datetime.to_datetime + class TestStockReleaseChannelCutoff(TransactionCase): @classmethod @@ -66,3 +69,38 @@ def test_cutoff_warning_with_process_end_date_yesterday(self): self.channel.cutoff_time = 8.0 self.assertTrue(self.channel.cutoff_warning) + + @freeze_time("2023-02-01 09:00:00") + def test_delivery_date_no_cutoff(self): + self.channel.state = "asleep" + self.env.company.partner_id.tz = "Europe/Brussels" + self.channel.cutoff_time = 0 + dt = to_datetime("2023-02-01 08:00:00") + gen = self.channel._next_delivery_date_cutoff(dt) + result = next(gen) + self.assertEqual(result, dt) + result = gen.send(result) + self.assertEqual(result, dt) + + @freeze_time("2023-02-01 09:00:00") + def test_delivery_date_cutoff(self): + self.channel.state = "asleep" + self.env.company.partner_id.tz = "Europe/Brussels" + self.channel.cutoff_time = 9.5 # = 8.5 in UTC + # before cutoff + dt = to_datetime("2023-02-01 08:00:00") + gen = self.channel._next_delivery_date_cutoff(dt) + result = next(gen) + self.assertEqual(result, dt) + result = gen.send(result) + self.assertEqual(result, dt) + # after cutoff + dt = to_datetime("2023-02-01 09:00:00") + result = gen.send(dt) + next_day = to_datetime("2023-02-01 23:00:00") + self.assertEqual(result, next_day) + result = gen.send(result) + self.assertEqual(result, next_day) + dt = to_datetime("2023-02-02 09:00:00") + result = gen.send(dt) + self.assertEqual(result, dt) From f02073eb0c5d1f4d5e2a10d12550d0525056cabb Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Mon, 26 May 2025 21:53:14 +0200 Subject: [PATCH 141/357] [IMP] stock_release_channel_shipment_lead_time Add next delivery date generator --- .../models/stock_release_channel.py | 76 +++++++++++++++---- .../readme/ROADMAP.rst | 1 + .../tests/test_release_shipment_date.py | 27 +++++++ 3 files changed, 88 insertions(+), 16 deletions(-) create mode 100644 stock_release_channel_shipment_lead_time/readme/ROADMAP.rst diff --git a/stock_release_channel_shipment_lead_time/models/stock_release_channel.py b/stock_release_channel_shipment_lead_time/models/stock_release_channel.py index e113394402a..7110ea7795a 100644 --- a/stock_release_channel_shipment_lead_time/models/stock_release_channel.py +++ b/stock_release_channel_shipment_lead_time/models/stock_release_channel.py @@ -1,6 +1,6 @@ # Copyright 2023 Camptocamp +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) -from datetime import timedelta from odoo import api, fields, models @@ -9,6 +9,7 @@ class StockReleaseChannel(models.Model): _inherit = "stock.release.channel" shipment_lead_time = fields.Integer(help="Shipment Lead Time (days)") + # Migration note: rename shipment_date to delivery_date shipment_date = fields.Date( compute="_compute_shipment_date", store=True, @@ -19,29 +20,72 @@ class StockReleaseChannel(models.Model): "number of days = lead time + 1" ), ) + delivery_calendar_id = fields.Many2one( + comodel_name="resource.calendar", + compute="_compute_delivery_calendar_id", + store=True, + help=( + "Shipment Working Hours. Defaults tot warehouse calendar " + "for simplicity but another calendar can be used." + ), + ) + + @api.depends("warehouse_id.calendar_id") + def _compute_delivery_calendar_id(self): + for channel in self: + channel.delivery_calendar_id = channel.warehouse_id.calendar_id + + def _add_shipment_lead_time(self, dt): + """Add lead time to given datetime. + + If no calendar: dt + lead time + else: use calendar.plan_days(days, date_from, compute_leaves=True) + where days is amount of required open days (= lead time + 1) + """ + self.ensure_one() + if not self.shipment_lead_time: + return dt + dt_tz = self._localize(dt) + if not self.delivery_calendar_id: + shipment_tz = fields.Datetime.add(dt_tz, days=self.shipment_lead_time) + else: + days = self.shipment_lead_time + 1 + shipment_tz = self.delivery_calendar_id.plan_days( + days, dt_tz, compute_leaves=True + ) + shipment_dt = self._naive(shipment_tz, reset_time=True) + return shipment_dt + # Migration note: rename _compute_shipment_date to _compute_delivery_date @api.depends( "process_end_date", "shipment_lead_time", - "warehouse_id", - "warehouse_id.calendar_id", + "delivery_calendar_id", ) def _compute_shipment_date(self): - """ - if no warehouse or no calendar on the warehouse: - process end date + lead time - else: use calendar.plan_days(days, date_from, compute_leaves=True) - where days is amount of required open days (= lead time + 1) - """ for channel in self: shipment_date = False if channel.process_end_date: - shipment_date = channel.process_end_date + timedelta( - days=channel.shipment_lead_time + shipment_date = channel._add_shipment_lead_time( + channel.process_end_date ) - if channel.warehouse_id.calendar_id: - days = channel.shipment_lead_time + 1 - shipment_date = channel.warehouse_id.calendar_id.plan_days( - days, channel.process_end_date, compute_leaves=True - ) channel.shipment_date = shipment_date + + @property + def _delivery_date_generators(self): + d = super()._delivery_date_generators + d["delivery"].append(self._next_delivery_date_shipment_lead_time) + return d + + def _next_delivery_date_shipment_lead_time(self, delivery_date, partner=None): + """Get the next valid delivery date respecting transport lead time. + + The delivery date must be postponed at least by the shipment lead time. + + A delivery date generator needs to provide the earliest valid date + starting from the received date. It can be called multiple times with a + new date to validate. + """ + arrival_date = self._add_shipment_lead_time(delivery_date) + while True: + delivery_date = yield max(delivery_date, arrival_date) diff --git a/stock_release_channel_shipment_lead_time/readme/ROADMAP.rst b/stock_release_channel_shipment_lead_time/readme/ROADMAP.rst new file mode 100644 index 00000000000..29c8317207b --- /dev/null +++ b/stock_release_channel_shipment_lead_time/readme/ROADMAP.rst @@ -0,0 +1 @@ +Rename "Shipment date" to "Delivery date" as it is misleading diff --git a/stock_release_channel_shipment_lead_time/tests/test_release_shipment_date.py b/stock_release_channel_shipment_lead_time/tests/test_release_shipment_date.py index a1755ea2c6e..994b713d9e9 100644 --- a/stock_release_channel_shipment_lead_time/tests/test_release_shipment_date.py +++ b/stock_release_channel_shipment_lead_time/tests/test_release_shipment_date.py @@ -1,9 +1,13 @@ # Copyright 2023 Camptocamp +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + from odoo import fields from odoo.addons.stock_release_channel.tests.common import ChannelReleaseCase +to_datetime = fields.Datetime.to_datetime + class TestChannelReleaseShipmentLeadTime(ChannelReleaseCase): def test_shipment_date(self): @@ -28,3 +32,26 @@ def test_shipment_date_with_calendar(self): "2023-07-10", fields.Date.to_string(self.channel.shipment_date), ) + + def test_delivery_date_shipment_lead_time(self): + self.channel.warehouse_id = self.wh + self.channel.warehouse_id.calendar_id = self.env.ref( + "resource.resource_calendar_std" + ) + self.channel.warehouse_id.partner_id.tz = "Europe/Brussels" + self.channel.shipment_lead_time = 1 + dt = to_datetime("2025-01-02 08:00:00") # Thursday + gen = self.channel._next_delivery_date_shipment_lead_time(dt) + result = next(gen) + next_day = to_datetime("2025-01-02 23:00:00") # Friday + self.assertEqual(result, next_day) + result = gen.send(dt) + self.assertEqual(result, next_day) + # around week-end + dt = to_datetime("2025-01-03 08:00:00") # Friday + gen = self.channel._next_delivery_date_shipment_lead_time(dt) + result = next(gen) + next_day = to_datetime("2025-01-05 23:00:00") # Monday + self.assertEqual(result, next_day) + result = gen.send(dt) + self.assertEqual(result, next_day) From d376d9e4f86b6d17670b8752f9e6e30c910e4881 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 May 2025 14:56:32 +0200 Subject: [PATCH 142/357] [IMP] stock_release_channel_partner_delivery_window Add next delivery date generator --- .../models/stock_release_channel.py | 79 +++++++++++++++++++ .../tests/test_release_window.py | 27 +++++++ 2 files changed, 106 insertions(+) diff --git a/stock_release_channel_partner_delivery_window/models/stock_release_channel.py b/stock_release_channel_partner_delivery_window/models/stock_release_channel.py index 31c49aef8fc..7e37d953828 100644 --- a/stock_release_channel_partner_delivery_window/models/stock_release_channel.py +++ b/stock_release_channel_partner_delivery_window/models/stock_release_channel.py @@ -1,6 +1,8 @@ # Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from datetime import datetime + from odoo import api, fields, models @@ -33,3 +35,80 @@ def _compute_delivery_date_weekday(self): channel.delivery_date_weekday = channel.shipment_date.weekday() else: channel.delivery_date_weekday = -1 + + @property + def _delivery_date_generators(self): + d = super()._delivery_date_generators + d["customer"].append(self._next_delivery_date_partner_delivery_window) + return d + + def _next_delivery_date_partner_delivery_window(self, delivery_date, partner): + """Get the next valid delivery date respecting customer delivery window. + + The delivery date must be when the customer is open. + From the initial delivery_date, if the customer is not open on that + date and time, postpone to the start of the next open window. + + A delivery date generator needs to provide the earliest valid date + starting from the received date. It can be called multiple times with a + new date to validate. + """ + self.ensure_one() + partner.ensure_one() + if not self.respect_partner_delivery_time_windows: + while True: + delivery_date = yield delivery_date + + if partner.delivery_time_preference == "anytime": + # no constrain, any date is valid + while True: + delivery_date = yield delivery_date + + tz = partner.tz + if partner.delivery_time_preference == "workdays": + # postpone to Monday when date is on a week-end + while True: + delivery_date_tz = self._localize(delivery_date, tz=tz) + # postpone on Monday if Sat or Sun + if delivery_date_tz.weekday() < 5: # Mon-Fri + delivery_date = yield delivery_date + continue + days = 0 + if delivery_date_tz.weekday() == 5: # Sat + days = 1 + elif delivery_date_tz.weekday() == 6: # Sun + days = 2 + delivery_date_tz = fields.Datetime.add(delivery_date_tz, days=days) + delivery_date = self._naive(delivery_date_tz, reset_time=days) + delivery_date = yield delivery_date + + while True: + # yield first delivery window + delivery_date_tz = self._localize(delivery_date, tz=tz) + weekday = delivery_date_tz.weekday() + for inc in range(8): + # Each weekday is tested to find a window. + # On the first day, we need a window that ends after current + # delivery time. Afterwards, we just need a window. + windows = partner.delivery_time_window_ids.filtered( + lambda w: str(weekday + inc) + in w.time_window_weekday_ids.mapped("name") + and (inc or w.get_time_window_end_time() >= delivery_date_tz.time()) + ) + if windows: + w = windows[0] + break + else: + # There is no time window, we consider any date valid + while True: + delivery_date = yield delivery_date + # Postpone the delivery date to that found window + delivery_date_tz = datetime.combine( + (fields.Datetime.add(delivery_date_tz, days=inc)).date(), + max(w.get_time_window_start_time(), delivery_date_tz.time()) + if not inc + else w.get_time_window_start_time(), + tzinfo=delivery_date_tz.tzinfo, + ) + delivery_date = self._naive(delivery_date_tz) + delivery_date = yield delivery_date diff --git a/stock_release_channel_partner_delivery_window/tests/test_release_window.py b/stock_release_channel_partner_delivery_window/tests/test_release_window.py index d61d375ecb1..383bbfcc5ba 100644 --- a/stock_release_channel_partner_delivery_window/tests/test_release_window.py +++ b/stock_release_channel_partner_delivery_window/tests/test_release_window.py @@ -8,6 +8,8 @@ from odoo.addons.stock_release_channel.tests.common import ChannelReleaseCase +to_datetime = fields.Datetime.to_datetime + class ReleaseChannelEndDateCase(ChannelReleaseCase): @classmethod @@ -104,3 +106,28 @@ def test_assign_channel_no_respect_delivery_time_window(self): self.picking.partner_id = self.customer_time_window self._assign_picking(self.picking) self.assertEqual(self.channel, self.picking.release_channel_id) + + def test_delivery_date_partner_time_window_workdays(self): + # before opening + dt = to_datetime("2025-01-01 05:00:00") # Wed + gen = self.channel._next_delivery_date_partner_delivery_window( + dt, self.customer_time_window + ) + result = next(gen) + opening = to_datetime("2025-01-02 08:00:00") # Thu + self.assertEqual(result, opening) + result = gen.send(result) + self.assertEqual(result, opening) + # during opening + dt = to_datetime("2025-01-02 09:00:00") + result = gen.send(dt) + self.assertEqual(result, dt) + result = gen.send(result) + self.assertEqual(result, dt) + # after opening + dt = to_datetime("2025-01-02 19:00:00") + result = gen.send(dt) + next_opening = to_datetime("2025-01-04 08:00:00") # Sat + self.assertEqual(result, next_opening) + result = gen.send(result) + self.assertEqual(result, next_opening) From ed94b62ae190a15d35a48be2df0850ebe13043ce Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 May 2025 18:16:31 +0200 Subject: [PATCH 143/357] [IMP] stock_release_channel_plan_shipment_lead_time Add next delivery date generator --- .../models/stock_release_channel.py | 41 +++++++++++++++++++ .../tests/test_lead_time_weekday.py | 22 ++++++++++ 2 files changed, 63 insertions(+) diff --git a/stock_release_channel_plan_shipment_lead_time/models/stock_release_channel.py b/stock_release_channel_plan_shipment_lead_time/models/stock_release_channel.py index 67d63fca9d8..780f5c7af6f 100644 --- a/stock_release_channel_plan_shipment_lead_time/models/stock_release_channel.py +++ b/stock_release_channel_plan_shipment_lead_time/models/stock_release_channel.py @@ -1,6 +1,9 @@ # Copyright 2024 Camptocamp SA +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from datetime import datetime, timedelta + from odoo import api, fields, models @@ -52,3 +55,41 @@ def _compute_preparation_weekday_ids(self): channel.preparation_weekday_ids = self.env["time.weekday"].search( [("name", "in", weekday_names)] ) + + @property + def _delivery_date_generators(self): + d = super()._delivery_date_generators + d["preparation"].append(self._next_delivery_date_plan_weekdays) + return d + + def _next_delivery_date_plan_weekdays(self, delivery_date, partner=None): + """Get the next valid delivery date respecting plan weekdays. + + The preparation date must be a plan preparation weekday. + We do not consider the delivery weekday as it could be postponed with + leaves. + + A delivery date generator needs to provide the earliest valid date + starting from the received date. It can be called multiple times with a + new date to validate. + """ + self.ensure_one() + if not self.preparation_weekday_ids: + while True: + delivery_date = yield delivery_date + while True: + delivery_date_tz = self._localize(delivery_date) + weekday = delivery_date_tz.weekday() + for inc in range(8): + inc_weekday = (inc + weekday) % 7 + if str(inc_weekday) in self.preparation_weekday_ids.mapped("name"): + break + else: + raise Exception("delivery date plan weekdays internal error") + delivery_date_tz = datetime.combine( + (delivery_date_tz + timedelta(days=inc)).date(), + delivery_date_tz.time() if not inc else datetime.min.time(), + tzinfo=delivery_date_tz.tzinfo, + ) + delivery_date = self._naive(delivery_date_tz) + delivery_date = yield delivery_date diff --git a/stock_release_channel_plan_shipment_lead_time/tests/test_lead_time_weekday.py b/stock_release_channel_plan_shipment_lead_time/tests/test_lead_time_weekday.py index d8c37e6b92a..ce1171d9330 100644 --- a/stock_release_channel_plan_shipment_lead_time/tests/test_lead_time_weekday.py +++ b/stock_release_channel_plan_shipment_lead_time/tests/test_lead_time_weekday.py @@ -2,10 +2,13 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) from freezegun import freeze_time +from odoo import fields from odoo.fields import Command from odoo.addons.stock_release_channel.tests.common import ReleaseChannelCase +to_datetime = fields.Datetime.to_datetime + class TestReleaseChannelLeadTimeWeekday(ReleaseChannelCase): @classmethod @@ -153,3 +156,22 @@ def test_preparation_weekday_without_calendar(self): {"delivery_weekday_ids": [Command.link(self.thursday.id)]} ) self.assertIn(self.monday, self.default_channel.preparation_weekday_ids) + + @freeze_time("2025-01-02") + def test_delivery_date_plan_weekdays(self): + self.default_channel.write({"delivery_weekday_ids": [Command.clear()]}) + self.default_channel.shipment_lead_time = 2 + self.default_channel.write( + {"delivery_weekday_ids": [Command.link(self.wednesday.id)]} + ) + dt = fields.Datetime.now() # Thursday + gen = self.default_channel._next_delivery_date_plan_weekdays(dt) + # next preparation date is on next Monday (Wed -2d lead time) + result = next(gen) + next_mon = to_datetime("2025-01-06 00:00:00") + self.assertEqual(result, next_mon) + result = gen.send(next_mon) + self.assertEqual(result, next_mon) + # if we add 1 day, the next preparation date is 1 week later + result = gen.send(fields.Datetime.add(next_mon, days=1)) + self.assertEqual(result, fields.Datetime.add(next_mon, weeks=1)) From bf98e12f7449da4c29e51aab6d2dfdc3bdffcc38 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 3 Jun 2025 08:34:40 +0000 Subject: [PATCH 144/357] [UPD] Update stock_release_channel_shipment_lead_time.pot --- .../stock_release_channel_shipment_lead_time.pot | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/stock_release_channel_shipment_lead_time/i18n/stock_release_channel_shipment_lead_time.pot b/stock_release_channel_shipment_lead_time/i18n/stock_release_channel_shipment_lead_time.pot index f954ef3a6b7..06e3110826c 100644 --- a/stock_release_channel_shipment_lead_time/i18n/stock_release_channel_shipment_lead_time.pot +++ b/stock_release_channel_shipment_lead_time/i18n/stock_release_channel_shipment_lead_time.pot @@ -13,6 +13,11 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: stock_release_channel_shipment_lead_time +#: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_stock_release_channel__delivery_calendar_id +msgid "Delivery Calendar" +msgstr "" + #. module: stock_release_channel_shipment_lead_time #: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_shipment_advice__delivery_date msgid "Delivery Date" @@ -43,6 +48,13 @@ msgstr "" msgid "Shipment Lead Time (days)" msgstr "" +#. module: stock_release_channel_shipment_lead_time +#: model:ir.model.fields,help:stock_release_channel_shipment_lead_time.field_stock_release_channel__delivery_calendar_id +msgid "" +"Shipment Working Hours. Defaults tot warehouse calendar for simplicity but " +"another calendar can be used." +msgstr "" + #. module: stock_release_channel_shipment_lead_time #: model:ir.model,name:stock_release_channel_shipment_lead_time.model_stock_release_channel msgid "Stock Release Channels" From cc9342b8f1754539ee58e8bf87841b0ca6e047c4 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 3 Jun 2025 08:48:03 +0000 Subject: [PATCH 145/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 7 ++++- .../__manifest__.py | 2 +- .../static/description/index.html | 31 +++++++++++-------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 0b4bbc51306..c9524d0ac00 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ addon | version | maintainers | summary [stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.0 | | This module adds an action to the release channel to automate the delivery of its shippings. [stock_release_channel_shipment_advice_process_end_time](stock_release_channel_shipment_advice_process_end_time/) | 16.0.1.0.0 | | This module allows to set a delay time (in minutes) between the release channel process end time and the shipment advice arrival to the dock time. [stock_release_channel_shipment_advice_toursolver](stock_release_channel_shipment_advice_toursolver/) | 16.0.1.0.1 | | Use TourSolver to plan shipment advices for ready and released pickings -[stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Release channel with shipment lead time +[stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Release channel with shipment lead time [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels [stock_storage_type](stock_storage_type/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) | Manage packages and locations storage types diff --git a/stock_release_channel_shipment_lead_time/README.rst b/stock_release_channel_shipment_lead_time/README.rst index f50ac6f922b..dbfe60bf1db 100644 --- a/stock_release_channel_shipment_lead_time/README.rst +++ b/stock_release_channel_shipment_lead_time/README.rst @@ -7,7 +7,7 @@ Release channel shipment lead time !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:c2158bf4a0b06dcc988a18ebdd178f8a8b1abeff288dfc1a4721dd6222d21135 + !! source digest: sha256:307b41b3025c23a659098c0fb9e5cca2998d7c2dc745ca6f02497a4597b14319 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -48,6 +48,11 @@ Add the delivery date on the shipment advice. .. contents:: :local: +Known issues / Roadmap +====================== + +Rename "Shipment date" to "Delivery date" as it is misleading + Bug Tracker =========== diff --git a/stock_release_channel_shipment_lead_time/__manifest__.py b/stock_release_channel_shipment_lead_time/__manifest__.py index f43eee19f4e..8c3728d6de2 100644 --- a/stock_release_channel_shipment_lead_time/__manifest__.py +++ b/stock_release_channel_shipment_lead_time/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Release channel shipment lead time", "summary": "Release channel with shipment lead time", - "version": "16.0.2.0.0", + "version": "16.0.2.1.0", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_shipment_lead_time/static/description/index.html b/stock_release_channel_shipment_lead_time/static/description/index.html index 8f2cd353d2f..a965b252c02 100644 --- a/stock_release_channel_shipment_lead_time/static/description/index.html +++ b/stock_release_channel_shipment_lead_time/static/description/index.html @@ -367,7 +367,7 @@

    Release channel shipment lead time

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:c2158bf4a0b06dcc988a18ebdd178f8a8b1abeff288dfc1a4721dd6222d21135 +!! source digest: sha256:307b41b3025c23a659098c0fb9e5cca2998d7c2dc745ca6f02497a4597b14319 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Manage shipment date and delivery lead time on release channel. @@ -384,18 +384,23 @@

    Release channel shipment lead time

    Table of contents

    +
    +

    Known issues / Roadmap

    +

    Rename “Shipment date” to “Delivery date” as it is misleading

    +
    -

    Bug Tracker

    +

    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 to smash it by providing a detailed and welcomed @@ -403,16 +408,16 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Camptocamp
    • BCIM
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by Camptocamp

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association From f99bfe431ca8e3a278f7f96e0710d62d6e07ac4a Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 3 Jun 2025 08:48:12 +0000 Subject: [PATCH 146/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_release_channel_shipment_lead_time Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_shipment_lead_time/ --- .../i18n/fr.po | 16 ++++++++++++++-- .../i18n/it.po | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/stock_release_channel_shipment_lead_time/i18n/fr.po b/stock_release_channel_shipment_lead_time/i18n/fr.po index 45844b84866..348f008dd9d 100644 --- a/stock_release_channel_shipment_lead_time/i18n/fr.po +++ b/stock_release_channel_shipment_lead_time/i18n/fr.po @@ -16,6 +16,11 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.6.2\n" +#. module: stock_release_channel_shipment_lead_time +#: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_stock_release_channel__delivery_calendar_id +msgid "Delivery Calendar" +msgstr "" + #. module: stock_release_channel_shipment_lead_time #: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_shipment_advice__delivery_date msgid "Delivery Date" @@ -46,6 +51,13 @@ msgstr "" msgid "Shipment Lead Time (days)" msgstr "" +#. module: stock_release_channel_shipment_lead_time +#: model:ir.model.fields,help:stock_release_channel_shipment_lead_time.field_stock_release_channel__delivery_calendar_id +msgid "" +"Shipment Working Hours. Defaults tot warehouse calendar for simplicity but " +"another calendar can be used." +msgstr "" + #. module: stock_release_channel_shipment_lead_time #: model:ir.model,name:stock_release_channel_shipment_lead_time.model_stock_release_channel msgid "Stock Release Channels" @@ -60,8 +72,8 @@ msgstr "Transfert" #: model:ir.model.fields,help:stock_release_channel_shipment_lead_time.field_stock_release_channel__shipment_date msgid "" "if no warehouse or no calendar on the warehouse:process end date + shipment " -"lead time.Otherwise, it's counted by calendar included leaves:number of days" -" = lead time + 1" +"lead time.Otherwise, it's counted by calendar included leaves:number of days " +"= lead time + 1" msgstr "" #. module: stock_release_channel_shipment_lead_time diff --git a/stock_release_channel_shipment_lead_time/i18n/it.po b/stock_release_channel_shipment_lead_time/i18n/it.po index c79a0908326..c64e7dc7759 100644 --- a/stock_release_channel_shipment_lead_time/i18n/it.po +++ b/stock_release_channel_shipment_lead_time/i18n/it.po @@ -16,6 +16,11 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17\n" +#. module: stock_release_channel_shipment_lead_time +#: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_stock_release_channel__delivery_calendar_id +msgid "Delivery Calendar" +msgstr "" + #. module: stock_release_channel_shipment_lead_time #: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_shipment_advice__delivery_date msgid "Delivery Date" @@ -46,6 +51,13 @@ msgstr "Durata spedizione" msgid "Shipment Lead Time (days)" msgstr "Durata spedizione (giorni)" +#. module: stock_release_channel_shipment_lead_time +#: model:ir.model.fields,help:stock_release_channel_shipment_lead_time.field_stock_release_channel__delivery_calendar_id +msgid "" +"Shipment Working Hours. Defaults tot warehouse calendar for simplicity but " +"another calendar can be used." +msgstr "" + #. module: stock_release_channel_shipment_lead_time #: model:ir.model,name:stock_release_channel_shipment_lead_time.model_stock_release_channel msgid "Stock Release Channels" @@ -60,8 +72,8 @@ msgstr "Trasferimento" #: model:ir.model.fields,help:stock_release_channel_shipment_lead_time.field_stock_release_channel__shipment_date msgid "" "if no warehouse or no calendar on the warehouse:process end date + shipment " -"lead time.Otherwise, it's counted by calendar included leaves:number of days" -" = lead time + 1" +"lead time.Otherwise, it's counted by calendar included leaves:number of days " +"= lead time + 1" msgstr "" "se non c'è il magazzino o il calendario del magazzino: data fine processo + " "durata spedizione. Altrimenti, è contata dal calendario dei livelli inclusi: " From 236f36bea215c52ae85b5489053d29bf5eb500d7 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 3 Jun 2025 08:59:29 +0000 Subject: [PATCH 147/357] [UPD] Update stock_release_channel_warehouse_calendar.pot --- ...ock_release_channel_warehouse_calendar.pot | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 stock_release_channel_warehouse_calendar/i18n/stock_release_channel_warehouse_calendar.pot diff --git a/stock_release_channel_warehouse_calendar/i18n/stock_release_channel_warehouse_calendar.pot b/stock_release_channel_warehouse_calendar/i18n/stock_release_channel_warehouse_calendar.pot new file mode 100644 index 00000000000..20ff234b523 --- /dev/null +++ b/stock_release_channel_warehouse_calendar/i18n/stock_release_channel_warehouse_calendar.pot @@ -0,0 +1,19 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_release_channel_warehouse_calendar +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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_release_channel_warehouse_calendar +#: model:ir.model,name:stock_release_channel_warehouse_calendar.model_stock_release_channel +msgid "Stock Release Channels" +msgstr "" From 82da58f6443dc595f5887b79865d806ec1e7d526 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 3 Jun 2025 09:10:41 +0000 Subject: [PATCH 148/357] [BOT] post-merge updates --- README.md | 1 + setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + .../README.rst | 2 +- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 2 +- 6 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 stock_release_channel_warehouse_calendar/static/description/icon.png diff --git a/README.md b/README.md index c9524d0ac00..27eaa7ce04b 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ addon | version | maintainers | summary [stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Release channel with shipment lead time [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels +[stock_release_channel_warehouse_calendar](stock_release_channel_warehouse_calendar/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue module between release channel and warehouse calendar [stock_storage_type](stock_storage_type/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) | Manage packages and locations storage types [stock_storage_type_putaway_abc](stock_storage_type_putaway_abc/) | 16.0.1.0.0 | | Advanced storage strategy ABC for WMS [stock_warehouse_flow](stock_warehouse_flow/) | 16.0.1.1.0 | | Configure routing flow for stock moves diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 28e8403b265..086eb2e47fb 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250528.1 \ No newline at end of file +16.0.20250603.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index ca8630470d8..21e7d19a358 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -59,6 +59,7 @@ 'odoo-addon-stock_release_channel_shipment_lead_time>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_show_volume>=16.0dev,<16.1dev', 'odoo-addon-stock_release_channel_show_weight>=16.0dev,<16.1dev', + 'odoo-addon-stock_release_channel_warehouse_calendar>=16.0dev,<16.1dev', 'odoo-addon-stock_storage_type>=16.0dev,<16.1dev', 'odoo-addon-stock_storage_type_putaway_abc>=16.0dev,<16.1dev', 'odoo-addon-stock_warehouse_flow>=16.0dev,<16.1dev', diff --git a/stock_release_channel_warehouse_calendar/README.rst b/stock_release_channel_warehouse_calendar/README.rst index a8df0fe1406..c6e52223951 100644 --- a/stock_release_channel_warehouse_calendar/README.rst +++ b/stock_release_channel_warehouse_calendar/README.rst @@ -7,7 +7,7 @@ Stock Release Channels Warehouse Calendar !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b9a622b5638dc89f2fe5ef7bb17be429c4b646474cf18c9c81cdea6dd3d9e007 + !! source digest: sha256:cb4a89c714e1c59bee2952cc7c607482defba205f0b5bf3ae01d1ad31ee2f78e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_warehouse_calendar/static/description/icon.png b/stock_release_channel_warehouse_calendar/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Release Channels Warehouse Calendar !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:b9a622b5638dc89f2fe5ef7bb17be429c4b646474cf18c9c81cdea6dd3d9e007 +!! source digest: sha256:cb4a89c714e1c59bee2952cc7c607482defba205f0b5bf3ae01d1ad31ee2f78e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Glue module when a calendar can be set on the warehouse.

    From 33438edc8393676c78cf105d530707c7f68da6e0 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 3 Jun 2025 11:59:53 +0000 Subject: [PATCH 149/357] [BOT] post-merge updates --- README.md | 58 +++++++++---------- stock_release_channel_cutoff/README.rst | 8 ++- stock_release_channel_cutoff/__manifest__.py | 2 +- .../static/description/index.html | 39 ++++++++----- 4 files changed, 60 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 27eaa7ce04b..bca1524aa00 100644 --- a/README.md +++ b/README.md @@ -24,56 +24,56 @@ addon | version | maintainers | summary [delivery_carrier_warehouse](delivery_carrier_warehouse/) | 16.0.1.0.1 | | Get delivery method used in sales orders from warehouse [sale_stock_available_to_promise_release](sale_stock_available_to_promise_release/) | 16.0.1.1.2 | | Integration between Sales and Available to Promise Release [sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.1.0 | | Block release of deliveries from sales orders. -[sale_stock_release_channel](sale_stock_release_channel/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Sales Stock Release Channel -[sale_stock_release_channel_delivery](sale_stock_release_channel_delivery/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Sales Stock Release Channel Delivery -[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Compute expected date based on available release channels -[sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Release channels integration with Sales -[sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.8.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | manage warehouse operations with barcode scanners -[shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Core module for creating mobile apps -[shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | [![guewen](https://github.com/guewen.png?size=30px)](https://github.com/guewen) | Create batch transfers for Cluster Picking -[shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Mobile frontend for WMS Shopfloor app -[shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Mobile frontend for WMS Shopfloor app +[sale_stock_release_channel](sale_stock_release_channel/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel +[sale_stock_release_channel_delivery](sale_stock_release_channel_delivery/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel Delivery +[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | jbaudoux | Compute expected date based on available release channels +[sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales +[sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. +[shopfloor](shopfloor/) | 16.0.2.8.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps +[shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking +[shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app +[shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.1.0 | [![mmequignon](https://github.com/mmequignon.png?size=30px)](https://github.com/mmequignon) [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Reception scenario for shopfloor -[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | [![JuMiSanAr](https://github.com/JuMiSanAr.png?size=30px)](https://github.com/JuMiSanAr) | Scenario for receiving products -[shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | [![simahawk](https://github.com/simahawk.png?size=30px)](https://github.com/simahawk) | Integrate rest_log into Shopfloor app +[shopfloor_reception](shopfloor_reception/) | 16.0.1.1.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | JuMiSanAr | Scenario for receiving products +[shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation [stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.7.1 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves -[stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.1.0.0 | [![lmignon](https://github.com/lmignon.png?size=30px)](https://github.com/lmignon) | Create a batch of pickings to be processed all together +[stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.1.0.0 | lmignon | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type -[stock_release_channel](stock_release_channel/) | 16.0.3.1.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![mt-software-de](https://github.com/mt-software-de.png?size=30px)](https://github.com/mt-software-de) | Manage workload in WMS with release channels +[stock_release_channel](stock_release_channel/) | 16.0.3.1.0 | sebalix jbaudoux mt-software-de | Manage workload in WMS with release channels [stock_release_channel_auto_release](stock_release_channel_auto_release/) | 16.0.1.1.0 | | Add an automatic release mode to the release channel [stock_release_channel_batch_mode_commercial_partner](stock_release_channel_batch_mode_commercial_partner/) | 16.0.1.0.2 | | Release pickings into channels by batch of same commercial entity -[stock_release_channel_cutoff](stock_release_channel_cutoff/) | 16.0.1.0.2 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add the cutoff time to the release channel +[stock_release_channel_cutoff](stock_release_channel_cutoff/) | 16.0.1.1.0 | jbaudoux | Add the cutoff time to the release channel [stock_release_channel_delivery](stock_release_channel_delivery/) | 16.0.3.0.0 | | Add a carrier selection criteria on the release channel [stock_release_channel_depot](stock_release_channel_depot/) | 16.0.1.0.0 | | This module allows users to add partner depot to stock release channel. [stock_release_channel_geoengine](stock_release_channel_geoengine/) | 16.0.2.0.0 | | Release channel based on geo-localization -[stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.2.0.1 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Set release channels for specific delivery dates -[stock_release_channel_partner_by_date_delivery_window](stock_release_channel_partner_by_date_delivery_window/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Delivery window -[stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue Stock Release Channels for Delivery Dates and Public holidays -[stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings -[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Add an option to exclude the public holidays when assigning th release channel -[stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Manage release channel preparation plan +[stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.2.0.1 | sebalix jbaudoux | Set release channels for specific delivery dates +[stock_release_channel_partner_by_date_delivery_window](stock_release_channel_partner_by_date_delivery_window/) | 16.0.1.0.0 | jbaudoux | Glue Stock Release Channels for Delivery Dates and Delivery window +[stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.2.0.0 | jbaudoux | Glue Stock Release Channels for Delivery Dates and Public holidays +[stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings +[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.0.0 | jbaudoux | Add an option to exclude the public holidays when assigning th release channel +[stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | jbaudoux | Manage release channel preparation plan [stock_release_channel_plan_depot](stock_release_channel_plan_depot/) | 16.0.1.0.0 | | This module allows users to set partner depot on stock release channel preparation plan. -[stock_release_channel_plan_process_end_time](stock_release_channel_plan_process_end_time/) | 16.0.1.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue module between release channel plan and process end time -[stock_release_channel_plan_shipment_lead_time](stock_release_channel_plan_shipment_lead_time/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Stock release channel plan shipment lead time -[stock_release_channel_process_end_time](stock_release_channel_process_end_time/) | 16.0.1.7.0 | [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings +[stock_release_channel_plan_process_end_time](stock_release_channel_plan_process_end_time/) | 16.0.1.1.0 | jbaudoux | Glue module between release channel plan and process end time +[stock_release_channel_plan_shipment_lead_time](stock_release_channel_plan_shipment_lead_time/) | 16.0.1.0.0 | jbaudoux | Stock release channel plan shipment lead time +[stock_release_channel_process_end_time](stock_release_channel_process_end_time/) | 16.0.1.7.0 | rousseldenis jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_propagate_channel_picking](stock_release_channel_propagate_channel_picking/) | 16.0.1.2.0 | | Allows to propagate the channel to every picking that is created from the original one. -[stock_release_channel_shipment_advice](stock_release_channel_shipment_advice/) | 16.0.1.2.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Plan shipment advices for ready and released pickings +[stock_release_channel_shipment_advice](stock_release_channel_shipment_advice/) | 16.0.1.2.0 | jbaudoux | Plan shipment advices for ready and released pickings [stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.0 | | This module adds an action to the release channel to automate the delivery of its shippings. [stock_release_channel_shipment_advice_process_end_time](stock_release_channel_shipment_advice_process_end_time/) | 16.0.1.0.0 | | This module allows to set a delay time (in minutes) between the release channel process end time and the shipment advice arrival to the dock time. [stock_release_channel_shipment_advice_toursolver](stock_release_channel_shipment_advice_toursolver/) | 16.0.1.0.1 | | Use TourSolver to plan shipment advices for ready and released pickings -[stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.1.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Release channel with shipment lead time +[stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.1.0 | jbaudoux | Release channel with shipment lead time [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels -[stock_release_channel_warehouse_calendar](stock_release_channel_warehouse_calendar/) | 16.0.1.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) | Glue module between release channel and warehouse calendar -[stock_storage_type](stock_storage_type/) | 16.0.2.0.0 | [![jbaudoux](https://github.com/jbaudoux.png?size=30px)](https://github.com/jbaudoux) [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) | Manage packages and locations storage types +[stock_release_channel_warehouse_calendar](stock_release_channel_warehouse_calendar/) | 16.0.1.0.0 | jbaudoux | Glue module between release channel and warehouse calendar +[stock_storage_type](stock_storage_type/) | 16.0.2.0.0 | jbaudoux rousseldenis | Manage packages and locations storage types [stock_storage_type_putaway_abc](stock_storage_type_putaway_abc/) | 16.0.1.0.0 | | Advanced storage strategy ABC for WMS [stock_warehouse_flow](stock_warehouse_flow/) | 16.0.1.1.0 | | Configure routing flow for stock moves [stock_warehouse_flow_delivery_refresh](stock_warehouse_flow_delivery_refresh/) | 16.0.1.0.0 | | Allow to refresh delivery flow when carrier changes diff --git a/stock_release_channel_cutoff/README.rst b/stock_release_channel_cutoff/README.rst index c793f979f15..7932ab7e664 100644 --- a/stock_release_channel_cutoff/README.rst +++ b/stock_release_channel_cutoff/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================= Stock Release Channels Cutoff ============================= @@ -7,13 +11,13 @@ Stock Release Channels Cutoff !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b9a622b5638dc89f2fe5ef7bb17be429c4b646474cf18c9c81cdea6dd3d9e007 + !! source digest: sha256:1990d9256b77b09bfb544585c91574bd064458fe5972b163e3843d6cd6d176da !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_release_channel_cutoff/__manifest__.py b/stock_release_channel_cutoff/__manifest__.py index 97a2927ccdd..6197f49cdee 100644 --- a/stock_release_channel_cutoff/__manifest__.py +++ b/stock_release_channel_cutoff/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Release Channels Cutoff", "summary": "Add the cutoff time to the release channel", - "version": "16.0.1.0.2", + "version": "16.0.1.1.0", "license": "AGPL-3", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "maintainers": ["jbaudoux"], diff --git a/stock_release_channel_cutoff/static/description/index.html b/stock_release_channel_cutoff/static/description/index.html index 08637543308..b3af95487b9 100644 --- a/stock_release_channel_cutoff/static/description/index.html +++ b/stock_release_channel_cutoff/static/description/index.html @@ -3,15 +3,16 @@ -Stock Release Channels Cutoff +README.rst -
    -

    Stock Release Channels Cutoff

    +
    + + +Odoo Community Association + +
    +

    Stock Release Channels Cutoff

    -

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    This module lets users select a release channel and set a specific cutoff time for it.

    When the current time (now) becomes later than the cutoff time and the channel is still open, the kanban view for that channel will display the cutoff time in red as a warning.

    @@ -386,7 +392,7 @@

    Stock Release Channels Cutoff

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -394,32 +400,34 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

  • Jacques-Etienne Baudoux <je@bcim.be>
  • Duong (Tran Quoc) <trobz.com>
-

Other credits

+

Other credits

The development of this module has been financially supported by:

  • Camptocamp
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

-Odoo Community Association + +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.

@@ -430,5 +438,6 @@

Maintainers

+ From b343aa9920e6819874dafa3e18fdeb6340c38fcc Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 3 Jun 2025 12:45:13 +0000 Subject: [PATCH 150/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 8 ++++-- .../__manifest__.py | 2 +- .../static/description/index.html | 26 ++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index bca1524aa00..ae54cf9eef7 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ addon | version | maintainers | summary [stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | jbaudoux | Manage release channel preparation plan [stock_release_channel_plan_depot](stock_release_channel_plan_depot/) | 16.0.1.0.0 | | This module allows users to set partner depot on stock release channel preparation plan. [stock_release_channel_plan_process_end_time](stock_release_channel_plan_process_end_time/) | 16.0.1.1.0 | jbaudoux | Glue module between release channel plan and process end time -[stock_release_channel_plan_shipment_lead_time](stock_release_channel_plan_shipment_lead_time/) | 16.0.1.0.0 | jbaudoux | Stock release channel plan shipment lead time +[stock_release_channel_plan_shipment_lead_time](stock_release_channel_plan_shipment_lead_time/) | 16.0.1.1.0 | jbaudoux | Stock release channel plan shipment lead time [stock_release_channel_process_end_time](stock_release_channel_process_end_time/) | 16.0.1.7.0 | rousseldenis jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_propagate_channel_picking](stock_release_channel_propagate_channel_picking/) | 16.0.1.2.0 | | Allows to propagate the channel to every picking that is created from the original one. [stock_release_channel_shipment_advice](stock_release_channel_shipment_advice/) | 16.0.1.2.0 | jbaudoux | Plan shipment advices for ready and released pickings diff --git a/stock_release_channel_plan_shipment_lead_time/README.rst b/stock_release_channel_plan_shipment_lead_time/README.rst index ce2ce557635..3de5c539b75 100644 --- a/stock_release_channel_plan_shipment_lead_time/README.rst +++ b/stock_release_channel_plan_shipment_lead_time/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================================= Stock release channel plan shipment lead time ============================================= @@ -7,13 +11,13 @@ Stock release channel plan shipment lead time !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e0e7fe225eb4c28b94ac0f956eb4cb837566524e04a5766633bb5d5eea00f87c + !! source digest: sha256:c0bbd5b6dd47084d43073a117ef85911df2c73869a7f01e53b6da789c0fd48f9 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_release_channel_plan_shipment_lead_time/__manifest__.py b/stock_release_channel_plan_shipment_lead_time/__manifest__.py index bcedbc28820..68f54601ae2 100644 --- a/stock_release_channel_plan_shipment_lead_time/__manifest__.py +++ b/stock_release_channel_plan_shipment_lead_time/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock release channel plan shipment lead time", "summary": "Stock release channel plan shipment lead time", - "version": "16.0.1.0.0", + "version": "16.0.1.1.0", "development_status": "Beta", "category": "Uncategorized", "website": "https://github.com/OCA/wms", diff --git a/stock_release_channel_plan_shipment_lead_time/static/description/index.html b/stock_release_channel_plan_shipment_lead_time/static/description/index.html index de88b873543..0fc8d468253 100644 --- a/stock_release_channel_plan_shipment_lead_time/static/description/index.html +++ b/stock_release_channel_plan_shipment_lead_time/static/description/index.html @@ -3,7 +3,7 @@ -Stock release channel plan shipment lead time +README.rst -
-

Stock release channel plan shipment lead time

+
+ + +Odoo Community Association + +
+

Stock release channel plan shipment lead time

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

When the release channel has a delivery lead time, visualize the preparation days based on the delivery days and the lead time. When creating your preparation plan, you can see which channel have to be prepared on which day.

@@ -386,7 +391,7 @@

Stock release channel plan shipment lead time

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -394,23 +399,23 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -425,5 +430,6 @@

Maintainers

+
From 0a052ed2ecb5ecb0e33ad1537659c43d2269005f Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 3 Jun 2025 13:54:47 +0000 Subject: [PATCH 151/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 9 ++++-- .../__manifest__.py | 2 +- .../static/description/index.html | 29 ++++++++++++------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ae54cf9eef7..9484303eb88 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ addon | version | maintainers | summary [stock_release_channel_partner_by_date_delivery_window](stock_release_channel_partner_by_date_delivery_window/) | 16.0.1.0.0 | jbaudoux | Glue Stock Release Channels for Delivery Dates and Delivery window [stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.2.0.0 | jbaudoux | Glue Stock Release Channels for Delivery Dates and Public holidays [stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings -[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.0.0 | jbaudoux | Add an option to exclude the public holidays when assigning th release channel +[stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.1.0 | jbaudoux | Add an option to exclude the public holidays when assigning th release channel [stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | jbaudoux | Manage release channel preparation plan [stock_release_channel_plan_depot](stock_release_channel_plan_depot/) | 16.0.1.0.0 | | This module allows users to set partner depot on stock release channel preparation plan. [stock_release_channel_plan_process_end_time](stock_release_channel_plan_process_end_time/) | 16.0.1.1.0 | jbaudoux | Glue module between release channel plan and process end time diff --git a/stock_release_channel_partner_public_holidays/README.rst b/stock_release_channel_partner_public_holidays/README.rst index b988d5298b3..a98d983e2ae 100644 --- a/stock_release_channel_partner_public_holidays/README.rst +++ b/stock_release_channel_partner_public_holidays/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================================= Stock Release Channel Partner Public Holidays ============================================= @@ -7,13 +11,13 @@ Stock Release Channel Partner Public Holidays !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f693a3d2112af69a449d66b8a67b3e64ee7c14c09368f96527b9035adc234a97 + !! source digest: sha256:477d3e7303508b90a197c9964ea9e067b6597e8504d6d8811f114cdd80ecfd98 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github @@ -63,6 +67,7 @@ Authors Contributors ~~~~~~~~~~~~ +* Jacques-Etienne Baudoux (BCIM) * Nguyen Minh Chien Maintainers diff --git a/stock_release_channel_partner_public_holidays/__manifest__.py b/stock_release_channel_partner_public_holidays/__manifest__.py index 1d3376f33b0..c4689a133c1 100644 --- a/stock_release_channel_partner_public_holidays/__manifest__.py +++ b/stock_release_channel_partner_public_holidays/__manifest__.py @@ -4,7 +4,7 @@ "name": "Stock Release Channel Partner Public Holidays", "summary": """ Add an option to exclude the public holidays when assigning th release channel""", - "version": "16.0.2.0.0", + "version": "16.0.2.1.0", "license": "AGPL-3", "maintainers": ["jbaudoux"], "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_public_holidays/static/description/index.html b/stock_release_channel_partner_public_holidays/static/description/index.html index 6ccc5d8c6cd..d23603d17e3 100644 --- a/stock_release_channel_partner_public_holidays/static/description/index.html +++ b/stock_release_channel_partner_public_holidays/static/description/index.html @@ -3,7 +3,7 @@ -Stock Release Channel Partner Public Holidays +README.rst -
-

Stock Release Channel Partner Public Holidays

+
+ + +Odoo Community Association + +
+

Stock Release Channel Partner Public Holidays

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This module adds an option to exclude the channel when its shipment date is a public holiday

Table of contents

@@ -385,14 +390,14 @@

Stock Release Channel Partner Public Holidays

-

Usage

+

Usage

  1. Go To Release Channels
  2. on Tab Selection criteria: Tick on the option Exclude Public Holidays?
-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -400,22 +405,23 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -430,5 +436,6 @@

Maintainers

+
From ad4ed6bca14ac2c30fa2617e19bcdd0a2bcd36e7 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 3 Jun 2025 15:20:50 +0000 Subject: [PATCH 152/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 8 ++++-- .../__manifest__.py | 2 +- .../static/description/index.html | 28 +++++++++++-------- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9484303eb88..8b4d1de758f 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ addon | version | maintainers | summary [stock_release_channel_partner_by_date](stock_release_channel_partner_by_date/) | 16.0.2.0.1 | sebalix jbaudoux | Set release channels for specific delivery dates [stock_release_channel_partner_by_date_delivery_window](stock_release_channel_partner_by_date_delivery_window/) | 16.0.1.0.0 | jbaudoux | Glue Stock Release Channels for Delivery Dates and Delivery window [stock_release_channel_partner_by_date_public_holidays](stock_release_channel_partner_by_date_public_holidays/) | 16.0.2.0.0 | jbaudoux | Glue Stock Release Channels for Delivery Dates and Public holidays -[stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.0.0 | jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings +[stock_release_channel_partner_delivery_window](stock_release_channel_partner_delivery_window/) | 16.0.2.1.0 | jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_partner_public_holidays](stock_release_channel_partner_public_holidays/) | 16.0.2.1.0 | jbaudoux | Add an option to exclude the public holidays when assigning th release channel [stock_release_channel_plan](stock_release_channel_plan/) | 16.0.1.3.0 | jbaudoux | Manage release channel preparation plan [stock_release_channel_plan_depot](stock_release_channel_plan_depot/) | 16.0.1.0.0 | | This module allows users to set partner depot on stock release channel preparation plan. diff --git a/stock_release_channel_partner_delivery_window/README.rst b/stock_release_channel_partner_delivery_window/README.rst index 89ec119f731..db66249b9b9 100644 --- a/stock_release_channel_partner_delivery_window/README.rst +++ b/stock_release_channel_partner_delivery_window/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================================= Stock Release Channel Partner Delivery Window ============================================= @@ -7,13 +11,13 @@ Stock Release Channel Partner Delivery Window !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:5883e42a1f877f4be3a892ba5719290292c453c87d886c95004d8859a6b76045 + !! source digest: sha256:f546d82efdafe203b5da0321d93e8a6b764c8baf232b7999ccfc32ff82bdefde !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_release_channel_partner_delivery_window/__manifest__.py b/stock_release_channel_partner_delivery_window/__manifest__.py index d444cd3afbb..a72cd7e6f66 100644 --- a/stock_release_channel_partner_delivery_window/__manifest__.py +++ b/stock_release_channel_partner_delivery_window/__manifest__.py @@ -6,7 +6,7 @@ "summary": """ Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings""", - "version": "16.0.2.0.0", + "version": "16.0.2.1.0", "license": "AGPL-3", "maintainers": ["jbaudoux"], "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/stock_release_channel_partner_delivery_window/static/description/index.html b/stock_release_channel_partner_delivery_window/static/description/index.html index 624ec1bc566..bbe8b3ee0bf 100644 --- a/stock_release_channel_partner_delivery_window/static/description/index.html +++ b/stock_release_channel_partner_delivery_window/static/description/index.html @@ -3,7 +3,7 @@ -Stock Release Channel Partner Delivery Window +README.rst -
-

Stock Release Channel Partner Delivery Window

+
+ + +Odoo Community Association + +
+

Stock Release Channel Partner Delivery Window

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This module excludes the channel when its shipment date is not in Partner delivery window

Table of contents

@@ -385,7 +390,7 @@

Stock Release Channel Partner Delivery Window

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -393,27 +398,27 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The development of this module has been financially supported by Camptocamp

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -428,5 +433,6 @@

Maintainers

+
From ead17951e7198891d0508ed3b9a2c0d008e194ee Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 4 Jun 2025 07:53:37 +0000 Subject: [PATCH 153/357] Translated using Weblate (Italian) Currently translated at 100.0% (12 of 12 strings) Translation: wms-16.0/wms-16.0-stock_release_channel_shipment_lead_time Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_shipment_lead_time/it/ --- stock_release_channel_shipment_lead_time/i18n/it.po | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/stock_release_channel_shipment_lead_time/i18n/it.po b/stock_release_channel_shipment_lead_time/i18n/it.po index c64e7dc7759..b4f80a59139 100644 --- a/stock_release_channel_shipment_lead_time/i18n/it.po +++ b/stock_release_channel_shipment_lead_time/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-11-23 10:35+0000\n" +"PO-Revision-Date: 2025-06-04 10:26+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,12 +14,12 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_release_channel_shipment_lead_time #: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_stock_release_channel__delivery_calendar_id msgid "Delivery Calendar" -msgstr "" +msgstr "Calendario consegna" #. module: stock_release_channel_shipment_lead_time #: model:ir.model.fields,field_description:stock_release_channel_shipment_lead_time.field_shipment_advice__delivery_date @@ -57,6 +57,8 @@ msgid "" "Shipment Working Hours. Defaults tot warehouse calendar for simplicity but " "another calendar can be used." msgstr "" +"Ore lavoro spedizioni. Per semplicità predefinite come il calendario del " +"magazzino ma può essere usato un altro calendario." #. module: stock_release_channel_shipment_lead_time #: model:ir.model,name:stock_release_channel_shipment_lead_time.model_stock_release_channel From 3b78879d3cf327bf4aff41c6bd7128d1549b0888 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 4 Jun 2025 07:51:55 +0000 Subject: [PATCH 154/357] Translated using Weblate (Italian) Currently translated at 100.0% (2 of 2 strings) Translation: wms-16.0/wms-16.0-sale_stock_release_channel_delivery_date Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-sale_stock_release_channel_delivery_date/it/ --- sale_stock_release_channel_delivery_date/i18n/it.po | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sale_stock_release_channel_delivery_date/i18n/it.po b/sale_stock_release_channel_delivery_date/i18n/it.po index 2ad225ac8de..767caf7b4ae 100644 --- a/sale_stock_release_channel_delivery_date/i18n/it.po +++ b/sale_stock_release_channel_delivery_date/i18n/it.po @@ -6,20 +6,22 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-06-04 10:26+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: sale_stock_release_channel_delivery_date #: model:ir.model,name:sale_stock_release_channel_delivery_date.model_sale_order msgid "Sales Order" -msgstr "" +msgstr "Ordine di vendita" #. module: sale_stock_release_channel_delivery_date #: model:ir.model,name:sale_stock_release_channel_delivery_date.model_sale_order_line msgid "Sales Order Line" -msgstr "" +msgstr "Riga ordine di vendita" From 15075a444620377aeb367e7636c2e1a6bea9602f Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 4 Jun 2025 12:09:07 +0000 Subject: [PATCH 155/357] Added translation using Weblate (Italian) --- .../i18n/it.po | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 stock_release_channel_warehouse_calendar/i18n/it.po diff --git a/stock_release_channel_warehouse_calendar/i18n/it.po b/stock_release_channel_warehouse_calendar/i18n/it.po new file mode 100644 index 00000000000..d0fd41a51a0 --- /dev/null +++ b/stock_release_channel_warehouse_calendar/i18n/it.po @@ -0,0 +1,20 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_release_channel_warehouse_calendar +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: stock_release_channel_warehouse_calendar +#: model:ir.model,name:stock_release_channel_warehouse_calendar.model_stock_release_channel +msgid "Stock Release Channels" +msgstr "" From cb53b2e70e2f5ec8d3e460e32c6f3719c197c532 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 4 Jun 2025 12:09:24 +0000 Subject: [PATCH 156/357] Translated using Weblate (Italian) Currently translated at 100.0% (1 of 1 strings) Translation: wms-16.0/wms-16.0-stock_release_channel_warehouse_calendar Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_warehouse_calendar/it/ --- stock_release_channel_warehouse_calendar/i18n/it.po | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stock_release_channel_warehouse_calendar/i18n/it.po b/stock_release_channel_warehouse_calendar/i18n/it.po index d0fd41a51a0..b02eaae39f7 100644 --- a/stock_release_channel_warehouse_calendar/i18n/it.po +++ b/stock_release_channel_warehouse_calendar/i18n/it.po @@ -6,15 +6,17 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-06-04 14:26+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_release_channel_warehouse_calendar #: model:ir.model,name:stock_release_channel_warehouse_calendar.model_stock_release_channel msgid "Stock Release Channels" -msgstr "" +msgstr "Canali rilascio magazzino" From 76ba3c4cb45452afa58c67158a2999277825e1ab Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Thu, 5 Jun 2025 17:34:24 +0200 Subject: [PATCH 157/357] [FIX] stock_storage_type: Allow to have two rules for a storage type If there are several rules for a storage type (e.g.: in Pallets, you have Pallets/Pallets UK), don't bypass the next rules after the first condition evaluation. --- .../demo/stock_storage_category.xml | 13 ++++- ...torage_category_allow_new_product_cond.xml | 15 ++++++ .../models/stock_storage_category.py | 4 +- ...test_storage_category_allow_new_product.py | 48 +++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/stock_storage_type/demo/stock_storage_category.xml b/stock_storage_type/demo/stock_storage_category.xml index 503e24ce0ab..d8b84b3a0b2 100644 --- a/stock_storage_type/demo/stock_storage_category.xml +++ b/stock_storage_type/demo/stock_storage_category.xml @@ -13,11 +13,22 @@ empty + + + + empty + Cardboxes diff --git a/stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml b/stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml index 33fec54528d..da2729548d1 100644 --- a/stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml +++ b/stock_storage_type/demo/stock_storage_category_allow_new_product_cond.xml @@ -11,6 +11,21 @@ + + + + + Package type is 'Pallets UK' + + diff --git a/stock_storage_type/models/stock_storage_category.py b/stock_storage_type/models/stock_storage_category.py index cb69e592a60..0196e1cc1a8 100644 --- a/stock_storage_type/models/stock_storage_category.py +++ b/stock_storage_type/models/stock_storage_category.py @@ -203,8 +203,8 @@ def get_allow_new_product( quants, ) if not res: - # Fallback on category option value - return self.allow_new_product + # Go to next rule + break # All conditions are matching if res: return rule.allow_new_product diff --git a/stock_storage_type/tests/test_storage_category_allow_new_product.py b/stock_storage_type/tests/test_storage_category_allow_new_product.py index 6a890113783..47f43acb63d 100644 --- a/stock_storage_type/tests/test_storage_category_allow_new_product.py +++ b/stock_storage_type/tests/test_storage_category_allow_new_product.py @@ -109,3 +109,51 @@ def test_storage_strategy_with_allow_new_product_rule(self): int_picking.move_line_ids.mapped("location_dest_id"), self.pallets_bin_1_location, ) + + def test_storage_category_mixed_allow_new_product(self): + self.category.allow_new_product = "mixed" + self.assertEqual(self.category.get_allow_new_product(self.product), "mixed") + + # Create a quant with a package of type Pallet to check the + # allow_new_product rule result + package_type_pallets = self.env.ref( + "stock_storage_type.package_storage_type_pallets" + ) + package_type_pallets_uk = self.env.ref( + "stock_storage_type.package_storage_type_pallets_uk" + ) + self.product2.package_type_id = package_type_pallets_uk + package = self.env["stock.quant.package"].create( + { + "name": "TEST PKG", + "package_type_id": package_type_pallets.id, + } + ) + package_uk = self.env["stock.quant.package"].create( + { + "name": "TEST PKG", + "package_type_id": package_type_pallets_uk.id, + } + ) + self.env["stock.quant"]._update_available_quantity( + self.product, + self.pallets_bin_2_location, + 1.0, + package_id=package, + ) + quant = self.env["stock.quant"].search( + [ + ("location_id", "=", self.pallets_bin_2_location.id), + ("product_id", "=", self.product.id), + ("package_id", "=", package.id), + ] + ) + self.assertEqual( + self.category.get_allow_new_product( + self.product2, + quants=quant, + package_type=package_type_pallets_uk, + package=package_uk, + ), + "same", + ) From 18c551ba3109095f443affbb906355f4de0bc9b4 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 6 Jun 2025 14:58:12 +0000 Subject: [PATCH 158/357] [BOT] post-merge updates --- README.md | 2 +- stock_storage_type/README.rst | 8 +++-- stock_storage_type/__manifest__.py | 2 +- .../static/description/index.html | 30 +++++++++++-------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 8b4d1de758f..da67a3f3705 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ addon | version | maintainers | summary [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels [stock_release_channel_warehouse_calendar](stock_release_channel_warehouse_calendar/) | 16.0.1.0.0 | jbaudoux | Glue module between release channel and warehouse calendar -[stock_storage_type](stock_storage_type/) | 16.0.2.0.0 | jbaudoux rousseldenis | Manage packages and locations storage types +[stock_storage_type](stock_storage_type/) | 16.0.2.0.1 | jbaudoux rousseldenis | Manage packages and locations storage types [stock_storage_type_putaway_abc](stock_storage_type_putaway_abc/) | 16.0.1.0.0 | | Advanced storage strategy ABC for WMS [stock_warehouse_flow](stock_warehouse_flow/) | 16.0.1.1.0 | | Configure routing flow for stock moves [stock_warehouse_flow_delivery_refresh](stock_warehouse_flow_delivery_refresh/) | 16.0.1.0.0 | | Allow to refresh delivery flow when carrier changes diff --git a/stock_storage_type/README.rst b/stock_storage_type/README.rst index 633cb1fcf73..d0161dc1d50 100644 --- a/stock_storage_type/README.rst +++ b/stock_storage_type/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================== Stock Storage Type ================== @@ -7,13 +11,13 @@ Stock Storage Type !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:2ba603cdf99d912947756d77b536a37fb3072493512a70674bc5ae64e57886c4 + !! source digest: sha256:6e88f11d38787ebe507555948d9734ed73f4e377a35f06d9b27903a223279da0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_storage_type/__manifest__.py b/stock_storage_type/__manifest__.py index 4e1510bfa12..d84d345fdc8 100644 --- a/stock_storage_type/__manifest__.py +++ b/stock_storage_type/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Stock Storage Type", "summary": "Manage packages and locations storage types", - "version": "16.0.2.0.0", + "version": "16.0.2.0.1", "development_status": "Beta", "category": "Warehouse Management", "website": "https://github.com/OCA/wms", diff --git a/stock_storage_type/static/description/index.html b/stock_storage_type/static/description/index.html index 1c0adcc8088..53d8298a301 100644 --- a/stock_storage_type/static/description/index.html +++ b/stock_storage_type/static/description/index.html @@ -3,7 +3,7 @@ -Stock Storage Type +README.rst -
-

Stock Storage Type

+
+ + +Odoo Community Association + +
+

Stock Storage Type

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

This module extends package types Odoo feature in order to better manage stock moves with packages according to the packaging and stock location properties (like height, weight or any customized conditions).

@@ -412,7 +417,7 @@

Stock Storage Type

-

Known issues / Roadmap

+

Known issues / Roadmap

Currently, the module supports only strategies applied on packages (stock.quant.package). For implementations that do not use packages, it would be possible to add compatibility with product packaging.

@@ -439,7 +444,7 @@

Known issues / Roadmap

like max_weight_in_kg in order make simple and efficient computations.

-

Limitation

+

Limitation

If the locations structure is using views intensively in order to separate storage types kindly (not mixing them), Odoo standard method to get putaway strategy is returning the first child if a move location destination is a view.

@@ -451,7 +456,7 @@

Limitation

apply standard child location selection’ could help filtering view candidates.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -459,16 +464,16 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -495,5 +500,6 @@

Maintainers

+
From f7c1839267b5c5039cdef8247767bcf7608406cb Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Sat, 21 Jun 2025 13:13:18 +0200 Subject: [PATCH 159/357] [FIX] sale_stock_available_to_promise_release_block: Unittests datetime --- .../tests/test_sale_block_release.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sale_stock_available_to_promise_release_block/tests/test_sale_block_release.py b/sale_stock_available_to_promise_release_block/tests/test_sale_block_release.py index b97b546887f..c7edb88a538 100644 --- a/sale_stock_available_to_promise_release_block/tests/test_sale_block_release.py +++ b/sale_stock_available_to_promise_release_block/tests/test_sale_block_release.py @@ -199,7 +199,6 @@ def test_unblock_release_automatic(self): ) today = wiz.date_deadline self.assertEqual(wiz.option, "automatic") - self.assertEqual(wiz.date_deadline, today) self.assertNotEqual(wiz.order_line_ids.move_ids.date, today) old_picking = wiz.order_line_ids.move_ids.picking_id wiz.validate() @@ -218,11 +217,10 @@ def test_unblock_release_automatic_from_moves(self): self.sale.commitment_date = yesterday self.sale.action_confirm() # Unblock deliveries through the wizard - today = fields.Datetime.now() wiz = self._create_unblock_release_wizard( self.sale.order_line.move_ids, option="automatic" ) - self.assertEqual(wiz.date_deadline, today) + today = wiz.date_deadline self.assertNotEqual(wiz.move_ids.date, today) old_picking = wiz.move_ids.picking_id wiz.validate() From c39bac4be4093f58563201e88257a1f898ea850d Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Tue, 4 Mar 2025 08:49:05 +0100 Subject: [PATCH 160/357] [IMP] stock_release_channel_shipment_advice_toursolver: link ts task to rc --- .../models/__init__.py | 1 + .../models/shipment_advice.py | 18 ++++++++++++++++++ .../test_shipment_advice_planner_toursolver.py | 1 + 3 files changed, 20 insertions(+) create mode 100644 stock_release_channel_shipment_advice_toursolver/models/shipment_advice.py diff --git a/stock_release_channel_shipment_advice_toursolver/models/__init__.py b/stock_release_channel_shipment_advice_toursolver/models/__init__.py index 5943f65274a..24db19cf91c 100644 --- a/stock_release_channel_shipment_advice_toursolver/models/__init__.py +++ b/stock_release_channel_shipment_advice_toursolver/models/__init__.py @@ -1,2 +1,3 @@ from . import stock_release_channel from . import toursolver_task +from . import shipment_advice diff --git a/stock_release_channel_shipment_advice_toursolver/models/shipment_advice.py b/stock_release_channel_shipment_advice_toursolver/models/shipment_advice.py new file mode 100644 index 00000000000..0cb2ece2051 --- /dev/null +++ b/stock_release_channel_shipment_advice_toursolver/models/shipment_advice.py @@ -0,0 +1,18 @@ +# Copyright 2025 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ShipmentAdvice(models.Model): + + _inherit = "shipment.advice" + + def create_toursolver_task(self): + self.ensure_one() + res = super().create_toursolver_task() + task = self.toursolver_task_id + rc = self.release_channel_id + task.release_channel_id = rc + task.name = f"{task.name} {rc.name}" + return res diff --git a/stock_release_channel_shipment_advice_toursolver/tests/test_shipment_advice_planner_toursolver.py b/stock_release_channel_shipment_advice_toursolver/tests/test_shipment_advice_planner_toursolver.py index c6effc6d438..8205db3a2f5 100644 --- a/stock_release_channel_shipment_advice_toursolver/tests/test_shipment_advice_planner_toursolver.py +++ b/stock_release_channel_shipment_advice_toursolver/tests/test_shipment_advice_planner_toursolver.py @@ -45,3 +45,4 @@ def test_plan_shipment_toursolver(self): ) self.assertTrue(self.channel.shipment_advice_ids) self.assertEqual(self.channel.shipment_advice_ids, task.shipment_advice_ids) + self.assertEqual(task.release_channel_id, self.channel) From c065cd2eab5922f8cf82f3059ecaa66165debf97 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 23 Jun 2025 07:50:35 +0000 Subject: [PATCH 161/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 8 ++++-- .../__manifest__.py | 2 +- .../static/description/index.html | 28 +++++++++++-------- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index da67a3f3705..541f51fb307 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ addon | version | maintainers | summary --- | --- | --- | --- [delivery_carrier_warehouse](delivery_carrier_warehouse/) | 16.0.1.0.1 | | Get delivery method used in sales orders from warehouse [sale_stock_available_to_promise_release](sale_stock_available_to_promise_release/) | 16.0.1.1.2 | | Integration between Sales and Available to Promise Release -[sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.1.0 | | Block release of deliveries from sales orders. +[sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block release of deliveries from sales orders. [sale_stock_release_channel](sale_stock_release_channel/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel [sale_stock_release_channel_delivery](sale_stock_release_channel_delivery/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel Delivery [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | jbaudoux | Compute expected date based on available release channels diff --git a/sale_stock_available_to_promise_release_block/README.rst b/sale_stock_available_to_promise_release_block/README.rst index 3f5cbb05d1d..c9b64a30916 100644 --- a/sale_stock_available_to_promise_release_block/README.rst +++ b/sale_stock_available_to_promise_release_block/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ===================================================== Stock Available to Promise Release - Block from Sales ===================================================== @@ -7,13 +11,13 @@ Stock Available to Promise Release - Block from Sales !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3d9773050fa015580ca1f200699c0df6bf9f3b377a4ae106a15c909f215c2847 + !! source digest: sha256:7034247fc3b671f076b8cd90e6ec65cd1641a1b03bc56cc2f776fe5ae2670347 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/sale_stock_available_to_promise_release_block/__manifest__.py b/sale_stock_available_to_promise_release_block/__manifest__.py index 20e32ef4f66..585b937cd6b 100644 --- a/sale_stock_available_to_promise_release_block/__manifest__.py +++ b/sale_stock_available_to_promise_release_block/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Stock Available to Promise Release - Block from Sales", "summary": """Block release of deliveries from sales orders.""", - "version": "16.0.1.1.0", + "version": "16.0.1.1.1", "license": "AGPL-3", "author": "Camptcamp, ACSONE SA/NV, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/sale_stock_available_to_promise_release_block/static/description/index.html b/sale_stock_available_to_promise_release_block/static/description/index.html index b2a57c1e549..72f1d0d6aba 100644 --- a/sale_stock_available_to_promise_release_block/static/description/index.html +++ b/sale_stock_available_to_promise_release_block/static/description/index.html @@ -3,7 +3,7 @@ -Stock Available to Promise Release - Block from Sales +README.rst -
-

Stock Available to Promise Release - Block from Sales

+
+ + +Odoo Community Association + +
+

Stock Available to Promise Release - Block from Sales

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Block and unblock release of deliveries from sale orders.

Release of deliveries can be blocked right after the sale order confirmation.

When encoding a new order sharing the same delivery address, the user can @@ -393,12 +398,12 @@

Stock Available to Promise Release - Block from Sales

-

Usage

+

Usage

When the order is confirmed, the release of the generated delivery will be blocked if the option “Block Release” is enabled.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -406,9 +411,9 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptcamp
  • ACSONE SA/NV
  • @@ -416,7 +421,7 @@

    Authors

-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -439,5 +444,6 @@

Maintainers

+
From aa1e59b3dfc2cb1c5310beaa368b70a483fe0c4c Mon Sep 17 00:00:00 2001 From: Ricardoalso Date: Tue, 10 Jun 2025 13:28:02 +0200 Subject: [PATCH 162/357] stock_available_to_promise_release: add where condition in post-migrate script In order to skip unnecessary updates --- .../migrations/16.0.3.1.0/post-migrate.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stock_available_to_promise_release/migrations/16.0.3.1.0/post-migrate.py b/stock_available_to_promise_release/migrations/16.0.3.1.0/post-migrate.py index caf4aafa9ef..6f228256c69 100644 --- a/stock_available_to_promise_release/migrations/16.0.3.1.0/post-migrate.py +++ b/stock_available_to_promise_release/migrations/16.0.3.1.0/post-migrate.py @@ -13,6 +13,9 @@ def migrate(cr, version): procurement_group WHERE stock_picking.state NOT IN ('done', 'cancel') - AND stock_picking.group_id = procurement_group.id + AND + stock_picking.group_id = procurement_group.id + AND + stock_picking.release_policy != procurement_group.move_type; """ ) From e04cb90f62f8ce5dabfd1efad3c4f368e3274b8f Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Thu, 12 Jun 2025 15:34:43 +0200 Subject: [PATCH 163/357] [FIX] stock_available_to_promise_release: Assign transfers after unrelease return --- .../models/stock_move.py | 8 ++ .../tests/__init__.py | 1 + .../tests/test_unrelease_cancel_fixed_pick.py | 87 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py diff --git a/stock_available_to_promise_release/models/stock_move.py b/stock_available_to_promise_release/models/stock_move.py index 874f3f065cf..86c816f3764 100644 --- a/stock_available_to_promise_release/models/stock_move.py +++ b/stock_available_to_promise_release/models/stock_move.py @@ -730,6 +730,14 @@ def _return_quantity_in_stock(self, qty_to_return_per_move): # Do not copy the responsible user from the source picking as somebody # else could scan the new cancel picking cancel_picking.user_id = False + + returned_moves = return_wiz.product_return_moves.move_id + pickings_to_assign = returned_moves.move_dest_ids.picking_id.filtered( + lambda picking: picking.id != cancel_picking.id + and picking.state == "confirmed" + ) + if pickings_to_assign: + pickings_to_assign.action_assign() return True def _unrelease_set_returnable_qty_per_move( diff --git a/stock_available_to_promise_release/tests/__init__.py b/stock_available_to_promise_release/tests/__init__.py index 41181f76399..234658fbefc 100644 --- a/stock_available_to_promise_release/tests/__init__.py +++ b/stock_available_to_promise_release/tests/__init__.py @@ -5,3 +5,4 @@ from . import test_unrelease_3steps from . import test_unrelease_merged_moves from . import test_unrelease_cancel +from . import test_unrelease_cancel_fixed_pick diff --git a/stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py b/stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py new file mode 100644 index 00000000000..49c778329a4 --- /dev/null +++ b/stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py @@ -0,0 +1,87 @@ +# Copyright 2025 Michael Tietz (MT Software) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from datetime import datetime + +from .common import PromiseReleaseCommonCase + + +class TestAvailableToPromiseReleaseCancelFixedPick(PromiseReleaseCommonCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls._update_qty_in_location(cls.loc_bin1, cls.product1, 50.0) + cls._update_qty_in_location(cls.loc_bin1, cls.product2, 50.0) + pick_rule = cls.wh.delivery_route_id.rule_ids.filtered( + lambda r: r.location_src_id == cls.loc_stock + ) + pick_rule.group_propagation_option = "fixed" + pick_rule.group_id = cls.env["procurement.group"].create({"name": "Fixed"}) + delivery_route = cls.wh.delivery_route_id + delivery_route.write( + { + "available_to_promise_defer_pull": True, + "allow_unrelease_return_done_move": True, + } + ) + cls.cleanup_type = cls.env["stock.picking.type"].create( + { + "name": "Cancel Cleanup", + "default_location_dest_id": cls.loc_stock.id, + "sequence_code": "CCP", + "code": "internal", + } + ) + cls.pick_type = pick_rule.picking_type_id + cls.pick_type.return_picking_type_id = cls.cleanup_type + + def test_full_cancel(self): + picking_chain1 = self._create_picking_chain( + self.wh, [(self.product1, 10)], date=datetime(2019, 9, 2, 16, 0) + ) + picking_chain2 = self._create_picking_chain( + self.wh, [(self.product1, 10)], date=datetime(2019, 9, 2, 16, 0) + ) + ship_picking1 = self._out_picking(picking_chain1) + ship_picking1.release_available_to_promise() + ship_picking2 = self._out_picking(picking_chain2) + ship_picking2.release_available_to_promise() + self.assertNotEqual(ship_picking1, ship_picking2) + pick1 = self._prev_picking(ship_picking1) + pick2 = self._prev_picking(ship_picking2) + self.assertEqual(pick1, pick2) + self._deliver(pick1) + self.assertEqual(ship_picking1.state, "assigned") + self.assertEqual(ship_picking2.state, "assigned") + ship_picking2.action_cancel() + self.assertEqual(ship_picking2.state, "cancel") + self.assertEqual(ship_picking1.state, "assigned") + + def test_partial_cancel(self): + picking_chain1 = self._create_picking_chain( + self.wh, + [(self.product1, 10), (self.product2, 10)], + date=datetime(2019, 9, 2, 16, 0), + ) + picking_chain2 = self._create_picking_chain( + self.wh, + [(self.product1, 10), (self.product2, 10)], + date=datetime(2019, 9, 2, 16, 0), + ) + ship_picking1 = self._out_picking(picking_chain1) + ship_picking1.release_available_to_promise() + ship_picking2 = self._out_picking(picking_chain2) + ship_picking2.release_available_to_promise() + self.assertNotEqual(ship_picking1, ship_picking2) + pick1 = self._prev_picking(ship_picking1) + pick2 = self._prev_picking(ship_picking2) + self.assertEqual(pick1, pick2) + self._deliver(pick1) + self.assertEqual(ship_picking1.state, "assigned") + self.assertEqual(ship_picking2.state, "assigned") + ship2_product2_move = ship_picking2.move_lines.filtered( + lambda m: m.product_id == self.product2 + ) + ship2_product2_move._action_cancel() + self.assertEqual(ship_picking2.state, "assigned") + self.assertEqual(ship_picking1.state, "assigned") From b822df4efa0e7ab1b5bfcd6f93f2cd0e1c8015a6 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Sat, 21 Jun 2025 13:06:53 +0200 Subject: [PATCH 164/357] [MIG] stock_available_to_promise_release: Migration of FWP Assign transfers after unrelease return #1053 --- .../tests/test_unrelease_cancel_fixed_pick.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py b/stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py index 49c778329a4..67e3b367948 100644 --- a/stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py +++ b/stock_available_to_promise_release/tests/test_unrelease_cancel_fixed_pick.py @@ -79,7 +79,7 @@ def test_partial_cancel(self): self._deliver(pick1) self.assertEqual(ship_picking1.state, "assigned") self.assertEqual(ship_picking2.state, "assigned") - ship2_product2_move = ship_picking2.move_lines.filtered( + ship2_product2_move = ship_picking2.move_ids.filtered( lambda m: m.product_id == self.product2 ) ship2_product2_move._action_cancel() From ee179c13871c13511050587103661c042bac0495 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 23 Jun 2025 08:36:30 +0000 Subject: [PATCH 165/357] [BOT] post-merge updates --- README.md | 2 +- stock_available_to_promise_release/README.rst | 8 +++-- .../__manifest__.py | 2 +- .../static/description/index.html | 32 +++++++++++-------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 541f51fb307..3f44a2bbdbd 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ addon | version | maintainers | summary [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation -[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.7.1 | | Release Operations based on available to promise +[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.7.2 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves diff --git a/stock_available_to_promise_release/README.rst b/stock_available_to_promise_release/README.rst index e53c2d9b265..2e16ffd2838 100644 --- a/stock_available_to_promise_release/README.rst +++ b/stock_available_to_promise_release/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================================== Stock Available to Promise Release ================================== @@ -7,13 +11,13 @@ Stock Available to Promise Release !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:df47a79046482b745cecd66a4940f7c1e1e98a8c070682b8feef4ac83c93de14 + !! source digest: sha256:9e23911bdae2f57b6c9c0fc5646e79f66d2516e0a223f4b74b98afe097f700c1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github diff --git a/stock_available_to_promise_release/__manifest__.py b/stock_available_to_promise_release/__manifest__.py index c046c59cf97..6bb58ee5788 100644 --- a/stock_available_to_promise_release/__manifest__.py +++ b/stock_available_to_promise_release/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Available to Promise Release", - "version": "16.0.3.7.1", + "version": "16.0.3.7.2", "summary": "Release Operations based on available to promise", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_available_to_promise_release/static/description/index.html b/stock_available_to_promise_release/static/description/index.html index ffc6603ea7c..a53a4e87ca3 100644 --- a/stock_available_to_promise_release/static/description/index.html +++ b/stock_available_to_promise_release/static/description/index.html @@ -3,7 +3,7 @@ -Stock Available to Promise Release +README.rst -
-

Stock Available to Promise Release

+
+ + +Odoo Community Association + +
+

Stock Available to Promise Release

-

Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Currently the reservation is performed by adding reserved quantities on quants, which is fine as long as the reservation is made right after the order confirmation. This way, the first arrived, first served principle is always @@ -422,13 +427,13 @@

Stock Available to Promise Release

-

Configuration

+

Configuration

In Inventory > Configuration > Routes, activate the option “Release based on Available to Promise” on the routes where you want to use the feature.

To modify the horizon go to “Inventory > Settings” and change “Stock reservation horizon”.

-

Usage

+

Usage

When an outgoing transfer would generate chained moves, it will not. The chained moves need to be released manually. To do so, open “Inventory > Operations > Stock Allocation”, select the moves to release and use “action > Release @@ -452,7 +457,7 @@

Usage

on the stock picking type.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -460,16 +465,16 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The development of this module has been financially supported by:

  • Camptocamp
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -500,5 +505,6 @@

Maintainers

+
From a2696ccac8b194714765c6895bfdd5b66f6c5ef3 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 23 Jun 2025 08:52:17 +0000 Subject: [PATCH 166/357] [BOT] post-merge updates --- README.md | 2 +- stock_available_to_promise_release/README.rst | 2 +- stock_available_to_promise_release/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3f44a2bbdbd..8af7271076b 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ addon | version | maintainers | summary [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation -[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.7.2 | | Release Operations based on available to promise +[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.7.3 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves diff --git a/stock_available_to_promise_release/README.rst b/stock_available_to_promise_release/README.rst index 2e16ffd2838..e69829610ba 100644 --- a/stock_available_to_promise_release/README.rst +++ b/stock_available_to_promise_release/README.rst @@ -11,7 +11,7 @@ Stock Available to Promise Release !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:9e23911bdae2f57b6c9c0fc5646e79f66d2516e0a223f4b74b98afe097f700c1 + !! source digest: sha256:cf3d12ff9a56d62425852901d05ccff8ba45ffd62c920ac68822d03f94499c32 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_available_to_promise_release/__manifest__.py b/stock_available_to_promise_release/__manifest__.py index 6bb58ee5788..d6506ee75f7 100644 --- a/stock_available_to_promise_release/__manifest__.py +++ b/stock_available_to_promise_release/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Available to Promise Release", - "version": "16.0.3.7.2", + "version": "16.0.3.7.3", "summary": "Release Operations based on available to promise", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_available_to_promise_release/static/description/index.html b/stock_available_to_promise_release/static/description/index.html index a53a4e87ca3..904a0985ae3 100644 --- a/stock_available_to_promise_release/static/description/index.html +++ b/stock_available_to_promise_release/static/description/index.html @@ -372,7 +372,7 @@

Stock Available to Promise Release

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:9e23911bdae2f57b6c9c0fc5646e79f66d2516e0a223f4b74b98afe097f700c1 +!! source digest: sha256:cf3d12ff9a56d62425852901d05ccff8ba45ffd62c920ac68822d03f94499c32 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Currently the reservation is performed by adding reserved quantities on quants, From 54d671a5758572954fa48036814060e4f29ad24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Mon, 23 Jun 2025 14:10:37 +0200 Subject: [PATCH 167/357] [FIX] shopfloor: inventory, fix typo when updating quants --- shopfloor/actions/inventory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopfloor/actions/inventory.py b/shopfloor/actions/inventory.py index f3c831acad8..923f1fe12cc 100644 --- a/shopfloor/actions/inventory.py +++ b/shopfloor/actions/inventory.py @@ -59,7 +59,7 @@ def _create_draft_inventory(self, location, product, package=None, lot=None): for quant in quants: if quant.inventory_quantity_set: continue - quants.write( + quant.write( { # Set an inventory quantity to prevent the zero quant cleanup "inventory_quantity": quant.inventory_quantity + 1, From 370cb219a72f923c4c6591412834b996d6852b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Mon, 23 Jun 2025 15:54:48 +0200 Subject: [PATCH 168/357] [IMP] shopfloor: inventory, prevent zero quant cleanup by assigning a user --- shopfloor/actions/inventory.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shopfloor/actions/inventory.py b/shopfloor/actions/inventory.py index 923f1fe12cc..694803b9107 100644 --- a/shopfloor/actions/inventory.py +++ b/shopfloor/actions/inventory.py @@ -61,8 +61,9 @@ def _create_draft_inventory(self, location, product, package=None, lot=None): continue quant.write( { - # Set an inventory quantity to prevent the zero quant cleanup - "inventory_quantity": quant.inventory_quantity + 1, + # Set a user to prevent the zero quant cleanup + "user_id": self.env.user.id, + "inventory_quantity": 0, "inventory_date": fields.Date.today(), } ) From 1271eee687fe2c41dec0322e9dd5d8fc6ac4cab4 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 23 Jun 2025 14:35:15 +0000 Subject: [PATCH 169/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 8 ++++-- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 38 ++++++++++++++----------- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 8af7271076b..149a3735e18 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.8.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.9.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index de6db2a196f..2dd9ab99360 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ========= Shopfloor ========= @@ -7,13 +11,13 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:8f4a1f9cca9cb3a4830c65a6a9d8a65ec3334a34722525fe5da87e77b0e90de2 + !! source digest: sha256:caca43b0b1116820cf13ea214d961ce551858e1a541dbdc6a453a21542017fdd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index c48d59adbd6..22bab82a62f 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.8.0", + "version": "16.0.2.9.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index 471606c4be6..2085d4a3f8c 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -3,7 +3,7 @@ -Shopfloor +README.rst -

-

Shopfloor

+
+ + +Odoo Community Association + +
+

Shopfloor

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

The application supports scenarios, to relate to Operation Types:

    @@ -408,7 +413,7 @@

    Shopfloor

-

Usage

+

Usage

An API key is created in the Demo data (for development), using the Demo user. The key to use in the HTTP header API-KEY is: 72B044F7AC780DAC

Curl example:

@@ -417,7 +422,7 @@

Usage

-

Known issues / Roadmap

+

Known issues / Roadmap

  • improve documentation
  • split out scenario components to their own modules
  • @@ -426,14 +431,14 @@

    Known issues / Roadmap

-

Changelog

+

Changelog

-

13.0.1.0.0

+

13.0.1.0.0

First official version.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -441,9 +446,9 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
  • @@ -451,7 +456,7 @@

    Authors

-

Contributors

+

Contributors

-

Design

+

Design

-

Other credits

+

Other credits

Financial support

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -499,5 +504,6 @@

Maintainers

+
From 2107c6a0c4ab6cd6634ad0a62bb9c717c620b264 Mon Sep 17 00:00:00 2001 From: MmeQuignon Date: Tue, 24 Jun 2025 13:32:05 +0200 Subject: [PATCH 170/357] [IMP] shopfloor: stock.picking add flag is_shopfloor_created --- shopfloor/__manifest__.py | 2 +- shopfloor/models/stock_picking.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 22bab82a62f..cfc3cb41715 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.9.0", + "version": "16.0.2.10.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/models/stock_picking.py b/shopfloor/models/stock_picking.py index 7289b17b376..6c2dbe96bef 100644 --- a/shopfloor/models/stock_picking.py +++ b/shopfloor/models/stock_picking.py @@ -23,6 +23,7 @@ class StockPicking(models.Model): help="Technical field. " "Indicates number of move lines without package included.", ) + is_shopfloor_created = fields.Boolean() @api.depends( "move_line_ids", "move_line_ids.reserved_qty", "move_line_ids.product_id.weight" From 26519b184d994a4134efc75322b678cd28099735 Mon Sep 17 00:00:00 2001 From: MmeQuignon Date: Tue, 24 Jun 2025 13:33:22 +0200 Subject: [PATCH 171/357] [IMP] shopfloor_reception: Move stock.picking is_shopfloor_created to shopfloor --- shopfloor_reception/__init__.py | 1 - shopfloor_reception/__manifest__.py | 1 + .../migrations/14.0.2.9.0/pre-migration.py | 17 +++++++++++++++++ shopfloor_reception/models/__init__.py | 1 - shopfloor_reception/models/stock_picking.py | 10 ---------- 5 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 shopfloor_reception/migrations/14.0.2.9.0/pre-migration.py delete mode 100644 shopfloor_reception/models/__init__.py delete mode 100644 shopfloor_reception/models/stock_picking.py diff --git a/shopfloor_reception/__init__.py b/shopfloor_reception/__init__.py index 2d9836a7424..ae16eb245f6 100644 --- a/shopfloor_reception/__init__.py +++ b/shopfloor_reception/__init__.py @@ -1,3 +1,2 @@ from . import services -from . import models from .hooks import post_init_hook, uninstall_hook diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 9a594c71d6f..e61513c8601 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -10,6 +10,7 @@ "license": "AGPL-3", "installable": True, "depends": ["shopfloor"], + "external_dependencies": {"python": ["openupgradelib"]}, "data": [ "data/shopfloor_scenario_data.xml", ], diff --git a/shopfloor_reception/migrations/14.0.2.9.0/pre-migration.py b/shopfloor_reception/migrations/14.0.2.9.0/pre-migration.py new file mode 100644 index 00000000000..05241eff250 --- /dev/null +++ b/shopfloor_reception/migrations/14.0.2.9.0/pre-migration.py @@ -0,0 +1,17 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + + +from openupgradelib import openupgrade + + +def move_fields_to_new_module(cr): + # is_shopfloor_created has been wrongly put in shopfloor_reception. + # this script moves it in shopfloor. + openupgrade.update_module_moved_fields( + cr, "stock.picking", "is_shopfloor_created", "shopfloor_reception", "shopfloor" + ) + + +def migrate(cr, version): + move_fields_to_new_module(cr) diff --git a/shopfloor_reception/models/__init__.py b/shopfloor_reception/models/__init__.py deleted file mode 100644 index ae4c27227f1..00000000000 --- a/shopfloor_reception/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import stock_picking diff --git a/shopfloor_reception/models/stock_picking.py b/shopfloor_reception/models/stock_picking.py deleted file mode 100644 index bd69e105a04..00000000000 --- a/shopfloor_reception/models/stock_picking.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright 2023 Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - -from odoo import fields, models - - -class StockPicking(models.Model): - _inherit = "stock.picking" - - is_shopfloor_created = fields.Boolean() From 80face560e2afb12dc9670cf30a34208e2bce06e Mon Sep 17 00:00:00 2001 From: MmeQuignon Date: Mon, 10 Jul 2023 15:52:45 +0200 Subject: [PATCH 172/357] [ADD] shopfloor_reception_refund_return: Mark created return as to refund --- .../addons/shopfloor_reception_refund_return | 1 + .../setup.py | 6 + shopfloor_reception_refund_return/README.rst | 88 ++++ shopfloor_reception_refund_return/__init__.py | 1 + .../__manifest__.py | 16 + .../actions/__init__.py | 1 + .../actions/stock.py | 14 + .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 3 + .../static/description/index.html | 426 ++++++++++++++++++ .../tests/__init__.py | 1 + .../tests/test_action_stock.py | 54 +++ 12 files changed, 613 insertions(+) create mode 120000 setup/shopfloor_reception_refund_return/odoo/addons/shopfloor_reception_refund_return create mode 100644 setup/shopfloor_reception_refund_return/setup.py create mode 100644 shopfloor_reception_refund_return/README.rst create mode 100644 shopfloor_reception_refund_return/__init__.py create mode 100644 shopfloor_reception_refund_return/__manifest__.py create mode 100644 shopfloor_reception_refund_return/actions/__init__.py create mode 100644 shopfloor_reception_refund_return/actions/stock.py create mode 100644 shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst create mode 100644 shopfloor_reception_refund_return/readme/DESCRIPTION.rst create mode 100644 shopfloor_reception_refund_return/static/description/index.html create mode 100644 shopfloor_reception_refund_return/tests/__init__.py create mode 100644 shopfloor_reception_refund_return/tests/test_action_stock.py diff --git a/setup/shopfloor_reception_refund_return/odoo/addons/shopfloor_reception_refund_return b/setup/shopfloor_reception_refund_return/odoo/addons/shopfloor_reception_refund_return new file mode 120000 index 00000000000..ea4784eccfc --- /dev/null +++ b/setup/shopfloor_reception_refund_return/odoo/addons/shopfloor_reception_refund_return @@ -0,0 +1 @@ +../../../../shopfloor_reception_refund_return \ No newline at end of file diff --git a/setup/shopfloor_reception_refund_return/setup.py b/setup/shopfloor_reception_refund_return/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/shopfloor_reception_refund_return/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopfloor_reception_refund_return/README.rst b/shopfloor_reception_refund_return/README.rst new file mode 100644 index 00000000000..a18364dac1d --- /dev/null +++ b/shopfloor_reception_refund_return/README.rst @@ -0,0 +1,88 @@ +================================= +Shopfloor Reception Refund Return +================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c21e3ca418cdb607fff8188aae7a7992b42879fa4abb73fecd180826f54273c0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/14.0/shopfloor_reception_refund_return + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-shopfloor_reception_refund_return + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Marks returns created by shopfloor as to refund. + +Sets `to_refund` to true when when creating a return move. + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp +* BCIM + +Contributors +~~~~~~~~~~~~ + +* Matthieu Méquignon +* Jacques-Etienne Baudoux (BCIM) + +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. + +.. |maintainer-mmequignon| image:: https://github.com/mmequignon.png?size=40px + :target: https://github.com/mmequignon + :alt: mmequignon + +Current `maintainer `__: + +|maintainer-mmequignon| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/shopfloor_reception_refund_return/__init__.py b/shopfloor_reception_refund_return/__init__.py new file mode 100644 index 00000000000..f5fe63aaf72 --- /dev/null +++ b/shopfloor_reception_refund_return/__init__.py @@ -0,0 +1 @@ +from . import actions diff --git a/shopfloor_reception_refund_return/__manifest__.py b/shopfloor_reception_refund_return/__manifest__.py new file mode 100644 index 00000000000..3e3c5d89fbc --- /dev/null +++ b/shopfloor_reception_refund_return/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +{ + "name": "Shopfloor Reception Refund Return", + "summary": "Mark created return as to refund", + "version": "14.0.1.0.0", + "category": "Inventory, Accounting", + "website": "https://github.com/OCA/wms", + "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", + "maintainers": ["mmequignon"], + "license": "AGPL-3", + "installable": True, + "auto_install": False, + "depends": ["shopfloor", "stock_account"], +} diff --git a/shopfloor_reception_refund_return/actions/__init__.py b/shopfloor_reception_refund_return/actions/__init__.py new file mode 100644 index 00000000000..12bab770a38 --- /dev/null +++ b/shopfloor_reception_refund_return/actions/__init__.py @@ -0,0 +1 @@ +from . import stock diff --git a/shopfloor_reception_refund_return/actions/stock.py b/shopfloor_reception_refund_return/actions/stock.py new file mode 100644 index 00000000000..ca70e8e42a7 --- /dev/null +++ b/shopfloor_reception_refund_return/actions/stock.py @@ -0,0 +1,14 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo.addons.component.core import Component + + +class StockAction(Component): + _inherit = "shopfloor.stock.action" + + def _create_return_move__get_vals(self, return_picking, origin_move): + res = super()._create_return_move__get_vals(return_picking, origin_move) + if return_picking.picking_type_code == "incoming": + res["to_refund"] = True + return res diff --git a/shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst b/shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..c732df9d08a --- /dev/null +++ b/shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Matthieu Méquignon +* Jacques-Etienne Baudoux (BCIM) diff --git a/shopfloor_reception_refund_return/readme/DESCRIPTION.rst b/shopfloor_reception_refund_return/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..48e692b9861 --- /dev/null +++ b/shopfloor_reception_refund_return/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +Marks returns created by shopfloor as to refund. + +Sets `to_refund` to true when when creating a return move. diff --git a/shopfloor_reception_refund_return/static/description/index.html b/shopfloor_reception_refund_return/static/description/index.html new file mode 100644 index 00000000000..727cb509ede --- /dev/null +++ b/shopfloor_reception_refund_return/static/description/index.html @@ -0,0 +1,426 @@ + + + + + + +Shopfloor Reception Refund Return + + + +
+

Shopfloor Reception Refund Return

+ + +

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Marks returns created by shopfloor as to refund.

+

Sets to_refund to true when when creating a return move.

+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
  • BCIM
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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

+

Current maintainer:

+

mmequignon

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + diff --git a/shopfloor_reception_refund_return/tests/__init__.py b/shopfloor_reception_refund_return/tests/__init__.py new file mode 100644 index 00000000000..c175a20bf4e --- /dev/null +++ b/shopfloor_reception_refund_return/tests/__init__.py @@ -0,0 +1 @@ +from . import test_action_stock diff --git a/shopfloor_reception_refund_return/tests/test_action_stock.py b/shopfloor_reception_refund_return/tests/test_action_stock.py new file mode 100644 index 00000000000..2766dff56f3 --- /dev/null +++ b/shopfloor_reception_refund_return/tests/test_action_stock.py @@ -0,0 +1,54 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo.addons.shopfloor.tests.common import CommonCase + + +class TestActionsStock(CommonCase): + @classmethod + def setUpClassVars(cls): + super().setUpClassVars() + cls.wh = cls.env.ref("stock.warehouse0") + cls.location_customers = cls.env.ref("stock.stock_location_customers") + cls.picking_type = cls.wh.out_type_id + cls.picking_type.sudo().write( + {"default_location_dest_id": cls.location_customers.id} + ) + cls.picking_type_in = cls.picking_type.return_picking_type_id + cls.picking_type_in.sudo().write( + {"default_location_src_id": cls.location_customers.id} + ) + + @classmethod + def setUpClass(cls): + super().setUpClass() + with cls.work_on_actions(cls) as work: + cls.stock = work.component(usage="stock") + cls.picking = cls._create_picking( + lines=[(cls.product_a, 10), (cls.product_b, 10)], confirm=True + ) + cls.move0 = cls.picking.move_lines[0] + cls.move1 = cls.picking.move_lines[1] + cls._fill_stock_for_moves(cls.move0) + cls._fill_stock_for_moves(cls.move1) + cls.picking.action_assign() + cls.picking._action_done() + + def test_create_return_move(self): + # For incoming returns, moves are set to `to_refund` + return_picking = self.stock.create_return_picking( + self.picking, self.picking_type_in, "potato" + ) + return_moves = self.stock.create_return_move( + return_picking, self.picking.move_lines + ) + self.assertTrue(all(move.to_refund for move in return_moves)) + return_picking.action_assign() + return_picking._action_done() + + # However, on outgoing returns, this field is False + outgoing_return = self.stock.create_return_picking( + return_picking, self.picking_type, "potato" + ) + outgoing_moves = self.stock.create_return_move(outgoing_return, return_moves) + self.assertTrue(all(not move.to_refund for move in outgoing_moves)) From 3111c728c7c1b35f96798cf952720da4d9556eaf Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 23 Jun 2025 13:55:21 +0200 Subject: [PATCH 173/357] [MIG] shopfloor_reception: Migration to Version 16.0 for FWP of #870 --- shopfloor_reception/__manifest__.py | 2 +- .../migrations/{14.0.2.9.0 => 16.0.1.2.0}/pre-migration.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename shopfloor_reception/migrations/{14.0.2.9.0 => 16.0.1.2.0}/pre-migration.py (100%) diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index e61513c8601..2a4b7cacad3 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.1.0", + "version": "16.0.1.2.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/migrations/14.0.2.9.0/pre-migration.py b/shopfloor_reception/migrations/16.0.1.2.0/pre-migration.py similarity index 100% rename from shopfloor_reception/migrations/14.0.2.9.0/pre-migration.py rename to shopfloor_reception/migrations/16.0.1.2.0/pre-migration.py From 4f9986dd2d215634fe29b35ab21f3d7e03f0d95f Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 23 Jun 2025 13:55:33 +0200 Subject: [PATCH 174/357] [MIG] shopfloor_reception_refund_return: Migration to Version 16.0 --- shopfloor_reception_refund_return/__manifest__.py | 2 +- shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst | 1 + .../tests/test_action_stock.py | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/shopfloor_reception_refund_return/__manifest__.py b/shopfloor_reception_refund_return/__manifest__.py index 3e3c5d89fbc..1322b1b5495 100644 --- a/shopfloor_reception_refund_return/__manifest__.py +++ b/shopfloor_reception_refund_return/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Shopfloor Reception Refund Return", "summary": "Mark created return as to refund", - "version": "14.0.1.0.0", + "version": "16.0.1.0.0", "category": "Inventory, Accounting", "website": "https://github.com/OCA/wms", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", diff --git a/shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst b/shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst index c732df9d08a..0c8ba3d75d4 100644 --- a/shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst +++ b/shopfloor_reception_refund_return/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Matthieu Méquignon * Jacques-Etienne Baudoux (BCIM) +* Michael Tietz (MT Software) diff --git a/shopfloor_reception_refund_return/tests/test_action_stock.py b/shopfloor_reception_refund_return/tests/test_action_stock.py index 2766dff56f3..68a6b525136 100644 --- a/shopfloor_reception_refund_return/tests/test_action_stock.py +++ b/shopfloor_reception_refund_return/tests/test_action_stock.py @@ -1,6 +1,6 @@ # Copyright 2023 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from odoo.addons.shopfloor.tests.common import CommonCase @@ -27,8 +27,8 @@ def setUpClass(cls): cls.picking = cls._create_picking( lines=[(cls.product_a, 10), (cls.product_b, 10)], confirm=True ) - cls.move0 = cls.picking.move_lines[0] - cls.move1 = cls.picking.move_lines[1] + cls.move0 = cls.picking.move_ids[0] + cls.move1 = cls.picking.move_ids[1] cls._fill_stock_for_moves(cls.move0) cls._fill_stock_for_moves(cls.move1) cls.picking.action_assign() @@ -40,7 +40,7 @@ def test_create_return_move(self): self.picking, self.picking_type_in, "potato" ) return_moves = self.stock.create_return_move( - return_picking, self.picking.move_lines + return_picking, self.picking.move_ids ) self.assertTrue(all(move.to_refund for move in return_moves)) return_picking.action_assign() From d36b91168704331511ca7a5ccfd4fe0d7e289f3f Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 24 Jun 2025 16:58:11 +0000 Subject: [PATCH 175/357] [UPD] Update shopfloor.pot --- shopfloor/i18n/shopfloor.pot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shopfloor/i18n/shopfloor.pot b/shopfloor/i18n/shopfloor.pot index b1eaf75a2b9..129676d4f29 100644 --- a/shopfloor/i18n/shopfloor.pot +++ b/shopfloor/i18n/shopfloor.pot @@ -527,6 +527,11 @@ msgstr "" msgid "Inventory Locations" msgstr "" +#. module: shopfloor +#: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created +msgid "Is Shopfloor Created" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/completion_info.py:0 From 10afefb7fe1ca473d1c9d9ba29a38c3933f2389a Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 24 Jun 2025 16:58:16 +0000 Subject: [PATCH 176/357] [UPD] Update shopfloor_reception.pot --- shopfloor_reception/i18n/shopfloor_reception.pot | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/shopfloor_reception/i18n/shopfloor_reception.pot b/shopfloor_reception/i18n/shopfloor_reception.pot index 78dd7fc6792..199e51dbea8 100644 --- a/shopfloor_reception/i18n/shopfloor_reception.pot +++ b/shopfloor_reception/i18n/shopfloor_reception.pot @@ -13,19 +13,9 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" -#. module: shopfloor_reception -#: model:ir.model.fields,field_description:shopfloor_reception.field_stock_picking__is_shopfloor_created -msgid "Is Shopfloor Created" -msgstr "" - #. module: shopfloor_reception #: model:shopfloor.menu,name:shopfloor_reception.shopfloor_menu_demo_reception #: model:shopfloor.scenario,name:shopfloor_reception.scenario_reception #: model:stock.picking.type,name:shopfloor_reception.picking_type_reception_demo msgid "Reception" msgstr "" - -#. module: shopfloor_reception -#: model:ir.model,name:shopfloor_reception.model_stock_picking -msgid "Transfer" -msgstr "" From eb536a120f44e1cace187725c15feee94182ffe5 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 24 Jun 2025 16:58:16 +0000 Subject: [PATCH 177/357] [UPD] Update shopfloor_reception_refund_return.pot --- .../i18n/shopfloor_reception_refund_return.pot | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 shopfloor_reception_refund_return/i18n/shopfloor_reception_refund_return.pot diff --git a/shopfloor_reception_refund_return/i18n/shopfloor_reception_refund_return.pot b/shopfloor_reception_refund_return/i18n/shopfloor_reception_refund_return.pot new file mode 100644 index 00000000000..78d58d53fe0 --- /dev/null +++ b/shopfloor_reception_refund_return/i18n/shopfloor_reception_refund_return.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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" From e26cf838b1883e1070563ebae6036d9b45c30e3f Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 24 Jun 2025 17:09:51 +0000 Subject: [PATCH 178/357] [BOT] post-merge updates --- README.md | 5 +- setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + shopfloor/README.rst | 2 +- shopfloor/static/description/index.html | 2 +- shopfloor_reception/README.rst | 8 +++- .../static/description/index.html | 28 +++++++----- shopfloor_reception_refund_return/README.rst | 19 +++++--- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 43 +++++++++++------- 10 files changed, 68 insertions(+), 42 deletions(-) create mode 100644 shopfloor_reception_refund_return/static/description/icon.png diff --git a/README.md b/README.md index 149a3735e18..63d6cc09fd2 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,15 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.9.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.10.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.1.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.2.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | JuMiSanAr | Scenario for receiving products +[shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 086eb2e47fb..9ef7d8bf9cd 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250603.0 \ No newline at end of file +16.0.20250624.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index 21e7d19a358..c6c7142b576 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -24,6 +24,7 @@ 'odoo-addon-shopfloor_mobile_base_auth_api_key>=16.0dev,<16.1dev', 'odoo-addon-shopfloor_reception>=16.0dev,<16.1dev', 'odoo-addon-shopfloor_reception_mobile>=16.0dev,<16.1dev', + 'odoo-addon-shopfloor_reception_refund_return>=16.0dev,<16.1dev', 'odoo-addon-shopfloor_rest_log>=16.0dev,<16.1dev', 'odoo-addon-shopfloor_workstation>=16.0dev,<16.1dev', 'odoo-addon-shopfloor_workstation_mobile>=16.0dev,<16.1dev', diff --git a/shopfloor/README.rst b/shopfloor/README.rst index 2dd9ab99360..e28204c6ac6 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:caca43b0b1116820cf13ea214d961ce551858e1a541dbdc6a453a21542017fdd + !! source digest: sha256:f6bf44c46907424c9adf6166901cdac6cda73038169d71fe37121d21ab72b2ea !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index 2085d4a3f8c..c8bdabae88f 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:caca43b0b1116820cf13ea214d961ce551858e1a541dbdc6a453a21542017fdd +!! source digest: sha256:f6bf44c46907424c9adf6166901cdac6cda73038169d71fe37121d21ab72b2ea !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index a467458adef..441fddc06e4 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =================== Shopfloor Reception =================== @@ -7,13 +11,13 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:91d600cf02ccddb57cc28496eef052a0d5a9179b984e2acb651fbab29a5e3586 + !! source digest: sha256:feb06dd56eaf11d01d3ccb49097195062f535f810c597442ded695ebb15b762f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 9a0d185d39a..ed77ddea028 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -3,7 +3,7 @@ -Shopfloor Reception +README.rst -
-

Shopfloor Reception

+
+ + +Odoo Community Association + +
+

Shopfloor Reception

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor implementation of the reception scenario. Allows to receive products and create the proper packs for each logistic unit.

Table of contents

@@ -386,11 +391,11 @@

Shopfloor Reception

-

Known issues / Roadmap

+

Known issues / Roadmap

Implement methods in the backend to cancel lines (to be used by the frontend in select_line & set_quantity).

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -398,15 +403,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -431,5 +436,6 @@

Maintainers

+
diff --git a/shopfloor_reception_refund_return/README.rst b/shopfloor_reception_refund_return/README.rst index a18364dac1d..9e827232860 100644 --- a/shopfloor_reception_refund_return/README.rst +++ b/shopfloor_reception_refund_return/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================================= Shopfloor Reception Refund Return ================================= @@ -7,23 +11,23 @@ Shopfloor Reception Refund Return !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:c21e3ca418cdb607fff8188aae7a7992b42879fa4abb73fecd180826f54273c0 + !! source digest: sha256:9042334ed3023cfdbad3925fdda86bfbc54efd128bba3ce83a1ca78b37eb14df !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github - :target: https://github.com/OCA/wms/tree/14.0/shopfloor_reception_refund_return + :target: https://github.com/OCA/wms/tree/16.0/shopfloor_reception_refund_return :alt: OCA/wms .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-shopfloor_reception_refund_return + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_reception_refund_return :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -43,7 +47,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -61,6 +65,7 @@ Contributors * Matthieu Méquignon * Jacques-Etienne Baudoux (BCIM) +* Michael Tietz (MT Software) Maintainers ~~~~~~~~~~~ @@ -83,6 +88,6 @@ Current `maintainer `__: |maintainer-mmequignon| -This module is part of the `OCA/wms `_ project on GitHub. +This module is part of the `OCA/wms `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/shopfloor_reception_refund_return/static/description/icon.png b/shopfloor_reception_refund_return/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 -Shopfloor Reception Refund Return +README.rst -
-

Shopfloor Reception Refund Return

+
+ + +Odoo Community Association + +
+

Shopfloor Reception Refund Return

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Marks returns created by shopfloor as to refund.

Sets to_refund to true when when creating a return move.

Table of contents

@@ -385,42 +390,46 @@

Shopfloor Reception Refund Return

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed -feedback.

+feedback.

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

-Odoo Community Association + +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.

Current maintainer:

mmequignon

-

This module is part of the OCA/wms project on GitHub.

+

This module is part of the OCA/wms project on GitHub.

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

+
From 32a203bb02748a31c58633cf7ed48044237f9e6b Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 24 Jun 2025 17:10:09 +0000 Subject: [PATCH 179/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/ --- shopfloor/i18n/ca.po | 5 +++++ shopfloor/i18n/de.po | 5 +++++ shopfloor/i18n/es_AR.po | 5 +++++ shopfloor/i18n/it.po | 8 +++++++- shopfloor/i18n/pt_BR.po | 5 +++++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/shopfloor/i18n/ca.po b/shopfloor/i18n/ca.po index 75d573f8ed5..e94a67ecabc 100644 --- a/shopfloor/i18n/ca.po +++ b/shopfloor/i18n/ca.po @@ -535,6 +535,11 @@ msgstr "" msgid "Inventory Locations" msgstr "" +#. module: shopfloor +#: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created +msgid "Is Shopfloor Created" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/completion_info.py:0 diff --git a/shopfloor/i18n/de.po b/shopfloor/i18n/de.po index 8ff690699a1..d983314959d 100644 --- a/shopfloor/i18n/de.po +++ b/shopfloor/i18n/de.po @@ -531,6 +531,11 @@ msgstr "" msgid "Inventory Locations" msgstr "" +#. module: shopfloor +#: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created +msgid "Is Shopfloor Created" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/completion_info.py:0 diff --git a/shopfloor/i18n/es_AR.po b/shopfloor/i18n/es_AR.po index 64c92088fb6..e666be9a750 100644 --- a/shopfloor/i18n/es_AR.po +++ b/shopfloor/i18n/es_AR.po @@ -577,6 +577,11 @@ msgstr "No se permite ignorar el almacenamiento no encontrado para el menú {}." msgid "Inventory Locations" msgstr "Ubicaciones de Inventario" +#. module: shopfloor +#: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created +msgid "Is Shopfloor Created" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/completion_info.py:0 diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index a157f8ecb94..2e0880642ac 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -142,7 +142,8 @@ msgstr "" #, python-format msgid "" "%(message_code)s not found in the current transfer or already in a package." -msgstr "%(message_code)s non trovato nel trasferimento attuale o già nel collo." +msgstr "" +"%(message_code)s non trovato nel trasferimento attuale o già nel collo." #. module: shopfloor #. odoo-python @@ -612,6 +613,11 @@ msgstr "Ignorare inoltro non trovato non è consentito per il menu {}." msgid "Inventory Locations" msgstr "Ubicazioni di inventario" +#. module: shopfloor +#: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created +msgid "Is Shopfloor Created" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/completion_info.py:0 diff --git a/shopfloor/i18n/pt_BR.po b/shopfloor/i18n/pt_BR.po index 333a530900c..0c22a107763 100644 --- a/shopfloor/i18n/pt_BR.po +++ b/shopfloor/i18n/pt_BR.po @@ -531,6 +531,11 @@ msgstr "" msgid "Inventory Locations" msgstr "" +#. module: shopfloor +#: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created +msgid "Is Shopfloor Created" +msgstr "" + #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/completion_info.py:0 From d0271c4f4e630bacba594f177e46088491e6cc52 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 24 Jun 2025 17:10:10 +0000 Subject: [PATCH 180/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-shopfloor_reception Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_reception/ --- shopfloor_reception/i18n/it.po | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/shopfloor_reception/i18n/it.po b/shopfloor_reception/i18n/it.po index 9fa89b51eeb..8b496488b7c 100644 --- a/shopfloor_reception/i18n/it.po +++ b/shopfloor_reception/i18n/it.po @@ -16,11 +16,6 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17\n" -#. module: shopfloor_reception -#: model:ir.model.fields,field_description:shopfloor_reception.field_stock_picking__is_shopfloor_created -msgid "Is Shopfloor Created" -msgstr "Il reparto è crato" - #. module: shopfloor_reception #: model:shopfloor.menu,name:shopfloor_reception.shopfloor_menu_demo_reception #: model:shopfloor.scenario,name:shopfloor_reception.scenario_reception @@ -28,10 +23,11 @@ msgstr "Il reparto è crato" msgid "Reception" msgstr "Ricezione" -#. module: shopfloor_reception -#: model:ir.model,name:shopfloor_reception.model_stock_picking -msgid "Transfer" -msgstr "Trasferimento" +#~ msgid "Is Shopfloor Created" +#~ msgstr "Il reparto è crato" + +#~ msgid "Transfer" +#~ msgstr "Trasferimento" #~ msgid "Display Name" #~ msgstr "Nome visualizzato" From c8f7ca45358a40599fd8c549c1b1459fdfa95848 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Tue, 24 Jun 2025 20:35:27 +0200 Subject: [PATCH 181/357] [FIX] shopfloor_reception: Fix migration stock.picking is_shopfloor_created --- shopfloor_reception/migrations/16.0.1.2.0/pre-migration.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shopfloor_reception/migrations/16.0.1.2.0/pre-migration.py b/shopfloor_reception/migrations/16.0.1.2.0/pre-migration.py index 05241eff250..edd8a66cda0 100644 --- a/shopfloor_reception/migrations/16.0.1.2.0/pre-migration.py +++ b/shopfloor_reception/migrations/16.0.1.2.0/pre-migration.py @@ -9,7 +9,11 @@ def move_fields_to_new_module(cr): # is_shopfloor_created has been wrongly put in shopfloor_reception. # this script moves it in shopfloor. openupgrade.update_module_moved_fields( - cr, "stock.picking", "is_shopfloor_created", "shopfloor_reception", "shopfloor" + cr, + "stock.picking", + ["is_shopfloor_created"], + "shopfloor_reception", + "shopfloor", ) From ef49628cbc615fb3fd5f19173de3facae7ae9933 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 24 Jun 2025 20:33:14 +0000 Subject: [PATCH 182/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 63d6cc09fd2..76426543244 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.2.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.2.1 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 441fddc06e4..e503ecdef49 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:feb06dd56eaf11d01d3ccb49097195062f535f810c597442ded695ebb15b762f + !! source digest: sha256:424c4104c1b11985aefef164d85bbc13e6b4b7c761a34ce3a07ccc335e130534 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 2a4b7cacad3..003d0381e2c 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.2.0", + "version": "16.0.1.2.1", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index ed77ddea028..22141814822 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor Reception

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:feb06dd56eaf11d01d3ccb49097195062f535f810c597442ded695ebb15b762f +!! source digest: sha256:424c4104c1b11985aefef164d85bbc13e6b4b7c761a34ce3a07ccc335e130534 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor implementation of the reception scenario. From c07997ff8e6d3ae3cb8ca54fa6d745d98dd802cf Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 25 Jun 2025 06:48:58 +0000 Subject: [PATCH 183/357] Translated using Weblate (Italian) Currently translated at 100.0% (329 of 329 strings) Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/it/ --- shopfloor/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index 2e0880642ac..81af46e8e83 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-05-28 10:54+0000\n" +"PO-Revision-Date: 2025-06-25 06:54+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -616,7 +616,7 @@ msgstr "Ubicazioni di inventario" #. module: shopfloor #: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created msgid "Is Shopfloor Created" -msgstr "" +msgstr "Il reparto è crato" #. module: shopfloor #. odoo-python From 4d3dc88529a608edf261589bf2028d3a5b927d2c Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 25 Jun 2025 06:54:39 +0000 Subject: [PATCH 184/357] Added translation using Weblate (Italian) --- shopfloor_reception_refund_return/i18n/it.po | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 shopfloor_reception_refund_return/i18n/it.po diff --git a/shopfloor_reception_refund_return/i18n/it.po b/shopfloor_reception_refund_return/i18n/it.po new file mode 100644 index 00000000000..73388557f6d --- /dev/null +++ b/shopfloor_reception_refund_return/i18n/it.po @@ -0,0 +1,14 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" From 7e6bf64825799a0e11d52e6ca33eae38a3b191b8 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Wed, 25 Jun 2025 13:47:52 +0200 Subject: [PATCH 185/357] =?UTF-8?q?[FIX]=20shopfloor:=20location=5Fcontent?= =?UTF-8?q?=5Ftransfer=20=E2=80=93=20restrict=20lot=20search=20by=20produc?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when scanning a lot barcode, if multiple products share the same lot name, the system could match the wrong lot this fix ensures that the search is restricted to the current product to avoid incorrect lot selection and related errors --- shopfloor/services/location_content_transfer.py | 6 +++++- shopfloor/tests/test_cluster_picking_scan_line.py | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/shopfloor/services/location_content_transfer.py b/shopfloor/services/location_content_transfer.py index 2983d084075..b60c8ce8062 100644 --- a/shopfloor/services/location_content_transfer.py +++ b/shopfloor/services/location_content_transfer.py @@ -611,7 +611,11 @@ def scan_line(self, location_id, move_line_id, barcode): "lot": self._scan_line__by_lot, "none": self._scan_line__fallback, } - search_result = search.find(barcode, types=handlers.keys()) + search_result = search.find( + barcode, + types=handlers.keys(), + handler_kw=dict(lot=dict(products=move_line.product_id)), + ) handler = handlers.get(search_result.type, self._scan_line__fallback) # handler might've been called but returned no response. # I.E. package is scanned but doesn't matches move_line's package. diff --git a/shopfloor/tests/test_cluster_picking_scan_line.py b/shopfloor/tests/test_cluster_picking_scan_line.py index be76f004260..151c2a10ff3 100644 --- a/shopfloor/tests/test_cluster_picking_scan_line.py +++ b/shopfloor/tests/test_cluster_picking_scan_line.py @@ -78,6 +78,12 @@ def test_scan_line_serial_ok(self): self.product_a.tracking = "serial" self._simulate_batch_selected(self.batch, in_lot=True) line = self.batch.picking_ids.move_line_ids + lot = line.lot_id + self.assertTrue(lot) + lot_with_same_name = line.lot_id.copy( + {"product_id": self.product_b.id, "name": line.lot_id.name} + ) + self.assertEqual(lot_with_same_name.name, lot.name) self._scan_line_ok(line, line.lot_id.name) def test_scan_line_error_product_tracked(self): From 1bfa01e706fc08912008514efde309e0a5ccc0eb Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 26 Jun 2025 16:09:50 +0000 Subject: [PATCH 186/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 76426543244..97f2e9681c8 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.10.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.10.1 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index e28204c6ac6..f305b90ca59 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f6bf44c46907424c9adf6166901cdac6cda73038169d71fe37121d21ab72b2ea + !! source digest: sha256:3b3e7f94a81872e7868a889ce80740558ad70732df2821188971ff06a639e995 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index cfc3cb41715..011d46e0f42 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.10.0", + "version": "16.0.2.10.1", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index c8bdabae88f..e417f6b5ae8 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:f6bf44c46907424c9adf6166901cdac6cda73038169d71fe37121d21ab72b2ea +!! source digest: sha256:3b3e7f94a81872e7868a889ce80740558ad70732df2821188971ff06a639e995 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

From a34b9659e68ef1d09d676a935f880f81ab395136 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Thu, 24 Apr 2025 15:53:35 +0200 Subject: [PATCH 187/357] [IMP] shopfloor_reception: Use move line base shopfloor search As move lines search is quite powerful and extendable (domain, sort), use that one instead of a picking search to present default pickings to do to user. --- shopfloor_reception/README.rst | 6 +---- shopfloor_reception/__manifest__.py | 2 +- .../migrations/16.0.1.3.0/post-migrate.py | 26 +++++++++++++++++++ shopfloor_reception/services/reception.py | 26 +++++++++++-------- .../static/description/index.html | 26 +++++++------------ 5 files changed, 53 insertions(+), 33 deletions(-) create mode 100644 shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index e503ecdef49..7bf259e09a8 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - =================== Shopfloor Reception =================== @@ -17,7 +13,7 @@ Shopfloor Reception .. |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/license-AGPL--3-blue.png +.. |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%2Fwms-lightgray.png?logo=github diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 003d0381e2c..3fb06952663 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.2.1", + "version": "16.0.1.3.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py b/shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py new file mode 100644 index 00000000000..64f36a51c68 --- /dev/null +++ b/shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py @@ -0,0 +1,26 @@ +import json +import logging + +from odoo import SUPERUSER_ID, api + +_logger = logging.getLogger(__name__) + + +def migrate(cr, version): + if not version: + return + env = api.Environment(cr, SUPERUSER_ID, {}) + reception = env.ref("shopfloor_reception.scenario_reception") + _update_scenario_options(reception, sort_order=False, additional_domain=True) + + +def _update_scenario_options(scenario, sort_order=True, additional_domain=True): + options = scenario.options + options["allow_move_line_search_sort_order"] = sort_order + options["allow_move_line_search_additional_domain"] = additional_domain + options_edit = json.dumps(options or {}, indent=4, sort_keys=True) + scenario.write({"options_edit": options_edit}) + _logger.info( + "Option allow_move_line_search_additional_domain added to scenario %s", + scenario.name, + ) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 8eab102accd..8ec2f6ad433 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -76,16 +76,19 @@ def _scheduled_date_today_domain(self): domain.append(("scheduled_date", "<=", today_end)) return domain - def _get_today_start_end_datetime(self): + def _get_today_start_end_datetime(self, naive=True): company = self.env.company tz = company.partner_id.tz or "UTC" today = fields.Datetime.today() - today_start = fields.Datetime.start_of(today, "day") - today_end = fields.Datetime.end_of(today, "day") - today_start_localized = ( - pytz.timezone(tz).localize(today_start).astimezone(pytz.utc) - ) - today_end_localized = pytz.timezone(tz).localize(today_end).astimezone(pytz.utc) + today_start = today_start_localized = fields.Datetime.start_of(today, "day") + today_end = today_end_localized = fields.Datetime.end_of(today, "day") + if not naive: + today_start_localized = ( + pytz.timezone(tz).localize(today_start).astimezone(pytz.utc) + ) + today_end_localized = ( + pytz.timezone(tz).localize(today_end).astimezone(pytz.utc) + ) return (today_start_localized, today_end_localized) # DOMAIN METHODS @@ -337,7 +340,7 @@ def _scan_document__by_picking(self, pickings, barcode): # could return more than one picking. # If there's only one picking due today, we go to the next screen. # Otherwise, we ask the user to scan a package instead. - today_start, today_end = self._get_today_start_end_datetime() + today_start, today_end = self._get_today_start_end_datetime(naive=False) picking_filter_result_due_today = picking_filter_result.filtered( lambda p: today_start <= p.scheduled_date.astimezone(pytz.utc) @@ -727,9 +730,10 @@ def _data_for_moves(self, moves, **kw): def _response_for_select_document(self, pickings=None, message=None): if not pickings: - pickings = self.env["stock.picking"].search( - self._domain_stock_picking(today_only=True), - order=self._order_stock_picking(), + # We use the standard shopfloor + move_lines = self.search_move_line.search_move_lines(match_user=True) + pickings = move_lines.picking_id.filtered_domain( + self._domain_stock_picking(today_only=True) ) else: # We sort by scheduled date first. However, there might be a case diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 22141814822..cedaaf528b2 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Shopfloor Reception -
+
+

Shopfloor Reception

- - -Odoo Community Association - -
-

Shopfloor Reception

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor implementation of the reception scenario. Allows to receive products and create the proper packs for each logistic unit.

Table of contents

@@ -391,11 +386,11 @@

Shopfloor Reception

-

Known issues / Roadmap

+

Known issues / Roadmap

Implement methods in the backend to cancel lines (to be used by the frontend in select_line & set_quantity).

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -403,15 +398,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -436,6 +431,5 @@

Maintainers

-
From c65b67b887306e06b0406f73d60a527834d4df11 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Thu, 24 Apr 2025 16:39:07 +0200 Subject: [PATCH 188/357] [IMP] shopfloor_reception: Allows to configure today pickings Introduce a new parameter on menu level to filter today pickings or not. Sometimes, we want to filter out pickings on other criteria (e.g.: GRN, ...) --- shopfloor_reception/__manifest__.py | 1 + .../data/shopfloor_scenario_data.xml | 3 +- .../migrations/16.0.1.3.0/post-migrate.py | 9 +++- shopfloor_reception/models/__init__.py | 1 + shopfloor_reception/models/shopfloor_menu.py | 46 +++++++++++++++++++ shopfloor_reception/services/reception.py | 8 +++- shopfloor_reception/tests/common.py | 1 + shopfloor_reception/views/shopfloor_menu.xml | 24 ++++++++++ 8 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 shopfloor_reception/models/__init__.py create mode 100644 shopfloor_reception/models/shopfloor_menu.py create mode 100644 shopfloor_reception/views/shopfloor_menu.xml diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 3fb06952663..922caa57dc4 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -13,6 +13,7 @@ "external_dependencies": {"python": ["openupgradelib"]}, "data": [ "data/shopfloor_scenario_data.xml", + "views/shopfloor_menu.xml", ], "demo": [ "demo/stock_picking_type_demo.xml", diff --git a/shopfloor_reception/data/shopfloor_scenario_data.xml b/shopfloor_reception/data/shopfloor_scenario_data.xml index 67b04aa8233..fd86065f8e0 100644 --- a/shopfloor_reception/data/shopfloor_scenario_data.xml +++ b/shopfloor_reception/data/shopfloor_scenario_data.xml @@ -10,7 +10,8 @@ { "auto_post_line": true, "allow_return": true, - "scan_location_or_pack_first": true + "scan_location_or_pack_first": true, + "allow_filter_today_scheduled_pickings": true }
diff --git a/shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py b/shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py index 64f36a51c68..be021b28919 100644 --- a/shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py +++ b/shopfloor_reception/migrations/16.0.1.3.0/post-migrate.py @@ -11,13 +11,18 @@ def migrate(cr, version): return env = api.Environment(cr, SUPERUSER_ID, {}) reception = env.ref("shopfloor_reception.scenario_reception") - _update_scenario_options(reception, sort_order=False, additional_domain=True) + _update_scenario_options( + reception, sort_order=False, additional_domain=True, today=True + ) -def _update_scenario_options(scenario, sort_order=True, additional_domain=True): +def _update_scenario_options( + scenario, sort_order=True, additional_domain=True, today=True +): options = scenario.options options["allow_move_line_search_sort_order"] = sort_order options["allow_move_line_search_additional_domain"] = additional_domain + options["allow_filter_today_scheduled_pickings"] = today options_edit = json.dumps(options or {}, indent=4, sort_keys=True) scenario.write({"options_edit": options_edit}) _logger.info( diff --git a/shopfloor_reception/models/__init__.py b/shopfloor_reception/models/__init__.py new file mode 100644 index 00000000000..8bd3d5195ca --- /dev/null +++ b/shopfloor_reception/models/__init__.py @@ -0,0 +1 @@ +from . import shopfloor_menu diff --git a/shopfloor_reception/models/shopfloor_menu.py b/shopfloor_reception/models/shopfloor_menu.py new file mode 100644 index 00000000000..c863b1b5cca --- /dev/null +++ b/shopfloor_reception/models/shopfloor_menu.py @@ -0,0 +1,46 @@ +# Copyright 2025 ACSONE SA/NV (https://www.acsone.eu) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import _, api, exceptions, fields, models + +FILTER_TODAY_SCHEDULED_PICKINGS_HELP = """ +By default, at first step, filter the available +pickings with the ones that are scheduled for today. +""" + + +class ShopfloorMenu(models.Model): + _inherit = "shopfloor.menu" + + filter_today_scheduled_pickings_is_possible = fields.Boolean( + compute="_compute_filter_today_scheduled_pickings_is_possible" + ) + filter_today_scheduled_pickings = fields.Boolean( + default=False, + help=FILTER_TODAY_SCHEDULED_PICKINGS_HELP, + ) + + @api.depends("scenario_id") + def _compute_filter_today_scheduled_pickings_is_possible(self): + for menu in self: + menu.filter_today_scheduled_pickings_is_possible = bool( + menu.scenario_id.has_option("allow_filter_today_scheduled_pickings") + ) + + @api.onchange("filter_today_scheduled_pickings_is_possible") + def onchange_filter_today_scheduled_pickings_is_possible(self): + self.filter_today_scheduled_pickings = ( + self.filter_today_scheduled_pickings_is_possible + ) + + @api.constrains("scenario_id", "picking_type_ids", "allow_move_create") + def _check_filter_today_scheduled_pickings(self): + for menu in self: + if ( + menu.filter_today_scheduled_pickings + and not menu.filter_today_scheduled_pickings_is_possible + ): + raise exceptions.ValidationError( + _("Filter Today Pickings is not allowed for menu {}.").format( + menu.name + ) + ) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 8ec2f6ad433..51fcf2e1a9e 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -91,6 +91,10 @@ def _get_today_start_end_datetime(self, naive=True): ) return (today_start_localized, today_end_localized) + @property + def filter_today_scheduled_pickings(self): + return self.work.menu.filter_today_scheduled_pickings + # DOMAIN METHODS def _domain_move_line_by_packaging(self, packaging): @@ -733,7 +737,9 @@ def _response_for_select_document(self, pickings=None, message=None): # We use the standard shopfloor move_lines = self.search_move_line.search_move_lines(match_user=True) pickings = move_lines.picking_id.filtered_domain( - self._domain_stock_picking(today_only=True) + self._domain_stock_picking( + today_only=self.filter_today_scheduled_pickings + ) ) else: # We sort by scheduled date first. However, there might be a case diff --git a/shopfloor_reception/tests/common.py b/shopfloor_reception/tests/common.py index 90bd62e323c..5ba54d72435 100644 --- a/shopfloor_reception/tests/common.py +++ b/shopfloor_reception/tests/common.py @@ -46,6 +46,7 @@ def _add_package(cls, picking): def setUpClassVars(cls, *args, **kwargs): super().setUpClassVars(*args, **kwargs) cls.menu = cls.env.ref("shopfloor_reception.shopfloor_menu_demo_reception") + cls.menu.sudo().filter_today_scheduled_pickings = True cls.profile = cls.env.ref("shopfloor.profile_demo_1") cls.picking_type = cls.menu.picking_type_ids cls.wh = cls.picking_type.warehouse_id diff --git a/shopfloor_reception/views/shopfloor_menu.xml b/shopfloor_reception/views/shopfloor_menu.xml new file mode 100644 index 00000000000..10f73482c0b --- /dev/null +++ b/shopfloor_reception/views/shopfloor_menu.xml @@ -0,0 +1,24 @@ + + + + + shopfloor.menu + + + + + + + + + + + + From 4e74c1f105aab3e9de92bef480efc14ab483f3d7 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 1 Jul 2025 08:23:28 +0000 Subject: [PATCH 189/357] [UPD] Update stock_release_channel_shipment_advice_toursolver.pot --- .../stock_release_channel_shipment_advice_toursolver.pot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stock_release_channel_shipment_advice_toursolver/i18n/stock_release_channel_shipment_advice_toursolver.pot b/stock_release_channel_shipment_advice_toursolver/i18n/stock_release_channel_shipment_advice_toursolver.pot index e4fcafe313d..13e05cbcfc8 100644 --- a/stock_release_channel_shipment_advice_toursolver/i18n/stock_release_channel_shipment_advice_toursolver.pot +++ b/stock_release_channel_shipment_advice_toursolver/i18n/stock_release_channel_shipment_advice_toursolver.pot @@ -23,6 +23,11 @@ msgstr "" msgid "Release Channel" msgstr "" +#. module: stock_release_channel_shipment_advice_toursolver +#: model:ir.model,name:stock_release_channel_shipment_advice_toursolver.model_shipment_advice +msgid "Shipment Advice" +msgstr "" + #. module: stock_release_channel_shipment_advice_toursolver #: model:ir.model,name:stock_release_channel_shipment_advice_toursolver.model_shipment_advice_planner msgid "Shipment Advice Planner" From 3fffad6034561c1df91311fbef11088a7c12586e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 1 Jul 2025 08:34:54 +0000 Subject: [PATCH 190/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 8 ++++-- .../__manifest__.py | 2 +- .../static/description/index.html | 26 ++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 97f2e9681c8..48bc9d01955 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ addon | version | maintainers | summary [stock_release_channel_shipment_advice](stock_release_channel_shipment_advice/) | 16.0.1.2.0 | jbaudoux | Plan shipment advices for ready and released pickings [stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.0 | | This module adds an action to the release channel to automate the delivery of its shippings. [stock_release_channel_shipment_advice_process_end_time](stock_release_channel_shipment_advice_process_end_time/) | 16.0.1.0.0 | | This module allows to set a delay time (in minutes) between the release channel process end time and the shipment advice arrival to the dock time. -[stock_release_channel_shipment_advice_toursolver](stock_release_channel_shipment_advice_toursolver/) | 16.0.1.0.1 | | Use TourSolver to plan shipment advices for ready and released pickings +[stock_release_channel_shipment_advice_toursolver](stock_release_channel_shipment_advice_toursolver/) | 16.0.1.1.0 | | Use TourSolver to plan shipment advices for ready and released pickings [stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.1.0 | jbaudoux | Release channel with shipment lead time [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels diff --git a/stock_release_channel_shipment_advice_toursolver/README.rst b/stock_release_channel_shipment_advice_toursolver/README.rst index 0c6c7086ab5..cd7a54dbfae 100644 --- a/stock_release_channel_shipment_advice_toursolver/README.rst +++ b/stock_release_channel_shipment_advice_toursolver/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================================================ Stock Release Channel Shipment Advice Toursolver ================================================ @@ -7,13 +11,13 @@ Stock Release Channel Shipment Advice Toursolver !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:cf692d6f796a74eace6fbaf8a76c1be68c27c5a0f90740956aaba1d4c807d669 + !! source digest: sha256:5ac3471d64445f78449a4a30d12717b0314774e114b146bcf9fe7a5b4183f680 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_release_channel_shipment_advice_toursolver/__manifest__.py b/stock_release_channel_shipment_advice_toursolver/__manifest__.py index bd6261e3cb4..bd38eb3be35 100644 --- a/stock_release_channel_shipment_advice_toursolver/__manifest__.py +++ b/stock_release_channel_shipment_advice_toursolver/__manifest__.py @@ -5,7 +5,7 @@ "name": "Stock Release Channel Shipment Advice Toursolver", "summary": """ Use TourSolver to plan shipment advices for ready and released pickings""", - "version": "16.0.1.0.1", + "version": "16.0.1.1.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_release_channel_shipment_advice_toursolver/static/description/index.html b/stock_release_channel_shipment_advice_toursolver/static/description/index.html index c1c88f40d04..d7bf61e8c04 100644 --- a/stock_release_channel_shipment_advice_toursolver/static/description/index.html +++ b/stock_release_channel_shipment_advice_toursolver/static/description/index.html @@ -3,7 +3,7 @@ -Stock Release Channel Shipment Advice Toursolver +README.rst -
-

Stock Release Channel Shipment Advice Toursolver

+
+ + +Odoo Community Association + +
+

Stock Release Channel Shipment Advice Toursolver

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Use TourSolver to plan shipment advices for ready and released pickings.

Table of contents

@@ -384,7 +389,7 @@

Stock Release Channel Shipment Advice Toursolver

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -392,22 +397,22 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -420,5 +425,6 @@

Maintainers

+
From 976f8922d7bec4a2fd59bb86c9afed1958910993 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 1 Jul 2025 08:35:02 +0000 Subject: [PATCH 191/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_release_channel_shipment_advice_toursolver Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_shipment_advice_toursolver/ --- stock_release_channel_shipment_advice_toursolver/i18n/it.po | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stock_release_channel_shipment_advice_toursolver/i18n/it.po b/stock_release_channel_shipment_advice_toursolver/i18n/it.po index 7fb07878523..a80eee5ddb2 100644 --- a/stock_release_channel_shipment_advice_toursolver/i18n/it.po +++ b/stock_release_channel_shipment_advice_toursolver/i18n/it.po @@ -26,6 +26,11 @@ msgstr "Risorse consegna" msgid "Release Channel" msgstr "Canale rilascio" +#. module: stock_release_channel_shipment_advice_toursolver +#: model:ir.model,name:stock_release_channel_shipment_advice_toursolver.model_shipment_advice +msgid "Shipment Advice" +msgstr "" + #. module: stock_release_channel_shipment_advice_toursolver #: model:ir.model,name:stock_release_channel_shipment_advice_toursolver.model_shipment_advice_planner msgid "Shipment Advice Planner" From c8b916205bd395440d8fc5d8904ba35ba69bc08b Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 1 Jul 2025 10:10:52 +0000 Subject: [PATCH 192/357] Translated using Weblate (Italian) Currently translated at 100.0% (9 of 9 strings) Translation: wms-16.0/wms-16.0-stock_release_channel_shipment_advice_toursolver Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_release_channel_shipment_advice_toursolver/it/ --- stock_release_channel_shipment_advice_toursolver/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stock_release_channel_shipment_advice_toursolver/i18n/it.po b/stock_release_channel_shipment_advice_toursolver/i18n/it.po index a80eee5ddb2..0c1b4998818 100644 --- a/stock_release_channel_shipment_advice_toursolver/i18n/it.po +++ b/stock_release_channel_shipment_advice_toursolver/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-04-22 09:34+0000\n" +"PO-Revision-Date: 2025-07-01 12:25+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_release_channel_shipment_advice_toursolver #: model:ir.model.fields,field_description:stock_release_channel_shipment_advice_toursolver.field_stock_release_channel__delivery_resource_ids @@ -29,7 +29,7 @@ msgstr "Canale rilascio" #. module: stock_release_channel_shipment_advice_toursolver #: model:ir.model,name:stock_release_channel_shipment_advice_toursolver.model_shipment_advice msgid "Shipment Advice" -msgstr "" +msgstr "Avviso spedizione" #. module: stock_release_channel_shipment_advice_toursolver #: model:ir.model,name:stock_release_channel_shipment_advice_toursolver.model_shipment_advice_planner From 523a80c57368b4625f2353613a1597734e39c1ec Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Wed, 4 Jan 2023 20:28:14 +0100 Subject: [PATCH 193/357] [14.0][IMP] stock_release_channel only call assign_release_channel on released moves --- stock_available_to_promise_release/models/stock_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_available_to_promise_release/models/stock_move.py b/stock_available_to_promise_release/models/stock_move.py index 86c816f3764..a437b94c54e 100644 --- a/stock_available_to_promise_release/models/stock_move.py +++ b/stock_available_to_promise_release/models/stock_move.py @@ -507,7 +507,7 @@ def _promise_reservation_horizon_date(self): return None def release_available_to_promise(self): - self._run_stock_rule() + return self._run_stock_rule() def _prepare_move_split_vals(self, qty): vals = super()._prepare_move_split_vals(qty) From ae98eae52dfbc79bf19ae512aec7b287df94e627 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Fri, 1 Sep 2023 19:30:52 +0200 Subject: [PATCH 194/357] [FIX] stock_dynamic_routing: merge moves Merge reclassified moves after release --- stock_available_to_promise_release/models/stock_move.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/stock_available_to_promise_release/models/stock_move.py b/stock_available_to_promise_release/models/stock_move.py index a437b94c54e..a30ecb3dc5f 100644 --- a/stock_available_to_promise_release/models/stock_move.py +++ b/stock_available_to_promise_release/models/stock_move.py @@ -586,10 +586,10 @@ def _run_stock_rule(self): ) self.env["procurement.group"].run_defer(procurement_requests) - released_moves._after_release_assign_moves() - released_moves._after_release_update_chain() + assigned_moves = released_moves._after_release_assign_moves() + assigned_moves._after_release_update_chain() - return released_moves + return assigned_moves def _before_release(self): """Hook that aims to be overridden.""" @@ -639,6 +639,7 @@ def _after_release_assign_moves(self): ).ids moves = self.browse(move_ids) moves._action_assign() + return moves def _release_split(self, remaining_qty): """Split move and put remaining_qty to a backorder move.""" From 9239f0d7e6004adff1321e556ed399a2e815603a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 1 Jul 2025 17:00:48 +0000 Subject: [PATCH 195/357] [BOT] post-merge updates --- README.md | 2 +- stock_available_to_promise_release/README.rst | 2 +- stock_available_to_promise_release/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 48bc9d01955..1dbd5acf0e6 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ addon | version | maintainers | summary [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation -[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.7.3 | | Release Operations based on available to promise +[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.8.0 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves diff --git a/stock_available_to_promise_release/README.rst b/stock_available_to_promise_release/README.rst index e69829610ba..a5af5b38be8 100644 --- a/stock_available_to_promise_release/README.rst +++ b/stock_available_to_promise_release/README.rst @@ -11,7 +11,7 @@ Stock Available to Promise Release !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:cf3d12ff9a56d62425852901d05ccff8ba45ffd62c920ac68822d03f94499c32 + !! source digest: sha256:78961ce607369a9406a3dff89ac11c679878e2fd7676bbefbf773aef26bbd8a0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_available_to_promise_release/__manifest__.py b/stock_available_to_promise_release/__manifest__.py index d6506ee75f7..18534ebebb7 100644 --- a/stock_available_to_promise_release/__manifest__.py +++ b/stock_available_to_promise_release/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Available to Promise Release", - "version": "16.0.3.7.3", + "version": "16.0.3.8.0", "summary": "Release Operations based on available to promise", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_available_to_promise_release/static/description/index.html b/stock_available_to_promise_release/static/description/index.html index 904a0985ae3..383978d8df2 100644 --- a/stock_available_to_promise_release/static/description/index.html +++ b/stock_available_to_promise_release/static/description/index.html @@ -372,7 +372,7 @@

Stock Available to Promise Release

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:cf3d12ff9a56d62425852901d05ccff8ba45ffd62c920ac68822d03f94499c32 +!! source digest: sha256:78961ce607369a9406a3dff89ac11c679878e2fd7676bbefbf773aef26bbd8a0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Currently the reservation is performed by adding reserved quantities on quants, From 0fc661108988b4f8e95025dc21678f37e3c3ed9d Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 13 Jan 2025 17:05:09 +0100 Subject: [PATCH 196/357] [IMP] shopfloor: Add a barcode parser to support multi representation As a some barcodes can represent more than one kind of record, add a helper to parse and return values. --- shopfloor/actions/__init__.py | 1 + shopfloor/actions/barcode_parser.py | 44 +++++++++++++++++++++++++++++ shopfloor/actions/search.py | 5 ++++ 3 files changed, 50 insertions(+) create mode 100644 shopfloor/actions/barcode_parser.py diff --git a/shopfloor/actions/__init__.py b/shopfloor/actions/__init__.py index 5fecbe84ced..7d705fca756 100644 --- a/shopfloor/actions/__init__.py +++ b/shopfloor/actions/__init__.py @@ -1,3 +1,4 @@ +from . import barcode_parser from . import change_package_lot from . import data from . import data_detail diff --git a/shopfloor/actions/barcode_parser.py b/shopfloor/actions/barcode_parser.py new file mode 100644 index 00000000000..1bff75949ce --- /dev/null +++ b/shopfloor/actions/barcode_parser.py @@ -0,0 +1,44 @@ +# Copyright 2025 ACSONE SA/NV (https://www.acsone.eu) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo.addons.component.core import Component + +from ..actions.search import SearchAction + + +class BarcodeResult: + + __slots__ = ("type", "value", "raw") + + def __init__(self, **kw) -> None: + for k in self.__slots__: + setattr(self, k, kw.get(k)) + + +class BarcodeParser(Component): + """ + Some barcodes can have complex data structure + """ + + _name = "shopfloor.barcode.parser" + _inherit = "shopfloor.process.action" + _usage = "barcode" + + def __init__(self, search_action: SearchAction): + # Get search action keys + self.search_action = search_action + + @property + def _authorized_barcode_types(self): + return self.search_action._barcode_type_handler.keys() + + def parse(self, barcode) -> list[BarcodeResult]: + """ + This method will parse the barcode and return the + value with its type if determined. + + Override this to implement specific parsing + + """ + + return [BarcodeResult(type="unknown", value=barcode, raw=barcode)] diff --git a/shopfloor/actions/search.py b/shopfloor/actions/search.py index acbf3b112c7..1c6b106770f 100644 --- a/shopfloor/actions/search.py +++ b/shopfloor/actions/search.py @@ -57,6 +57,8 @@ def _barcode_type_handler(self): "packaging": self.packaging_from_scan, "delivery_packaging": self.delivery_packaging_from_scan, "origin_move": self.origin_move_from_scan, + # Extra data can be contained in barcodes + "expiration_date": self.dummy_from_scan, } def _make_search_result(self, **kwargs): @@ -188,3 +190,6 @@ def origin_move_from_scan(self, barcode, extra_domain=None): if extra_domain: outgoing_move_domain = AND([outgoing_move_domain, extra_domain]) return model.search(outgoing_move_domain) + + def dummy_from_scan(self, barcode): + return None From 43ce375e28fcdcf881cab825f5dfbaad760df0f1 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Thu, 3 Apr 2025 12:11:32 +0200 Subject: [PATCH 197/357] [IMP] shopfloor: Add parser to search action --- shopfloor/actions/barcode_parser.py | 2 +- shopfloor/actions/search.py | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/shopfloor/actions/barcode_parser.py b/shopfloor/actions/barcode_parser.py index 1bff75949ce..349f23b996a 100644 --- a/shopfloor/actions/barcode_parser.py +++ b/shopfloor/actions/barcode_parser.py @@ -32,7 +32,7 @@ def __init__(self, search_action: SearchAction): def _authorized_barcode_types(self): return self.search_action._barcode_type_handler.keys() - def parse(self, barcode) -> list[BarcodeResult]: + def parse(self, barcode, types) -> list[BarcodeResult]: """ This method will parse the barcode and return the value with its type if determined. diff --git a/shopfloor/actions/search.py b/shopfloor/actions/search.py index 1c6b106770f..acd559ebdc6 100644 --- a/shopfloor/actions/search.py +++ b/shopfloor/actions/search.py @@ -8,7 +8,8 @@ class SearchResult: - __slots__ = ("record", "type", "code") + + __slots__ = ("record", "type", "code", "parse_result") def __init__(self, **kw) -> None: for k in self.__slots__: @@ -44,6 +45,12 @@ class SearchAction(Component): _inherit = "shopfloor.search.action" + @property + def parser(self): + parser = self._actions_for("barcode") + parser.search_action = self + return parser + @property def _barcode_type_handler(self): return { @@ -87,11 +94,20 @@ def _find_record_by_type(self, barcode, btype, handler_kw=None): def generic_find(self, barcode, types=None, handler_kw=None): _types = types or self._barcode_type_handler.keys() # TODO: decide the best default order in case we don't pass `types` - for btype in _types: - record = self._find_record_by_type(barcode, btype, handler_kw) - if record: - return self._make_search_result(record=record, code=barcode, type=btype) - return self._make_search_result(type="none") + parse_results = self.parser.parse(barcode, types) + for parse_result in parse_results: + for btype in _types: + record = self._find_record_by_type( + parse_result.value, btype, handler_kw + ) + if record: + return self._make_search_result( + record=record, + code=barcode, + type=btype, + parse_result=parse_results, + ) + return self._make_search_result(type="none", parse_result=parse_results) def location_from_scan(self, barcode, limit=1): model = self.env["stock.location"] From 426acd92eebd3d52eef15f4f77ba610616cad7b8 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 2 Jul 2025 12:56:10 +0200 Subject: [PATCH 198/357] [IMP] shopfloor: Add dummy barcode handler for expiration dates --- shopfloor/actions/search.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shopfloor/actions/search.py b/shopfloor/actions/search.py index acd559ebdc6..ff6e4350b98 100644 --- a/shopfloor/actions/search.py +++ b/shopfloor/actions/search.py @@ -65,7 +65,7 @@ def _barcode_type_handler(self): "delivery_packaging": self.delivery_packaging_from_scan, "origin_move": self.origin_move_from_scan, # Extra data can be contained in barcodes - "expiration_date": self.dummy_from_scan, + "expiration_date": self.expiration_date_from_scan, } def _make_search_result(self, **kwargs): @@ -209,3 +209,7 @@ def origin_move_from_scan(self, barcode, extra_domain=None): def dummy_from_scan(self, barcode): return None + + def expiration_date_from_scan(self, barcode): + # TODO + return None From 810c755770932e4ff0dcf6b2c266e5887eb2beec Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Fri, 27 Jun 2025 08:37:09 +0200 Subject: [PATCH 199/357] [IMP] shopfloor_reception: Take into account warehouse timezone for today pickings --- shopfloor_reception/__init__.py | 2 +- shopfloor_reception/services/reception.py | 14 +++++++----- .../tests/test_select_document.py | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/shopfloor_reception/__init__.py b/shopfloor_reception/__init__.py index ae16eb245f6..b447b57f1b2 100644 --- a/shopfloor_reception/__init__.py +++ b/shopfloor_reception/__init__.py @@ -1,2 +1,2 @@ -from . import services +from . import services, models from .hooks import post_init_hook, uninstall_hook diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 51fcf2e1a9e..97cf8672b8d 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -77,8 +77,14 @@ def _scheduled_date_today_domain(self): return domain def _get_today_start_end_datetime(self, naive=True): + # TODO: Put warehouse tz retrieval in shopfloor module? company = self.env.company - tz = company.partner_id.tz or "UTC" + warehouse = self.picking_types.warehouse_id + tz = ( + warehouse.partner_id.tz + if (len(warehouse) == 1 and warehouse.partner_id.tz) + else company.partner_id.tz or "UTC" + ) today = fields.Datetime.today() today_start = today_start_localized = fields.Datetime.start_of(today, "day") today_end = today_end_localized = fields.Datetime.end_of(today, "day") @@ -344,11 +350,9 @@ def _scan_document__by_picking(self, pickings, barcode): # could return more than one picking. # If there's only one picking due today, we go to the next screen. # Otherwise, we ask the user to scan a package instead. - today_start, today_end = self._get_today_start_end_datetime(naive=False) + today_start, today_end = self._get_today_start_end_datetime() picking_filter_result_due_today = picking_filter_result.filtered( - lambda p: today_start - <= p.scheduled_date.astimezone(pytz.utc) - < today_end + lambda p: today_start <= p.scheduled_date < today_end ) if len(picking_filter_result_due_today) == 1: return self._select_picking(picking_filter_result_due_today) diff --git a/shopfloor_reception/tests/test_select_document.py b/shopfloor_reception/tests/test_select_document.py index 8ab5386a0bb..83c93267227 100644 --- a/shopfloor_reception/tests/test_select_document.py +++ b/shopfloor_reception/tests/test_select_document.py @@ -9,6 +9,7 @@ _TODAY = "2022-12-07" _TOMORROW = "2022-12-08" +_TODAY_ELEVEN = "2022-12-07 23:30:00" class TestSelectDocument(CommonCase): @@ -81,6 +82,27 @@ def test_scan_picking_origin_multiple_pickings_one_today(self): data=self._data_for_select_move(picking_today), ) + @freeze_time(_TODAY_ELEVEN, tz_offset=0) + def test_scan_picking_origin_multiple_pickings_one_today_tz(self): + # freezed today is UTC time, set warehouse user to Brussels + self.wh.partner_id.sudo().tz = "Europe/Brussels" + + # Create a picking with the UTC hour + picking_today = self._create_picking(scheduled_date=_TODAY_ELEVEN) + + picking_tomorrow = self._create_picking(scheduled_date=_TOMORROW) + pickings = picking_today | picking_tomorrow + pickings = pickings.sorted(lambda p: (p.scheduled_date, p.id), reverse=False) + pickings.write({"origin": "Somewhere together"}) + response = self.service.dispatch( + "scan_document", params={"barcode": "Somewhere together"} + ) + self.assert_response( + response, + next_state="select_move", + data=self._data_for_select_move(picking_today), + ) + def test_scan_picking_origin_one_picking(self): # Only 1 picking with this origin is found. # Move to select_move. From 90a9ceb77ed26319d1755fa8db087dae532e52e9 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 2 Jul 2025 12:01:18 +0000 Subject: [PATCH 200/357] [UPD] Update shopfloor_reception.pot --- .../i18n/shopfloor_reception.pot | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/shopfloor_reception/i18n/shopfloor_reception.pot b/shopfloor_reception/i18n/shopfloor_reception.pot index 199e51dbea8..eea68040e3c 100644 --- a/shopfloor_reception/i18n/shopfloor_reception.pot +++ b/shopfloor_reception/i18n/shopfloor_reception.pot @@ -13,6 +13,36 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: shopfloor_reception +#: model:ir.model.fields,help:shopfloor_reception.field_shopfloor_menu__filter_today_scheduled_pickings +msgid "" +"\n" +"By default, at first step, filter the available\n" +"pickings with the ones that are scheduled for today.\n" +msgstr "" + +#. module: shopfloor_reception +#. odoo-python +#: code:addons/shopfloor_reception/models/shopfloor_menu.py:0 +#, python-format +msgid "Filter Today Pickings is not allowed for menu {}." +msgstr "" + +#. module: shopfloor_reception +#: model:ir.model.fields,field_description:shopfloor_reception.field_shopfloor_menu__filter_today_scheduled_pickings +msgid "Filter Today Scheduled Pickings" +msgstr "" + +#. module: shopfloor_reception +#: model:ir.model.fields,field_description:shopfloor_reception.field_shopfloor_menu__filter_today_scheduled_pickings_is_possible +msgid "Filter Today Scheduled Pickings Is Possible" +msgstr "" + +#. module: shopfloor_reception +#: model:ir.model,name:shopfloor_reception.model_shopfloor_menu +msgid "Menu displayed in the scanner application" +msgstr "" + #. module: shopfloor_reception #: model:shopfloor.menu,name:shopfloor_reception.shopfloor_menu_demo_reception #: model:shopfloor.scenario,name:shopfloor_reception.scenario_reception From 5e9c264255e5a5938d22898f1f5566c8a7be9645 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 2 Jul 2025 12:13:24 +0000 Subject: [PATCH 201/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 8 ++++-- .../static/description/index.html | 28 +++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1dbd5acf0e6..e1ad2d1e706 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.2.1 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.3.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 7bf259e09a8..4457621163d 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =================== Shopfloor Reception =================== @@ -7,13 +11,13 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:424c4104c1b11985aefef164d85bbc13e6b4b7c761a34ce3a07ccc335e130534 + !! source digest: sha256:087bb6f09231a4d2a723f612b196536aead10654371f9ce81a61a63ceef07ff1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index cedaaf528b2..b44c68a9050 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -3,7 +3,7 @@ -Shopfloor Reception +README.rst -

-

Shopfloor Reception

+
+ + +Odoo Community Association + +
+

Shopfloor Reception

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor implementation of the reception scenario. Allows to receive products and create the proper packs for each logistic unit.

Table of contents

@@ -386,11 +391,11 @@

Shopfloor Reception

-

Known issues / Roadmap

+

Known issues / Roadmap

Implement methods in the backend to cancel lines (to be used by the frontend in select_line & set_quantity).

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -398,15 +403,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -431,5 +436,6 @@

Maintainers

+
From 495ab2a1d662ced55bd451735737874098763dd7 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 2 Jul 2025 12:13:33 +0000 Subject: [PATCH 202/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-shopfloor_reception Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_reception/ --- shopfloor_reception/i18n/it.po | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/shopfloor_reception/i18n/it.po b/shopfloor_reception/i18n/it.po index 8b496488b7c..ade78723449 100644 --- a/shopfloor_reception/i18n/it.po +++ b/shopfloor_reception/i18n/it.po @@ -16,6 +16,36 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.17\n" +#. module: shopfloor_reception +#: model:ir.model.fields,help:shopfloor_reception.field_shopfloor_menu__filter_today_scheduled_pickings +msgid "" +"\n" +"By default, at first step, filter the available\n" +"pickings with the ones that are scheduled for today.\n" +msgstr "" + +#. module: shopfloor_reception +#. odoo-python +#: code:addons/shopfloor_reception/models/shopfloor_menu.py:0 +#, python-format +msgid "Filter Today Pickings is not allowed for menu {}." +msgstr "" + +#. module: shopfloor_reception +#: model:ir.model.fields,field_description:shopfloor_reception.field_shopfloor_menu__filter_today_scheduled_pickings +msgid "Filter Today Scheduled Pickings" +msgstr "" + +#. module: shopfloor_reception +#: model:ir.model.fields,field_description:shopfloor_reception.field_shopfloor_menu__filter_today_scheduled_pickings_is_possible +msgid "Filter Today Scheduled Pickings Is Possible" +msgstr "" + +#. module: shopfloor_reception +#: model:ir.model,name:shopfloor_reception.model_shopfloor_menu +msgid "Menu displayed in the scanner application" +msgstr "" + #. module: shopfloor_reception #: model:shopfloor.menu,name:shopfloor_reception.shopfloor_menu_demo_reception #: model:shopfloor.scenario,name:shopfloor_reception.scenario_reception From 2c296e4c67055e752c998a43ae669d74d119c2ba Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 2 Jul 2025 15:00:09 +0000 Subject: [PATCH 203/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e1ad2d1e706..bcf53d7a35d 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.10.1 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.11.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index f305b90ca59..27b0681a2e0 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3b3e7f94a81872e7868a889ce80740558ad70732df2821188971ff06a639e995 + !! source digest: sha256:45e38752c97272a2846012a4dfd2597a7df126607d2ec7e5ff0489e3477b63a5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 011d46e0f42..f4581e22268 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.10.1", + "version": "16.0.2.11.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index e417f6b5ae8..72c95b71250 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:3b3e7f94a81872e7868a889ce80740558ad70732df2821188971ff06a639e995 +!! source digest: sha256:45e38752c97272a2846012a4dfd2597a7df126607d2ec7e5ff0489e3477b63a5 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

From b9d50c844ed1e9ea0f1dcc13848f4eefe4f8f2ed Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Thu, 3 Jul 2025 08:34:25 +0200 Subject: [PATCH 204/357] [IMP] shopfloor_reception_mobile: Add also product info action on current line --- .../static/src/scenario/reception.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shopfloor_reception_mobile/static/src/scenario/reception.js b/shopfloor_reception_mobile/static/src/scenario/reception.js index 6a743658734..dcf4dd86a4c 100644 --- a/shopfloor_reception_mobile/static/src/scenario/reception.js +++ b/shopfloor_reception_mobile/static/src/scenario/reception.js @@ -302,6 +302,13 @@ const Reception = { picking_detail_options_for_set_lot: function () { return { key_title: "product.display_name", + title_action_field: { + action_val_path: function (record, field) { + return record.product.barcode + ? "product.barcode" + : "product.default_code"; + }, + }, fields: [ { path: "product.supplier_code", From a708c483dd31fb5ed735e2926d83b6bb2659357f Mon Sep 17 00:00:00 2001 From: Thierry Ducrest Date: Tue, 19 Mar 2024 16:48:41 +0100 Subject: [PATCH 205/357] s_a_promise_release: Reset last_release_date on unrelease When a transfer has been unreleased the `last_release_date` is not reset. This breaks the counters and the list of records (To Release, To Do) on the related channel. --- stock_available_to_promise_release/models/stock_move.py | 1 + stock_available_to_promise_release/tests/test_unrelease.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/stock_available_to_promise_release/models/stock_move.py b/stock_available_to_promise_release/models/stock_move.py index a30ecb3dc5f..8daae2adc70 100644 --- a/stock_available_to_promise_release/models/stock_move.py +++ b/stock_available_to_promise_release/models/stock_move.py @@ -872,6 +872,7 @@ def unrelease(self, safe_unrelease=False): move_names=move_names, ) picking.message_post(body=body) + picking.last_release_date = False def _split_origins(self, origins, qty=None): """Split the origins of the move according to the quantity into the diff --git a/stock_available_to_promise_release/tests/test_unrelease.py b/stock_available_to_promise_release/tests/test_unrelease.py index 2909d9288dd..e1634878889 100644 --- a/stock_available_to_promise_release/tests/test_unrelease.py +++ b/stock_available_to_promise_release/tests/test_unrelease.py @@ -55,13 +55,14 @@ def _assert_full_unreleased(self): ) self.assertEqual(self.picking.move_ids.state, "cancel") self.assertEqual(self.picking.state, "cancel") + self.assertFalse(self.picking.last_release_date) def test_unrelease_full(self): """Unrelease all moves of a released ship. The pick should be deleted and the moves should be mark as to release""" with self._assert_full_unreleased(): self.shipping.move_ids.unrelease() - + self.assertFalse(self.shipping.last_release_date) # I can release again the move and a new pick is created self.shipping.release_available_to_promise() new_picking = self._prev_picking(self.shipping) - self.picking From fdd5905f8da59d2bec1aefaadec5dfae24394a21 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Thu, 12 Jun 2025 17:44:50 +0200 Subject: [PATCH 206/357] [IMP] stock_available_to_promise_release: Fix unittest ensure move is not getting merged --- .../tests/test_unrelease_cancel.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/stock_available_to_promise_release/tests/test_unrelease_cancel.py b/stock_available_to_promise_release/tests/test_unrelease_cancel.py index fed784ff931..337c0b91f69 100644 --- a/stock_available_to_promise_release/tests/test_unrelease_cancel.py +++ b/stock_available_to_promise_release/tests/test_unrelease_cancel.py @@ -1,5 +1,6 @@ # Copyright 2025 Camptocamp SA # Copyright 2025 Raumschmiede GmbH +# Copyright 2025 Michael Tietz (MT Software) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from datetime import datetime @@ -155,7 +156,11 @@ def test_unrelease_multiple_moves_same_product(self): ship_picking = self._out_picking(picking_chain) ship_picking.release_available_to_promise() # Creating a second move. Both moves thave the same origin (pack.move_line) - self.env["stock.move"].create(ship_picking.move_ids._split(4)) + split_move_vals = ship_picking.move_ids._split(4) + split_move_vals[0]["date_deadline"] = datetime.now() + split_move = self.env["stock.move"].create(split_move_vals) + split_move._action_confirm() + split_move._action_assign() pack_picking = self._prev_picking(ship_picking) pick_picking = self._prev_picking(pack_picking) self._deliver(pick_picking) From d7ffe88928d41912d13e13acc4e330f8d3f02c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Thu, 3 Jul 2025 10:15:31 +0200 Subject: [PATCH 207/357] oca-port: blacklist PR(s) 556, 604, 686, 810, 1015 for stock_available_to_promise_release --- .../blacklist/stock_available_to_promise_release.json | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .oca/oca-port/blacklist/stock_available_to_promise_release.json diff --git a/.oca/oca-port/blacklist/stock_available_to_promise_release.json b/.oca/oca-port/blacklist/stock_available_to_promise_release.json new file mode 100644 index 00000000000..842603423a1 --- /dev/null +++ b/.oca/oca-port/blacklist/stock_available_to_promise_release.json @@ -0,0 +1,9 @@ +{ + "pull_requests": { + "OCA/wms#556": "Already ported", + "OCA/wms#604": "v14 migration update, not relevant", + "OCA/wms#686": "Already ported", + "OCA/wms#810": "Already ported + not relevant", + "OCA/wms#1015": "14.0 backport from 16.0 (already there, false positive)" + } +} From 3f7916bca4274d6063bc4dfc2263de39c8a64eae Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 3 Jul 2025 08:43:43 +0000 Subject: [PATCH 208/357] [UPD] Update stock_full_location_reservation.pot --- .../i18n/stock_full_location_reservation.pot | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 stock_full_location_reservation/i18n/stock_full_location_reservation.pot diff --git a/stock_full_location_reservation/i18n/stock_full_location_reservation.pot b/stock_full_location_reservation/i18n/stock_full_location_reservation.pot new file mode 100644 index 00000000000..8de34cfc990 --- /dev/null +++ b/stock_full_location_reservation/i18n/stock_full_location_reservation.pot @@ -0,0 +1,85 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_full_location_reservation +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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_full_location_reservation +#: model_terms:ir.ui.view,arch_db:stock_full_location_reservation.stock_picking_form_view +msgid "Do Full location reservation" +msgstr "" + +#. module: stock_full_location_reservation +#: model:res.groups,name:stock_full_location_reservation.group_user +msgid "Full location reservation" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_move__is_full_location_reservation +msgid "Full location reservation move" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking__has_full_location_reservations +msgid "Has full location reservations" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model.fields,help:stock_full_location_reservation.field_stock_picking__is_full_location_reservation_visible +#: model:ir.model.fields,help:stock_full_location_reservation.field_stock_picking_type__is_full_location_reservation_visible +msgid "If this is checked, the full reservation of a the picking is visible" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model.fields,help:stock_full_location_reservation.field_stock_picking_type__merge_move_for_full_location_reservation +msgid "" +"If this is checked, the full reservation of a the picking will be done\n" +" resulting of only one move (original one + full reservation one).\n" +" WARNING: If checked, it will be impossible to get the original move back.\n" +" " +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking__is_full_location_reservation_visible +#: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking_type__is_full_location_reservation_visible +msgid "Is full location reservation visible" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking_type__merge_move_for_full_location_reservation +msgid "Merge Move For Full Location Reservation" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model,name:stock_full_location_reservation.model_stock_picking_type +msgid "Picking Type" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model,name:stock_full_location_reservation.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model,name:stock_full_location_reservation.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: stock_full_location_reservation +#: model:ir.model,name:stock_full_location_reservation.model_stock_picking +msgid "Transfer" +msgstr "" + +#. module: stock_full_location_reservation +#: model_terms:ir.ui.view,arch_db:stock_full_location_reservation.stock_picking_form_view +msgid "Undo Full location reservation" +msgstr "" From 36d202c91cfc7d887aed09bed0fb663363624676 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 3 Jul 2025 08:55:09 +0000 Subject: [PATCH 209/357] [BOT] post-merge updates --- README.md | 1 + setup/_metapackage/VERSION.txt | 2 +- setup/_metapackage/setup.py | 1 + .../static/description/icon.png | Bin 0 -> 10254 bytes 4 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 stock_full_location_reservation/static/description/icon.png diff --git a/README.md b/README.md index bcf53d7a35d..89495d04227 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ addon | version | maintainers | summary [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves +[stock_full_location_reservation](stock_full_location_reservation/) | 16.0.1.0.0 | mt-software-de | Extend reservation to full content of location [stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.1.0.0 | lmignon | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type diff --git a/setup/_metapackage/VERSION.txt b/setup/_metapackage/VERSION.txt index 9ef7d8bf9cd..a6845d0bc1a 100644 --- a/setup/_metapackage/VERSION.txt +++ b/setup/_metapackage/VERSION.txt @@ -1 +1 @@ -16.0.20250624.0 \ No newline at end of file +16.0.20250703.0 \ No newline at end of file diff --git a/setup/_metapackage/setup.py b/setup/_metapackage/setup.py index c6c7142b576..a1864705630 100644 --- a/setup/_metapackage/setup.py +++ b/setup/_metapackage/setup.py @@ -32,6 +32,7 @@ 'odoo-addon-stock_available_to_promise_release_block>=16.0dev,<16.1dev', 'odoo-addon-stock_available_to_promise_release_exclude_location>=16.0dev,<16.1dev', 'odoo-addon-stock_dynamic_routing>=16.0dev,<16.1dev', + 'odoo-addon-stock_full_location_reservation>=16.0dev,<16.1dev', 'odoo-addon-stock_picking_batch_creation>=16.0dev,<16.1dev', 'odoo-addon-stock_picking_completion_info>=16.0dev,<16.1dev', 'odoo-addon-stock_picking_type_shipping_policy>=16.0dev,<16.1dev', diff --git a/stock_full_location_reservation/static/description/icon.png b/stock_full_location_reservation/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Date: Thu, 3 Jul 2025 15:30:20 +0530 Subject: [PATCH 210/357] [FIX] sale_stock_release_channel_delivery_date: Solved singletone error while shipping address not exist for domain. --- sale_stock_release_channel_delivery_date/models/sale_order.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sale_stock_release_channel_delivery_date/models/sale_order.py b/sale_stock_release_channel_delivery_date/models/sale_order.py index 271609dce44..e75498e5712 100644 --- a/sale_stock_release_channel_delivery_date/models/sale_order.py +++ b/sale_stock_release_channel_delivery_date/models/sale_order.py @@ -75,6 +75,8 @@ def _get_partner_release_channels(self, carrier): domain_order = self._release_channel_possible_candidate_domain_base domain_partner = ( self.partner_shipping_id._release_channel_possible_candidate_domain + if self.partner_shipping_id + else [] ) domain_channel = [("is_manual_assignment", "=", False)] domain = expression.AND([domain_order, domain_partner, domain_channel]) From 5c31cec7ea53eb97560202976f4795351c30a4b8 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 3 Jul 2025 10:06:15 +0000 Subject: [PATCH 211/357] [BOT] post-merge updates --- README.md | 2 +- stock_available_to_promise_release/README.rst | 2 +- stock_available_to_promise_release/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 89495d04227..58b856c6b76 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ addon | version | maintainers | summary [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation -[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.8.0 | | Release Operations based on available to promise +[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.8.1 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves diff --git a/stock_available_to_promise_release/README.rst b/stock_available_to_promise_release/README.rst index a5af5b38be8..a0291c53d2b 100644 --- a/stock_available_to_promise_release/README.rst +++ b/stock_available_to_promise_release/README.rst @@ -11,7 +11,7 @@ Stock Available to Promise Release !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:78961ce607369a9406a3dff89ac11c679878e2fd7676bbefbf773aef26bbd8a0 + !! source digest: sha256:b2609ab06e8b3bda3f86543ba4a4fc871ac9b39fb86bcb5ab8008505cf0fd972 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_available_to_promise_release/__manifest__.py b/stock_available_to_promise_release/__manifest__.py index 18534ebebb7..f1e561f8b6d 100644 --- a/stock_available_to_promise_release/__manifest__.py +++ b/stock_available_to_promise_release/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Available to Promise Release", - "version": "16.0.3.8.0", + "version": "16.0.3.8.1", "summary": "Release Operations based on available to promise", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_available_to_promise_release/static/description/index.html b/stock_available_to_promise_release/static/description/index.html index 383978d8df2..6f06eb5bf17 100644 --- a/stock_available_to_promise_release/static/description/index.html +++ b/stock_available_to_promise_release/static/description/index.html @@ -372,7 +372,7 @@

Stock Available to Promise Release

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:78961ce607369a9406a3dff89ac11c679878e2fd7676bbefbf773aef26bbd8a0 +!! source digest: sha256:b2609ab06e8b3bda3f86543ba4a4fc871ac9b39fb86bcb5ab8008505cf0fd972 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Currently the reservation is performed by adding reserved quantities on quants, From 3bbbac944c41ed393a03d34a4b088769e8c0c618 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Thu, 17 Aug 2023 09:50:36 +0200 Subject: [PATCH 212/357] stock_dynamic_routing: add test Add test for the rerouting of waiting moves in a pull flow --- .../tests/test_routing_pull.py | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/stock_dynamic_routing/tests/test_routing_pull.py b/stock_dynamic_routing/tests/test_routing_pull.py index fc76a6d8d7b..4f9bcbe95f6 100644 --- a/stock_dynamic_routing/tests/test_routing_pull.py +++ b/stock_dynamic_routing/tests/test_routing_pull.py @@ -1053,3 +1053,54 @@ def test_mix_routing_reservation_same_location(self): {"location_id": self.location_hb_1_2.id, "reserved_uom_qty": 7}, ], ) + + def test_route_waiting_moves(self): + """Routing of waiting moves. + + When the initial move is rerouted, the waiting moves in the chain + are also rerouted in cascade even if the destination location of the + initial move is not changed. + """ + # make a routing that does not change locations + self.pick_type_routing_op.write( + { + "default_location_src_id": self.wh.pick_type_id.default_location_src_id, + "default_location_dest_id": self.wh.pick_type_id.default_location_dest_id, + } + ) + self.routing.location_id = ( + self.pick_type_routing_op.default_location_src_id.id, + ) + out_type_routing = self.wh.out_type_id.copy( + {"name": "OUTP Routing", "sequence_code": "WH/OUTP"} + ) + self.env["stock.routing"].create( + { + "location_id": out_type_routing.default_location_src_id.id, + "picking_type_id": self.wh.out_type_id.id, + "rule_ids": [ + (0, 0, {"method": "pull", "picking_type_id": out_type_routing.id}) + ], + } + ) + pick_picking, customer_picking = self._create_pick_ship( + self.wh, [(self.product1, 10)] + ) + self._update_product_qty_in_location(self.location_shelf_1, self.product1, 20.0) + pick_picking.action_assign() + new_cust_picking = self.env["stock.picking"].search( + [("picking_type_id", "=", out_type_routing.id)] + ) + + self.assertEqual(len(new_cust_picking), 1) + self.assertRecordValues( + new_cust_picking, + [ + { + "state": "waiting", + "location_id": self.wh.wh_output_stock_loc_id.id, + "location_dest_id": self.customer_loc.id, + "picking_type_id": out_type_routing.id, + } + ], + ) From b346a4e2437fcc5710a16d51da0e5807af62adcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Wed, 20 Dec 2023 18:41:58 +0100 Subject: [PATCH 213/357] [FIX] stock_dynamic_routing: routing moves has to be MTO This is causing trouble by merging back moves in the `stock_available_to_promise_release_dynamic_routing` glue module which were split on purpose by the dynamic routing rules. --- stock_dynamic_routing/models/stock_move.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stock_dynamic_routing/models/stock_move.py b/stock_dynamic_routing/models/stock_move.py index e6f91731c5c..0afb987006e 100644 --- a/stock_dynamic_routing/models/stock_move.py +++ b/stock_dynamic_routing/models/stock_move.py @@ -518,4 +518,6 @@ def _prepare_routing_move_values(self, picking_type, source, destination): # https://github.com/odoo/odoo/commit/ecf726ae # to be on the safe side, force it to False "package_level_id": False, + # A routing move is always in MTO + "procure_method": "make_to_order", } From 4fd7dc78a738f34c0025b9d39037d4a27fce5745 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 3 Jul 2025 11:41:29 +0000 Subject: [PATCH 214/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 8 ++++-- .../__manifest__.py | 2 +- .../static/description/index.html | 26 ++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 58b856c6b76..8b3499b7a49 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ addon | version | maintainers | summary [sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block release of deliveries from sales orders. [sale_stock_release_channel](sale_stock_release_channel/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel [sale_stock_release_channel_delivery](sale_stock_release_channel_delivery/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel Delivery -[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.0 | jbaudoux | Compute expected date based on available release channels +[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.1 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. [shopfloor](shopfloor/) | 16.0.2.11.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners diff --git a/sale_stock_release_channel_delivery_date/README.rst b/sale_stock_release_channel_delivery_date/README.rst index e082b25a80d..b9c25e4abdf 100644 --- a/sale_stock_release_channel_delivery_date/README.rst +++ b/sale_stock_release_channel_delivery_date/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ======================================== Sale Stock Release Channel Delivery Date ======================================== @@ -7,13 +11,13 @@ Sale Stock Release Channel Delivery Date !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:25ade9facd700085d5a846f91dba83b941e48f66a3caa8355679480daf6275d8 + !! source digest: sha256:27ccecbfeea1adbc17e433cedf809b7791a58163044af8edf72d58c2c6a25662 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/sale_stock_release_channel_delivery_date/__manifest__.py b/sale_stock_release_channel_delivery_date/__manifest__.py index 9078c3f286c..e01e797aae1 100644 --- a/sale_stock_release_channel_delivery_date/__manifest__.py +++ b/sale_stock_release_channel_delivery_date/__manifest__.py @@ -5,7 +5,7 @@ "name": "Sale Stock Release Channel Delivery Date", "summary": """ Compute expected date based on available release channels """, - "version": "16.0.1.1.0", + "version": "16.0.1.1.1", "license": "AGPL-3", "author": "BCIM,Camptocamp,Odoo Community Association (OCA)", "maintainers": ["jbaudoux"], diff --git a/sale_stock_release_channel_delivery_date/static/description/index.html b/sale_stock_release_channel_delivery_date/static/description/index.html index f1e78abda4e..f03f0873fa4 100644 --- a/sale_stock_release_channel_delivery_date/static/description/index.html +++ b/sale_stock_release_channel_delivery_date/static/description/index.html @@ -3,7 +3,7 @@ -Sale Stock Release Channel Delivery Date +README.rst -

-

Sale Stock Release Channel Delivery Date

+
+ + +Odoo Community Association + +
+

Sale Stock Release Channel Delivery Date

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Provide the SO expected date according to possible channels respecting SO warehouse, carrier and shipping partner.

Table of contents

@@ -385,7 +390,7 @@

Sale Stock Release Channel Delivery Date

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -393,23 +398,23 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • BCIM
  • Camptocamp
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -424,5 +429,6 @@

Maintainers

+
From 104c056dab7259264966e8a29b584997e04e097f Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Fri, 11 Sep 2020 12:05:04 +0200 Subject: [PATCH 215/357] Ensure compatibility between release and dynamic routing Add a module with tests to check a release of moves with dynamic routing correctly sets the "printed" flag on all the chain. When we release moves, we set the "printed" flag on the released transfers, so we do not include any new moves (like a "wave" of release). As the dynamic routing is applied when we assign the moves, new moves and transfers may be created after the "assign". We therefore have to set the printed flag after it. --- .../__init__.py | 0 .../__manifest__.py | 17 ++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 5 + .../tests/__init__.py | 1 + .../tests/test_release_dynamic_routing.py | 223 ++++++++++++++++++ 6 files changed, 247 insertions(+) create mode 100644 stock_available_to_promise_release_dynamic_routing/__init__.py create mode 100644 stock_available_to_promise_release_dynamic_routing/__manifest__.py create mode 100644 stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst create mode 100644 stock_available_to_promise_release_dynamic_routing/readme/DESCRIPTION.rst create mode 100644 stock_available_to_promise_release_dynamic_routing/tests/__init__.py create mode 100644 stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py diff --git a/stock_available_to_promise_release_dynamic_routing/__init__.py b/stock_available_to_promise_release_dynamic_routing/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/stock_available_to_promise_release_dynamic_routing/__manifest__.py b/stock_available_to_promise_release_dynamic_routing/__manifest__.py new file mode 100644 index 00000000000..5fe2bfc53ff --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2020 Camptocamp (https://www.camptocamp.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Available to Promise Release - Dynamic Routing", + "summary": "Glue between moves release and dynamic routing", + "author": "Camptocamp, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/wms", + "category": "Warehouse Management", + "version": "13.0.1.0.0", + "license": "AGPL-3", + "depends": ["stock_available_to_promise_release", "stock_dynamic_routing"], + "demo": [], + "data": [], + "auto_install": True, + "installable": True, + "development_status": "Alpha", +} diff --git a/stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst b/stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..48286263cd3 --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Guewen Baconnier diff --git a/stock_available_to_promise_release_dynamic_routing/readme/DESCRIPTION.rst b/stock_available_to_promise_release_dynamic_routing/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..4d1b651744f --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +Glue module between ``stock_available_to_promise_release`` and +``stock_dynamic_routing``. + +Currently, the module only contains tests to verify the compatibility +between these two modules, but compatibility code may be needed later. diff --git a/stock_available_to_promise_release_dynamic_routing/tests/__init__.py b/stock_available_to_promise_release_dynamic_routing/tests/__init__.py new file mode 100644 index 00000000000..e2abf0474a7 --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/tests/__init__.py @@ -0,0 +1 @@ +from . import test_release_dynamic_routing diff --git a/stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py b/stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py new file mode 100644 index 00000000000..ae52890aa8c --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py @@ -0,0 +1,223 @@ +# Copyright 2020 Camptocamp (https://www.camptocamp.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +""" +When we "release" moves, we set the "printed" flag on the transfers, +because after a release, we shouldn't have any new move merged in a +"wave" of release. + +The stock_available_to_promise_release module adds the flag on all +the transfer chain (pick, pack, ship, ...), but as transfers created +for dynamic routing are created later, we have to ensure that transfers +for these new moves have the flag. These tests check this. +""" + +from odoo.addons.stock_available_to_promise_release.tests.common import ( + PromiseReleaseCommonCase, +) + + +class TestAvailableToPromiseReleaseDynamicRouting(PromiseReleaseCommonCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.location_hb = cls.env["stock.location"].create( + {"name": "Highbay", "location_id": cls.wh.lot_stock_id.id} + ) + cls.location_hb_1 = cls.env["stock.location"].create( + {"name": "Highbay Shelf 1", "location_id": cls.location_hb.id} + ) + cls.location_handover = cls.env["stock.location"].create( + {"name": "Handover", "location_id": cls.wh.lot_stock_id.id} + ) + + def test_dynamic_routing_pull_printed(self): + """Pull Dynamic routing applied after release get "printed" flag""" + pick_type_routing_op = self.env["stock.picking.type"].create( + { + "name": "Dynamic Routing", + "code": "internal", + "sequence_code": "WH/HO", + "warehouse_id": self.wh.id, + "use_create_lots": False, + "use_existing_lots": True, + "default_location_src_id": self.location_hb.id, + "default_location_dest_id": self.location_handover.id, + } + ) + self.env["stock.routing"].create( + { + "location_id": self.location_hb.id, + "picking_type_id": self.wh.pick_type_id.id, + "rule_ids": [ + ( + 0, + 0, + {"method": "pull", "picking_type_id": pick_type_routing_op.id}, + ) + ], + } + ) + self.wh.delivery_route_id.write({"available_to_promise_defer_pull": True}) + + self._update_qty_in_location(self.location_hb_1, self.product1, 20.0) + self._update_qty_in_location(self.location_hb_1, self.product2, 10.0) + + pickings = self._create_picking_chain( + self.wh, [(self.product1, 20), (self.product2, 10)], + ) + self.assertEqual(len(pickings), 1, "expect only the last out->customer") + cust_picking = pickings + self.assertRecordValues( + cust_picking, + [ + { + "state": "waiting", + "location_id": self.wh.wh_output_stock_loc_id.id, + "location_dest_id": self.loc_customer.id, + } + ], + ) + cust_picking.release_available_to_promise() + + pick_moves = cust_picking.move_lines.move_orig_ids + self.assertEqual(len(pick_moves), 2) + # this picking is created by standard 2-step rules + pick_picking = pick_moves.picking_id + # this flag is set by stock_available_to_promise_release + self.assertTrue(pick_picking.printed) + + routing_moves = pick_moves.move_orig_ids + # if we put "printed" after we assign the 1st move only, the 2nd + # move will not be grouped in the same picking + self.assertEqual(len(routing_moves), 2) + routing_picking = routing_moves.picking_id + self.assertEqual(routing_picking.picking_type_id, pick_type_routing_op) + + self.assertTrue(routing_picking.printed) + + def test_dynamic_routing_change_picking_type_printed(self): + """Type Dynamic routing applied after release get "printed" flag""" + self.wh.delivery_route_id.write({"available_to_promise_defer_pull": True}) + + area1 = self.env["stock.location"].create( + {"location_id": self.wh.wh_output_stock_loc_id.id, "name": "Area1"} + ) + pick_loc = self.wh.pick_type_id.default_location_src_id + pick_type_routing_op = self.env["stock.picking.type"].create( + { + "name": "Dynamic Routing", + "code": "internal", + "sequence_code": "WH/PICK2", + "warehouse_id": self.wh.id, + "use_create_lots": False, + "use_existing_lots": True, + "default_location_src_id": pick_loc.id, + "default_location_dest_id": area1.id, + } + ) + self.env["stock.routing"].create( + { + "location_id": pick_loc.id, + "picking_type_id": self.wh.pick_type_id.id, + "rule_ids": [ + ( + 0, + 0, + {"method": "pull", "picking_type_id": pick_type_routing_op.id}, + ) + ], + } + ) + + self._update_qty_in_location(self.loc_bin1, self.product1, 20.0) + self._update_qty_in_location(self.loc_bin1, self.product2, 10.0) + + pickings = self._create_picking_chain( + self.wh, [(self.product1, 20), (self.product2, 10)], + ) + self.assertEqual(len(pickings), 1, "expect only the last out->customer") + cust_picking = pickings + self.assertRecordValues( + cust_picking, + [ + { + "state": "waiting", + "location_id": self.wh.wh_output_stock_loc_id.id, + "location_dest_id": self.loc_customer.id, + } + ], + ) + cust_picking.release_available_to_promise() + + pick_moves = cust_picking.move_lines.move_orig_ids + self.assertEqual(len(pick_moves), 2) + # this picking has been created to change the picking type + pick_picking = pick_moves.picking_id + self.assertEqual(pick_picking.picking_type_id, pick_type_routing_op) + # this flag is set by stock_available_to_promise_release + self.assertTrue(pick_picking.printed) + + def test_dynamic_routing_change_picking_type_out_printed(self): + """Type Dynamic routing (on OUT) applied after release get "printed" flag + + Ensure the "printed" flag is set even when we have no "move_dest_ids" + moves. + """ + self.wh.delivery_route_id.write({"available_to_promise_defer_pull": True}) + pick_type_routing = self.wh.pick_type_id.copy( + {"name": "PICKP Routing", "sequence_code": "WH/PICKP"} + ) + self.env["stock.routing"].create( + { + "location_id": pick_type_routing.default_location_src_id.id, + "picking_type_id": self.wh.pick_type_id.id, + "rule_ids": [ + (0, 0, {"method": "pull", "picking_type_id": pick_type_routing.id},) + ], + } + ) + out_type_routing = self.wh.out_type_id.copy( + {"name": "OUTP Routing", "sequence_code": "WH/OUTP"} + ) + self.env["stock.routing"].create( + { + "location_id": out_type_routing.default_location_src_id.id, + "picking_type_id": self.wh.out_type_id.id, + "rule_ids": [ + (0, 0, {"method": "pull", "picking_type_id": out_type_routing.id}) + ], + } + ) + + self._update_qty_in_location(self.loc_bin1, self.product1, 20.0) + self._update_qty_in_location(self.loc_bin1, self.product2, 10.0) + + pickings = self._create_picking_chain( + self.wh, [(self.product1, 20), (self.product2, 10)], + ) + self.assertEqual(len(pickings), 1, "expect only the last out->customer") + cust_picking = pickings + cust_picking.release_available_to_promise() + + # the original cust_picking has been canceled, because it is replaced + # by picking with the "OUTP" picking type + self.assertRecordValues(cust_picking, [{"state": "cancel"}]) + + new_cust_picking = self.env["stock.picking"].search( + [("picking_type_id", "=", out_type_routing.id)] + ) + + self.assertEqual(len(new_cust_picking.move_lines), 2) + self.assertRecordValues( + new_cust_picking, + [ + { + "state": "waiting", + "location_id": self.wh.wh_output_stock_loc_id.id, + "location_dest_id": self.loc_customer.id, + "picking_type_id": out_type_routing.id, + "printed": True, + } + ], + ) From 961dfb4d04f74ad08f52f29d3e097ca3f6673f00 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Tue, 13 Oct 2020 08:21:26 +0000 Subject: [PATCH 216/357] [UPD] Update stock_available_to_promise_release_dynamic_routing.pot --- ...available_to_promise_release_dynamic_routing.pot | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 stock_available_to_promise_release_dynamic_routing/i18n/stock_available_to_promise_release_dynamic_routing.pot diff --git a/stock_available_to_promise_release_dynamic_routing/i18n/stock_available_to_promise_release_dynamic_routing.pot b/stock_available_to_promise_release_dynamic_routing/i18n/stock_available_to_promise_release_dynamic_routing.pot new file mode 100644 index 00000000000..cc93d01ee54 --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/i18n/stock_available_to_promise_release_dynamic_routing.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" From 86adbcfa3e525073a3cab65e9a953bbc1fa8dc22 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 13 Oct 2020 08:28:33 +0000 Subject: [PATCH 217/357] [UPD] README.rst --- .../README.rst | 82 ++++ .../static/description/index.html | 428 ++++++++++++++++++ 2 files changed, 510 insertions(+) create mode 100644 stock_available_to_promise_release_dynamic_routing/README.rst create mode 100644 stock_available_to_promise_release_dynamic_routing/static/description/index.html diff --git a/stock_available_to_promise_release_dynamic_routing/README.rst b/stock_available_to_promise_release_dynamic_routing/README.rst new file mode 100644 index 00000000000..7bac538da96 --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/README.rst @@ -0,0 +1,82 @@ +============================================== +Available to Promise Release - Dynamic Routing +============================================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :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 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/13.0/stock_available_to_promise_release_dynamic_routing + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-13-0/wms-13-0-stock_available_to_promise_release_dynamic_routing + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/285/13.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module between ``stock_available_to_promise_release`` and +``stock_dynamic_routing``. + +Currently, the module only contains tests to verify the compatibility +between these two modules, but compatibility code may be needed later. + +.. 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:: + :local: + +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 + +Contributors +~~~~~~~~~~~~ + +* Guewen Baconnier + +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/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_available_to_promise_release_dynamic_routing/static/description/index.html b/stock_available_to_promise_release_dynamic_routing/static/description/index.html new file mode 100644 index 00000000000..33f1a0b02fd --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/static/description/index.html @@ -0,0 +1,428 @@ + + + + + + +Available to Promise Release - Dynamic Routing + + + +
+

Available to Promise Release - Dynamic Routing

+ + +

Alpha License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runbot

+

Glue module between stock_available_to_promise_release and +stock_dynamic_routing.

+

Currently, the module only contains tests to verify the compatibility +between these two modules, but compatibility code may be needed later.

+
+

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

+ +
+

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
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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

+

This module is part of the OCA/wms project on GitHub.

+

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

+
+
+
+ + From 708d85f0e51ffff57a69b234103700e1e71b05ee Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 13 Oct 2020 08:28:34 +0000 Subject: [PATCH 218/357] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 stock_available_to_promise_release_dynamic_routing/static/description/icon.png diff --git a/stock_available_to_promise_release_dynamic_routing/static/description/icon.png b/stock_available_to_promise_release_dynamic_routing/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From eafb61920b70a67f817a0db44eb419e120c7e2eb Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 13 Oct 2020 08:28:38 +0000 Subject: [PATCH 219/357] stock_available_to_promise_release_dynamic_routing 13.0.1.0.1 --- .../__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_available_to_promise_release_dynamic_routing/__manifest__.py b/stock_available_to_promise_release_dynamic_routing/__manifest__.py index 5fe2bfc53ff..102f26235d7 100644 --- a/stock_available_to_promise_release_dynamic_routing/__manifest__.py +++ b/stock_available_to_promise_release_dynamic_routing/__manifest__.py @@ -6,7 +6,7 @@ "author": "Camptocamp, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "13.0.1.0.0", + "version": "13.0.1.0.1", "license": "AGPL-3", "depends": ["stock_available_to_promise_release", "stock_dynamic_routing"], "demo": [], From 15d7a1c45060d5d6795a50d8e326fbff202e201d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Thu, 10 Dec 2020 11:15:40 +0100 Subject: [PATCH 220/357] [IMP] black, isort, prettier --- .../tests/test_release_dynamic_routing.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py b/stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py index ae52890aa8c..cdb6fb69c21 100644 --- a/stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py +++ b/stock_available_to_promise_release_dynamic_routing/tests/test_release_dynamic_routing.py @@ -64,7 +64,8 @@ def test_dynamic_routing_pull_printed(self): self._update_qty_in_location(self.location_hb_1, self.product2, 10.0) pickings = self._create_picking_chain( - self.wh, [(self.product1, 20), (self.product2, 10)], + self.wh, + [(self.product1, 20), (self.product2, 10)], ) self.assertEqual(len(pickings), 1, "expect only the last out->customer") cust_picking = pickings @@ -134,7 +135,8 @@ def test_dynamic_routing_change_picking_type_printed(self): self._update_qty_in_location(self.loc_bin1, self.product2, 10.0) pickings = self._create_picking_chain( - self.wh, [(self.product1, 20), (self.product2, 10)], + self.wh, + [(self.product1, 20), (self.product2, 10)], ) self.assertEqual(len(pickings), 1, "expect only the last out->customer") cust_picking = pickings @@ -173,7 +175,11 @@ def test_dynamic_routing_change_picking_type_out_printed(self): "location_id": pick_type_routing.default_location_src_id.id, "picking_type_id": self.wh.pick_type_id.id, "rule_ids": [ - (0, 0, {"method": "pull", "picking_type_id": pick_type_routing.id},) + ( + 0, + 0, + {"method": "pull", "picking_type_id": pick_type_routing.id}, + ) ], } ) @@ -194,7 +200,8 @@ def test_dynamic_routing_change_picking_type_out_printed(self): self._update_qty_in_location(self.loc_bin1, self.product2, 10.0) pickings = self._create_picking_chain( - self.wh, [(self.product1, 20), (self.product2, 10)], + self.wh, + [(self.product1, 20), (self.product2, 10)], ) self.assertEqual(len(pickings), 1, "expect only the last out->customer") cust_picking = pickings From 09fc16a7f20eff47e4e57268f69777103e24bfed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Thu, 10 Dec 2020 11:17:55 +0100 Subject: [PATCH 221/357] [IMP] set module uninstallable --- .../__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_available_to_promise_release_dynamic_routing/__manifest__.py b/stock_available_to_promise_release_dynamic_routing/__manifest__.py index 102f26235d7..2e0bb847eac 100644 --- a/stock_available_to_promise_release_dynamic_routing/__manifest__.py +++ b/stock_available_to_promise_release_dynamic_routing/__manifest__.py @@ -12,6 +12,6 @@ "demo": [], "data": [], "auto_install": True, - "installable": True, + "installable": False, "development_status": "Alpha", } From 572551599e635eb1c0d4c1980b35f914355d3a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=A9ng=20=28Tr=E1=BA=A7n=20=C4=90=C3=ACnh=29?= Date: Wed, 22 Sep 2021 12:51:13 +0700 Subject: [PATCH 222/357] [MIG] stock_move_source_relocate_dynamic_routing: Migration to 14.0 --- .../README.rst | 17 ++++++++++++----- .../readme/CONTRIBUTORS.rst | 2 ++ .../readme/CREDITS.rst | 1 + .../static/description/index.html | 19 +++++++++++++------ 4 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 stock_available_to_promise_release_dynamic_routing/readme/CREDITS.rst diff --git a/stock_available_to_promise_release_dynamic_routing/README.rst b/stock_available_to_promise_release_dynamic_routing/README.rst index 7bac538da96..dc836e7ce6a 100644 --- a/stock_available_to_promise_release_dynamic_routing/README.rst +++ b/stock_available_to_promise_release_dynamic_routing/README.rst @@ -14,13 +14,13 @@ Available to Promise Release - Dynamic Routing :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github - :target: https://github.com/OCA/wms/tree/13.0/stock_available_to_promise_release_dynamic_routing + :target: https://github.com/OCA/wms/tree/14.0/stock_available_to_promise_release_dynamic_routing :alt: OCA/wms .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/wms-13-0/wms-13-0-stock_available_to_promise_release_dynamic_routing + :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-stock_available_to_promise_release_dynamic_routing :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/285/13.0 + :target: https://runbot.odoo-community.org/runbot/285/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -47,7 +47,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -63,6 +63,13 @@ Contributors ~~~~~~~~~~~~ * Guewen Baconnier +* `Trobz `_: + * Dung Tran + +Other credits +~~~~~~~~~~~~~ + +The migration of this module from 13.0 to 14.0 was financially supported by Camptocamp Maintainers ~~~~~~~~~~~ @@ -77,6 +84,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/wms `_ project on GitHub. +This module is part of the `OCA/wms `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst b/stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst index 48286263cd3..de871c4d10e 100644 --- a/stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst +++ b/stock_available_to_promise_release_dynamic_routing/readme/CONTRIBUTORS.rst @@ -1 +1,3 @@ * Guewen Baconnier +* `Trobz `_: + * Dung Tran diff --git a/stock_available_to_promise_release_dynamic_routing/readme/CREDITS.rst b/stock_available_to_promise_release_dynamic_routing/readme/CREDITS.rst new file mode 100644 index 00000000000..f37ebe75704 --- /dev/null +++ b/stock_available_to_promise_release_dynamic_routing/readme/CREDITS.rst @@ -0,0 +1 @@ +The migration of this module from 13.0 to 14.0 was financially supported by Camptocamp diff --git a/stock_available_to_promise_release_dynamic_routing/static/description/index.html b/stock_available_to_promise_release_dynamic_routing/static/description/index.html index 33f1a0b02fd..d8c5025bdac 100644 --- a/stock_available_to_promise_release_dynamic_routing/static/description/index.html +++ b/stock_available_to_promise_release_dynamic_routing/static/description/index.html @@ -3,7 +3,7 @@ - + Available to Promise Release - Dynamic Routing -
-

Available to Promise Release - Dynamic Routing

+
+ + +Odoo Community Association + +
+

Available to Promise Release - Dynamic Routing

-

Alpha License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Alpha License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Glue module between stock_available_to_promise_release and stock_dynamic_routing.

Currently, the module only contains tests to verify the compatibility @@ -382,18 +388,18 @@

Available to Promise Release - Dynamic Routing

Table of contents

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -401,16 +407,16 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • BCIM
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The migration of this module from 13.0 to 14.0 was financially supported by Camptocamp

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

-Odoo Community Association + +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.

Current maintainer:

-

jbaudoux

+

jbaudoux

This module is part of the OCA/wms project on GitHub.

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

+
From 4be48ea01289885c4714023da80f054896bfca58 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 12 May 2025 16:02:37 +0200 Subject: [PATCH 245/357] [IMP] shopfloor_reception: Allows to set picking as started --- shopfloor_reception/services/reception.py | 3 ++- shopfloor_reception/tests/test_select_move.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 97cf8672b8d..203d313a473 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -290,7 +290,8 @@ def _scan_line__find_or_create_line(self, picking, move, qty_done=1): def _scan_line__assign_user(self, picking, line, qty_done): product = line.product_id self._assign_user_to_line(line) - line.qty_done += qty_done + stock = self._actions_for("stock") + stock.mark_move_line_as_picked(line, quantity=qty_done, split=False) if product.tracking not in ("lot", "serial") or (line.lot_id or line.lot_name): return self._before_state__set_quantity(picking, line) return self._response_for_set_lot(picking, line) diff --git a/shopfloor_reception/tests/test_select_move.py b/shopfloor_reception/tests/test_select_move.py index 5e9b9cf1534..a184443e0a4 100644 --- a/shopfloor_reception/tests/test_select_move.py +++ b/shopfloor_reception/tests/test_select_move.py @@ -26,6 +26,7 @@ def test_scan_barcode_not_found(self): def test_scan_product(self): picking = self._create_picking() + self.assertFalse(picking.printed) response = self.service.dispatch( "scan_line", params={"picking_id": picking.id, "barcode": self.product_a.barcode}, @@ -34,6 +35,7 @@ def test_scan_product(self): selected_move_line = picking.move_line_ids.filtered( lambda l: l.product_id == self.product_a ) + self.assertTrue(selected_move_line.picking_id.printed) self.assert_response( response, next_state="set_lot", From c4a4711d24dfd9b301ed06fce3fb6d1744783c60 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 2 Jul 2025 14:19:09 +0200 Subject: [PATCH 246/357] [IMP] shopfloor_reception: Don't assign twice shopfloor user --- shopfloor_reception/services/reception.py | 1 - 1 file changed, 1 deletion(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 203d313a473..156f600c677 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -289,7 +289,6 @@ def _scan_line__find_or_create_line(self, picking, move, qty_done=1): def _scan_line__assign_user(self, picking, line, qty_done): product = line.product_id - self._assign_user_to_line(line) stock = self._actions_for("stock") stock.mark_move_line_as_picked(line, quantity=qty_done, split=False) if product.tracking not in ("lot", "serial") or (line.lot_id or line.lot_name): From dcdcd1274190d9b83e7f1555760ddd617b772199 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 8 Jul 2025 09:13:20 +0000 Subject: [PATCH 247/357] Translated using Weblate (Italian) Currently translated at 100.0% (13 of 13 strings) Translation: wms-16.0/wms-16.0-stock_full_location_reservation Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_full_location_reservation/it/ --- stock_full_location_reservation/i18n/it.po | 34 +++++++++++++--------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/stock_full_location_reservation/i18n/it.po b/stock_full_location_reservation/i18n/it.po index 86ad408691a..8fde52495d6 100644 --- a/stock_full_location_reservation/i18n/it.po +++ b/stock_full_location_reservation/i18n/it.po @@ -6,39 +6,41 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-07-08 09:40+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_full_location_reservation #: model_terms:ir.ui.view,arch_db:stock_full_location_reservation.stock_picking_form_view msgid "Do Full location reservation" -msgstr "" +msgstr "Esegui prenotazione completa ubicazione" #. module: stock_full_location_reservation #: model:res.groups,name:stock_full_location_reservation.group_user msgid "Full location reservation" -msgstr "" +msgstr "Prenotazione completa ubicazione" #. module: stock_full_location_reservation #: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_move__is_full_location_reservation msgid "Full location reservation move" -msgstr "" +msgstr "Movimento prenotazione completa ubicazione" #. module: stock_full_location_reservation #: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking__has_full_location_reservations msgid "Has full location reservations" -msgstr "" +msgstr "Ha prenotazione completa ubicazione" #. module: stock_full_location_reservation #: model:ir.model.fields,help:stock_full_location_reservation.field_stock_picking__is_full_location_reservation_visible #: model:ir.model.fields,help:stock_full_location_reservation.field_stock_picking_type__is_full_location_reservation_visible msgid "If this is checked, the full reservation of a the picking is visible" -msgstr "" +msgstr "Se è selezionata, la prenotazione completa è visibile al prelievo" #. module: stock_full_location_reservation #: model:ir.model.fields,help:stock_full_location_reservation.field_stock_picking_type__merge_move_for_full_location_reservation @@ -48,39 +50,45 @@ msgid "" " WARNING: If checked, it will be impossible to get the original move back.\n" " " msgstr "" +"Se questa opzione è selezionata, verrà effettuata la prenotazione completa \n" +" del prelievo risultante da un solo movimento (quello originale + " +"quello con prenotazione completa).\n" +" ATTENZIONE: se questa opzione è selezionata, sarà impossibile " +"recuperare il movimento originale.\n" +" " #. module: stock_full_location_reservation #: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking__is_full_location_reservation_visible #: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking_type__is_full_location_reservation_visible msgid "Is full location reservation visible" -msgstr "" +msgstr "La prenotazione completa è visibile" #. module: stock_full_location_reservation #: model:ir.model.fields,field_description:stock_full_location_reservation.field_stock_picking_type__merge_move_for_full_location_reservation msgid "Merge Move For Full Location Reservation" -msgstr "" +msgstr "Unione movimento per la prenotazione completa ubicazione" #. module: stock_full_location_reservation #: model:ir.model,name:stock_full_location_reservation.model_stock_picking_type msgid "Picking Type" -msgstr "" +msgstr "Tipo prelievo" #. module: stock_full_location_reservation #: model:ir.model,name:stock_full_location_reservation.model_stock_move_line msgid "Product Moves (Stock Move Line)" -msgstr "" +msgstr "Movimenti prodotto (riga movimento di magazzino)" #. module: stock_full_location_reservation #: model:ir.model,name:stock_full_location_reservation.model_stock_move msgid "Stock Move" -msgstr "" +msgstr "Movimento di magazzino" #. module: stock_full_location_reservation #: model:ir.model,name:stock_full_location_reservation.model_stock_picking msgid "Transfer" -msgstr "" +msgstr "Trasferimento" #. module: stock_full_location_reservation #: model_terms:ir.ui.view,arch_db:stock_full_location_reservation.stock_picking_form_view msgid "Undo Full location reservation" -msgstr "" +msgstr "Annulla prenotazione completa ubicazione" From 29a20e3732e32bfe6a07a1704d92db6458c29626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Wed, 9 Jul 2025 10:58:04 +0200 Subject: [PATCH 248/357] stock_available_to_promise_release: bump version (patch) Following the merge of f41c665b4f64b15b4006020d28624518c09328b4 and 795af363f85c85b0597d477c8fc65d8ab69df1cb. --- stock_available_to_promise_release/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_available_to_promise_release/__manifest__.py b/stock_available_to_promise_release/__manifest__.py index f1e561f8b6d..a6022e9dbf8 100644 --- a/stock_available_to_promise_release/__manifest__.py +++ b/stock_available_to_promise_release/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Available to Promise Release", - "version": "16.0.3.8.1", + "version": "16.0.3.8.2", "summary": "Release Operations based on available to promise", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", From 7dbcdb515674022cbd5914d21ab5346c97432114 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 9 Jul 2025 09:15:52 +0000 Subject: [PATCH 249/357] [BOT] post-merge updates --- README.md | 2 +- stock_available_to_promise_release/README.rst | 2 +- .../static/description/index.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dc3ce8ee604..43436b32db4 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ addon | version | maintainers | summary [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation -[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.8.1 | | Release Operations based on available to promise +[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.8.2 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_dynamic_routing](stock_available_to_promise_release_dynamic_routing/) | 16.0.1.0.0 | jbaudoux | Glue between moves release and dynamic routing [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock diff --git a/stock_available_to_promise_release/README.rst b/stock_available_to_promise_release/README.rst index a0291c53d2b..48b48bf8f91 100644 --- a/stock_available_to_promise_release/README.rst +++ b/stock_available_to_promise_release/README.rst @@ -11,7 +11,7 @@ Stock Available to Promise Release !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b2609ab06e8b3bda3f86543ba4a4fc871ac9b39fb86bcb5ab8008505cf0fd972 + !! source digest: sha256:a2c7d3a98fbb4bc85708fd746ece6b40695d865ff74d05fccbb4622ac019fe93 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_available_to_promise_release/static/description/index.html b/stock_available_to_promise_release/static/description/index.html index 6f06eb5bf17..3619102b694 100644 --- a/stock_available_to_promise_release/static/description/index.html +++ b/stock_available_to_promise_release/static/description/index.html @@ -372,7 +372,7 @@

Stock Available to Promise Release

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:b2609ab06e8b3bda3f86543ba4a4fc871ac9b39fb86bcb5ab8008505cf0fd972 +!! source digest: sha256:a2c7d3a98fbb4bc85708fd746ece6b40695d865ff74d05fccbb4622ac019fe93 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Currently the reservation is performed by adding reserved quantities on quants, From 484fde6284e1ebd168127b4100ed95596b9cf099 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 9 Jul 2025 12:56:07 +0000 Subject: [PATCH 250/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 43436b32db4..62b8e002346 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.3.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.4.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 4457621163d..48a93328ad7 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:087bb6f09231a4d2a723f612b196536aead10654371f9ce81a61a63ceef07ff1 + !! source digest: sha256:82b16d13b5d7ebcba93ae526d0c5727e0ca12b1698e301b18cd31341567a3808 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 922caa57dc4..0805b9e780b 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.3.0", + "version": "16.0.1.4.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index b44c68a9050..f644def1d2e 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor Reception

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:087bb6f09231a4d2a723f612b196536aead10654371f9ce81a61a63ceef07ff1 +!! source digest: sha256:82b16d13b5d7ebcba93ae526d0c5727e0ca12b1698e301b18cd31341567a3808 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor implementation of the reception scenario. From 103a0b48274e23c6ecbf2fff560b9031a13234e6 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 9 Jul 2025 16:34:29 +0200 Subject: [PATCH 251/357] [FIX] shopfloor_reception: Restrict lot find to the current product --- shopfloor_reception/services/reception.py | 6 ++- .../tests/test_set_quantity.py | 41 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 97cf8672b8d..91b7630f089 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -1104,7 +1104,11 @@ def _set_quantity__by_barcode( ): handlers_by_type = self._set_quantity__get_handlers_by_type() search = self._actions_for("search") - search_result = search.find(barcode, handlers_by_type.keys()) + search_result = search.find( + barcode, + handlers_by_type.keys(), + handler_kw=dict(lot=dict(products=selected_line.product_id)), + ) handler = handlers_by_type.get(search_result.type) if handler: return handler(picking, selected_line, search_result.record) diff --git a/shopfloor_reception/tests/test_set_quantity.py b/shopfloor_reception/tests/test_set_quantity.py index 8cd13962002..9b4da52973e 100644 --- a/shopfloor_reception/tests/test_set_quantity.py +++ b/shopfloor_reception/tests/test_set_quantity.py @@ -53,6 +53,47 @@ def test_set_quantity_scan_product(self): }, ) + def test_set_quantity_scan_wrong_lot(self): + # create lot "4" for product b + self.env["stock.lot"].create( + { + "name": "4", + "product_id": self.product_b.id, + } + ) + self.product_a.sudo().tracking = "lot" + + picking = self._create_picking() + selected_move_line = picking.move_line_ids.filtered( + lambda l: l.product_id == self.product_a + ) + selected_move_line.shopfloor_user_id = self.env.uid + response = self.service.dispatch( + "set_quantity", + params={ + "picking_id": picking.id, + "selected_line_id": selected_move_line.id, + "quantity": 10.0, + "barcode": "4", + }, + ) + self.assertEqual(selected_move_line.qty_done, 10.0) + data = self.data.picking(picking) + message = { + "message_type": "warning", + "body": "Create new PACK 4? Scan it again to confirm.", + } + self.assert_response( + response, + next_state="set_quantity", + data={ + "picking": data, + "selected_move_line": self.data.move_lines(selected_move_line), + "confirmation_required": "4", + }, + message=message, + ) + def test_set_quantity_scan_packaging(self): picking = self._create_picking() selected_move_line = picking.move_line_ids.filtered( From 5d6c6c0881895233d8f599835012ba16573f9be4 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 18 Jul 2025 12:32:55 +0000 Subject: [PATCH 252/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 62b8e002346..622a7eccf6f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.1 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.11.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.12.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index 27b0681a2e0..4bdb1b12ed5 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:45e38752c97272a2846012a4dfd2597a7df126607d2ec7e5ff0489e3477b63a5 + !! source digest: sha256:c418f1851f7591fa3b9cde9ce01a2a3507baf0066f7453d93cfea051273d85fc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index f4581e22268..4001f5be366 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.11.0", + "version": "16.0.2.12.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index 72c95b71250..42008a3cb7f 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:45e38752c97272a2846012a4dfd2597a7df126607d2ec7e5ff0489e3477b63a5 +!! source digest: sha256:c418f1851f7591fa3b9cde9ce01a2a3507baf0066f7453d93cfea051273d85fc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

From 658f33712853757045f840e3f6f7895f91446113 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 22 Jul 2025 09:30:44 +0000 Subject: [PATCH 253/357] Translated using Weblate (Italian) Currently translated at 100.0% (329 of 329 strings) Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/it/ --- shopfloor/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index 81af46e8e83..1020eca7341 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-06-25 06:54+0000\n" +"PO-Revision-Date: 2025-07-22 11:25+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -616,7 +616,7 @@ msgstr "Ubicazioni di inventario" #. module: shopfloor #: model:ir.model.fields,field_description:shopfloor.field_stock_picking__is_shopfloor_created msgid "Is Shopfloor Created" -msgstr "Il reparto è crato" +msgstr "Il reparto è creato" #. module: shopfloor #. odoo-python From 4671319e9310751658e1006cba684f8b0e59d188 Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 22 Jul 2025 09:25:03 +0000 Subject: [PATCH 254/357] Translated using Weblate (Italian) Currently translated at 100.0% (31 of 31 strings) Translation: wms-16.0/wms-16.0-sale_stock_available_to_promise_release Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-sale_stock_available_to_promise_release/it/ --- sale_stock_available_to_promise_release/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sale_stock_available_to_promise_release/i18n/it.po b/sale_stock_available_to_promise_release/i18n/it.po index 5514224458e..0f8c0d7f11e 100644 --- a/sale_stock_available_to_promise_release/i18n/it.po +++ b/sale_stock_available_to_promise_release/i18n/it.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Odoo Server 13.0+e\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-07-12 17:07+0000\n" -"PO-Revision-Date: 2024-06-24 13:35+0000\n" +"PO-Revision-Date: 2025-07-22 11:25+0000\n" "Last-Translator: mymage \n" "Language-Team: \n" "Language: it\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.10.4\n" #. module: sale_stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release.report_saleorder_document @@ -105,7 +105,7 @@ msgstr "No" #. module: sale_stock_available_to_promise_release #: model:ir.model.fields.selection,name:sale_stock_available_to_promise_release.selection__sale_order_line__availability_status__no msgid "Not available" -msgstr "No disponibile" +msgstr "Non disponibile" #. module: sale_stock_available_to_promise_release #: model:ir.model.fields.selection,name:sale_stock_available_to_promise_release.selection__sale_order_line__availability_status__on_order From 00d95ae656b08c183543a45c585cbacdab9e06db Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 7 Aug 2025 13:01:14 +0000 Subject: [PATCH 255/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception_mobile/README.rst | 8 ++++-- shopfloor_reception_mobile/__manifest__.py | 2 +- .../static/description/index.html | 26 ++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 622a7eccf6f..16ea4e90a08 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ addon | version | maintainers | summary [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app [shopfloor_reception](shopfloor_reception/) | 16.0.1.4.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor -[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.0.1 | JuMiSanAr | Scenario for receiving products +[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.0 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners diff --git a/shopfloor_reception_mobile/README.rst b/shopfloor_reception_mobile/README.rst index 9e3eae11480..5642e14bc56 100644 --- a/shopfloor_reception_mobile/README.rst +++ b/shopfloor_reception_mobile/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ========================== Shopfloor reception mobile ========================== @@ -7,13 +11,13 @@ Shopfloor reception mobile !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:160fe3ea1390fd4c12a76fba12c0f662dcb164d2e39fd9455d08e1e0bf2b4b94 + !! source digest: sha256:eadcaffae32d8dda952fe04de4f3a40041f7a2022d6ddef8a9e2015cad125da3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/shopfloor_reception_mobile/__manifest__.py b/shopfloor_reception_mobile/__manifest__.py index c95cac6d191..46b31ca73ce 100644 --- a/shopfloor_reception_mobile/__manifest__.py +++ b/shopfloor_reception_mobile/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Shopfloor reception mobile", "summary": "Scenario for receiving products", - "version": "16.0.1.0.1", + "version": "16.0.1.1.0", "development_status": "Beta", "depends": ["shopfloor_mobile_base", "shopfloor_reception"], "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/shopfloor_reception_mobile/static/description/index.html b/shopfloor_reception_mobile/static/description/index.html index 88ec49d8a34..4ad84f2d3b4 100644 --- a/shopfloor_reception_mobile/static/description/index.html +++ b/shopfloor_reception_mobile/static/description/index.html @@ -3,7 +3,7 @@ -Shopfloor reception mobile +README.rst -
-

Shopfloor reception mobile

+
+ + +Odoo Community Association + +
+

Shopfloor reception mobile

-

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Frontend for the reception scenario in shopfloor. Allows to receive products and create the proper packs for each logistic unit.

Table of contents

@@ -385,7 +390,7 @@

Shopfloor reception mobile

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -393,15 +398,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -424,5 +429,6 @@

Maintainers

+
From 7336852400c12053b0fe847f48e5c43872dfdda8 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 23 Jun 2025 12:01:48 +0200 Subject: [PATCH 256/357] [REF] shopfloor: Add _lock_lines and set_destination_and_unload_lines to actions stock --- shopfloor/actions/stock.py | 24 +++++++++++++++++++ shopfloor/services/cluster_picking.py | 11 ++++----- .../services/location_content_transfer.py | 5 ++-- shopfloor/services/single_pack_transfer.py | 7 +++--- shopfloor/services/zone_picking.py | 15 ++++-------- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/shopfloor/actions/stock.py b/shopfloor/actions/stock.py index c55af22da21..8fe8f8c8c29 100644 --- a/shopfloor/actions/stock.py +++ b/shopfloor/actions/stock.py @@ -1,4 +1,5 @@ # Copyright 2020 Camptocamp SA (http://www.camptocamp.com) +# Copyright 2025 Michael Tietz (MT Software) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, fields from odoo.tools.float_utils import float_round @@ -250,3 +251,26 @@ def no_putaway_available(self, picking_types, move_lines): # when no putaway is found, the move line destination stays the # default's of the picking type return any(line.location_dest_id in base_locations for line in move_lines) + + def _lock_lines(self, lines): + self._actions_for("lock").for_update(lines) + + def _set_destination_on_lines(self, lines, location_dest): + # when writing the destination on the package level, it writes + # on the moves and move lines + lines_with_package_level = lines.package_level_id.move_line_ids + lines_without_package_level = lines - lines_with_package_level + if lines_with_package_level: + lines_with_package_level.package_level_id.location_dest_id = location_dest + if lines_without_package_level: + lines_without_package_level.location_dest_id = location_dest + lines_without_package_level.move_id.location_dest_id = location_dest + + def _unload_package(self, lines): + lines.result_package_id = False + + def set_destination_and_unload_lines(self, lines, location_dest, unload=False): + self._lock_lines(lines) + self._set_destination_on_lines(lines, location_dest) + if unload: + self._unload_package(lines) diff --git a/shopfloor/services/cluster_picking.py b/shopfloor/services/cluster_picking.py index d54ef12b9f6..92775a91011 100644 --- a/shopfloor/services/cluster_picking.py +++ b/shopfloor/services/cluster_picking.py @@ -1146,8 +1146,9 @@ def set_destination_all(self, picking_batch_id, barcode, confirmation=None): return self._unload_end(batch, completion_info_popup=completion_info_popup) def _unload_write_destination_on_lines(self, lines, location): - lines.write({"shopfloor_unloaded": True, "location_dest_id": location.id}) - lines.package_level_id.location_dest_id = location + stock = self._actions_for("stock") + stock.set_destination_and_unload_lines(lines, location) + lines.write({"shopfloor_unloaded": True}) for picking in lines.batch_id.picking_ids: picking_lines = lines.filtered(lambda x, p=picking: x.picking_id == p) self._unload_set_picking_to_done(picking, picking_lines) @@ -1283,15 +1284,11 @@ def unload_scan_destination( batch, package, lines, barcode, confirmation=confirmation ) - def _lock_lines(self, lines): - """Lock move lines""" - self._actions_for("lock").for_update(lines) - def _unload_scan_destination_lines( self, batch, package, lines, barcode, confirmation=None ): # Lock move lines that will be updated - self._lock_lines(lines) + self._actions_for("lock").for_update(lines) first_line = fields.first(lines) scanned_location = self._actions_for("search").location_from_scan(barcode) if not scanned_location: diff --git a/shopfloor/services/location_content_transfer.py b/shopfloor/services/location_content_transfer.py index b60c8ce8062..16679e5bcd0 100644 --- a/shopfloor/services/location_content_transfer.py +++ b/shopfloor/services/location_content_transfer.py @@ -428,10 +428,9 @@ def _find_transfer_move_lines(self, location): ) return lines - # hook used in module shopfloor_checkout_sync def _write_destination_on_lines(self, lines, location): - lines.location_dest_id = location - lines.package_level_id.picking_id.location_dest_id = location + stock = self._actions_for("stock") + stock.set_destination_and_unload_lines(lines, location) def _set_all_destination_lines_and_done(self, pickings, move_lines, dest_location): self._write_destination_on_lines(move_lines, dest_location) diff --git a/shopfloor/services/single_pack_transfer.py b/shopfloor/services/single_pack_transfer.py index 50f721a06f8..1b3eb2a9eb9 100644 --- a/shopfloor/services/single_pack_transfer.py +++ b/shopfloor/services/single_pack_transfer.py @@ -1,6 +1,7 @@ # Copyright 2020-2021 Camptocamp SA (http://www.camptocamp.com) # Copyright 2020-2021 Jacques-Etienne Baudoux (BCIM) # Copyright 2020 Akretion (http://www.akretion.com) +# Copyright 2025 Michael Tietz (MT Software) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields @@ -265,10 +266,10 @@ def _router_validate_success(self, package_level): return self._response_for_start(message=message, popup=completion_info_popup) def _set_destination_and_done(self, package_level, scanned_location): - # when writing the destination on the package level, it writes - # on the move lines - package_level.location_dest_id = scanned_location stock = self._actions_for("stock") + stock.set_destination_and_unload_lines( + package_level.move_line_ids, scanned_location + ) stock.put_package_level_in_move(package_level) stock.validate_moves(package_level.move_line_ids.move_id) diff --git a/shopfloor/services/zone_picking.py b/shopfloor/services/zone_picking.py index b69f5edd42a..d4a4c0e880f 100644 --- a/shopfloor/services/zone_picking.py +++ b/shopfloor/services/zone_picking.py @@ -1043,7 +1043,7 @@ def _set_destination_package(self, move_line, quantity, package): ) return (package_changed, response) stock = self._actions_for("stock") - self._lock_lines(move_line) + stock._lock_lines(move_line) try: stock.mark_move_line_as_picked( move_line, quantity, package, check_user=True @@ -1585,11 +1585,10 @@ def set_destination_all(self, barcode, confirmation=None): return self._set_destination_all_response(buffer_lines, message=message) def _write_destination_on_lines(self, lines, location): - self._lock_lines(lines) - lines.location_dest_id = location - lines.package_level_id.location_dest_id = location - if self.work.menu.unload_package_at_destination: - lines.result_package_id = False + stock = self._actions_for("stock") + stock.set_destination_and_unload_lines( + lines, location, unload=self.work.menu.unload_package_at_destination + ) def unload_split(self): """Indicates that now the buffer must be treated line per line @@ -1670,10 +1669,6 @@ def unload_scan_pack(self, package_id, barcode): unload_single_message=self.msg_store.barcode_no_match(package.name), ) - def _lock_lines(self, lines): - """Lock move lines""" - self._actions_for("lock").for_update(lines) - def unload_set_destination(self, package_id, barcode, confirmation=None): """Scan the final destination for move lines in the buffer with the destination package From 9d09905bd1f720e38114b9a14acea54a9d886559 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 23 Jun 2025 12:14:55 +0200 Subject: [PATCH 257/357] [IMP] shopfloor: Ensure destination location is also set on move --- shopfloor/tests/test_single_pack_transfer.py | 74 +++++++++++++++++++- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/shopfloor/tests/test_single_pack_transfer.py b/shopfloor/tests/test_single_pack_transfer.py index 7dd52e62361..3146c08afd5 100644 --- a/shopfloor/tests/test_single_pack_transfer.py +++ b/shopfloor/tests/test_single_pack_transfer.py @@ -188,7 +188,8 @@ def test_start_no_operation_create(self): package_level = move_line.package_level_id self.assertTrue(package_level.is_done) - + self.assertEqual(move_line.location_id, self.pack_a.location_id) + self.assertEqual(move_line.move_id.location_id, self.pack_a.location_id) expected_data = { "id": package_level.id, "name": package_level.package_id.name, @@ -206,6 +207,60 @@ def test_start_no_operation_create(self): self.assert_response(response, next_state="scan_location", data=expected_data) + def test_start_validate_no_operation_create(self): + self.menu.sudo().allow_move_create = True + self.picking.do_unreserve() + barcode = self.pack_a.name + params = {"barcode": barcode} + + # Simulate the client scanning a package's barcode, which + # in turns should start the operation in odoo + response = self.service.dispatch("start", params=params) + + move_line = self.env["stock.move.line"].search( + [("package_id", "=", self.pack_a.id)] + ) + package_level = move_line.package_level_id + + response = self.service.dispatch( + "validate", + params={ + "package_level_id": package_level.id, + "location_barcode": self.shelf2.barcode, + }, + ) + + self.assert_response( + response, + next_state="start", + message={ + "message_type": "success", + "body": "The pack has been moved, you can scan a new pack.", + }, + ) + + self.assertRecordValues( + package_level.move_line_ids, + [ + { + "qty_done": 1.0, + "location_dest_id": self.shelf2.id, + "location_id": self.shelf1.id, + "state": "done", + } + ], + ) + self.assertRecordValues( + package_level.move_line_ids.move_id, + [ + { + "location_dest_id": self.shelf2.id, + "location_id": self.shelf1.id, + "state": "done", + } + ], + ) + def test_start_barcode_not_known(self): """Test /start when the barcode is unknown @@ -451,11 +506,24 @@ def test_validate(self): self.assertRecordValues( package_level.move_line_ids, - [{"qty_done": 1.0, "location_dest_id": self.shelf2.id, "state": "done"}], + [ + { + "qty_done": 1.0, + "location_dest_id": self.shelf2.id, + "location_id": self.shelf1.id, + "state": "done", + } + ], ) self.assertRecordValues( package_level.move_line_ids.move_id, - [{"location_dest_id": self.shelf2.id, "state": "done"}], + [ + { + "location_dest_id": self.shelf2.id, + "location_id": self.shelf1.location_id.id, + "state": "done", + } + ], ) def test_validate_completion_info(self): From 847e512c7c0a4877d62bf1450583fbd1698e0269 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 11 Aug 2025 17:24:44 +0200 Subject: [PATCH 258/357] [IMP] shopfloor: Call unload_package with separate method in scenarios --- shopfloor/actions/stock.py | 6 ++---- shopfloor/services/cluster_picking.py | 2 +- shopfloor/services/location_content_transfer.py | 2 +- shopfloor/services/single_pack_transfer.py | 4 +--- shopfloor/services/zone_picking.py | 6 +++--- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/shopfloor/actions/stock.py b/shopfloor/actions/stock.py index 8fe8f8c8c29..6c661d84ea5 100644 --- a/shopfloor/actions/stock.py +++ b/shopfloor/actions/stock.py @@ -266,11 +266,9 @@ def _set_destination_on_lines(self, lines, location_dest): lines_without_package_level.location_dest_id = location_dest lines_without_package_level.move_id.location_dest_id = location_dest - def _unload_package(self, lines): + def unload_package(self, lines): lines.result_package_id = False - def set_destination_and_unload_lines(self, lines, location_dest, unload=False): + def set_destination_on_lines(self, lines, location_dest): self._lock_lines(lines) self._set_destination_on_lines(lines, location_dest) - if unload: - self._unload_package(lines) diff --git a/shopfloor/services/cluster_picking.py b/shopfloor/services/cluster_picking.py index 92775a91011..454ba27f3d4 100644 --- a/shopfloor/services/cluster_picking.py +++ b/shopfloor/services/cluster_picking.py @@ -1147,7 +1147,7 @@ def set_destination_all(self, picking_batch_id, barcode, confirmation=None): def _unload_write_destination_on_lines(self, lines, location): stock = self._actions_for("stock") - stock.set_destination_and_unload_lines(lines, location) + stock.set_destination_on_lines(lines, location) lines.write({"shopfloor_unloaded": True}) for picking in lines.batch_id.picking_ids: picking_lines = lines.filtered(lambda x, p=picking: x.picking_id == p) diff --git a/shopfloor/services/location_content_transfer.py b/shopfloor/services/location_content_transfer.py index 16679e5bcd0..b798208863b 100644 --- a/shopfloor/services/location_content_transfer.py +++ b/shopfloor/services/location_content_transfer.py @@ -430,7 +430,7 @@ def _find_transfer_move_lines(self, location): def _write_destination_on_lines(self, lines, location): stock = self._actions_for("stock") - stock.set_destination_and_unload_lines(lines, location) + stock.set_destination_on_lines(lines, location) def _set_all_destination_lines_and_done(self, pickings, move_lines, dest_location): self._write_destination_on_lines(move_lines, dest_location) diff --git a/shopfloor/services/single_pack_transfer.py b/shopfloor/services/single_pack_transfer.py index 1b3eb2a9eb9..e3e98c72354 100644 --- a/shopfloor/services/single_pack_transfer.py +++ b/shopfloor/services/single_pack_transfer.py @@ -267,9 +267,7 @@ def _router_validate_success(self, package_level): def _set_destination_and_done(self, package_level, scanned_location): stock = self._actions_for("stock") - stock.set_destination_and_unload_lines( - package_level.move_line_ids, scanned_location - ) + stock.set_destination_on_lines(package_level.move_line_ids, scanned_location) stock.put_package_level_in_move(package_level) stock.validate_moves(package_level.move_line_ids.move_id) diff --git a/shopfloor/services/zone_picking.py b/shopfloor/services/zone_picking.py index d4a4c0e880f..ff6512cfe2e 100644 --- a/shopfloor/services/zone_picking.py +++ b/shopfloor/services/zone_picking.py @@ -1586,9 +1586,9 @@ def set_destination_all(self, barcode, confirmation=None): def _write_destination_on_lines(self, lines, location): stock = self._actions_for("stock") - stock.set_destination_and_unload_lines( - lines, location, unload=self.work.menu.unload_package_at_destination - ) + stock.set_destination_on_lines(lines, location) + if self.work.menu.unload_package_at_destination: + stock.unload_package(lines) def unload_split(self): """Indicates that now the buffer must be treated line per line From 1cdf606361a1b09eae42e332814e551289401d47 Mon Sep 17 00:00:00 2001 From: mymage Date: Sat, 16 Aug 2025 10:44:39 +0000 Subject: [PATCH 259/357] Translated using Weblate (Italian) Currently translated at 100.0% (329 of 329 strings) Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/it/ --- shopfloor/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index 1020eca7341..c611764fe3b 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-07-22 11:25+0000\n" +"PO-Revision-Date: 2025-08-16 13:25+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -1900,7 +1900,7 @@ msgstr "Il record su cui si stava lavorando non esiste più." #: code:addons/shopfloor/models/stock_move.py:0 #, python-format msgid "The split order {} has been created." -msgstr "L'ordine sddiviso {} è stato creato." +msgstr "L'ordine suddiviso {} è stato creato." #. module: shopfloor #: model:ir.model.fields,help:shopfloor.field_stock_move_line__picking_id From 9c134cd7432d70b5d8ee6182b2ca635a24ce064a Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Thu, 10 Oct 2024 11:58:32 +0200 Subject: [PATCH 260/357] [IMP] stock_picking_batch_creation: Allows to split picking A new option 'Split picking exceeding the limits' on the wizard allow, when the system is not able to find a picking that fits the criteria to create the batch, to lower the criteria by removing those based on the volume, weight and number of lines. If a picking is found and you allow to split it, the system will try to split the picking so that the new picking fits the criteria and can be added to the batch. --- stock_picking_batch_creation/__manifest__.py | 3 +- stock_picking_batch_creation/readme/USAGE.rst | 10 +++ .../tests/test_clustering_conditions.py | 90 ++++++++++++++++++- .../wizards/make_picking_batch.py | 86 ++++++++++++------ .../wizards/make_picking_batch.xml | 4 +- 5 files changed, 158 insertions(+), 35 deletions(-) diff --git a/stock_picking_batch_creation/__manifest__.py b/stock_picking_batch_creation/__manifest__.py index 8335457cc46..947d8251958 100644 --- a/stock_picking_batch_creation/__manifest__.py +++ b/stock_picking_batch_creation/__manifest__.py @@ -5,7 +5,7 @@ "name": "Stock Picking Batch Creation", "summary": """ Create a batch of pickings to be processed all together""", - "version": "16.0.1.0.0", + "version": "16.0.2.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", @@ -16,6 +16,7 @@ "delivery", # weight on picking "stock_picking_batch", "stock_picking_volume", # OCA/stock-logistics-warehouse + "stock_split_picking_dimension", # OCA/stock-logistics-workflow ], "data": [ "views/stock_device_type.xml", diff --git a/stock_picking_batch_creation/readme/USAGE.rst b/stock_picking_batch_creation/readme/USAGE.rst index 3c67061e1fe..a227e47a365 100644 --- a/stock_picking_batch_creation/readme/USAGE.rst +++ b/stock_picking_batch_creation/readme/USAGE.rst @@ -66,3 +66,13 @@ will prevent to consume at least one bin for each picking if pickings are for the same partner. When activated, the computation of the number of bins consumed by the picking into the batch will take into account the volume of the pickings for the same partners already. + +Splitting picking if needed +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can also activate the option *Split picking exceeding the limits* on the +wizard. This will allow, when the system is not able to find a picking that +fits the criteria to create the batch, to lower the criteria by removing those +based on the volume, weight and number of lines. If a picking is found and +you allow to split it, the system will try to split the picking so that the +new picking fits the criteria and can be added to the batch. \ No newline at end of file diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index 73d2313e14e..b15dac032b6 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -432,7 +432,7 @@ def test_pickings_with_different_partners(self): batch2 = self.make_picking_batch._create_batch() self.assertEqual(self.pick1 | self.pick2, batch2.picking_ids) - def test_picking_with_maximum_number_of_lines_exceed(self): + def test_picking_split_with_maximum_number_of_lines_exceed(self): # pick 3 has 2 lines # create a batch picking with maximum number of lines = 1 self.pick1.action_cancel() @@ -441,12 +441,94 @@ def test_picking_with_maximum_number_of_lines_exceed(self): self.make_picking_batch.write( { "maximum_number_of_preparation_lines": 1, - "no_line_limit_if_no_candidate": False, + "split_picking_exceeding_limits": False, } ) with self.assertRaises(PickingCandidateNumberLineExceedError): self.make_picking_batch._create_batch(raise_if_not_possible=True) - self.make_picking_batch.no_line_limit_if_no_candidate = True + self.make_picking_batch.split_picking_exceeding_limits = True batch = self.make_picking_batch._create_batch() self.assertEqual(self.pick3, batch.picking_ids) - self.assertEqual(len(batch.move_line_ids), 2) + self.assertEqual(len(batch.move_line_ids), 1) + + def test_picking_split_with_weight_exceed(self): + # pick 3 has 2 lines + # we will set a weight by line under the maximum weight of the device + # but the total weight of the picking will exceed the maximum weight of the device + # when the batch is created, the picking 3 should be split and the batch + # should contain only pick3 with 1 line + + self.pick1.action_cancel() + self.pick2.action_cancel() + self.assertEqual(len(self.pick3.move_line_ids), 2) + max_weight = 200 + device = self.env["stock.device.type"].create( + { + "name": "test volume null devices and one bin", + "min_volume": 0, + "max_volume": 200, + "max_weight": max_weight, + "nbr_bins": 1, + "sequence": 50, + } + ) + + self.make_picking_batch.write( + { + "split_picking_exceeding_limits": False, + "stock_device_type_ids": [(6, 0, [device.id])], + } + ) + self.pick3.move_ids.product_id.weight = max_weight - 1 + self.pick3.move_ids._cal_move_weight() + with self.assertRaises(NoSuitableDeviceError): + self.make_picking_batch._create_batch(raise_if_not_possible=True) + self.make_picking_batch.split_picking_exceeding_limits = True + batch = self.make_picking_batch._create_batch() + self.assertEqual(self.pick3, batch.picking_ids) + self.assertEqual(len(batch.move_line_ids), 1) + + def test_picking_split_with_volume_exceed(self): + # pick 3 has 2 lines + # we will set a volume by line under the maximum volume of the device + # but the total volume of the picking will exceed the maximum volume of the device + # when the batch is created, the picking 3 should be split and the batch + # should contain only pick3 with 1 line + + self.pick1.action_cancel() + self.pick2.action_cancel() + self.assertEqual(len(self.pick3.move_line_ids), 2) + + max_volume = 200 + device = self.env["stock.device.type"].create( + { + "name": "test volume null devices and one bin", + "min_volume": 0, + "max_volume": max_volume, + "max_weight": 300, + "nbr_bins": 1, + "sequence": 50, + } + ) + + self.make_picking_batch.write( + { + "split_picking_exceeding_limits": False, + "stock_device_type_ids": [(6, 0, [device.id])], + } + ) + # each product has a volume of 120 + self.pick3.move_ids.product_id.write( + { + "product_length": 12, + "product_height": 5, + "product_width": 2, + } + ) + self.pick3.move_ids._compute_volume() + with self.assertRaises(NoSuitableDeviceError): + self.make_picking_batch._create_batch(raise_if_not_possible=True) + self.make_picking_batch.split_picking_exceeding_limits = True + batch = self.make_picking_batch._create_batch() + self.assertEqual(self.pick3, batch.picking_ids) + self.assertEqual(len(batch.move_line_ids), 1) diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 9c4e4455589..ac45e0d02f3 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -80,16 +80,14 @@ class MakePickingBatch(models.TransientModel): "by default.", ) - no_line_limit_if_no_candidate = fields.Boolean( - default=True, - string="No line limit if no candidate", - help="If checked, the maximum number of lines will not be applied if there is " - "no candidate to add to the batch with a number of lines less than the maximum " - "number of lines. This option is useful if you want relax the maximum number " - "of lines to allow to create a batch even if there is no candidate to add to " - "the batch at first. This will avoid to manually create a batch with a single " - "picking for the sole case where a device is suitable for the picking but the " - "picking has more lines than the maximum number of lines.", + split_picking_exceeding_limits = fields.Boolean( + default=False, + string="Split pickings exceeding limits", + help="If checked, the pickings exceeding the maximum number of lines, " + "volume or weight of available devices will be split into multiple pickings " + "to respect the limits. If unchecked, the pickings exceeding the limits will not " + "be added to the batch. The limits are defined by the limits of the last available " + "devices.", ) __slots__ = ( @@ -260,15 +258,41 @@ def _execute_search_pickings(self, domain, limit=None): domain, order=self._get_picking_order_by(), limit=limit ) - def _get_first_picking(self, no_nbr_lines_limit=False): - domain = self._get_picking_domain_for_first( - no_nbr_lines_limit=no_nbr_lines_limit - ) - device_domains = [] - for device in self.stock_device_type_ids: - device_domains.append(self._get_picking_domain_for_device(device)) - domain = AND([domain, OR(device_domains)]) - return self._execute_search_pickings(domain, limit=1) + def _get_picking_max_dimensions(self): + self.ensure_one() + nbr_lines = self.maximum_number_of_preparation_lines + last_device = self.stock_device_type_ids[-1] + volume = last_device.max_volume + weight = last_device.max_weight + return nbr_lines, volume, weight + + def _split_first_picking_for_limit(self, picking): + nbr_lines, volume, weight = self._get_picking_max_dimensions() + wizard = self.env["stock.split.picking"].with_context(active_ids=picking.ids) + wizard.create( + { + "mode": "dimensions", + "max_nbr_lines": nbr_lines, + "max_volume": volume, + "max_weight": weight, + } + ).action_apply() + return picking + + def _get_first_picking(self, no_limit=False): + domain = self._get_picking_domain_for_first(no_nbr_lines_limit=no_limit) + if not no_limit: + device_domains = [] + for device in self.stock_device_type_ids: + device_domains.append(self._get_picking_domain_for_device(device)) + domain = AND([domain, OR(device_domains)]) + picking = self._execute_search_pickings(domain, limit=1) + if self.split_picking_exceeding_limits: + if not no_limit and not picking: + return self._get_first_picking(no_limit=True) + if no_limit and picking: + return self._split_first_picking_for_limit(picking) + return picking def _get_additional_picking(self): """Get the next picking to add to the batch.""" @@ -334,13 +358,17 @@ def _raise_create_batch_not_possible(self): # constrains. If not, we raise an error to inform the user that there # is no picking to process otherwise we raise an error to inform the # user that there is not suitable device to process the pickings. - if not self.no_line_limit_if_no_candidate: - domain = self._get_picking_domain_for_first(no_nbr_lines_limit=True) - candidates = self.env["stock.picking"].search(domain, limit=1) - if candidates: - raise PickingCandidateNumberLineExceedError( - candidates, self.maximum_number_of_preparation_lines - ) + domain = self._get_picking_domain_for_first(no_nbr_lines_limit=True) + device_domains = [] + for device in self.stock_device_type_ids: + device_domains.append(self._get_picking_domain_for_device(device)) + domain = AND([domain, OR(device_domains)]) + candidates = self.env["stock.picking"].search(domain, limit=1) + if candidates: + raise PickingCandidateNumberLineExceedError( + candidates, self.maximum_number_of_preparation_lines + ) + domain = self._get_picking_domain_for_first() limit = 1 if self.add_picking_list_in_error: @@ -356,13 +384,15 @@ def _create_batch(self, raise_if_not_possible=False): self._reset_counters() # first we try to get the first picking for the user first_picking = self._get_first_picking() - if not first_picking and self.no_line_limit_if_no_candidate: - first_picking = self._get_first_picking(no_nbr_lines_limit=True) if not first_picking: if raise_if_not_possible: self._raise_create_batch_not_possible() return self.env["stock.picking.batch"].browse() device = self._compute_device_to_use(first_picking) + if not device: + if raise_if_not_possible: + raise NoSuitableDeviceError(pickings=first_picking) + return self.env["stock.picking.batch"].browse() self._init_counters(first_picking, device) self._apply_limits() vals = self._create_batch_values() diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.xml b/stock_picking_batch_creation/wizards/make_picking_batch.xml index c28c1fb1977..6cd89624065 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.xml +++ b/stock_picking_batch_creation/wizards/make_picking_batch.xml @@ -10,11 +10,10 @@
- + - From d15b4b2dda0a81450c893174778922a2dc6bff3c Mon Sep 17 00:00:00 2001 From: "Laurent Mignonn (ACSONE)" Date: Wed, 23 Oct 2024 14:25:34 +0200 Subject: [PATCH 261/357] [IMP] stock_picking_batch_creation: Right pickings order When we allow pickings to be split if one of the volume, weight or number of lines criteria exceeds the set limits, we take care to select the first picking to be processed in accordance with the processing order defined in the system. --- stock_picking_batch_creation/README.rst | 17 ++++++ stock_picking_batch_creation/exceptions.py | 16 ++++- stock_picking_batch_creation/readme/USAGE.rst | 17 ++++-- .../static/description/index.html | 52 ++++++++++------ .../tests/test_clustering_conditions.py | 50 +++++++++++++++ .../wizards/make_picking_batch.py | 61 +++++++++++++++---- 6 files changed, 176 insertions(+), 37 deletions(-) diff --git a/stock_picking_batch_creation/README.rst b/stock_picking_batch_creation/README.rst index 1f349d7e869..a4123e3c627 100644 --- a/stock_picking_batch_creation/README.rst +++ b/stock_picking_batch_creation/README.rst @@ -140,6 +140,23 @@ are for the same partner. When activated, the computation of the number of bins consumed by the picking into the batch will take into account the volume of the pickings for the same partners already. +Splitting picking if needed +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can also activate the option *Split picking exceeding the limits* on the +wizard. In this case, when the system select the first picking to add to the +batch, it will disable the criteria based on the volume, weight and number of +lines. If the picking is exceeding the limits, the system will then try to split +the picking so that the new picking fits the criteria and can be added to the +batch. If the picking can't be split, an exception will be raised. + +This option is useful to allow to create a batch picking with pickings that +are exceeding the limits defined in the wizard. It also ensures that the +processing of pickings is done in the order of the pickings. If the option is +not activated, the system will try to find a picking that fits the criteria +and will ignore those that are exceeding the limits even if they are to be +processed first. + Bug Tracker =========== diff --git a/stock_picking_batch_creation/exceptions.py b/stock_picking_batch_creation/exceptions.py index 430648b561e..0b6b8d15807 100644 --- a/stock_picking_batch_creation/exceptions.py +++ b/stock_picking_batch_creation/exceptions.py @@ -6,7 +6,8 @@ class NoPickingCandidateError(UserError): - def __init__(self): + def __init__(self, env): + self.env = env super(NoPickingCandidateError, self).__init__( _("no candidate pickings to batch") ) @@ -14,6 +15,7 @@ def __init__(self): class PickingCandidateNumberLineExceedError(UserError): def __init__(self, picking, max_line): + self.env = picking.env self.picking = picking super(PickingCandidateNumberLineExceedError, self).__init__( _( @@ -28,7 +30,8 @@ def __init__(self, picking, max_line): class NoSuitableDeviceError(UserError): - def __init__(self, pickings): + def __init__(self, env, pickings): + self.env = env self.pickings = pickings message = _("No device found for batch picking.") if pickings: @@ -37,3 +40,12 @@ def __init__(self, pickings): names=", ".join(self.pickings.mapped("name")), ) super(NoSuitableDeviceError, self).__init__(message) + + +class PickingSplitNotPossibleError(UserError): + def __init__(self, picking): + self.env = picking.env + self.picking = picking + super(PickingSplitNotPossibleError, self).__init_( + _("Picking %(name)s cannot be split", name=self.picking.name) + ) diff --git a/stock_picking_batch_creation/readme/USAGE.rst b/stock_picking_batch_creation/readme/USAGE.rst index a227e47a365..c27f24e1703 100644 --- a/stock_picking_batch_creation/readme/USAGE.rst +++ b/stock_picking_batch_creation/readme/USAGE.rst @@ -71,8 +71,15 @@ Splitting picking if needed ^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can also activate the option *Split picking exceeding the limits* on the -wizard. This will allow, when the system is not able to find a picking that -fits the criteria to create the batch, to lower the criteria by removing those -based on the volume, weight and number of lines. If a picking is found and -you allow to split it, the system will try to split the picking so that the -new picking fits the criteria and can be added to the batch. \ No newline at end of file +wizard. In this case, when the system select the first picking to add to the +batch, it will disable the criteria based on the volume, weight and number of +lines. If the picking is exceeding the limits, the system will then try to split +the picking so that the new picking fits the criteria and can be added to the +batch. If the picking can't be split, an exception will be raised. + +This option is useful to allow to create a batch picking with pickings that +are exceeding the limits defined in the wizard. It also ensures that the +processing of pickings is done in the order of the pickings. If the option is +not activated, the system will try to find a picking that fits the criteria +and will ignore those that are exceeding the limits even if they are to be +processed first. \ No newline at end of file diff --git a/stock_picking_batch_creation/static/description/index.html b/stock_picking_batch_creation/static/description/index.html index c42de5c9b97..a7183aa0d02 100644 --- a/stock_picking_batch_creation/static/description/index.html +++ b/stock_picking_batch_creation/static/description/index.html @@ -1,4 +1,3 @@ - @@ -9,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -409,16 +409,17 @@

Stock device types

  • Advanced configuration
  • -
  • Bug Tracker
  • -
  • Credits @@ -483,10 +484,25 @@

    Grouping by partner

    number of bins consumed by the picking into the batch will take into account the volume of the pickings for the same partners already.

  • +
    +

    Splitting picking if needed

    +

    You can also activate the option Split picking exceeding the limits on the +wizard. In this case, when the system select the first picking to add to the +batch, it will disable the criteria based on the volume, weight and number of +lines. If the picking is exceeding the limits, the system will then try to split +the picking so that the new picking fits the criteria and can be added to the +batch. If the picking can’t be split, an exception will be raised.

    +

    This option is useful to allow to create a batch picking with pickings that +are exceeding the limits defined in the wizard. It also ensures that the +processing of pickings is done in the order of the pickings. If the option is +not activated, the system will try to find a picking that fits the criteria +and will ignore those that are exceeding the limits even if they are to be +processed first.

    +
    -

    Bug Tracker

    +

    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 to smash it by providing a detailed and welcomed @@ -494,22 +510,22 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ACSONE SA/NV
    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +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.

    diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index b15dac032b6..cb513cfbb3c 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -532,3 +532,53 @@ def test_picking_split_with_volume_exceed(self): batch = self.make_picking_batch._create_batch() self.assertEqual(self.pick3, batch.picking_ids) self.assertEqual(len(batch.move_line_ids), 1) + + def test_picking_split_priority(self): + # We ensure than even if a picking with a higher priority has a volume + # exceeding the device capacity, it will be split and processed first + # if the split_picking_exceeding_limits is set to True + # the processing order for picks of type 1 will be: + # pick3 (priority), pick1 (lower id), pick2 + self.assertEqual(len(self.pick3.move_line_ids), 2) + + max_volume = 200 + device = self.env["stock.device.type"].create( + { + "name": "test volume null devices and one bin", + "min_volume": 0, + "max_volume": max_volume, + "max_weight": 300, + "nbr_bins": 1, + "sequence": 50, + } + ) + + self.make_picking_batch.write( + { + "split_picking_exceeding_limits": False, + "stock_device_type_ids": [(6, 0, [device.id])], + } + ) + # each product has a volume of 120 + self.pick3.move_ids.product_id.write( + { + "product_length": 12, + "product_height": 5, + "product_width": 2, + } + ) + self.pick3.move_ids._compute_volume() + + # since pick3 exceeds the device capacity and + # the split_picking_exceeding_limits is set to False + # the next picking to process should be pick1 + batch = self.make_picking_batch._create_batch() + self.assertEqual(self.pick1, batch.picking_ids) + + batch.unlink() + + # if the split_picking_exceeding_limits is set to True. + # then pick3 should be split and processed first + self.make_picking_batch.split_picking_exceeding_limits = True + batch = self.make_picking_batch._create_batch() + self.assertEqual(self.pick3, batch.picking_ids) diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index ac45e0d02f3..94653aaf17a 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -1,6 +1,6 @@ # Copyright 2021 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - +import logging import math import threading from collections import defaultdict @@ -13,8 +13,11 @@ NoPickingCandidateError, NoSuitableDeviceError, PickingCandidateNumberLineExceedError, + PickingSplitNotPossibleError, ) +_logger = logging.getLogger(__name__) + class MakePickingBatch(models.TransientModel): @@ -279,7 +282,29 @@ def _split_first_picking_for_limit(self, picking): ).action_apply() return picking - def _get_first_picking(self, no_limit=False): + def _is_picking_exceeding_limits(self, picking): + """Check if the picking exceeds the limits of the available devices. + + :param picking: the picking to check + """ + nbr_lines, volume, weight = self._get_picking_max_dimensions() + return ( + picking.nbr_picking_lines > nbr_lines + or picking.volume > volume + or picking.weight > weight + ) + + def _get_first_picking(self, raise_if_not_found=False): + """Get the first picking to add to the batch. + + If the split_picking_exceeding_limits is set, we try to find the first picking + without taking into account the limit on the number of lines and we split it + if it exceeds the limits. If the split is not possible, we raise an error. + + Otherwise, we try to find the first picking taking into account the limit on the + number of lines. + """ + no_limit = self.split_picking_exceeding_limits domain = self._get_picking_domain_for_first(no_nbr_lines_limit=no_limit) if not no_limit: device_domains = [] @@ -287,11 +312,21 @@ def _get_first_picking(self, no_limit=False): device_domains.append(self._get_picking_domain_for_device(device)) domain = AND([domain, OR(device_domains)]) picking = self._execute_search_pickings(domain, limit=1) - if self.split_picking_exceeding_limits: - if not no_limit and not picking: - return self._get_first_picking(no_limit=True) - if no_limit and picking: - return self._split_first_picking_for_limit(picking) + if not picking and not no_limit and raise_if_not_found: + self._raise_create_batch_not_possible() + # at this stage we have the first picking to add to the batch but it could + # exceed the limits of the available devices. In this case we split the + # picking and return the picking to add to the batch. The split is done only + # if the split_picking_exceeding_limits is set to True. + if ( + picking + and self.split_picking_exceeding_limits + and self._is_picking_exceeding_limits(picking) + ): + split_picking = self._split_first_picking_for_limit(picking) + if not split_picking and raise_if_not_found: + raise PickingSplitNotPossibleError(picking) + picking = split_picking return picking def _get_additional_picking(self): @@ -376,22 +411,22 @@ def _raise_create_batch_not_possible(self): candidates = self.env["stock.picking"].search(domain, limit=limit) if candidates: pickings = candidates if self.add_picking_list_in_error else None - raise NoSuitableDeviceError(pickings=pickings) - raise NoPickingCandidateError() + raise NoSuitableDeviceError(self.env, pickings=pickings) + raise NoPickingCandidateError(self.env) def _create_batch(self, raise_if_not_possible=False): """Create a batch transfer.""" self._reset_counters() # first we try to get the first picking for the user - first_picking = self._get_first_picking() + first_picking = self._get_first_picking( + raise_if_not_found=raise_if_not_possible + ) if not first_picking: - if raise_if_not_possible: - self._raise_create_batch_not_possible() return self.env["stock.picking.batch"].browse() device = self._compute_device_to_use(first_picking) if not device: if raise_if_not_possible: - raise NoSuitableDeviceError(pickings=first_picking) + raise NoSuitableDeviceError(self.env, pickings=first_picking) return self.env["stock.picking.batch"].browse() self._init_counters(first_picking, device) self._apply_limits() From 2472109de4ed5ee8e450eb70f675e0c1c6006bc0 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Mon, 18 Aug 2025 08:53:08 +0000 Subject: [PATCH 262/357] [UPD] Update stock_picking_batch_creation.pot --- .../i18n/stock_picking_batch_creation.pot | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot b/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot index feaebf25ac4..5cb3a7fdddd 100644 --- a/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot +++ b/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot @@ -150,15 +150,13 @@ msgid "ID" msgstr "" #. module: stock_picking_batch_creation -#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__no_line_limit_if_no_candidate +#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits msgid "" -"If checked, the maximum number of lines will not be applied if there is no " -"candidate to add to the batch with a number of lines less than the maximum " -"number of lines. This option is useful if you want relax the maximum number " -"of lines to allow to create a batch even if there is no candidate to add to " -"the batch at first. This will avoid to manually create a batch with a single" -" picking for the sole case where a device is suitable for the picking but " -"the picking has more lines than the maximum number of lines." +"If checked, the pickings exceeding the maximum number of lines, volume or " +"weight of available devices will be split into multiple pickings to respect " +"the limits. If unchecked, the pickings exceeding the limits will not be " +"added to the batch. The limits are defined by the limits of the last " +"available devices." msgstr "" #. module: stock_picking_batch_creation @@ -272,11 +270,6 @@ msgstr "" msgid "No device found for batch picking." msgstr "" -#. module: stock_picking_batch_creation -#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__no_line_limit_if_no_candidate -msgid "No line limit if no candidate" -msgstr "" - #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__nbr_bins #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_picking_batch__batch_nbr_bins @@ -310,6 +303,13 @@ msgstr "" msgid "Packaging volume unit of measure" msgstr "" +#. module: stock_picking_batch_creation +#. odoo-python +#: code:addons/stock_picking_batch_creation/exceptions.py:0 +#, python-format +msgid "Picking %(name)s cannot be split" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__picking_locking_mode msgid "Picking locking mode" @@ -340,6 +340,11 @@ msgstr "" msgid "SQL FOR UPDATE SKIP LOCKED" msgstr "" +#. module: stock_picking_batch_creation +#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits +msgid "Split pickings exceeding limits" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.actions.act_window,name:stock_picking_batch_creation.stock_device_type_act_window #: model:ir.model,name:stock_picking_batch_creation.model_stock_device_type From d5a5f63522cd08d2fe0c804e6078ce128ba25b8e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 18 Aug 2025 09:04:43 +0000 Subject: [PATCH 263/357] [BOT] post-merge updates --- README.md | 2 +- stock_picking_batch_creation/README.rst | 8 +++- stock_picking_batch_creation/__manifest__.py | 2 +- .../static/description/index.html | 42 +++++++++++-------- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 16ea4e90a08..12181ac76bc 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ addon | version | maintainers | summary [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves [stock_full_location_reservation](stock_full_location_reservation/) | 16.0.1.0.0 | mt-software-de | Extend reservation to full content of location -[stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.1.0.0 | lmignon | Create a batch of pickings to be processed all together +[stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.2.1.0 | lmignon | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type [stock_release_channel](stock_release_channel/) | 16.0.3.1.0 | sebalix jbaudoux mt-software-de | Manage workload in WMS with release channels diff --git a/stock_picking_batch_creation/README.rst b/stock_picking_batch_creation/README.rst index a4123e3c627..da35af542be 100644 --- a/stock_picking_batch_creation/README.rst +++ b/stock_picking_batch_creation/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================ Stock Picking Batch Creation ============================ @@ -7,13 +11,13 @@ Stock Picking Batch Creation !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:557c220536f625bc1a34b247c50dd7af3d0700fc112ddf1e1bb9e92e7094be97 + !! source digest: sha256:af42f7a43dd7eff1c265bcf1ee896c20a5de4226c3c313fd6251d8c94fae1cad !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_picking_batch_creation/__manifest__.py b/stock_picking_batch_creation/__manifest__.py index 947d8251958..f81633c5056 100644 --- a/stock_picking_batch_creation/__manifest__.py +++ b/stock_picking_batch_creation/__manifest__.py @@ -5,7 +5,7 @@ "name": "Stock Picking Batch Creation", "summary": """ Create a batch of pickings to be processed all together""", - "version": "16.0.2.0.0", + "version": "16.0.2.1.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_picking_batch_creation/static/description/index.html b/stock_picking_batch_creation/static/description/index.html index a7183aa0d02..1022bbc0f1b 100644 --- a/stock_picking_batch_creation/static/description/index.html +++ b/stock_picking_batch_creation/static/description/index.html @@ -3,7 +3,7 @@ -Stock Picking Batch Creation +README.rst -
    -

    Stock Picking Batch Creation

    +
    + + +Odoo Community Association + +
    +

    Stock Picking Batch Creation

    -

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Odoo allows you to create batches of pickings by hand or automatically by specifying some criteria on the picking type definition.

    The approach in this addon is slightly different. It doesn’t depend on the @@ -382,7 +387,7 @@

    Stock Picking Batch Creation

  • A maximum number of lines in the batch
  • -

    Stock device types

    +

    Stock device types

    A stock device type is a new concept that allows to define a type of device that can be used by an operator to process operations into the warehouse (like a forklift, a compartmentalized trolleys, …).

    @@ -425,7 +430,7 @@

    Stock device types

    -

    Usage

    +

    Usage

    First of all, you need to create your stock device type. To do so, go to the Inventory -> Configuration -> Stock Device Types menu.

    Once it’s done, you can start creating your picking batches.

    @@ -436,7 +441,7 @@

    Usage

    Create Batch Picking and lets the magic happen. A new window will open with the created batch picking.

    -

    Behind the scene

    +

    Behind the scene

    The creation of the picking batch is done in 3 steps:

    1. We search for a picking ready to be processed and that fits the @@ -466,9 +471,9 @@

      Behind the scene

      the updated criteria and update the criteria at each loop iteration.

    -

    Advanced configuration

    +

    Advanced configuration

    -

    Locking

    +
    Locking

    You can choice on the wizard to apply a LOCK into the database for each picking added to the batch. This is useful in a multi-user environment with a lot of users that can trigger the creation of bach picking to avoid @@ -476,7 +481,7 @@

    Locking

    process will be skipped.

    -

    Grouping by partner

    +
    Grouping by partner

    If you want to allow to group pickings of the same partner into the same bins, you can activate the option Group by partner on the wizard. This will prevent to consume at least one bin for each picking if pickings @@ -485,7 +490,7 @@

    Grouping by partner

    the volume of the pickings for the same partners already.

    -

    Splitting picking if needed

    +
    Splitting picking if needed

    You can also activate the option Split picking exceeding the limits on the wizard. In this case, when the system select the first picking to add to the batch, it will disable the criteria based on the volume, weight and number of @@ -502,7 +507,7 @@

    Splitting picking if needed

    -

    Bug Tracker

    +

    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 to smash it by providing a detailed and welcomed @@ -510,22 +515,22 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ACSONE SA/NV
    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -549,5 +554,6 @@

    Maintainers

    +
    From 4c12a9a41513a464c7c628b612eb10cb94395c1a Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 18 Aug 2025 09:04:52 +0000 Subject: [PATCH 264/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_picking_batch_creation Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_picking_batch_creation/ --- stock_picking_batch_creation/i18n/fr.po | 31 ++++++----- stock_picking_batch_creation/i18n/it.po | 68 ++++++++++++++++--------- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/stock_picking_batch_creation/i18n/fr.po b/stock_picking_batch_creation/i18n/fr.po index 699210fc2ae..92c64904dcc 100644 --- a/stock_picking_batch_creation/i18n/fr.po +++ b/stock_picking_batch_creation/i18n/fr.po @@ -163,15 +163,13 @@ msgid "ID" msgstr "" #. module: stock_picking_batch_creation -#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__no_line_limit_if_no_candidate +#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits msgid "" -"If checked, the maximum number of lines will not be applied if there is no " -"candidate to add to the batch with a number of lines less than the maximum " -"number of lines. This option is useful if you want relax the maximum number " -"of lines to allow to create a batch even if there is no candidate to add to " -"the batch at first. This will avoid to manually create a batch with a single " -"picking for the sole case where a device is suitable for the picking but the " -"picking has more lines than the maximum number of lines." +"If checked, the pickings exceeding the maximum number of lines, volume or " +"weight of available devices will be split into multiple pickings to respect " +"the limits. If unchecked, the pickings exceeding the limits will not be " +"added to the batch. The limits are defined by the limits of the last " +"available devices." msgstr "" #. module: stock_picking_batch_creation @@ -291,11 +289,6 @@ msgstr "Nom" msgid "No device found for batch picking." msgstr "Aucun matériel de préparation trouvé pour la vague de transferts." -#. module: stock_picking_batch_creation -#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__no_line_limit_if_no_candidate -msgid "No line limit if no candidate" -msgstr "" - #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__nbr_bins #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_picking_batch__batch_nbr_bins @@ -331,6 +324,13 @@ msgstr "" msgid "Packaging volume unit of measure" msgstr "Unité de mesure de volume" +#. module: stock_picking_batch_creation +#. odoo-python +#: code:addons/stock_picking_batch_creation/exceptions.py:0 +#, python-format +msgid "Picking %(name)s cannot be split" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__picking_locking_mode msgid "Picking locking mode" @@ -361,6 +361,11 @@ msgstr "" msgid "SQL FOR UPDATE SKIP LOCKED" msgstr "SQL FOR UPDATE SKIP LOCKED" +#. module: stock_picking_batch_creation +#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits +msgid "Split pickings exceeding limits" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.actions.act_window,name:stock_picking_batch_creation.stock_device_type_act_window #: model:ir.model,name:stock_picking_batch_creation.model_stock_device_type diff --git a/stock_picking_batch_creation/i18n/it.po b/stock_picking_batch_creation/i18n/it.po index 9a79f3cbb8a..f22047f4db3 100644 --- a/stock_picking_batch_creation/i18n/it.po +++ b/stock_picking_batch_creation/i18n/it.po @@ -103,8 +103,7 @@ msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__picking_type_ids -msgid "" -"Default list of eligible operation types when creating a batch transfer" +msgid "Default list of eligible operation types when creating a batch transfer" msgstr "" "Lista predefinita dei tipi operazione utilizzabili nella creazione di un " "trasferimento raggruppato" @@ -165,31 +164,21 @@ msgid "ID" msgstr "ID" #. module: stock_picking_batch_creation -#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__no_line_limit_if_no_candidate +#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits msgid "" -"If checked, the maximum number of lines will not be applied if there is no " -"candidate to add to the batch with a number of lines less than the maximum " -"number of lines. This option is useful if you want relax the maximum number " -"of lines to allow to create a batch even if there is no candidate to add to " -"the batch at first. This will avoid to manually create a batch with a single" -" picking for the sole case where a device is suitable for the picking but " -"the picking has more lines than the maximum number of lines." +"If checked, the pickings exceeding the maximum number of lines, volume or " +"weight of available devices will be split into multiple pickings to respect " +"the limits. If unchecked, the pickings exceeding the limits will not be " +"added to the batch. The limits are defined by the limits of the last " +"available devices." msgstr "" -"Se selezionate, il massimo nimero di righe non verrà applicato se non ci " -"sono candidati da aggiungere al gruppo con un numero di righe inferiore al " -"massimo numero di righe. L'opzione è utile se si vuolerilasciare il massimo " -"numero di righe per consentire di creare un gruppo anche se non ci sono " -"candidati da aggiungere al gruppo come primi. Questo eviterà di creare " -"manualmente un gruppo con un singolo prelievo per il solo caso in cui un " -"dispositivo sia disponibile per il prelievo ma il prelievo ha più righe del " -"massimo." #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__add_picking_list_in_error msgid "" "If not suitable device is provided for the pickings candidates, the error " -"message will contain the list of the pickings names. In somecases, this list" -" can be very long. That's why this option is uncheckedby default." +"message will contain the list of the pickings names. In somecases, this list " +"can be very long. That's why this option is uncheckedby default." msgstr "" "Se non viene fornito un dispositivo idoneo per i prelievi candidati, il " "messaggio di errore conterrà la lista dei nomi dei prelievi. In alcunui " @@ -299,11 +288,6 @@ msgstr "Nome" msgid "No device found for batch picking." msgstr "Nessun dispositivo trovato per il gruppo prelievo." -#. module: stock_picking_batch_creation -#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__no_line_limit_if_no_candidate -msgid "No line limit if no candidate" -msgstr "Nessun limite riga se non c'è il candidato" - #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__nbr_bins #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_picking_batch__batch_nbr_bins @@ -340,6 +324,13 @@ msgstr "" msgid "Packaging volume unit of measure" msgstr "Unità di misura per il volume dell'imballaggio" +#. module: stock_picking_batch_creation +#. odoo-python +#: code:addons/stock_picking_batch_creation/exceptions.py:0 +#, python-format +msgid "Picking %(name)s cannot be split" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__picking_locking_mode msgid "Picking locking mode" @@ -370,6 +361,11 @@ msgstr "Restringi alla stessa priorità" msgid "SQL FOR UPDATE SKIP LOCKED" msgstr "SQL PER SALTO AGGIORNAMENTO BLOCCATO" +#. module: stock_picking_batch_creation +#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits +msgid "Split pickings exceeding limits" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.actions.act_window,name:stock_picking_batch_creation.stock_device_type_act_window #: model:ir.model,name:stock_picking_batch_creation.model_stock_device_type @@ -444,3 +440,25 @@ msgstr "es. muletto" #, python-format msgid "no candidate pickings to batch" msgstr "nessun prelievo candidato da raggruppare" + +#~ msgid "" +#~ "If checked, the maximum number of lines will not be applied if there is " +#~ "no candidate to add to the batch with a number of lines less than the " +#~ "maximum number of lines. This option is useful if you want relax the " +#~ "maximum number of lines to allow to create a batch even if there is no " +#~ "candidate to add to the batch at first. This will avoid to manually " +#~ "create a batch with a single picking for the sole case where a device is " +#~ "suitable for the picking but the picking has more lines than the maximum " +#~ "number of lines." +#~ msgstr "" +#~ "Se selezionate, il massimo nimero di righe non verrà applicato se non ci " +#~ "sono candidati da aggiungere al gruppo con un numero di righe inferiore " +#~ "al massimo numero di righe. L'opzione è utile se si vuolerilasciare il " +#~ "massimo numero di righe per consentire di creare un gruppo anche se non " +#~ "ci sono candidati da aggiungere al gruppo come primi. Questo eviterà di " +#~ "creare manualmente un gruppo con un singolo prelievo per il solo caso in " +#~ "cui un dispositivo sia disponibile per il prelievo ma il prelievo ha più " +#~ "righe del massimo." + +#~ msgid "No line limit if no candidate" +#~ msgstr "Nessun limite riga se non c'è il candidato" From 641d3bbc70f471305d2eb53f496a303218b10f24 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 20 Aug 2025 15:11:01 +0000 Subject: [PATCH 265/357] Translated using Weblate (Italian) Currently translated at 100.0% (73 of 73 strings) Translation: wms-16.0/wms-16.0-stock_picking_batch_creation Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_picking_batch_creation/it/ --- stock_picking_batch_creation/i18n/it.po | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/stock_picking_batch_creation/i18n/it.po b/stock_picking_batch_creation/i18n/it.po index f22047f4db3..1cbd40cefb4 100644 --- a/stock_picking_batch_creation/i18n/it.po +++ b/stock_picking_batch_creation/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-06-07 12:35+0000\n" +"PO-Revision-Date: 2025-08-20 17:27+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_picking_batch_creation #. odoo-python @@ -172,6 +172,11 @@ msgid "" "added to the batch. The limits are defined by the limits of the last " "available devices." msgstr "" +"Se selezionata, i prelievi che superano il numero massimo di righe, volume o " +"peso dei dispositivi disponibili verranno suddivisi in più prelievi per " +"rispettare i limiti. Se deselezionata, i prelievi che superano i limiti non " +"verranno aggiunti al lotto. I limiti sono definiti dai limiti degli ultimi " +"dispositivi disponibili." #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__add_picking_list_in_error @@ -329,7 +334,7 @@ msgstr "Unità di misura per il volume dell'imballaggio" #: code:addons/stock_picking_batch_creation/exceptions.py:0 #, python-format msgid "Picking %(name)s cannot be split" -msgstr "" +msgstr "Il prelievo %(name)s non può essere suddiviso" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__picking_locking_mode @@ -364,7 +369,7 @@ msgstr "SQL PER SALTO AGGIORNAMENTO BLOCCATO" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits msgid "Split pickings exceeding limits" -msgstr "" +msgstr "Prelievi suddivisi che ecceedono i limiti" #. module: stock_picking_batch_creation #: model:ir.actions.act_window,name:stock_picking_batch_creation.stock_device_type_act_window From 566251fd028f7ed58fc09d30bd0c92232cdc9b58 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Fri, 22 Aug 2025 13:50:17 +0200 Subject: [PATCH 266/357] [IMP] shopfloor_reception: Don't display error message if just one picking has been found --- shopfloor_reception/services/reception.py | 6 +++++- shopfloor_reception/tests/test_select_document.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 156f600c677..a0076e69ea4 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -206,9 +206,13 @@ def _select_document_from_product(self, product): ) pickings = move_lines.move_id.picking_id if pickings: + message = None + # Don't display error message if just one picking has been found + if len(pickings) > 1: + message = self.msg_store.multiple_picks_found_select_manually() return self._response_for_select_document( pickings=pickings, - message=self.msg_store.multiple_picks_found_select_manually(), + message=message, ) return self._response_for_select_document( pickings=pickings, diff --git a/shopfloor_reception/tests/test_select_document.py b/shopfloor_reception/tests/test_select_document.py index 83c93267227..7de580e35b4 100644 --- a/shopfloor_reception/tests/test_select_document.py +++ b/shopfloor_reception/tests/test_select_document.py @@ -149,6 +149,19 @@ def test_scan_product_multiple_pickings(self): message={"message_type": "error", "body": body}, ) + def test_scan_product_one_picking(self): + # next step is select_document, with document filtered based on the product + p1 = self._create_picking() + response = self.service.dispatch( + "scan_document", params={"barcode": self.product_a.barcode} + ) + self.assert_response( + response, + next_state="select_document", + data={"pickings": self._data_for_pickings(p1)}, + message=None, + ) + def test_scan_product_no_picking(self): # next_step is select_document, with an error message picking = self._create_picking() From 0080a2d5d4ed7392add4b5ca1cec0126aa1e291e Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 7 Apr 2025 16:03:09 +0200 Subject: [PATCH 267/357] [IMP] shopfloor_reception: Allows to interpret parsed result for multi attribute barcode As some barcodes structures (like GS1) interpretation possibilities. --- shopfloor_reception/models/__init__.py | 1 + shopfloor_reception/models/stock_move_line.py | 19 +++++ shopfloor_reception/services/reception.py | 77 +++++++++++++++++-- shopfloor_reception/tests/common.py | 1 - .../tests/test_multi_barcode.py | 59 ++++++++++++++ 5 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 shopfloor_reception/models/stock_move_line.py create mode 100644 shopfloor_reception/tests/test_multi_barcode.py diff --git a/shopfloor_reception/models/__init__.py b/shopfloor_reception/models/__init__.py index 8bd3d5195ca..eacaa196020 100644 --- a/shopfloor_reception/models/__init__.py +++ b/shopfloor_reception/models/__init__.py @@ -1 +1,2 @@ from . import shopfloor_menu +from . import stock_move_line diff --git a/shopfloor_reception/models/stock_move_line.py b/shopfloor_reception/models/stock_move_line.py new file mode 100644 index 00000000000..03bb9d6e2da --- /dev/null +++ b/shopfloor_reception/models/stock_move_line.py @@ -0,0 +1,19 @@ +# Copyright 2025 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) + +from odoo import models + + +class StockMoveLine(models.Model): + + _inherit = "stock.move.line" + + @property + def shopfloor_should_create_lot(self) -> bool: + """ + This will return True if the line should be used to create lots + """ + return bool( + (not self.lot_id and not self.lot_name) + and self.picking_type_use_create_lots + ) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 156f600c677..ffdaf6e4242 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -5,12 +5,14 @@ import pytz +from decorator import contextmanager from odoo import fields from odoo.tools import float_compare from odoo.addons.base_rest.components.service import to_int from odoo.addons.component.core import Component +from odoo.addons.shopfloor.actions.search import SearchResult from odoo.addons.shopfloor.utils import to_float @@ -48,6 +50,19 @@ class Reception(Component): _usage = "reception" _description = __doc__ + search_result = SearchResult() + + @contextmanager + def with_search_result(self, search_result: SearchResult): + """ + Use this context manager if you want to include search result in + component behavior. + + """ + self.search_result = search_result + yield + self.search_result = SearchResult() + def _check_picking_processible(self, pickings): # When returns are allowed, # the created picking might be empty and cannot be assigned. @@ -439,7 +454,13 @@ def _scan_line__by_product__return(self, picking, product): picking.action_assign() return self._scan_line__find_or_create_line(picking, return_move) + def _scan_line__dummy(self): + return + def _scan_line__by_product(self, picking, product): + """ + Try to find a move by product + """ moves = picking.move_ids.filtered(lambda m: m.product_id == product) # Only create a return if don't already have a maching reception move if not moves and self.work.menu.allow_return: @@ -499,6 +520,9 @@ def _scan_line__by_packaging(self, picking, packaging): return self._scan_line__find_or_create_line(picking, move) def _scan_line__by_lot(self, picking, lot): + """ + Try to find a move line by its lot (it should already be assigned) + """ lines = picking.move_line_ids.filtered( lambda l: ( lot == l.lot_id @@ -540,7 +564,11 @@ def _scan_line__fallback(self, picking, barcode): message=message, ) - def _check_move_available(self, move, message_code="product"): + def _check_move_available(self, move, message_code="product") -> bool: + """ + This will check if move is available to be selected by user + scan + """ if not move: message_code = message_code.capitalize() return self.msg_store.x_not_found_or_already_in_dest_package(message_code) @@ -549,6 +577,7 @@ def _check_move_available(self, move, message_code="product"): ) if move.product_uom_qty - move.quantity_done < 1 and not line_without_package: return self.msg_store.move_already_done() + return False def _set_quantity__check_quantity_done(self, selected_line): move = selected_line.move_id @@ -764,6 +793,7 @@ def _response_for_manual_selection(self): return self._response(next_state="manual_selection", data=data) def _response_for_set_lot(self, picking, line, message=None): + self._set_lot_from_parse(picking, line) return self._response( next_state="set_lot", data={ @@ -773,6 +803,38 @@ def _response_for_set_lot(self, picking, line, message=None): message=message, ) + def _set_lot_from_parse(self, picking, line): + """ + The lot has not been found in move lines before this call. + + Following the picking type configuration, set it: + + - on lot_id if record is found + - on lot_name if record is not found + - set expiration date if found in parse result + """ + if line.shopfloor_should_create_lot and self.search_result.parse_result: + expiration_date = None + lot_name = None + found = False + for result in self.search_result.parse_result: + if result.type == "lot": + if self.search_result.type == "lot" and self.search_result.record: + lot_id = self.search_result.record + lot_name = lot_id.name + found = True + else: + lot_name = result.value + found = True + if ( + result.type == "expiration_date" + and line.product_id.use_expiration_date + ): + expiration_date = result.value + + if found: + return self.set_lot(picking.id, line.id, lot_name, expiration_date) + def _align_display_product_uom_qty(self, line, response): # This method aligns product uom qties on move lines. # In the shopfloor context, we might have multiple users working at @@ -960,14 +1022,19 @@ def scan_line(self, picking_id, barcode): "product": self._scan_line__by_product, "packaging": self._scan_line__by_packaging, "lot": self._scan_line__by_lot, + "expiration_date": self._scan_line__dummy, } search = self._actions_for("search") search_result = search.find(barcode, handlers_by_type.keys()) # Fallback handler, returns a barcode not found error handler = handlers_by_type.get(search_result.type) - if handler: - return handler(picking, search_result.record) - return self._scan_line__fallback(picking, barcode) + + # This could maybe be removed if we pass instead + # the search result through all calls + with self.with_search_result(search_result): + if handler: + return handler(picking, search_result.record) + return self._scan_line__fallback(picking, barcode) def manual_select_move(self, move_id): move = self.env["stock.move"].browse(move_id) @@ -1059,7 +1126,7 @@ def set_lot( ) selected_line.lot_id = lot.id selected_line._onchange_lot_id() - elif expiration_date: + if expiration_date: selected_line.write({"expiration_date": expiration_date}) selected_line.lot_id.write({"expiration_date": expiration_date}) return self._response_for_set_lot(picking, selected_line) diff --git a/shopfloor_reception/tests/common.py b/shopfloor_reception/tests/common.py index 5ba54d72435..1580e75011f 100644 --- a/shopfloor_reception/tests/common.py +++ b/shopfloor_reception/tests/common.py @@ -1,7 +1,6 @@ # Copyright 2020 Camptocamp SA (http://www.camptocamp.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # pylint: disable=missing-return - from odoo import fields from odoo.addons.shopfloor.tests.common import CommonCase as BaseCommonCase diff --git a/shopfloor_reception/tests/test_multi_barcode.py b/shopfloor_reception/tests/test_multi_barcode.py new file mode 100644 index 00000000000..82c9d40023a --- /dev/null +++ b/shopfloor_reception/tests/test_multi_barcode.py @@ -0,0 +1,59 @@ +# Copyright 2025 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +import mock + +from odoo import fields + +from odoo.addons.shopfloor.actions.barcode_parser import BarcodeParser, BarcodeResult + +from .common import CommonCase + + +class TestStructuredBarcode(CommonCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.product_a.tracking = "lot" + cls.product_a.use_expiration_date = True + cls.picking_type.sudo().use_create_lots = True + + def test_scan_multiple_attribute_barcode(self): + """ + Check that scanning a product with multi attribute barcode + will fill in the lot + """ + picking = self._create_picking() + lot = self._create_lot() + selected_move_line = picking.move_line_ids.filtered( + lambda l: l.product_id == self.product_a + ) + # selected_move_line.lot_id = lot + with mock.patch.object(BarcodeParser, "parse") as mock_parse: + mock_parse.return_value = [ + BarcodeResult(type="lot", value=lot.name, raw=lot.name), + BarcodeResult( + type="expiration_date", + value=fields.Date.to_date("2025-04-15"), + raw="250415", + ), + ] + response = self.service.dispatch( + "scan_line", + params={ + "picking_id": picking.id, + "barcode": lot.name, + }, + ) + data = self.data.picking(picking) + self.assert_response( + response, + next_state="set_lot", + data={ + "picking": data, + "selected_move_line": self.data.move_lines(selected_move_line), + }, + ) + self.assertEqual( + selected_move_line.expiration_date, + fields.Datetime.to_datetime("2025-04-15"), + ) From d41035df2e63e999c248b00189cc2c884c32cd51 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 25 Aug 2025 15:42:09 +0200 Subject: [PATCH 268/357] [FIX] shopfloor_reception_mobile: Use correct dependency As we use wms utils javascript defined in shopfloor_mobile, depend on it. --- shopfloor_reception_mobile/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopfloor_reception_mobile/__manifest__.py b/shopfloor_reception_mobile/__manifest__.py index 46b31ca73ce..10481cba756 100644 --- a/shopfloor_reception_mobile/__manifest__.py +++ b/shopfloor_reception_mobile/__manifest__.py @@ -5,7 +5,7 @@ "summary": "Scenario for receiving products", "version": "16.0.1.1.0", "development_status": "Beta", - "depends": ["shopfloor_mobile_base", "shopfloor_reception"], + "depends": ["shopfloor_mobile_base", "shopfloor_mobile", "shopfloor_reception"], "author": "Camptocamp, Odoo Community Association (OCA)", "maintainers": ["JuMiSanAr"], "website": "https://github.com/OCA/wms", From 1593c2dc83edaae70ef62942aabc98b3b173ae70 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 26 Aug 2025 13:56:24 +0000 Subject: [PATCH 269/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception_mobile/README.rst | 2 +- shopfloor_reception_mobile/__manifest__.py | 2 +- shopfloor_reception_mobile/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 12181ac76bc..82d48d93ecb 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ addon | version | maintainers | summary [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app [shopfloor_reception](shopfloor_reception/) | 16.0.1.4.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor -[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.0 | JuMiSanAr | Scenario for receiving products +[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.1 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners diff --git a/shopfloor_reception_mobile/README.rst b/shopfloor_reception_mobile/README.rst index 5642e14bc56..274187a831d 100644 --- a/shopfloor_reception_mobile/README.rst +++ b/shopfloor_reception_mobile/README.rst @@ -11,7 +11,7 @@ Shopfloor reception mobile !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:eadcaffae32d8dda952fe04de4f3a40041f7a2022d6ddef8a9e2015cad125da3 + !! source digest: sha256:b879beedb5cce9459631565e96ed0249b6be452e4fd66b2f07c811af8649bfab !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception_mobile/__manifest__.py b/shopfloor_reception_mobile/__manifest__.py index 10481cba756..0e374183958 100644 --- a/shopfloor_reception_mobile/__manifest__.py +++ b/shopfloor_reception_mobile/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Shopfloor reception mobile", "summary": "Scenario for receiving products", - "version": "16.0.1.1.0", + "version": "16.0.1.1.1", "development_status": "Beta", "depends": ["shopfloor_mobile_base", "shopfloor_mobile", "shopfloor_reception"], "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/shopfloor_reception_mobile/static/description/index.html b/shopfloor_reception_mobile/static/description/index.html index 4ad84f2d3b4..237f3246ee6 100644 --- a/shopfloor_reception_mobile/static/description/index.html +++ b/shopfloor_reception_mobile/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor reception mobile

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:eadcaffae32d8dda952fe04de4f3a40041f7a2022d6ddef8a9e2015cad125da3 +!! source digest: sha256:b879beedb5cce9459631565e96ed0249b6be452e4fd66b2f07c811af8649bfab !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Frontend for the reception scenario in shopfloor. From d93c923fdd5b6b3b0efb8c839e34c5a36c646c41 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 26 Aug 2025 16:18:05 +0000 Subject: [PATCH 270/357] [UPD] Update shopfloor_reception.pot --- shopfloor_reception/i18n/shopfloor_reception.pot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shopfloor_reception/i18n/shopfloor_reception.pot b/shopfloor_reception/i18n/shopfloor_reception.pot index eea68040e3c..419d7292ed6 100644 --- a/shopfloor_reception/i18n/shopfloor_reception.pot +++ b/shopfloor_reception/i18n/shopfloor_reception.pot @@ -43,6 +43,11 @@ msgstr "" msgid "Menu displayed in the scanner application" msgstr "" +#. module: shopfloor_reception +#: model:ir.model,name:shopfloor_reception.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "" + #. module: shopfloor_reception #: model:shopfloor.menu,name:shopfloor_reception.shopfloor_menu_demo_reception #: model:shopfloor.scenario,name:shopfloor_reception.scenario_reception From fa12c5c767df75bdbff2fe4df675391373718c12 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 26 Aug 2025 16:30:35 +0000 Subject: [PATCH 271/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 82d48d93ecb..02241b90d87 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.4.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.5.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.1 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 48a93328ad7..18bb43c599d 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:82b16d13b5d7ebcba93ae526d0c5727e0ca12b1698e301b18cd31341567a3808 + !! source digest: sha256:a941855efca480b7009e3c55ee14be1fb95a92669a8c6fd6e64cbed7716c4592 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 0805b9e780b..8bd507879bb 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.4.0", + "version": "16.0.1.5.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index f644def1d2e..f6505ed9ed0 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:82b16d13b5d7ebcba93ae526d0c5727e0ca12b1698e301b18cd31341567a3808 +!! source digest: sha256:a941855efca480b7009e3c55ee14be1fb95a92669a8c6fd6e64cbed7716c4592 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From 4f2a2669da9d0398b2f377d0ec4c57d7ebe8557b Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 26 Aug 2025 16:30:47 +0000 Subject: [PATCH 272/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-shopfloor_reception Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_reception/ --- shopfloor_reception/i18n/it.po | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shopfloor_reception/i18n/it.po b/shopfloor_reception/i18n/it.po index c25120d0433..3fe6dbdbf86 100644 --- a/shopfloor_reception/i18n/it.po +++ b/shopfloor_reception/i18n/it.po @@ -49,6 +49,11 @@ msgstr "Filtro Possibili prelievi schedulati oggi" msgid "Menu displayed in the scanner application" msgstr "Menu visualizzato nell'applicazione di scansione" +#. module: shopfloor_reception +#: model:ir.model,name:shopfloor_reception.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "" + #. module: shopfloor_reception #: model:shopfloor.menu,name:shopfloor_reception.shopfloor_menu_demo_reception #: model:shopfloor.scenario,name:shopfloor_reception.scenario_reception From 6c1c1d158feba690a6dbf4dc342cf34b788eb789 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 27 Aug 2025 12:35:13 +0000 Subject: [PATCH 273/357] Translated using Weblate (Italian) Currently translated at 100.0% (7 of 7 strings) Translation: wms-16.0/wms-16.0-shopfloor_reception Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_reception/it/ --- shopfloor_reception/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shopfloor_reception/i18n/it.po b/shopfloor_reception/i18n/it.po index 3fe6dbdbf86..bc65cfa65bd 100644 --- a/shopfloor_reception/i18n/it.po +++ b/shopfloor_reception/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-07-07 08:53+0000\n" +"PO-Revision-Date: 2025-08-27 15:25+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -52,7 +52,7 @@ msgstr "Menu visualizzato nell'applicazione di scansione" #. module: shopfloor_reception #: model:ir.model,name:shopfloor_reception.model_stock_move_line msgid "Product Moves (Stock Move Line)" -msgstr "" +msgstr "Movimenti prodotto (riga movimento di magazzino)" #. module: shopfloor_reception #: model:shopfloor.menu,name:shopfloor_reception.shopfloor_menu_demo_reception From 4eae6091711928f770651dc758d2fe2f2ac034da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Fri, 29 Aug 2025 16:40:28 +0200 Subject: [PATCH 274/357] [FIX] stock_storage_type: migrate 'max_height' values to loc. categories --- .../migrations/16.0.1.0.1/post-migrate.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stock_storage_type/migrations/16.0.1.0.1/post-migrate.py b/stock_storage_type/migrations/16.0.1.0.1/post-migrate.py index 532acba534a..8ad4f5c6f46 100644 --- a/stock_storage_type/migrations/16.0.1.0.1/post-migrate.py +++ b/stock_storage_type/migrations/16.0.1.0.1/post-migrate.py @@ -61,6 +61,16 @@ def _move_location_storage_type(env): WHERE slst.id = sscc.old_location_storage_type_id """ openupgrade.logged_query(env.cr, query) + query = """ + UPDATE stock_storage_category ssc + SET max_height = slst.max_height + FROM stock_location_storage_type slst, + stock_storage_category_capacity sscc + WHERE slst.id = sscc.old_location_storage_type_id + AND sscc.storage_category_id = ssc.id + AND slst.max_height > 0 + """ + openupgrade.logged_query(env.cr, query) def _update_location_sequence(env): From afbd27c4d7b910865cc0aa40e44a07a96bf3969c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 29 Aug 2025 18:18:38 +0000 Subject: [PATCH 275/357] [BOT] post-merge updates --- README.md | 2 +- stock_storage_type/README.rst | 2 +- stock_storage_type/__manifest__.py | 2 +- stock_storage_type/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 02241b90d87..8a011e4822a 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ addon | version | maintainers | summary [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels [stock_release_channel_warehouse_calendar](stock_release_channel_warehouse_calendar/) | 16.0.1.0.0 | jbaudoux | Glue module between release channel and warehouse calendar -[stock_storage_type](stock_storage_type/) | 16.0.2.0.1 | jbaudoux rousseldenis | Manage packages and locations storage types +[stock_storage_type](stock_storage_type/) | 16.0.2.0.2 | jbaudoux rousseldenis | Manage packages and locations storage types [stock_storage_type_putaway_abc](stock_storage_type_putaway_abc/) | 16.0.1.0.0 | | Advanced storage strategy ABC for WMS [stock_warehouse_flow](stock_warehouse_flow/) | 16.0.1.1.0 | | Configure routing flow for stock moves [stock_warehouse_flow_delivery_refresh](stock_warehouse_flow_delivery_refresh/) | 16.0.1.0.0 | | Allow to refresh delivery flow when carrier changes diff --git a/stock_storage_type/README.rst b/stock_storage_type/README.rst index d0161dc1d50..0225d800a5e 100644 --- a/stock_storage_type/README.rst +++ b/stock_storage_type/README.rst @@ -11,7 +11,7 @@ Stock Storage Type !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:6e88f11d38787ebe507555948d9734ed73f4e377a35f06d9b27903a223279da0 + !! source digest: sha256:92c6e16f26be7f40451d47a3bbad2d0886f35677d3c74da9c39fb98af1258143 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_storage_type/__manifest__.py b/stock_storage_type/__manifest__.py index d84d345fdc8..bc41c326afe 100644 --- a/stock_storage_type/__manifest__.py +++ b/stock_storage_type/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Stock Storage Type", "summary": "Manage packages and locations storage types", - "version": "16.0.2.0.1", + "version": "16.0.2.0.2", "development_status": "Beta", "category": "Warehouse Management", "website": "https://github.com/OCA/wms", diff --git a/stock_storage_type/static/description/index.html b/stock_storage_type/static/description/index.html index 53d8298a301..4bfd9428d76 100644 --- a/stock_storage_type/static/description/index.html +++ b/stock_storage_type/static/description/index.html @@ -372,7 +372,7 @@

    Stock Storage Type

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:6e88f11d38787ebe507555948d9734ed73f4e377a35f06d9b27903a223279da0 +!! source digest: sha256:92c6e16f26be7f40451d47a3bbad2d0886f35677d3c74da9c39fb98af1258143 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    This module extends package types Odoo feature in order to better manage stock From 58b04da14161c11012881c11aade5fab1c7dfcf3 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 3 Sep 2025 06:46:38 +0000 Subject: [PATCH 276/357] Translated using Weblate (Italian) Currently translated at 100.0% (31 of 31 strings) Translation: wms-16.0/wms-16.0-sale_stock_available_to_promise_release Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-sale_stock_available_to_promise_release/it/ --- sale_stock_available_to_promise_release/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sale_stock_available_to_promise_release/i18n/it.po b/sale_stock_available_to_promise_release/i18n/it.po index 0f8c0d7f11e..60fd8cc7b1e 100644 --- a/sale_stock_available_to_promise_release/i18n/it.po +++ b/sale_stock_available_to_promise_release/i18n/it.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Odoo Server 13.0+e\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-07-12 17:07+0000\n" -"PO-Revision-Date: 2025-07-22 11:25+0000\n" +"PO-Revision-Date: 2025-09-03 09:42+0000\n" "Last-Translator: mymage \n" "Language-Team: \n" "Language: it\n" @@ -79,7 +79,7 @@ msgstr "Data di disponibilità prevista" #. module: sale_stock_available_to_promise_release #: model:ir.model.fields.selection,name:sale_stock_available_to_promise_release.selection__sale_order_line__availability_status__full msgid "Fully Available" -msgstr "Completamente Disponibile" +msgstr "Completamente disponibile" #. module: sale_stock_available_to_promise_release #: model_terms:ir.ui.view,arch_db:sale_stock_available_to_promise_release.view_move_release_search @@ -116,7 +116,7 @@ msgstr "Su ordine" #. module: sale_stock_available_to_promise_release #: model:ir.model.fields.selection,name:sale_stock_available_to_promise_release.selection__sale_order_line__availability_status__partial msgid "Partially Available" -msgstr "Parzialmente Disponibile" +msgstr "Parzialmente disponibile" #. module: sale_stock_available_to_promise_release #: model:ir.model,name:sale_stock_available_to_promise_release.model_procurement_group From adc3ef9b9ab12bb390d67d8e226b3c0f76eb814b Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Fri, 5 Sep 2025 09:09:05 +0200 Subject: [PATCH 277/357] [FIX] stock_dynamic_routing: use _action_confirm result _action_confirm returns a recordset; we should rely on that result for subsequent logic --- stock_dynamic_routing/models/stock_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_dynamic_routing/models/stock_move.py b/stock_dynamic_routing/models/stock_move.py index e6f91731c5c..a69c691298d 100644 --- a/stock_dynamic_routing/models/stock_move.py +++ b/stock_dynamic_routing/models/stock_move.py @@ -505,7 +505,7 @@ def _insert_routing_moves(self, picking_type, location, destination): ) if dest_moves: dest_moves.write({"move_orig_ids": [(3, self.id), (4, routing_move.id)]}) - routing_move._action_confirm(merge=False) + routing_move = routing_move._action_confirm(merge=False) return routing_move def _prepare_routing_move_values(self, picking_type, source, destination): From 1d19110f2c8d38a018cf7f772a4f00bafe967cdf Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 22 Sep 2025 14:05:58 +0000 Subject: [PATCH 278/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8a011e4822a..5c3e02db40f 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.5.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.1 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 18bb43c599d..7d972f097cf 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:a941855efca480b7009e3c55ee14be1fb95a92669a8c6fd6e64cbed7716c4592 + !! source digest: sha256:68d68d8487fb10ab5f0605bb30d17ceb584107ab6a545ed33d1af7bf59233209 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 8bd507879bb..c219be9bbd6 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.5.0", + "version": "16.0.1.6.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index f6505ed9ed0..8795b82eb8b 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:a941855efca480b7009e3c55ee14be1fb95a92669a8c6fd6e64cbed7716c4592 +!! source digest: sha256:68d68d8487fb10ab5f0605bb30d17ceb584107ab6a545ed33d1af7bf59233209 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From 11395fd5616ace2c93ccbb301886403354c6443c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 22 Sep 2025 14:25:35 +0000 Subject: [PATCH 279/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5c3e02db40f..af66946c769 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.0 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.1 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.1 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 7d972f097cf..c84f1b279ff 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:68d68d8487fb10ab5f0605bb30d17ceb584107ab6a545ed33d1af7bf59233209 + !! source digest: sha256:f724db0c0a6ed0e3dd0600120d9817de4c24f15b45632433203125be44998f1b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index c219be9bbd6..9826fa75aea 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.6.0", + "version": "16.0.1.6.1", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 8795b82eb8b..2bcb59cbc9c 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:68d68d8487fb10ab5f0605bb30d17ceb584107ab6a545ed33d1af7bf59233209 +!! source digest: sha256:f724db0c0a6ed0e3dd0600120d9817de4c24f15b45632433203125be44998f1b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From 740d2f63c692889f6468b3a865ac4bd303fe433c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20G=C3=BCnther?= Date: Thu, 25 Sep 2025 13:40:38 +0000 Subject: [PATCH 280/357] Added translation using Weblate (German) --- stock_picking_completion_info/i18n/de.po | 70 ++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 stock_picking_completion_info/i18n/de.po diff --git a/stock_picking_completion_info/i18n/de.po b/stock_picking_completion_info/i18n/de.po new file mode 100644 index 00000000000..c3d4afbe803 --- /dev/null +++ b/stock_picking_completion_info/i18n/de.po @@ -0,0 +1,70 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_picking_completion_info +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: stock_picking_completion_info +#: model:ir.model.fields,field_description:stock_picking_completion_info.field_stock_picking__completion_info +msgid "Completion Info" +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model.fields,field_description:stock_picking_completion_info.field_stock_picking_type__display_completion_info +msgid "Display Completion Info" +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model.fields.selection,name:stock_picking_completion_info.selection__stock_picking__completion_info__full_order_picking +msgid "" +"Full order picking: You are processing a full order picking that will allow " +"next operation to be processed" +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model.fields,help:stock_picking_completion_info.field_stock_picking_type__display_completion_info +msgid "" +"Inform operator of a completed operation at processing and at completion" +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model.fields.selection,name:stock_picking_completion_info.selection__stock_picking__completion_info__last_picking +msgid "" +"Last picking: Completion of this operation allows next operations to be " +"processed." +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model.fields.selection,name:stock_picking_completion_info.selection__stock_picking__completion_info__next_picking_ready +msgid "Next operations are ready to be processed." +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model.fields.selection,name:stock_picking_completion_info.selection__stock_picking__completion_info__no +msgid "No" +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model,name:stock_picking_completion_info.model_stock_picking_type +msgid "Picking Type" +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model,name:stock_picking_completion_info.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: stock_picking_completion_info +#: model:ir.model,name:stock_picking_completion_info.model_stock_picking +msgid "Transfer" +msgstr "" From c110498bf41c846b7d4eccc50c611cb4759f09d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20G=C3=BCnther?= Date: Thu, 25 Sep 2025 13:40:43 +0000 Subject: [PATCH 281/357] Added translation using Weblate (German) --- shopfloor_mobile_base_auth_api_key/i18n/de.po | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 shopfloor_mobile_base_auth_api_key/i18n/de.po diff --git a/shopfloor_mobile_base_auth_api_key/i18n/de.po b/shopfloor_mobile_base_auth_api_key/i18n/de.po new file mode 100644 index 00000000000..754a4ff5e97 --- /dev/null +++ b/shopfloor_mobile_base_auth_api_key/i18n/de.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * shopfloor_mobile_base_auth_api_key +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: shopfloor_mobile_base_auth_api_key +#: model:ir.model,name:shopfloor_mobile_base_auth_api_key.model_shopfloor_app +msgid "A Shopfloor application" +msgstr "" + +#. module: shopfloor_mobile_base_auth_api_key +#: model:ir.model.fields,field_description:shopfloor_mobile_base_auth_api_key.field_shopfloor_app__auth_api_key_group_ids +msgid "Allowed API key groups" +msgstr "" + +#. module: shopfloor_mobile_base_auth_api_key +#: model_terms:ir.ui.view,arch_db:shopfloor_mobile_base_auth_api_key.shopfloor_app_form_view +msgid "Manage groups" +msgstr "" + +#. module: shopfloor_mobile_base_auth_api_key +#: model:shopfloor.app,name:shopfloor_mobile_base_auth_api_key.app_demo1 +msgid "Shopfloor Demo (api key auth)" +msgstr "" + +#. module: shopfloor_mobile_base_auth_api_key +#: model:shopfloor.app,short_name:shopfloor_mobile_base_auth_api_key.app_demo1 +msgid "demo api key" +msgstr "" From 51f92095b9a43504a469f50866ddd89076bb03a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20G=C3=BCnther?= Date: Fri, 26 Sep 2025 09:59:32 +0000 Subject: [PATCH 282/357] Added translation using Weblate (German) --- shopfloor_mobile_base/i18n/de.po | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 shopfloor_mobile_base/i18n/de.po diff --git a/shopfloor_mobile_base/i18n/de.po b/shopfloor_mobile_base/i18n/de.po new file mode 100644 index 00000000000..ef568d1bd0f --- /dev/null +++ b/shopfloor_mobile_base/i18n/de.po @@ -0,0 +1,29 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * shopfloor_mobile_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: shopfloor_mobile_base +#: model_terms:ir.ui.view,arch_db:shopfloor_mobile_base.shopfloor_app_main +msgid "" +"\n" +" We're sorry but wms doesn't work properly without JavaScript enabled.\n" +" Please enable it to continue.\n" +" " +msgstr "" + +#. module: shopfloor_mobile_base +#: model_terms:ir.ui.view,arch_db:shopfloor_mobile_base.shopfloor_app_assets +msgid "Hook to this element to inject your own scenario" +msgstr "" From 18cce5f9951274e060f3175f6e17d85557d01ca8 Mon Sep 17 00:00:00 2001 From: davidbeckercbl Date: Fri, 26 Sep 2025 14:43:13 +0000 Subject: [PATCH 283/357] Translated using Weblate (German) Currently translated at 100.0% (2 of 2 strings) Translation: wms-16.0/wms-16.0-shopfloor_mobile_base Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_mobile_base/de/ --- shopfloor_mobile_base/i18n/de.po | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/shopfloor_mobile_base/i18n/de.po b/shopfloor_mobile_base/i18n/de.po index ef568d1bd0f..9ffa2e95e47 100644 --- a/shopfloor_mobile_base/i18n/de.po +++ b/shopfloor_mobile_base/i18n/de.po @@ -6,13 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-09-26 15:00+0000\n" +"Last-Translator: davidbeckercbl \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: shopfloor_mobile_base #: model_terms:ir.ui.view,arch_db:shopfloor_mobile_base.shopfloor_app_main @@ -22,8 +24,13 @@ msgid "" " Please enable it to continue.\n" " " msgstr "" +"\n" +" Es tut uns leid, aber das Lagerverwaltungssystem funktioniert " +"nicht richtig, wenn JavaScript nicht aktiviert ist.\n" +" Bitte aktivieren Sie es, um fortzufahren.\n" +" " #. module: shopfloor_mobile_base #: model_terms:ir.ui.view,arch_db:shopfloor_mobile_base.shopfloor_app_assets msgid "Hook to this element to inject your own scenario" -msgstr "" +msgstr "Hängen Sie sich in dieses Element mit Ihrem eigenen Szenario ein" From 8fbb767a6b1f22ac88df3e7a6942e18096611387 Mon Sep 17 00:00:00 2001 From: davidbeckercbl Date: Fri, 26 Sep 2025 14:44:46 +0000 Subject: [PATCH 284/357] Translated using Weblate (German) Currently translated at 20.0% (1 of 5 strings) Translation: wms-16.0/wms-16.0-shopfloor_mobile_base_auth_api_key Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_mobile_base_auth_api_key/de/ --- shopfloor_mobile_base_auth_api_key/i18n/de.po | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shopfloor_mobile_base_auth_api_key/i18n/de.po b/shopfloor_mobile_base_auth_api_key/i18n/de.po index 754a4ff5e97..fb8ad2de6d4 100644 --- a/shopfloor_mobile_base_auth_api_key/i18n/de.po +++ b/shopfloor_mobile_base_auth_api_key/i18n/de.po @@ -6,18 +6,20 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-09-26 15:00+0000\n" +"Last-Translator: davidbeckercbl \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: shopfloor_mobile_base_auth_api_key #: model:ir.model,name:shopfloor_mobile_base_auth_api_key.model_shopfloor_app msgid "A Shopfloor application" -msgstr "" +msgstr "Eine Lagerverwaltungssystemanwendung" #. module: shopfloor_mobile_base_auth_api_key #: model:ir.model.fields,field_description:shopfloor_mobile_base_auth_api_key.field_shopfloor_app__auth_api_key_group_ids From 2e7f43451f1ebfbd07d27a306c3412f279921a3c Mon Sep 17 00:00:00 2001 From: davidbeckercbl Date: Fri, 26 Sep 2025 14:47:41 +0000 Subject: [PATCH 285/357] Translated using Weblate (German) Currently translated at 0.8% (1 of 113 strings) Translation: wms-16.0/wms-16.0-stock_storage_type Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_storage_type/de/ --- stock_storage_type/i18n/de.po | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stock_storage_type/i18n/de.po b/stock_storage_type/i18n/de.po index 288d7da3af7..f1f6fdef903 100644 --- a/stock_storage_type/i18n/de.po +++ b/stock_storage_type/i18n/de.po @@ -6,13 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-09-26 15:00+0000\n" +"Last-Translator: davidbeckercbl \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: stock_storage_type #. odoo-python @@ -146,7 +148,7 @@ msgstr "" #: model:ir.model.fields,field_description:stock_storage_type.field_stock_storage_category_allow_new_product__condition_ids #: model:ir.model.fields,field_description:stock_storage_type.field_stock_storage_location_sequence__location_sequence_cond_ids msgid "Conditions" -msgstr "" +msgstr "Bedingungen" #. module: stock_storage_type #: model:ir.model.fields,field_description:stock_storage_type.field_stock_storage_category_allow_new_product__create_uid From c78e8c024d3842987004af0549568bf3c31413d0 Mon Sep 17 00:00:00 2001 From: davidbeckercbl Date: Mon, 29 Sep 2025 07:36:36 +0000 Subject: [PATCH 286/357] Translated using Weblate (German) Currently translated at 7.5% (6 of 79 strings) Translation: wms-16.0/wms-16.0-shopfloor_base Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_base/de/ --- shopfloor_base/i18n/de.po | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shopfloor_base/i18n/de.po b/shopfloor_base/i18n/de.po index 299fa7646d6..23bf3975eae 100644 --- a/shopfloor_base/i18n/de.po +++ b/shopfloor_base/i18n/de.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-05-13 13:24+0000\n" +"PO-Revision-Date: 2025-09-29 08:28+0000\n" "Last-Translator: davidbeckercbl \n" "Language-Team: none\n" "Language: de\n" @@ -24,6 +24,10 @@ msgid "" " internal controller-ready version.\n" " " msgstr "" +"\n" +" BBasisroute für Endpunkte, die dieser Anwendung zugeordnet sind,\n" +" interne, controller-fertige Version.\n" +" " #. module: shopfloor_base #. odoo-python From 088e98f7ddf3a4e44ac68a24f6adced98b08a8eb Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Sat, 4 Oct 2025 18:11:59 +0200 Subject: [PATCH 287/357] [FIX] sale_stock_release_channel_delivery_date: fix no shipping partner Do not compute delivery date when the SO has lines but no shipping partner --- .../models/sale_order.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sale_stock_release_channel_delivery_date/models/sale_order.py b/sale_stock_release_channel_delivery_date/models/sale_order.py index e75498e5712..159299d16d8 100644 --- a/sale_stock_release_channel_delivery_date/models/sale_order.py +++ b/sale_stock_release_channel_delivery_date/models/sale_order.py @@ -25,9 +25,6 @@ class SaleOrder(models.Model): def _compute_expected_date(self): res = super()._compute_expected_date() for order in self: - if not order.partner_shipping_id: - # do not recompute - continue if order.order_line: # will be managed at line level continue @@ -35,12 +32,16 @@ def _compute_expected_date(self): order_dt = order.date_order else: order_dt = fields.Datetime.now() - - order.expected_date = order._get_release_channel_expected_date(order_dt) + expected_date = order._get_release_channel_expected_date(order_dt) + if expected_date: + order.expected_date = expected_date return res def _get_release_channel_expected_date(self, order_dt): self.ensure_one() + if not self.partner_shipping_id: + # do not compute + return # If the carrier is not set, assume the partner default carrier carrier = ( self.carrier_id or self.partner_shipping_id.property_delivery_carrier_id From cefe00c8843dfca21a175a3cc26ee95a69c913cf Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 7 Oct 2025 07:43:15 +0000 Subject: [PATCH 288/357] Translated using Weblate (Italian) Currently translated at 100.0% (113 of 113 strings) Translation: wms-16.0/wms-16.0-stock_storage_type Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_storage_type/it/ --- stock_storage_type/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock_storage_type/i18n/it.po b/stock_storage_type/i18n/it.po index 162f3cb223a..2d7e271d093 100644 --- a/stock_storage_type/i18n/it.po +++ b/stock_storage_type/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-05-13 10:23+0000\n" +"PO-Revision-Date: 2025-10-07 10:43+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -188,7 +188,7 @@ msgid "" "for product not in a package" msgstr "" "Definisce un tipo collo 'predefinito' per questo prodotto da utilizzare nei " -"colli senza imballaggio prdotto e nel calcolo del deposito in base al tipo " +"colli senza imballaggio prodotto e nel calcolo del deposito in base al tipo " "collo per prodotto non in un collo" #. module: stock_storage_type From 30a82fc997bd4ef29cd580ea99e1c502043fd65c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 7 Oct 2025 14:58:08 +0000 Subject: [PATCH 289/357] [BOT] post-merge updates --- README.md | 2 +- sale_stock_release_channel_delivery_date/README.rst | 2 +- sale_stock_release_channel_delivery_date/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index af66946c769..10d2932de25 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ addon | version | maintainers | summary [sale_stock_available_to_promise_release_block](sale_stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block release of deliveries from sales orders. [sale_stock_release_channel](sale_stock_release_channel/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel [sale_stock_release_channel_delivery](sale_stock_release_channel_delivery/) | 16.0.1.0.0 | jbaudoux | Sales Stock Release Channel Delivery -[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.1 | jbaudoux | Compute expected date based on available release channels +[sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. [shopfloor](shopfloor/) | 16.0.2.12.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners diff --git a/sale_stock_release_channel_delivery_date/README.rst b/sale_stock_release_channel_delivery_date/README.rst index b9c25e4abdf..d0f2a52408f 100644 --- a/sale_stock_release_channel_delivery_date/README.rst +++ b/sale_stock_release_channel_delivery_date/README.rst @@ -11,7 +11,7 @@ Sale Stock Release Channel Delivery Date !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:27ccecbfeea1adbc17e433cedf809b7791a58163044af8edf72d58c2c6a25662 + !! source digest: sha256:2ae76b0bacde574bbfe8ddaa4d7f67bc83790798b2b7e5362c01e94440c5be25 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/sale_stock_release_channel_delivery_date/__manifest__.py b/sale_stock_release_channel_delivery_date/__manifest__.py index e01e797aae1..538a159eda7 100644 --- a/sale_stock_release_channel_delivery_date/__manifest__.py +++ b/sale_stock_release_channel_delivery_date/__manifest__.py @@ -5,7 +5,7 @@ "name": "Sale Stock Release Channel Delivery Date", "summary": """ Compute expected date based on available release channels """, - "version": "16.0.1.1.1", + "version": "16.0.1.1.2", "license": "AGPL-3", "author": "BCIM,Camptocamp,Odoo Community Association (OCA)", "maintainers": ["jbaudoux"], diff --git a/sale_stock_release_channel_delivery_date/static/description/index.html b/sale_stock_release_channel_delivery_date/static/description/index.html index f03f0873fa4..05eeab39651 100644 --- a/sale_stock_release_channel_delivery_date/static/description/index.html +++ b/sale_stock_release_channel_delivery_date/static/description/index.html @@ -372,7 +372,7 @@

    Sale Stock Release Channel Delivery Date

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:27ccecbfeea1adbc17e433cedf809b7791a58163044af8edf72d58c2c6a25662 +!! source digest: sha256:2ae76b0bacde574bbfe8ddaa4d7f67bc83790798b2b7e5362c01e94440c5be25 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Provide the SO expected date according to possible channels respecting SO From df0b6adfc11eff96ac30036eaecf36780ccbb9bf Mon Sep 17 00:00:00 2001 From: davidbeckercbl Date: Wed, 8 Oct 2025 07:55:04 +0000 Subject: [PATCH 290/357] Translated using Weblate (German) Currently translated at 36.7% (29 of 79 strings) Translation: wms-16.0/wms-16.0-shopfloor_base Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_base/de/ --- shopfloor_base/i18n/de.po | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/shopfloor_base/i18n/de.po b/shopfloor_base/i18n/de.po index 23bf3975eae..ba868b228cb 100644 --- a/shopfloor_base/i18n/de.po +++ b/shopfloor_base/i18n/de.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-09-29 08:28+0000\n" +"PO-Revision-Date: 2025-10-08 08:42+0000\n" "Last-Translator: davidbeckercbl \n" "Language-Team: none\n" "Language: de\n" @@ -39,34 +39,34 @@ msgstr "%s aktualisiert." #. module: shopfloor_base #: model:ir.model,name:shopfloor_base.model_shopfloor_app msgid "A Shopfloor application" -msgstr "" +msgstr "Eine Lagerverwaltungssystemanwendung" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__active #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_menu__active #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__active msgid "Active" -msgstr "" +msgstr "Aktiv" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_search_view msgid "All" -msgstr "" +msgstr "Alle" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__api_docs_url msgid "Api Docs Url" -msgstr "" +msgstr "API-Dokumentations-URL" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__api_route msgid "Api Route" -msgstr "" +msgstr "API-Route" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__app_version msgid "App Version" -msgstr "" +msgstr "App-Version" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view @@ -75,33 +75,33 @@ msgstr "" #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_profile_form_view #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_profile_search_view msgid "Archived" -msgstr "" +msgstr "Archiviert" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view msgid "Auth" -msgstr "" +msgstr "Authentifizierung" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__auth_type msgid "Auth Type" -msgstr "" +msgstr "Authentifizierungsart" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__lang_ids msgid "Available languages" -msgstr "" +msgstr "Verfügbare Sprachen" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__category #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_search_view msgid "Category" -msgstr "" +msgstr "Kategorie" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_scenario__options_edit msgid "Configure options via JSON" -msgstr "" +msgstr "Optionen über JSON konfigurieren" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__create_uid @@ -109,7 +109,7 @@ msgstr "" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__create_uid #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__create_uid msgid "Created by" -msgstr "" +msgstr "Erstellt von" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__create_date @@ -117,32 +117,32 @@ msgstr "" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__create_date #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__create_date msgid "Created on" -msgstr "" +msgstr "Erzeugt am" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__lang_id msgid "Default language" -msgstr "" +msgstr "Standardsprache" #. module: shopfloor_base #: model:shopfloor.profile,name:shopfloor_base.profile_demo_1 msgid "Demo Profile 1" -msgstr "" +msgstr "Demoprofil 1" #. module: shopfloor_base #: model:shopfloor.profile,name:shopfloor_base.profile_demo_2 msgid "Demo Profile 2" -msgstr "" +msgstr "Demoprofil 2" #. module: shopfloor_base #: model:shopfloor.scenario,name:shopfloor_base.shopfloor_scenario_demo_1 msgid "Demo scenario 1" -msgstr "" +msgstr "Demoszenario 1" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view msgid "Developer" -msgstr "" +msgstr "Entwickler" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__display_name @@ -150,18 +150,18 @@ msgstr "" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__display_name #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__display_name msgid "Display Name" -msgstr "" +msgstr "Anzeigname" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_search_view #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_menu_search_view msgid "Group By" -msgstr "" +msgstr "Gruppiere nach" #. module: shopfloor_base #: model:ir.model,name:shopfloor_base.model_ir_http msgid "HTTP Routing" -msgstr "" +msgstr "HTTP-Weiterleitung" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__id @@ -169,7 +169,7 @@ msgstr "" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__id #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__id msgid "ID" -msgstr "" +msgstr "ID" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_menu__scenario_key From 2ad1c234f2ee66085d24961956f62e79db08038d Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 13 Oct 2025 12:35:10 +0000 Subject: [PATCH 291/357] [BOT] post-merge updates --- README.md | 2 +- stock_dynamic_routing/README.rst | 8 +++- stock_dynamic_routing/__manifest__.py | 2 +- .../static/description/index.html | 44 +++++++++++-------- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 10d2932de25..9b6b725c39c 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ addon | version | maintainers | summary [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_dynamic_routing](stock_available_to_promise_release_dynamic_routing/) | 16.0.1.0.0 | jbaudoux | Glue between moves release and dynamic routing [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock -[stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.2 | | Dynamic routing of stock moves +[stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.3 | | Dynamic routing of stock moves [stock_full_location_reservation](stock_full_location_reservation/) | 16.0.1.0.0 | mt-software-de | Extend reservation to full content of location [stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.2.1.0 | lmignon | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations diff --git a/stock_dynamic_routing/README.rst b/stock_dynamic_routing/README.rst index 10dcaab6434..a4063a44cc1 100644 --- a/stock_dynamic_routing/README.rst +++ b/stock_dynamic_routing/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ===================== Stock Dynamic Routing ===================== @@ -7,13 +11,13 @@ Stock Dynamic Routing !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:15e4cc4851a06363897abf22b9922d8521c0d0e6fd1bb1e765ac8689351e1b0c + !! source digest: sha256:b8ff4de8bbec57bae3a5a74c1e07985f1d51cc3c36a5c03020f3146203836d7f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_dynamic_routing/__manifest__.py b/stock_dynamic_routing/__manifest__.py index 152a1dd194c..0408ed0648e 100644 --- a/stock_dynamic_routing/__manifest__.py +++ b/stock_dynamic_routing/__manifest__.py @@ -5,7 +5,7 @@ "author": "Camptocamp, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "16.0.1.0.2", + "version": "16.0.1.0.3", "license": "AGPL-3", "depends": ["stock", "stock_helper"], "demo": [ diff --git a/stock_dynamic_routing/static/description/index.html b/stock_dynamic_routing/static/description/index.html index 8bbe0b5447d..2d86767758a 100644 --- a/stock_dynamic_routing/static/description/index.html +++ b/stock_dynamic_routing/static/description/index.html @@ -1,18 +1,18 @@ - -Stock Dynamic Routing +README.rst -

    -

    Stock Dynamic Routing

    +
    + + +Odoo Community Association + +
    +

    Stock Dynamic Routing

    -

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Standard Stock Routes explain the steps you want to produce whereas the “Dynamic Routing” defines how operations are grouped according to their final source and destination location.

    @@ -417,7 +422,7 @@

    Stock Dynamic Routing

    -

    Configuration

    +

    Configuration

    In Inventory Settings, you must have:

    -

    Usage

    +

    Usage

    -

    Try on runbot

    +

    Try on runbot

    • In Inventory Settings, activate:
    -

    Bug Tracker

    +

    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 to smash it by providing a detailed and welcomed @@ -497,15 +502,15 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Camptocamp
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +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.

    @@ -525,5 +532,6 @@

    Maintainers

    +
    From ac694158277f6f171f3ead2366e8ecc974fdd07f Mon Sep 17 00:00:00 2001 From: Bastian Guenther Date: Mon, 3 Nov 2025 19:36:51 +0530 Subject: [PATCH 292/357] [FIX] stock_storage_type: Fixed wrong usage of create function --- stock_storage_type/models/stock_quant_package.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock_storage_type/models/stock_quant_package.py b/stock_storage_type/models/stock_quant_package.py index f7b642c7fad..8c72ec8c829 100644 --- a/stock_storage_type/models/stock_quant_package.py +++ b/stock_storage_type/models/stock_quant_package.py @@ -57,8 +57,8 @@ def auto_assign_packaging(self): return res @api.model_create_multi - def create(self, vals): - records = super().create(vals) + def create(self, vals_list): + records = super().create(vals_list) records._sync_package_type_from_packaging() return records From da5e224621c6f128e84031f77f3a910673022f87 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 7 Nov 2025 08:56:49 +0000 Subject: [PATCH 293/357] [BOT] post-merge updates --- README.md | 2 +- stock_storage_type/README.rst | 2 +- stock_storage_type/__manifest__.py | 2 +- stock_storage_type/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b6b725c39c..9e10e4a07c1 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ addon | version | maintainers | summary [stock_release_channel_show_volume](stock_release_channel_show_volume/) | 16.0.1.1.0 | | Display volumes of stock release channels [stock_release_channel_show_weight](stock_release_channel_show_weight/) | 16.0.1.1.0 | | Display weights of stock release channels [stock_release_channel_warehouse_calendar](stock_release_channel_warehouse_calendar/) | 16.0.1.0.0 | jbaudoux | Glue module between release channel and warehouse calendar -[stock_storage_type](stock_storage_type/) | 16.0.2.0.2 | jbaudoux rousseldenis | Manage packages and locations storage types +[stock_storage_type](stock_storage_type/) | 16.0.2.0.3 | jbaudoux rousseldenis | Manage packages and locations storage types [stock_storage_type_putaway_abc](stock_storage_type_putaway_abc/) | 16.0.1.0.0 | | Advanced storage strategy ABC for WMS [stock_warehouse_flow](stock_warehouse_flow/) | 16.0.1.1.0 | | Configure routing flow for stock moves [stock_warehouse_flow_delivery_refresh](stock_warehouse_flow_delivery_refresh/) | 16.0.1.0.0 | | Allow to refresh delivery flow when carrier changes diff --git a/stock_storage_type/README.rst b/stock_storage_type/README.rst index 0225d800a5e..e679aad239b 100644 --- a/stock_storage_type/README.rst +++ b/stock_storage_type/README.rst @@ -11,7 +11,7 @@ Stock Storage Type !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:92c6e16f26be7f40451d47a3bbad2d0886f35677d3c74da9c39fb98af1258143 + !! source digest: sha256:c46ce97684eda7baf75edac00f005ea18baac91d81a4f0df32ba6f49ce1b34ee !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_storage_type/__manifest__.py b/stock_storage_type/__manifest__.py index bc41c326afe..03e0ce4b10f 100644 --- a/stock_storage_type/__manifest__.py +++ b/stock_storage_type/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Stock Storage Type", "summary": "Manage packages and locations storage types", - "version": "16.0.2.0.2", + "version": "16.0.2.0.3", "development_status": "Beta", "category": "Warehouse Management", "website": "https://github.com/OCA/wms", diff --git a/stock_storage_type/static/description/index.html b/stock_storage_type/static/description/index.html index 4bfd9428d76..4cdf66d916d 100644 --- a/stock_storage_type/static/description/index.html +++ b/stock_storage_type/static/description/index.html @@ -372,7 +372,7 @@

    Stock Storage Type

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:92c6e16f26be7f40451d47a3bbad2d0886f35677d3c74da9c39fb98af1258143 +!! source digest: sha256:c46ce97684eda7baf75edac00f005ea18baac91d81a4f0df32ba6f49ce1b34ee !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    This module extends package types Odoo feature in order to better manage stock From abdabad3eea822fe144535e21e1596ec6edab814 Mon Sep 17 00:00:00 2001 From: santostelmo Date: Wed, 19 Nov 2025 10:10:10 +0100 Subject: [PATCH 294/357] [FIX] stock_release_channel_shipment_advice_deliver job funtion process_shipments --- .../data/queue_job_function.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock_release_channel_shipment_advice_deliver/data/queue_job_function.xml b/stock_release_channel_shipment_advice_deliver/data/queue_job_function.xml index 65724046a64..722994cb509 100644 --- a/stock_release_channel_shipment_advice_deliver/data/queue_job_function.xml +++ b/stock_release_channel_shipment_advice_deliver/data/queue_job_function.xml @@ -2,14 +2,14 @@ - _action_deliver + _process_shipments From 3558334c8529f4c425333b2673c9f04c2e76a6f2 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 24 Nov 2025 10:05:03 +0000 Subject: [PATCH 295/357] [BOT] post-merge updates --- README.md | 2 +- .../README.rst | 8 ++++-- .../__manifest__.py | 2 +- .../static/description/index.html | 26 ++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9e10e4a07c1..620426039dd 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ addon | version | maintainers | summary [stock_release_channel_process_end_time](stock_release_channel_process_end_time/) | 16.0.1.7.0 | rousseldenis jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_propagate_channel_picking](stock_release_channel_propagate_channel_picking/) | 16.0.1.2.0 | | Allows to propagate the channel to every picking that is created from the original one. [stock_release_channel_shipment_advice](stock_release_channel_shipment_advice/) | 16.0.1.2.0 | jbaudoux | Plan shipment advices for ready and released pickings -[stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.0 | | This module adds an action to the release channel to automate the delivery of its shippings. +[stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.1 | | This module adds an action to the release channel to automate the delivery of its shippings. [stock_release_channel_shipment_advice_process_end_time](stock_release_channel_shipment_advice_process_end_time/) | 16.0.1.0.0 | | This module allows to set a delay time (in minutes) between the release channel process end time and the shipment advice arrival to the dock time. [stock_release_channel_shipment_advice_toursolver](stock_release_channel_shipment_advice_toursolver/) | 16.0.1.1.0 | | Use TourSolver to plan shipment advices for ready and released pickings [stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.1.0 | jbaudoux | Release channel with shipment lead time diff --git a/stock_release_channel_shipment_advice_deliver/README.rst b/stock_release_channel_shipment_advice_deliver/README.rst index 53f0c38e290..759a2f738e7 100644 --- a/stock_release_channel_shipment_advice_deliver/README.rst +++ b/stock_release_channel_shipment_advice_deliver/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================================= Stock Release Channel Shipment Advice Deliver ============================================= @@ -7,13 +11,13 @@ Stock Release Channel Shipment Advice Deliver !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:db140089539861042d53b0bd663c8a69a99e5d2da9609f9bec7a28556b4409d1 + !! source digest: sha256:39da7fc0bf93470a6fd5bf80c0d5cdfa9422ac87a32eb2d473d47908e568feb3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_release_channel_shipment_advice_deliver/__manifest__.py b/stock_release_channel_shipment_advice_deliver/__manifest__.py index c35abcc2e3e..935726fe157 100644 --- a/stock_release_channel_shipment_advice_deliver/__manifest__.py +++ b/stock_release_channel_shipment_advice_deliver/__manifest__.py @@ -8,7 +8,7 @@ "author": "ACSONE SA/NV, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "16.0.2.0.0", + "version": "16.0.2.0.1", "license": "AGPL-3", "depends": [ "stock_release_channel", diff --git a/stock_release_channel_shipment_advice_deliver/static/description/index.html b/stock_release_channel_shipment_advice_deliver/static/description/index.html index feb704a6cf1..13e605d4f1c 100644 --- a/stock_release_channel_shipment_advice_deliver/static/description/index.html +++ b/stock_release_channel_shipment_advice_deliver/static/description/index.html @@ -3,7 +3,7 @@ -Stock Release Channel Shipment Advice Deliver +README.rst -

    -

    Stock Release Channel Shipment Advice Deliver

    +
    + + +Odoo Community Association + +
    +

    Stock Release Channel Shipment Advice Deliver

    -

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    This module adds an action to the release channel to automate the delivery of its shippings through shipment advices.

    Table of contents

    @@ -385,7 +390,7 @@

    Stock Release Channel Shipment Advice Deliver

    -

    Usage

    +

    Usage

    A “Deliver” button for locked release channels is added.

    When this new button is pressed:
    @@ -413,7 +418,7 @@

    Usage

    -

    Bug Tracker

    +

    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 to smash it by providing a detailed and welcomed @@ -421,16 +426,16 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ACSONE SA/NV
    • BCIM
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -443,5 +448,6 @@

    Maintainers

    +
    From 04f2e6a2bd3f10e48f1ded58a8f88f813c0e651f Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 15 Dec 2025 13:19:03 +0000 Subject: [PATCH 296/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 620426039dd..4738e112926 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.12.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.13.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index 4bdb1b12ed5..21124adccd9 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:c418f1851f7591fa3b9cde9ce01a2a3507baf0066f7453d93cfea051273d85fc + !! source digest: sha256:53f50a05edfd87a129dd2c23f9f1e19fcd5e21956251f1450cfe3e47f0bbf883 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 4001f5be366..0cf27c92866 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.12.0", + "version": "16.0.2.13.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index 42008a3cb7f..c53c175a12f 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:c418f1851f7591fa3b9cde9ce01a2a3507baf0066f7453d93cfea051273d85fc +!! source digest: sha256:53f50a05edfd87a129dd2c23f9f1e19fcd5e21956251f1450cfe3e47f0bbf883 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor is a barcode scanner application for internal warehouse operations.

    From 9bfbe4b80de1abd899016de3f9fd4f725a3c7f7f Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Thu, 22 Aug 2024 16:54:46 +0200 Subject: [PATCH 297/357] [IMP] shopfloor: Improve message for location content transfer items In case of content transfer line by line, user wants to be recalled which origin location he comes from if he wants to transfer partially and put the remaining products back to source (e.g.: no more space on destination location) --- shopfloor/actions/message.py | 8 ++++++-- .../services/location_content_transfer.py | 4 ++-- ...transfer_set_destination_package_or_line.py | 18 +++++++++--------- .../test_location_content_transfer_single.py | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/shopfloor/actions/message.py b/shopfloor/actions/message.py index 117ae161a3b..e8962bf19bc 100644 --- a/shopfloor/actions/message.py +++ b/shopfloor/actions/message.py @@ -637,10 +637,14 @@ def transfer_complete(self, picking): "body": _("Transfer {} complete").format(picking.name), } - def location_content_transfer_item_complete(self, location_dest): + def location_content_transfer_item_complete(self, location_src, location_dest): return { "message_type": "success", - "body": _("Content transfer to {} completed").format(location_dest.name), + "body": _( + "Content line transferred from %(location_name)s to %(location_dest_name)s", + location_name=location_src.name, + location_dest_name=location_dest.name, + ), } def location_content_transfer_complete(self, location_src, location_dest): diff --git a/shopfloor/services/location_content_transfer.py b/shopfloor/services/location_content_transfer.py index b798208863b..e68bdcc8b65 100644 --- a/shopfloor/services/location_content_transfer.py +++ b/shopfloor/services/location_content_transfer.py @@ -709,7 +709,7 @@ def set_destination_package( stock.validate_moves(package_moves) move_lines = self._find_transfer_move_lines(location) message = self.msg_store.location_content_transfer_item_complete( - scanned_location + location, scanned_location ) completion_info = self._actions_for("completion.info") completion_info_popup = completion_info.popup(package_moves.move_line_ids) @@ -776,7 +776,7 @@ def set_destination_line( else: move_lines = self._find_transfer_move_lines(move_line.location_id) message = self.msg_store.location_content_transfer_item_complete( - scanned_location + location, scanned_location ) completion_info = self._actions_for("completion.info") completion_info_popup = completion_info.popup(move_line) diff --git a/shopfloor/tests/test_location_content_transfer_set_destination_package_or_line.py b/shopfloor/tests/test_location_content_transfer_set_destination_package_or_line.py index 1fd599b260c..803d2cb7c32 100644 --- a/shopfloor/tests/test_location_content_transfer_set_destination_package_or_line.py +++ b/shopfloor/tests/test_location_content_transfer_set_destination_package_or_line.py @@ -187,7 +187,7 @@ def test_set_destination_package_dest_location_ok(self): response, move_lines.mapped("picking_id"), message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), ) for move in package_level.move_line_ids.mapped("move_id"): @@ -235,7 +235,7 @@ def test_set_destination_package_dest_location_ok_with_completion_info(self): response, move_lines.mapped("picking_id"), message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), popup=completion_info_popup, ) @@ -385,7 +385,7 @@ def test_set_destination_line_dest_location_ok(self): response, move_lines.mapped("picking_id"), message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), ) @@ -436,7 +436,7 @@ def test_set_destination_line_dest_location_ok_with_completion_info(self): response, move_lines.mapped("picking_id"), message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), popup=completion_info_popup, ) @@ -485,7 +485,7 @@ def test_set_destination_line_partial_qty(self): response, done_picking.backorder_ids, message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), ) self.assertEqual(move_line_c.move_id.state, "done") @@ -754,7 +754,7 @@ def test_set_destination_package_split_move(self): response, move_lines.mapped("picking_id"), message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), ) @@ -812,7 +812,7 @@ def test_set_destination_line_split_move(self): response, move_lines.mapped("picking_id"), message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), ) # Process the other move lines (lines w/o package + package levels) @@ -1047,7 +1047,7 @@ def test_set_destination_lines_partial_qty_next_line(self): response, backorder, message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), ) # check that the next operation has the appropriate attributes @@ -1071,6 +1071,6 @@ def test_set_destination_lines_partial_qty_next_line(self): response, self.picking, message=self.service.msg_store.location_content_transfer_item_complete( - self.dest_location + self.content_loc, self.dest_location ), ) diff --git a/shopfloor/tests/test_location_content_transfer_single.py b/shopfloor/tests/test_location_content_transfer_single.py index 3ef9e59384e..92a62006f62 100644 --- a/shopfloor/tests/test_location_content_transfer_single.py +++ b/shopfloor/tests/test_location_content_transfer_single.py @@ -573,7 +573,7 @@ def test_postpone_line_ok_with_two_lines_and_view(self): backorder = self.picking3.backorder_ids self.assertTrue(backorder) message = { - "body": "Content transfer to Shelf 1 completed", + "body": "Content line transferred from Content Location to Shelf 1", "message_type": "success", } From b056aee3313ab3103421cbe1bf48cd93aaf4c2e5 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 8 Jan 2026 12:59:52 +0000 Subject: [PATCH 298/357] [UPD] Update shopfloor.pot --- shopfloor/i18n/shopfloor.pot | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shopfloor/i18n/shopfloor.pot b/shopfloor/i18n/shopfloor.pot index 129676d4f29..de47765895d 100644 --- a/shopfloor/i18n/shopfloor.pot +++ b/shopfloor/i18n/shopfloor.pot @@ -349,7 +349,8 @@ msgstr "" #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Content transfer to {} completed" +msgid "" +"Content line transferred from %(location_name)s to %(location_dest_name)s" msgstr "" #. module: shopfloor From 60f4b5ab0ba6e57018873ea01b79fe093b97d6db Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 8 Jan 2026 13:12:49 +0000 Subject: [PATCH 299/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4738e112926..19b90a5d461 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.13.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.14.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index 21124adccd9..5e2dde5c4fb 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:53f50a05edfd87a129dd2c23f9f1e19fcd5e21956251f1450cfe3e47f0bbf883 + !! source digest: sha256:e393dd59712ff8f5ff542bcda9e7405966f33c6dc787ef439d16051a70aaadf0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 0cf27c92866..36610727298 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.13.0", + "version": "16.0.2.14.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index c53c175a12f..d61019c6cd3 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:53f50a05edfd87a129dd2c23f9f1e19fcd5e21956251f1450cfe3e47f0bbf883 +!! source digest: sha256:e393dd59712ff8f5ff542bcda9e7405966f33c6dc787ef439d16051a70aaadf0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor is a barcode scanner application for internal warehouse operations.

    From 2f6e29d42410437e5873f583ef78caa7f50ab5da Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 8 Jan 2026 13:13:00 +0000 Subject: [PATCH 300/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/ --- shopfloor/i18n/ca.po | 9 +++++++-- shopfloor/i18n/de.po | 3 ++- shopfloor/i18n/es_AR.po | 9 +++++++-- shopfloor/i18n/it.po | 9 +++++++-- shopfloor/i18n/pt_BR.po | 3 ++- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/shopfloor/i18n/ca.po b/shopfloor/i18n/ca.po index e94a67ecabc..a32d0cf2d55 100644 --- a/shopfloor/i18n/ca.po +++ b/shopfloor/i18n/ca.po @@ -355,8 +355,9 @@ msgstr "" #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Content transfer to {} completed" -msgstr "Transferència de contingut a {} competada" +msgid "" +"Content line transferred from %(location_name)s to %(location_dest_name)s" +msgstr "" #. module: shopfloor #. odoo-python @@ -2193,6 +2194,10 @@ msgstr "" msgid "{} is not a valid destination package." msgstr "" +#, python-format +#~ msgid "Content transfer to {} completed" +#~ msgstr "Transferència de contingut a {} competada" + #, python-format #~ msgid "A draft inventory has been created for control." #~ msgstr "S'ha creat un inventari esborrany per a control." diff --git a/shopfloor/i18n/de.po b/shopfloor/i18n/de.po index d983314959d..c1f4205f404 100644 --- a/shopfloor/i18n/de.po +++ b/shopfloor/i18n/de.po @@ -353,7 +353,8 @@ msgstr "" #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Content transfer to {} completed" +msgid "" +"Content line transferred from %(location_name)s to %(location_dest_name)s" msgstr "" #. module: shopfloor diff --git a/shopfloor/i18n/es_AR.po b/shopfloor/i18n/es_AR.po index e666be9a750..2c8125f8cf7 100644 --- a/shopfloor/i18n/es_AR.po +++ b/shopfloor/i18n/es_AR.po @@ -387,8 +387,9 @@ msgstr "" #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Content transfer to {} completed" -msgstr "Transferencia de contenido a {} completada" +msgid "" +"Content line transferred from %(location_name)s to %(location_dest_name)s" +msgstr "" #. module: shopfloor #. odoo-python @@ -2299,6 +2300,10 @@ msgstr "Zona de Entreda" msgid "{} is not a valid destination package." msgstr "{} no es un paquete de destino válido." +#, python-format +#~ msgid "Content transfer to {} completed" +#~ msgstr "Transferencia de contenido a {} completada" + #, python-format #~ msgid "Package {} is not in the current transfer." #~ msgstr "El Paquete {} no está en la transferencia actual." diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index c611764fe3b..5e8f7753ae2 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -417,8 +417,9 @@ msgstr "Conferma modifica ubicazione da %(location_from)s a %(location_to)s?" #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Content transfer to {} completed" -msgstr "Tasferimento contenuto a {} completato" +msgid "" +"Content line transferred from %(location_name)s to %(location_dest_name)s" +msgstr "" #. module: shopfloor #. odoo-python @@ -2364,6 +2365,10 @@ msgstr "Prelievo per area" msgid "{} is not a valid destination package." msgstr "{} non è un collo destinazione valido." +#, python-format +#~ msgid "Content transfer to {} completed" +#~ msgstr "Tasferimento contenuto a {} completato" + #, python-format #~ msgid "" #~ "{message_code} not found in the current transfer or already in a package." diff --git a/shopfloor/i18n/pt_BR.po b/shopfloor/i18n/pt_BR.po index 0c22a107763..e9ffe5b9a58 100644 --- a/shopfloor/i18n/pt_BR.po +++ b/shopfloor/i18n/pt_BR.po @@ -353,7 +353,8 @@ msgstr "" #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format -msgid "Content transfer to {} completed" +msgid "" +"Content line transferred from %(location_name)s to %(location_dest_name)s" msgstr "" #. module: shopfloor From 072f3822faddf5cf66443517d6a743fc8757a573 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 8 Jan 2026 15:42:32 +0000 Subject: [PATCH 301/357] Translated using Weblate (Italian) Currently translated at 100.0% (329 of 329 strings) Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/it/ --- shopfloor/i18n/it.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shopfloor/i18n/it.po b/shopfloor/i18n/it.po index 5e8f7753ae2..5bab7c9d7b6 100644 --- a/shopfloor/i18n/it.po +++ b/shopfloor/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-08-16 13:25+0000\n" +"PO-Revision-Date: 2026-01-08 17:42+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -419,7 +419,7 @@ msgstr "Conferma modifica ubicazione da %(location_from)s a %(location_to)s?" #, python-format msgid "" "Content line transferred from %(location_name)s to %(location_dest_name)s" -msgstr "" +msgstr "Riga contenuto trasferita da %(location_name)s a %(location_dest_name)s" #. module: shopfloor #. odoo-python From fb419f287952f372bfc1fc590c6e700a65f0db1a Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Thu, 22 Jan 2026 16:13:32 +0100 Subject: [PATCH 302/357] [FIX] shopfloor_reception_mobile: fix display package name --- shopfloor_reception_mobile/static/src/scenario/reception.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopfloor_reception_mobile/static/src/scenario/reception.js b/shopfloor_reception_mobile/static/src/scenario/reception.js index dcf4dd86a4c..ce2117091a5 100644 --- a/shopfloor_reception_mobile/static/src/scenario/reception.js +++ b/shopfloor_reception_mobile/static/src/scenario/reception.js @@ -429,7 +429,7 @@ const Reception = { return values; }, select_dest_package_display_name: function (rec) { - var values = this.select_dest_package_display_name_values(); + var values = this.select_dest_package_display_name_values(rec); return values.join(" - "); }, picking_detail_options_for_select_dest_package: function () { From 7e5998bd29af733c3e8dd68ab8c08c5f86e93633 Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Thu, 22 Jan 2026 16:43:14 +0100 Subject: [PATCH 303/357] [FIX] shopfloor_reception: Make lot_id mandatory at set_lot step --- shopfloor_reception/services/reception.py | 18 ++++++++++--- .../tests/test_set_lot_confirm.py | 25 ++++++++++++++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 7e06c5d4b1a..88fa1d4d017 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -1149,11 +1149,23 @@ def set_lot_confirm_action(self, picking_id, selected_line_id): selected_line = self.env["stock.move.line"].browse(selected_line_id) if message: return self._response_for_set_lot(picking, selected_line, message=message) - message = self._check_expiry_date(selected_line) - if message: - return self._response_for_set_lot(picking, selected_line, message=message) + checks = [ + self._check_expiry_date, + self._check_lot, + ] + for check in checks: + message = check(selected_line) + if message: + return self._response_for_set_lot( + picking, selected_line, message=message + ) return self._before_state__set_quantity(picking, selected_line) + def _check_lot(self, line): + need_lot = line.product_id.tracking == "lot" + if need_lot and not line.lot_id: + return self.msg_store.scan_lot_on_product_tracked_by_lot() + def _check_expiry_date(self, line): use_expiration_date = ( line.product_id.use_expiration_date or line.lot_id.use_expiration_date diff --git a/shopfloor_reception/tests/test_set_lot_confirm.py b/shopfloor_reception/tests/test_set_lot_confirm.py index e8d4f6efe53..238f4546f66 100644 --- a/shopfloor_reception/tests/test_set_lot_confirm.py +++ b/shopfloor_reception/tests/test_set_lot_confirm.py @@ -8,7 +8,30 @@ class TestSetLotConfirm(CommonCase): @classmethod def setUpClassBaseData(cls): super().setUpClassBaseData() - cls.product_a.tracking = "lot" + + def test_ensure_lot(self): + picking = self._create_picking() + self.product_a.tracking = "lot" + selected_move_line = picking.move_line_ids.filtered( + lambda li: li.product_id == self.product_a + ) + response = self.service.dispatch( + "set_lot_confirm_action", + params={ + "picking_id": picking.id, + "selected_line_id": selected_move_line.id, + }, + ) + message = self.msg_store.scan_lot_on_product_tracked_by_lot() + self.assert_response( + response, + next_state="set_lot", + data={ + "picking": self.data.picking(picking), + "selected_move_line": self.data.move_lines(selected_move_line), + }, + message=message, + ) def test_ensure_expiry_date(self): picking = self._create_picking() From bc7d2b9695f9f6c6b5783b45adee2492f976eff0 Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Fri, 23 Jan 2026 08:22:48 +0100 Subject: [PATCH 304/357] [FIX] shopfloor_reception: Fix set_destination next screen. --- shopfloor_reception/services/reception.py | 20 +++-- .../tests/test_set_destination.py | 79 ++++++++++++++++++- 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 7e06c5d4b1a..4fe88795a80 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -1372,17 +1372,11 @@ def _auto_post_line(self, selected_line): # In such case, we must ensure there's another move with the remaining # quantity to do, so selected_line is extracted in a new move as expected. - # Always keep the quantity todo at zero, the same is done - # in Odoo when move lines are created manually (setting) lines_with_qty_todo = selected_line.move_id.move_line_ids.filtered( lambda line: line.state not in ("cancel", "done") and line.reserved_uom_qty > 0 ) move = selected_line.move_id - lock = self._actions_for("lock") - lock.for_update(move) - if lines_with_qty_todo: - lines_with_qty_todo.reserved_uom_qty = 0 move_quantity = move.product_uom._compute_quantity( move.product_uom_qty, selected_line.product_uom_id @@ -1390,6 +1384,14 @@ def _auto_post_line(self, selected_line): if selected_line.qty_done == move_quantity: # In case of full quantity, post the initial move return selected_line.move_id.extract_and_action_done() + + # Always keep the quantity todo at zero, the same is done + # in Odoo when move lines are created manually (setting) + lock = self._actions_for("lock") + lock.for_update(move) + if lines_with_qty_todo: + lines_with_qty_todo.reserved_uom_qty = 0 + split_move_vals = move._split(selected_line.qty_done) new_move = move.create(split_move_vals) new_move.move_line_ids = selected_line @@ -1470,6 +1472,12 @@ def set_destination( response = self._post_line(selected_line) if response: return response + # After line is posted, if picking is done, + # return select document with success message + if picking.state == "done": + message = self.msg_store.transfer_done_success(picking) + return self._response_for_select_document(message=message) + # Else return select move return self._response_for_select_move(picking) def select_dest_package( diff --git a/shopfloor_reception/tests/test_set_destination.py b/shopfloor_reception/tests/test_set_destination.py index 2c730360ce1..9f962c9fdb4 100644 --- a/shopfloor_reception/tests/test_set_destination.py +++ b/shopfloor_reception/tests/test_set_destination.py @@ -107,9 +107,10 @@ def test_scan_location_not_child_of_dest_locations(self): message={"message_type": "error", "body": "You cannot place it here"}, ) - def test_auto_posting(self): + def test_auto_posting_partial(self): self.menu.sudo().auto_post_line = True - picking = self._create_picking() + # Creating a picking with a single move, with qty todo = 10 + picking = self._create_picking(lines=[(self.product_a, 10)]) selected_move_line = picking.move_line_ids.filtered( lambda l: l.product_id == self.product_a ) @@ -129,7 +130,7 @@ def test_auto_posting(self): # and dest package & dest location are set, # a line with 3 demand will be automatically extracted # in a new picking, which will be marked as done. - self.service.dispatch( + response = self.service.dispatch( "set_destination", params={ "picking_id": picking.id, @@ -137,6 +138,10 @@ def test_auto_posting(self): "location_name": self.dispatch_location.name, }, ) + # Next screen is select move, because picking is not done + self.assert_response( + response, next_state="select_move", data=self._data_for_select_move(picking) + ) # The line has been moved to a different picking. self.assertNotEqual(picking, selected_move_line.picking_id) # Its qty_done is 3. @@ -152,6 +157,74 @@ def test_auto_posting(self): self.assertEqual(line_in_picking.qty_done, 0) self.assertEqual(picking.state, "assigned") + def test_auto_posting_full_one_line(self): + self.menu.sudo().auto_post_line = True + # Create a picking with a single move with qty todo = 10 + picking = self._create_picking(lines=[(self.product_a, 10)]) + selected_move_line = picking.move_line_ids.filtered( + lambda li: li.product_id == self.product_a + ) + # User has previously scanned the full qty + # A new pack has been created and assigned to the line. + self.service.dispatch( + "process_with_new_pack", + params={ + "picking_id": picking.id, + "selected_line_id": selected_move_line.id, + "quantity": 10, + }, + ) + # Full qty processed, picking is done, and next screen is select document. + response = self.service.dispatch( + "set_destination", + params={ + "picking_id": picking.id, + "selected_line_id": selected_move_line.id, + "location_name": self.dispatch_location.name, + }, + ) + message = self.msg_store.transfer_done_success(picking) + self.assert_response( + response, next_state="select_document", data=self.ANY, message=message + ) + + def test_auto_posting_full_two_lines(self): + self.menu.sudo().auto_post_line = True + # Create a picking with a two moves with qty todo = 10 + picking = self._create_picking() + selected_move_line = picking.move_line_ids.filtered( + lambda li: li.product_id == self.product_a + ) + # User has previously scanned the full qty + # A new pack has been created and assigned to the line. + self.service.dispatch( + "process_with_new_pack", + params={ + "picking_id": picking.id, + "selected_line_id": selected_move_line.id, + "quantity": 10, + }, + ) + # Full qty processed, but one more line to process, + # next screen is select_move + response = self.service.dispatch( + "set_destination", + params={ + "picking_id": picking.id, + "selected_line_id": selected_move_line.id, + "location_name": self.dispatch_location.name, + }, + ) + self.assert_response( + response, next_state="select_move", data=self._data_for_select_move(picking) + ) + # Lines has been moved in another picking + self.assertNotEqual(picking, selected_move_line.picking_id) + # Fully processed + self.assertEqual(selected_move_line.picking_id.state, "done") + # One move remaining in the picking, for product b, still to be processed + self.assertEqual(picking.move_ids.product_id, self.product_b) + def test_auto_posting_concurent_work(self): """Check 2 users working on the same move. From 0cbd5e4fded8d05e2003f903f19b5966aa008ed1 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 23 Jan 2026 11:36:23 +0000 Subject: [PATCH 305/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception_mobile/README.rst | 2 +- shopfloor_reception_mobile/__manifest__.py | 2 +- shopfloor_reception_mobile/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 19b90a5d461..c572c26ecfb 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ addon | version | maintainers | summary [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app [shopfloor_reception](shopfloor_reception/) | 16.0.1.6.1 | mmequignon JuMiSanAr | Reception scenario for shopfloor -[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.1 | JuMiSanAr | Scenario for receiving products +[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners diff --git a/shopfloor_reception_mobile/README.rst b/shopfloor_reception_mobile/README.rst index 274187a831d..08644d8a2b7 100644 --- a/shopfloor_reception_mobile/README.rst +++ b/shopfloor_reception_mobile/README.rst @@ -11,7 +11,7 @@ Shopfloor reception mobile !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b879beedb5cce9459631565e96ed0249b6be452e4fd66b2f07c811af8649bfab + !! source digest: sha256:e6e5bdb9f20c104e11b2d9c6c67bdf6b418ca342dd36317955c679a68d278ca4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception_mobile/__manifest__.py b/shopfloor_reception_mobile/__manifest__.py index 0e374183958..88acd316c1d 100644 --- a/shopfloor_reception_mobile/__manifest__.py +++ b/shopfloor_reception_mobile/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Shopfloor reception mobile", "summary": "Scenario for receiving products", - "version": "16.0.1.1.1", + "version": "16.0.1.1.2", "development_status": "Beta", "depends": ["shopfloor_mobile_base", "shopfloor_mobile", "shopfloor_reception"], "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/shopfloor_reception_mobile/static/description/index.html b/shopfloor_reception_mobile/static/description/index.html index 237f3246ee6..97f13521bbf 100644 --- a/shopfloor_reception_mobile/static/description/index.html +++ b/shopfloor_reception_mobile/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor reception mobile

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:b879beedb5cce9459631565e96ed0249b6be452e4fd66b2f07c811af8649bfab +!! source digest: sha256:e6e5bdb9f20c104e11b2d9c6c67bdf6b418ca342dd36317955c679a68d278ca4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Frontend for the reception scenario in shopfloor. From 6166bfd3d8dd4b69ce4ae1916bb69e9426e36048 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 23 Jan 2026 13:03:02 +0000 Subject: [PATCH 306/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c572c26ecfb..60e3fc04206 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.1 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.2 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index c84f1b279ff..ad8a3b7c854 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f724db0c0a6ed0e3dd0600120d9817de4c24f15b45632433203125be44998f1b + !! source digest: sha256:ea41fbc94c56ab07cb7647c02c90940166f099c84a0da09795704c527b091020 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 9826fa75aea..cd2a988aa9e 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.6.1", + "version": "16.0.1.6.2", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 2bcb59cbc9c..f14e0640218 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:f724db0c0a6ed0e3dd0600120d9817de4c24f15b45632433203125be44998f1b +!! source digest: sha256:ea41fbc94c56ab07cb7647c02c90940166f099c84a0da09795704c527b091020 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From dc80182558bebedf7c2d5ec3ff2a8f132969f5a6 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 26 Jan 2026 09:11:13 +0000 Subject: [PATCH 307/357] [BOT] post-merge updates --- README.md | 2 +- stock_dynamic_routing/README.rst | 2 +- stock_dynamic_routing/__manifest__.py | 2 +- stock_dynamic_routing/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 60e3fc04206..6092f0d8cfb 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ addon | version | maintainers | summary [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_dynamic_routing](stock_available_to_promise_release_dynamic_routing/) | 16.0.1.0.0 | jbaudoux | Glue between moves release and dynamic routing [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock -[stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.3 | | Dynamic routing of stock moves +[stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.4 | | Dynamic routing of stock moves [stock_full_location_reservation](stock_full_location_reservation/) | 16.0.1.0.0 | mt-software-de | Extend reservation to full content of location [stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.2.1.0 | lmignon | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations diff --git a/stock_dynamic_routing/README.rst b/stock_dynamic_routing/README.rst index a4063a44cc1..68e498b415c 100644 --- a/stock_dynamic_routing/README.rst +++ b/stock_dynamic_routing/README.rst @@ -11,7 +11,7 @@ Stock Dynamic Routing !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b8ff4de8bbec57bae3a5a74c1e07985f1d51cc3c36a5c03020f3146203836d7f + !! source digest: sha256:2609c19524a5c26b26ebf02be6eaa998af4ed30d6847d0d57a0f352939133db3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_dynamic_routing/__manifest__.py b/stock_dynamic_routing/__manifest__.py index 0408ed0648e..0aceee6b566 100644 --- a/stock_dynamic_routing/__manifest__.py +++ b/stock_dynamic_routing/__manifest__.py @@ -5,7 +5,7 @@ "author": "Camptocamp, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "16.0.1.0.3", + "version": "16.0.1.0.4", "license": "AGPL-3", "depends": ["stock", "stock_helper"], "demo": [ diff --git a/stock_dynamic_routing/static/description/index.html b/stock_dynamic_routing/static/description/index.html index 2d86767758a..59267db92fa 100644 --- a/stock_dynamic_routing/static/description/index.html +++ b/stock_dynamic_routing/static/description/index.html @@ -372,7 +372,7 @@

    Stock Dynamic Routing

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:b8ff4de8bbec57bae3a5a74c1e07985f1d51cc3c36a5c03020f3146203836d7f +!! source digest: sha256:2609c19524a5c26b26ebf02be6eaa998af4ed30d6847d0d57a0f352939133db3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Standard Stock Routes explain the steps you want to produce whereas the From 17cb8a133b70138a85fc1696cb8d43fc63964b9e Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Mon, 26 Jan 2026 11:47:14 +0100 Subject: [PATCH 308/357] [FIX] shopfloor_mobile: fix duplicate title in "detail-product" component. The "Lots" title was incorrectly placed inside the for loop, making it appear at every iteration --- .../static/wms/src/components/detail/detail_product.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shopfloor_mobile/static/wms/src/components/detail/detail_product.js b/shopfloor_mobile/static/wms/src/components/detail/detail_product.js index fc3d1db0ca1..84736c8db47 100644 --- a/shopfloor_mobile/static/wms/src/components/detail/detail_product.js +++ b/shopfloor_mobile/static/wms/src/components/detail/detail_product.js @@ -136,9 +136,10 @@ Vue.component("detail-product", { - + Lots Date: Mon, 27 Oct 2025 18:11:32 +0100 Subject: [PATCH 309/357] shopfloor_reception: Add session recover at scan_line --- shopfloor_reception/services/reception.py | 39 +++-- shopfloor_reception/tests/__init__.py | 1 + shopfloor_reception/tests/common.py | 3 + shopfloor_reception/tests/test_recover.py | 176 ++++++++++++++++++++++ 4 files changed, 207 insertions(+), 12 deletions(-) create mode 100644 shopfloor_reception/tests/test_recover.py diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 7e06c5d4b1a..6d85f954efb 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -8,7 +8,7 @@ from decorator import contextmanager from odoo import fields -from odoo.tools import float_compare +from odoo.tools import float_compare, float_is_zero from odoo.addons.base_rest.components.service import to_int from odoo.addons.component.core import Component @@ -285,17 +285,14 @@ def _scan_line__find_or_create_line(self, picking, move, qty_done=1): If none are found create a new line. """ - line = None unassigned_lines = self.env["stock.move.line"] - for move_line in move.move_line_ids: - if move_line.result_package_id: - continue - if move_line.shopfloor_user_id.id == self.env.uid: - line = move_line - break - elif not move_line.shopfloor_user_id: - unassigned_lines |= move_line - if not line and unassigned_lines: + for line in move.move_line_ids: + if line.shopfloor_user_id.id == self.env.uid: + return self._scan_line__recover(picking, line, qty_done) + elif not line.shopfloor_user_id: + unassigned_lines |= line + line = None + if unassigned_lines: lock = self._actions_for("lock") for move_line in unassigned_lines: if lock.for_update(move_line, skip_locked=True): @@ -306,6 +303,24 @@ def _scan_line__find_or_create_line(self, picking, move, qty_done=1): line = self.env["stock.move.line"].create(values) return self._scan_line__assign_user(picking, line, qty_done) + def _scan_line__recover(self, picking, line, default_qty): + product = line.product_id + message = self.msg_store.recovered_previous_session() + # Do not restore further than set_destination, because a destination location + # might be set by default, and we want the user to be allowed to change it. + if line.result_package_id: + # Destination package is set, go to set_destination + return self._response_for_set_destination(picking, line, message=message) + if product.tracking not in ("lot", "serial") or (line.lot_id or line.lot_name): + # If lot already set, go to set_quantity + rounding = line.product_uom_id.rounding + if float_is_zero(line.qty_done, precision_rounding=rounding): + # If no qty_done, set default qty_done + line.qty_done = default_qty + return self._before_state__set_quantity(picking, line, message=message) + # Otherwise go to select_lot + return self._response_for_set_lot(picking, line, message=message) + def _scan_line__assign_user(self, picking, line, qty_done): product = line.product_id stock = self._actions_for("stock") @@ -1706,7 +1721,7 @@ def _list_stock_pickings_next_states(self): } def _scan_line_next_states(self): - return {"select_move", "set_lot", "set_quantity"} + return {"select_move", "set_lot", "set_quantity", "set_destination"} def _set_lot_next_states(self): return {"select_move", "set_lot", "set_quantity"} diff --git a/shopfloor_reception/tests/__init__.py b/shopfloor_reception/tests/__init__.py index a5861ce2928..7e192132e7e 100644 --- a/shopfloor_reception/tests/__init__.py +++ b/shopfloor_reception/tests/__init__.py @@ -13,3 +13,4 @@ from . import test_return_scan_line from . import test_return_set_quantity from . import test_return_reception_done +from . import test_recover diff --git a/shopfloor_reception/tests/common.py b/shopfloor_reception/tests/common.py index 1580e75011f..38733a76893 100644 --- a/shopfloor_reception/tests/common.py +++ b/shopfloor_reception/tests/common.py @@ -144,6 +144,9 @@ def assertMessage(self, response, expected_message): for key, value in expected_message.items(): self.assertEqual(message.get(key), value) + def assertNotMessage(self, response, expected_message): + self.assertMessage(response, expected_message) + @classmethod def _get_move_ids_from_response(cls, response): state = response.get("next_state") diff --git a/shopfloor_reception/tests/test_recover.py b/shopfloor_reception/tests/test_recover.py new file mode 100644 index 00000000000..622366cc096 --- /dev/null +++ b/shopfloor_reception/tests/test_recover.py @@ -0,0 +1,176 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +# Recover happens at line selection. +# If a line exists for current user + +from .common import CommonCase + + +class TestRecover(CommonCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.recover_msg = { + "message_type": "info", + "body": "Recovered previous session.", + } + + def test_recover(self): + # here, product isn't tracked by lot, but the move has a move + # line already assigned to the user. + # No quantity done, we should be redirected to set_quantity, + # with the default qty set + picking = self._create_picking() + # First time we select the line, no recover + response = self.service.dispatch( + "scan_line", + params={"picking_id": picking.id, "barcode": self.product_a.default_code}, + ) + selected_move_line = picking.move_line_ids.filtered( + lambda li: li.product_id == self.product_a + ) + self.assertEqual(selected_move_line.qty_done, 1) + self.assertEqual(selected_move_line.shopfloor_user_id.id, self.env.uid) + picking_data = self.data.picking(picking) + move_line_data = self.data.move_lines(selected_move_line) + self.assert_response( + response, + next_state="set_quantity", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + "confirmation_required": None, + }, + ) + # Now that there's a shopfloor_user_id, we should recover the session + # but since didn't change anything, nothing should change. + # Most importantly, the existing move_line should be reused throughout + # the whole process + response = self.service.dispatch( + "scan_line", + params={"picking_id": picking.id, "barcode": self.product_a.default_code}, + ) + # qty done is the same + self.assertEqual(selected_move_line.qty_done, 1) + self.assert_response( + response, + next_state="set_quantity", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + "confirmation_required": None, + }, + message=self.recover_msg, + ) + # Set qty_done to 5/10 on the move line, we should recover it + selected_move_line.qty_done = 5 + response = self.service.dispatch( + "scan_line", + params={"picking_id": picking.id, "barcode": self.product_a.default_code}, + ) + self.assertEqual(selected_move_line.qty_done, 5) + move_line_data = self.data.move_lines(selected_move_line) + self.assert_response( + response, + next_state="set_quantity", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + "confirmation_required": None, + }, + message=self.recover_msg, + ) + # If the goods were put in a pack, we move to set destination + response = self.service.dispatch( + "process_with_new_pack", + params={ + "picking_id": picking.id, + "selected_line_id": selected_move_line.id, + "quantity": selected_move_line.qty_done, + }, + ) + package = selected_move_line.result_package_id + self.assertTrue(package) + self.assertEqual(selected_move_line.qty_done, 5) + self.assertEqual(selected_move_line.reserved_uom_qty, 5) + picking_data = self.data.picking(picking) + move_line_data = self.data.move_lines(selected_move_line) + self.assert_response( + response, + next_state="set_destination", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + }, + ) + # Scan the line again, we should end up with the exact same result + # with the additionnal recover message + response = self.service.dispatch( + "scan_line", + params={"picking_id": picking.id, "barcode": self.product_a.default_code}, + ) + self.assert_response( + response, + next_state="set_destination", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + }, + message=self.recover_msg, + ) + + def test_recover_tracking_by_lot(self): + # exact same test, just showing that we skip the set lot when recovering + picking = self._create_picking() + self.product_a.tracking = "lot" + # First time we select the line, no recover + response = self.service.dispatch( + "scan_line", + params={"picking_id": picking.id, "barcode": self.product_a.default_code}, + ) + selected_move_line = picking.move_line_ids.filtered( + lambda li: li.product_id == self.product_a + ) + picking_data = self.data.picking(picking) + move_line_data = self.data.move_lines(selected_move_line) + self.assert_response( + response, + next_state="set_lot", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + }, + ) + # Scan the same line, we end up on the same screen, but with a recover msg + response = self.service.dispatch( + "scan_line", + params={"picking_id": picking.id, "barcode": self.product_a.default_code}, + ) + self.assert_response( + response, + next_state="set_lot", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + }, + message=self.recover_msg, + ) + # Set a lot to the move line, we recover again, but straight to set quantity. + selected_move_line.lot_id = self._create_lot() + response = self.service.dispatch( + "scan_line", + params={"picking_id": picking.id, "barcode": self.product_a.default_code}, + ) + move_line_data = self.data.move_lines(selected_move_line) + self.assert_response( + response, + next_state="set_quantity", + data={ + "picking": picking_data, + "selected_move_line": move_line_data, + "confirmation_required": None, + }, + message=self.recover_msg, + ) + # The rest is all the same as test_recover From 1e83dde81c82faf86729d11f9e355486e94db00b Mon Sep 17 00:00:00 2001 From: Thierry Ducrest Date: Thu, 18 Sep 2025 13:12:37 +0200 Subject: [PATCH 310/357] shopfloor_reception: fix destination on use existing pack --- shopfloor_reception/services/reception.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 7e06c5d4b1a..53af11c2ea2 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -665,6 +665,14 @@ def _set_package_on_move_line(self, picking, line, package): """ pack_location = package.location_id + if not pack_location: + package_line = fields.first( + picking.move_line_ids.filtered( + lambda ml: ml.result_package_id == package + ) + ) + if package_line: + pack_location = package_line.location_dest_id if not pack_location: line.result_package_id = package return None From 4bdbcee79bb569689845aebd99bc99c0c8efaa0e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 28 Jan 2026 09:58:20 +0000 Subject: [PATCH 311/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6092f0d8cfb..4759cbdde73 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.2 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.3 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index ad8a3b7c854..65c9e765fd6 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:ea41fbc94c56ab07cb7647c02c90940166f099c84a0da09795704c527b091020 + !! source digest: sha256:0671200ed3be5ca4af9e8eae404a86a86b1b3cb47ac0154ee1682030fead4341 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index cd2a988aa9e..b574685c47e 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.6.2", + "version": "16.0.1.6.3", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index f14e0640218..1cd51b7810a 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:ea41fbc94c56ab07cb7647c02c90940166f099c84a0da09795704c527b091020 +!! source digest: sha256:0671200ed3be5ca4af9e8eae404a86a86b1b3cb47ac0154ee1682030fead4341 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From f905a0cac79a477bf5004f476542bc67cc50cc01 Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Wed, 28 Jan 2026 11:08:31 +0100 Subject: [PATCH 312/357] [FIX] shopfloor_reception: incorrect increment of move line qty_done on manual selection. --- shopfloor_reception/services/reception.py | 2 +- shopfloor_reception/tests/test_set_destination.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 541b0e7d4b5..4609de76e62 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -1043,7 +1043,7 @@ def scan_line(self, picking_id, barcode): def manual_select_move(self, move_id): move = self.env["stock.move"].browse(move_id) picking = move.picking_id - return self._scan_line__find_or_create_line(picking, move) + return self._scan_line__find_or_create_line(picking, move, qty_done=0) def done_action(self, picking_id, confirmation=False): """Mark a picking as done diff --git a/shopfloor_reception/tests/test_set_destination.py b/shopfloor_reception/tests/test_set_destination.py index 9f962c9fdb4..d79a44681f3 100644 --- a/shopfloor_reception/tests/test_set_destination.py +++ b/shopfloor_reception/tests/test_set_destination.py @@ -250,13 +250,12 @@ def test_auto_posting_concurent_work(self): # User 1 finishes his work move_line_data = res_u1["data"]["set_quantity"]["selected_move_line"][0] line_id_u1 = move_line_data["id"] - qty_done_u1 = move_line_data["qty_done"] res_u1 = service_u1.dispatch( "process_without_pack", params={ "picking_id": picking.id, "selected_line_id": line_id_u1, - "quantity": qty_done_u1, + "quantity": 1, }, ) res_u1 = service_u1.dispatch( From 6f2ba372c26414e174367be24829a8451c7b0b24 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 28 Jan 2026 10:15:44 +0000 Subject: [PATCH 313/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4759cbdde73..8fdfd4b4e55 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.3 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.4 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 65c9e765fd6..9b698e743d4 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:0671200ed3be5ca4af9e8eae404a86a86b1b3cb47ac0154ee1682030fead4341 + !! source digest: sha256:860e6a935c2c3922621bbc05e1641a7637358d8de202dcc723ab2c93865cfb27 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index b574685c47e..3076e4e40b5 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.6.3", + "version": "16.0.1.6.4", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 1cd51b7810a..81e9b719000 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:0671200ed3be5ca4af9e8eae404a86a86b1b3cb47ac0154ee1682030fead4341 +!! source digest: sha256:860e6a935c2c3922621bbc05e1641a7637358d8de202dcc723ab2c93865cfb27 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From d40e04277dfdc39c72308bbd8be58f24311ff459 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 28 Jan 2026 12:36:07 +0000 Subject: [PATCH 314/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8fdfd4b4e55..f6fafb8f61e 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.4 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.5 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 9b698e743d4..6e0fdc30774 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:860e6a935c2c3922621bbc05e1641a7637358d8de202dcc723ab2c93865cfb27 + !! source digest: sha256:40ba81ab584552fe151e2a4d6021706cb34380a9bdc9ed7f08963394a45030b9 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 3076e4e40b5..2346cf0deca 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.6.4", + "version": "16.0.1.6.5", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 81e9b719000..a1af0acb72a 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:860e6a935c2c3922621bbc05e1641a7637358d8de202dcc723ab2c93865cfb27 +!! source digest: sha256:40ba81ab584552fe151e2a4d6021706cb34380a9bdc9ed7f08963394a45030b9 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From 3f924995954516e3c77ee28e13ededea3a8d4c97 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 28 Jan 2026 15:59:56 +0000 Subject: [PATCH 315/357] Translated using Weblate (Italian) Currently translated at 100.0% (73 of 73 strings) Translation: wms-16.0/wms-16.0-stock_picking_batch_creation Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_picking_batch_creation/it/ --- stock_picking_batch_creation/i18n/it.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stock_picking_batch_creation/i18n/it.po b/stock_picking_batch_creation/i18n/it.po index 1cbd40cefb4..57346a6d3f5 100644 --- a/stock_picking_batch_creation/i18n/it.po +++ b/stock_picking_batch_creation/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-08-20 17:27+0000\n" +"PO-Revision-Date: 2026-01-28 18:09+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.10.4\n" +"X-Generator: Weblate 5.15.2\n" #. module: stock_picking_batch_creation #. odoo-python @@ -249,12 +249,12 @@ msgstr "Volume massimo per contenitore" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines msgid "Maximum number of preparation lines for the batch" -msgstr "Numero massim di righe di preparazione per il gruppo" +msgstr "Numero massimo di righe di preparazione per il gruppo" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__user_max_volume msgid "Maximum total net volume for electing this device" -msgstr "Massimo voume totale netto per selezionare questo dispositivo" +msgstr "Massimo volume totale netto per selezionare questo dispositivo" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__max_volume From 92361f43bae1de22bd21e8cb5a0ba1708a227c50 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 28 Jan 2026 16:00:10 +0000 Subject: [PATCH 316/357] Translated using Weblate (Italian) Currently translated at 100.0% (18 of 18 strings) Translation: wms-16.0/wms-16.0-shopfloor_batch_automatic_creation Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_batch_automatic_creation/it/ --- shopfloor_batch_automatic_creation/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shopfloor_batch_automatic_creation/i18n/it.po b/shopfloor_batch_automatic_creation/i18n/it.po index c2d549ad374..ff8dca0c1ab 100644 --- a/shopfloor_batch_automatic_creation/i18n/it.po +++ b/shopfloor_batch_automatic_creation/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-10-05 17:06+0000\n" +"PO-Revision-Date: 2026-01-28 18:09+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.6.2\n" +"X-Generator: Weblate 5.15.2\n" #. module: shopfloor_batch_automatic_creation #: model_terms:ir.ui.view,arch_db:shopfloor_batch_automatic_creation.stock_device_type_form_view @@ -103,7 +103,7 @@ msgstr "Metodo chiave di ordinamento della riga" #. module: shopfloor_batch_automatic_creation #: model:ir.model.fields,field_description:shopfloor_batch_automatic_creation.field_shopfloor_menu__batch_maximum_number_of_preparation_lines msgid "Maximum number of preparation lines for the batch" -msgstr "Numero massim di righe di preparazione per il gruppo" +msgstr "Numero massimo di righe di preparazione per il gruppo" #. module: shopfloor_batch_automatic_creation #: model:ir.model,name:shopfloor_batch_automatic_creation.model_shopfloor_menu From b26ec39220d1f4fbf6c9036891e41c3e2a4cc2d9 Mon Sep 17 00:00:00 2001 From: Artur Machura Date: Wed, 11 Feb 2026 08:49:14 +0000 Subject: [PATCH 317/357] Translated using Weblate (German) Currently translated at 55.6% (44 of 79 strings) Translation: wms-16.0/wms-16.0-shopfloor_base Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_base/de/ --- shopfloor_base/i18n/de.po | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/shopfloor_base/i18n/de.po b/shopfloor_base/i18n/de.po index ba868b228cb..7ef6765e184 100644 --- a/shopfloor_base/i18n/de.po +++ b/shopfloor_base/i18n/de.po @@ -6,15 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-10-08 08:42+0000\n" -"Last-Translator: davidbeckercbl \n" +"PO-Revision-Date: 2026-02-11 08:49+0000\n" +"Last-Translator: Artur Machura \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.10.4\n" +"X-Generator: Weblate 5.15.2\n" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_app__api_route @@ -182,18 +182,18 @@ msgstr "" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_app__lang_id msgid "If set, the app will be first loaded with this lang." -msgstr "" +msgstr "Falls gesetzt, wird die App zunächst in dieser Sprache geladen." #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_menu__scenario_key #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__key msgid "Key" -msgstr "" +msgstr "Schlüssel" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view msgid "Language" -msgstr "" +msgstr "Sprache" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app____last_update @@ -201,7 +201,7 @@ msgstr "" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile____last_update #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario____last_update msgid "Last Modified on" -msgstr "" +msgstr "Zuletzt geändert am" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__write_uid @@ -209,7 +209,7 @@ msgstr "" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__write_uid #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__write_uid msgid "Last Updated by" -msgstr "" +msgstr "Zuletzt aktualisiert von" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__write_date @@ -217,7 +217,7 @@ msgstr "" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__write_date #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__write_date msgid "Last Updated on" -msgstr "" +msgstr "Zuletzt aktualisiert am" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_menu__scenario @@ -257,12 +257,12 @@ msgstr "Für dieses Profil sichtbare Menüs" #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__name #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__name msgid "Name" -msgstr "" +msgstr "Name" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_app__short_name msgid "Needed for app manifest" -msgstr "" +msgstr "Für das Manifest der App notwendig" #. module: shopfloor_base #: model:ir.model.fields.selection,name:shopfloor_base.selection__shopfloor_app__category__ @@ -281,23 +281,23 @@ msgstr "" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view msgid "Open app" -msgstr "" +msgstr "App öffnen" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__options msgid "Options" -msgstr "" +msgstr "Optionen" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_scenario__options_edit msgid "Options Edit" -msgstr "" +msgstr "Optionen editiern" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_menu__profile_id #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_menu_search_view msgid "Profile" -msgstr "" +msgstr "Profil" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__profile_required @@ -327,7 +327,7 @@ msgstr "" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_app__api_docs_url msgid "Public URL for api docs." -msgstr "" +msgstr "Öffentliche URL für Schnittstellendokumentation." #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_app__url @@ -339,7 +339,7 @@ msgstr "" #: code:addons/shopfloor_base/actions/message.py:0 #, python-format msgid "Record not found." -msgstr "" +msgstr "Datensatz nicht gefunden." #. module: shopfloor_base #. odoo-python @@ -353,7 +353,7 @@ msgstr "" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__registered_routes msgid "Registered Routes" -msgstr "" +msgstr "Registrierte Routen" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__registry_sync From 4b3cca0e26df20a1d294cd7edbb87fb3b21a685a Mon Sep 17 00:00:00 2001 From: Artur Machura Date: Wed, 11 Feb 2026 09:15:53 +0000 Subject: [PATCH 318/357] Translated using Weblate (German) Currently translated at 1.2% (4 of 329 strings) Translation: wms-16.0/wms-16.0-shopfloor Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor/de/ --- shopfloor/i18n/de.po | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/shopfloor/i18n/de.po b/shopfloor/i18n/de.po index c1f4205f404..ce2aa53e01a 100644 --- a/shopfloor/i18n/de.po +++ b/shopfloor/i18n/de.po @@ -6,13 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2026-02-11 11:09+0000\n" +"Last-Translator: Artur Machura \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.15.2\n" #. module: shopfloor #: model:ir.model.fields,help:shopfloor.field_shopfloor_menu__pick_pack_same_time @@ -271,26 +273,26 @@ msgstr "" #: code:addons/shopfloor/actions/message.py:0 #, python-format msgid "Barcode not found" -msgstr "" +msgstr "Strichcode nicht gefunden" #. module: shopfloor #: model:ir.model,name:shopfloor.model_stock_picking_batch msgid "Batch Transfer" -msgstr "" +msgstr "Stapeltransfer" #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format msgid "Batch Transfer complete" -msgstr "" +msgstr "Stapeltransfer fertiggestellt" #. module: shopfloor #. odoo-python #: code:addons/shopfloor/actions/message.py:0 #, python-format msgid "Batch Transfer line done" -msgstr "" +msgstr "Stapeltransferzeile erledigt" #. module: shopfloor #. odoo-python From 803fcd2781a8af55ffb14f4124525975d25b75d9 Mon Sep 17 00:00:00 2001 From: Artur Machura Date: Wed, 11 Feb 2026 09:10:48 +0000 Subject: [PATCH 319/357] Translated using Weblate (German) Currently translated at 100.0% (5 of 5 strings) Translation: wms-16.0/wms-16.0-shopfloor_mobile_base_auth_api_key Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_mobile_base_auth_api_key/de/ --- shopfloor_mobile_base_auth_api_key/i18n/de.po | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/shopfloor_mobile_base_auth_api_key/i18n/de.po b/shopfloor_mobile_base_auth_api_key/i18n/de.po index fb8ad2de6d4..b09e8ad2021 100644 --- a/shopfloor_mobile_base_auth_api_key/i18n/de.po +++ b/shopfloor_mobile_base_auth_api_key/i18n/de.po @@ -6,15 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-09-26 15:00+0000\n" -"Last-Translator: davidbeckercbl \n" +"PO-Revision-Date: 2026-02-11 11:09+0000\n" +"Last-Translator: Artur Machura \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.10.4\n" +"X-Generator: Weblate 5.15.2\n" #. module: shopfloor_mobile_base_auth_api_key #: model:ir.model,name:shopfloor_mobile_base_auth_api_key.model_shopfloor_app @@ -24,19 +24,19 @@ msgstr "Eine Lagerverwaltungssystemanwendung" #. module: shopfloor_mobile_base_auth_api_key #: model:ir.model.fields,field_description:shopfloor_mobile_base_auth_api_key.field_shopfloor_app__auth_api_key_group_ids msgid "Allowed API key groups" -msgstr "" +msgstr "Erlaubte API Schlüsselgruppen" #. module: shopfloor_mobile_base_auth_api_key #: model_terms:ir.ui.view,arch_db:shopfloor_mobile_base_auth_api_key.shopfloor_app_form_view msgid "Manage groups" -msgstr "" +msgstr "Gruppen verwalten" #. module: shopfloor_mobile_base_auth_api_key #: model:shopfloor.app,name:shopfloor_mobile_base_auth_api_key.app_demo1 msgid "Shopfloor Demo (api key auth)" -msgstr "" +msgstr "Shopfloor Demo (Auth Schnittstellenschlüssel)" #. module: shopfloor_mobile_base_auth_api_key #: model:shopfloor.app,short_name:shopfloor_mobile_base_auth_api_key.app_demo1 msgid "demo api key" -msgstr "" +msgstr "Demo Schnittstellenschlüssel" From 59ba2cdf292094d338b995c14d237dc6487f702b Mon Sep 17 00:00:00 2001 From: Artur Machura Date: Wed, 11 Feb 2026 09:24:20 +0000 Subject: [PATCH 320/357] Translated using Weblate (German) Currently translated at 83.5% (66 of 79 strings) Translation: wms-16.0/wms-16.0-shopfloor_base Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_base/de/ --- shopfloor_base/i18n/de.po | 46 ++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/shopfloor_base/i18n/de.po b/shopfloor_base/i18n/de.po index 7ef6765e184..c74b16f5f36 100644 --- a/shopfloor_base/i18n/de.po +++ b/shopfloor_base/i18n/de.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2026-02-11 08:49+0000\n" +"PO-Revision-Date: 2026-02-11 11:09+0000\n" "Last-Translator: Artur Machura \n" "Language-Team: none\n" "Language: de\n" @@ -232,7 +232,7 @@ msgstr "" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_menu_form_view msgid "Menu Options" -msgstr "" +msgstr "Menüoptionen" #. module: shopfloor_base #: model:ir.model,name:shopfloor_base.model_shopfloor_menu @@ -366,6 +366,8 @@ msgid "" "Registry out of sync. Likely the record has been modified but not sync'ed " "with the routing registry." msgstr "" +"Die Registry ist nicht synchron. Wahrscheinlich wurde der Datensatz " +"geändert, aber nicht mit der Routing-Registry synchronisiert." #. module: shopfloor_base #: model:ir.actions.act_window,name:shopfloor_base.action_shopfloor_scenario @@ -373,55 +375,55 @@ msgstr "" #: model:ir.ui.menu,name:shopfloor_base.menu_action_shopfloor_scenario #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_menu_search_view msgid "Scenario" -msgstr "" +msgstr "Szenario" #. module: shopfloor_base #: model:ir.model.constraint,message:shopfloor_base.constraint_shopfloor_scenario_key msgid "Scenario key must be unique" -msgstr "" +msgstr "Der Szenarioschlüssel muss eindeutig sein" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_menu__sequence #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_profile__sequence msgid "Sequence" -msgstr "" +msgstr "Reihenfolge" #. module: shopfloor_base #: model:ir.module.category,name:shopfloor_base.module_category_shopfloor #: model:ir.ui.menu,name:shopfloor_base.menu_shopfloor_root msgid "Shopfloor" -msgstr "" +msgstr "Shopfloor" #. module: shopfloor_base #: model:res.groups,name:shopfloor_base.group_shopfloor_manager msgid "Shopfloor Manager" -msgstr "" +msgstr "Shopfloor Manager" #. module: shopfloor_base #: model:ir.model,name:shopfloor_base.model_shopfloor_scenario msgid "Shopfloor Scenario" -msgstr "" +msgstr "Shopfloor Szenario" #. module: shopfloor_base #: model:res.groups,name:shopfloor_base.group_shopfloor_user msgid "Shopfloor User" -msgstr "" +msgstr "Shopfloor Benutzer" #. module: shopfloor_base #: model:ir.actions.act_window,name:shopfloor_base.action_shopfloor_app #: model:ir.ui.menu,name:shopfloor_base.menu_action_shopfloor_app msgid "Shopfloor apps" -msgstr "" +msgstr "Shopfloor Apps" #. module: shopfloor_base #: model:ir.model,name:shopfloor_base.model_shopfloor_profile msgid "Shopfloor profile settings" -msgstr "" +msgstr "Shopfloor Profileinstellungen" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__short_name msgid "Short Name" -msgstr "" +msgstr "Kurzname" #. module: shopfloor_base #: model:shopfloor.menu,name:shopfloor_base.shopfloor_menu_demo_1 @@ -431,35 +433,37 @@ msgstr "" #. module: shopfloor_base #: model:ir.actions.server,name:shopfloor_base.server_action_registry_sync msgid "Sync registry" -msgstr "" +msgstr "Registry synchronisieren" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__tech_name msgid "Tech Name" -msgstr "" +msgstr "Technischer Name" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_app__registered_routes msgid "" "Technical field to allow developers to check registered routes on the form" msgstr "" +"Technisches Feld, das es Entwicklern ermöglicht, registrierte Routen im " +"Formular zu überprüfen" #. module: shopfloor_base #. odoo-python #: code:addons/shopfloor_base/services/service.py:0 #, python-format msgid "The record {model} {_id} does not exist" -msgstr "" +msgstr "Der Datensatz {model} {_id} existiert nicht" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_search_view msgid "To sync" -msgstr "" +msgstr "Zu synchronisieren" #. module: shopfloor_base #: model:ir.model.fields,field_description:shopfloor_base.field_shopfloor_app__url msgid "Url" -msgstr "" +msgstr "URL" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view @@ -467,16 +471,18 @@ msgid "" "Use the action \"Sync registry\" to make changes effective once you are done" " with edits and creates." msgstr "" +"Verwenden Sie die Aktion „Registry synchronisieren“, um Änderungen nach " +"Abschluss der Bearbeitungen und Erstellungen wirksam werden zu lassen." #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view msgid "View api docs" -msgstr "" +msgstr "Schnittstellendokumentation ansehen" #. module: shopfloor_base #: model_terms:ir.ui.view,arch_db:shopfloor_base.shopfloor_app_form_view msgid "View menu items" -msgstr "" +msgstr "Menüeinträge ansehen" #. module: shopfloor_base #: model:ir.model.fields,help:shopfloor_base.field_shopfloor_menu__profile_id @@ -486,4 +492,4 @@ msgstr "" #. module: shopfloor_base #: model:ir.model.constraint,message:shopfloor_base.constraint_shopfloor_app_tech_name msgid "tech_name must be unique" -msgstr "" +msgstr "tech_name muss einzigartig sein" From 30c46fa6e614f1d1d5c4953075f19cf2a528bbed Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Thu, 19 Feb 2026 00:03:42 +0100 Subject: [PATCH 321/357] [FIX] stock_release_channel: Add missing multi company ir.rule --- stock_release_channel/security/stock_release_channel.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stock_release_channel/security/stock_release_channel.xml b/stock_release_channel/security/stock_release_channel.xml index 991948df60b..86dc13b2ca9 100644 --- a/stock_release_channel/security/stock_release_channel.xml +++ b/stock_release_channel/security/stock_release_channel.xml @@ -31,4 +31,10 @@ + + Stock Release Channel multi-company + + [('company_id', 'in', company_ids)] + + From a9edc69e6096c085cadb9fedbccfeaf2599e100e Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Thu, 19 Feb 2026 00:30:16 +0100 Subject: [PATCH 322/357] [FIX] stock_release_channel_shipment_advice_deliver: Add missing method argument --- .../models/shipment_advice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock_release_channel_shipment_advice_deliver/models/shipment_advice.py b/stock_release_channel_shipment_advice_deliver/models/shipment_advice.py index 213da9c246c..648cda1845d 100644 --- a/stock_release_channel_shipment_advice_deliver/models/shipment_advice.py +++ b/stock_release_channel_shipment_advice_deliver/models/shipment_advice.py @@ -76,8 +76,8 @@ def _auto_process(self): ) return True - def _postprocess_action_done(self): - res = super()._postprocess_action_done() + def _postprocess_action_done(self, backorder_policy): + res = super()._postprocess_action_done(backorder_policy) if not self.release_channel_id: return res if self.state == "error": From 1db28f1b0b976ca9b43a645361c1092a39269fcb Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Thu, 19 Feb 2026 16:59:32 +0100 Subject: [PATCH 323/357] oca-addons-repo-template 1.38 --- .copier-answers.yml | 6 +-- .gitattributes | 1 + .github/workflows/pre-commit.yml | 1 + .github/workflows/test.yml | 7 ++++ .pre-commit-config.yaml | 7 ++-- .pylintrc | 69 ++++++++++++++++---------------- .pylintrc-mandatory | 50 +++++++++++------------ 7 files changed, 76 insertions(+), 65 deletions(-) create mode 100644 .gitattributes diff --git a/.copier-answers.yml b/.copier-answers.yml index 625e7e59390..d5e90db716f 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,6 +1,6 @@ # Do NOT update manually; changes here will be overwritten by Copier -_commit: v1.29 -_src_path: gh:oca/oca-addons-repo-template +_commit: v1.38 +_src_path: https://github.com/OCA/oca-addons-repo-template.git ci: GitHub convert_readme_fragments_to_markdown: false enable_checklog_odoo: false @@ -18,7 +18,7 @@ org_name: Odoo Community Association (OCA) org_slug: OCA rebel_module_groups: [] repo_description: WMS modules for Odoo -repo_name: wms +repo_name: Warehouse Management System (WMS) repo_slug: wms repo_website: https://github.com/OCA/wms use_pyproject_toml: false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..e0d56685a95 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +test-requirements.txt merge=union diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index afd7524ef0d..5e6c3fb4395 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -17,6 +17,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.11" + cache: 'pip' - name: Get python version run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - uses: actions/cache@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4ccc216aff6..743814303f6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -63,6 +63,13 @@ jobs: run: oca_init_test_database - name: Run tests run: oca_run_tests + - name: Upload screenshots from JS tests + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: Screenshots of failed JS tests - ${{ matrix.name }}${{ join(matrix.include) }} + path: /tmp/odoo_tests/${{ env.PGDATABASE }} + if-no-files-found: ignore - uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5bb727f5655..3fa6f98534f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ exclude: | # Maybe reactivate this when all README files include prettier ignore tags? ^README\.md$| # Library files can have extraneous formatting (even minimized) - lib/| + /static/(src/)?lib/| # Repos using Sphinx to generate docs don't need prettying ^docs/_templates/.*\.html$| # Don't bother non-technical authors with formatting issues in docs @@ -39,7 +39,7 @@ repos: language: fail files: '[a-zA-Z0-9_]*/i18n/en\.po$' - repo: https://github.com/oca/maintainer-tools - rev: d5fab7ee87fceee858a3d01048c78a548974d935 + rev: f9b919b9868143135a9c9cb03021089cabba8223 hooks: # update the NOT INSTALLABLE ADDONS section above - id: oca-update-pre-commit-excluded-addons @@ -104,6 +104,7 @@ repos: additional_dependencies: - "eslint@8.24.0" - "eslint-plugin-jsdoc@" + - "globals@" # SPECIAL CASE: barcode scanner app use Vue.js + # advanced JS (modules, classes, etc) # which are not supported by OCA rules yet. @@ -144,7 +145,7 @@ repos: - --settings=. exclude: /__init__\.py$ - repo: https://github.com/acsone/setuptools-odoo - rev: 3.1.8 + rev: 3.3.2 hooks: - id: setuptools-odoo-make-default - id: setuptools-odoo-get-requirements diff --git a/.pylintrc b/.pylintrc index 554913276b4..0a521c31ffe 100644 --- a/.pylintrc +++ b/.pylintrc @@ -25,19 +25,25 @@ disable=all enable=anomalous-backslash-in-string, api-one-deprecated, api-one-multi-together, - assignment-from-none, - attribute-deprecated, class-camelcase, - dangerous-default-value, dangerous-view-replace-wo-priority, - development-status-allowed, duplicate-id-csv, - duplicate-key, duplicate-xml-fields, duplicate-xml-record-id, eval-referenced, - eval-used, incoherent-interpreter-exec-perm, + openerp-exception-warning, + redundant-modulename-xml, + relative-import, + rst-syntax-error, + wrong-tabs-instead-of-spaces, + xml-syntax-error, + assignment-from-none, + attribute-deprecated, + dangerous-default-value, + development-status-allowed, + duplicate-key, + eval-used, license-allowed, manifest-author-string, manifest-deprecated-key, @@ -48,73 +54,68 @@ enable=anomalous-backslash-in-string, method-inverse, method-required-super, method-search, - openerp-exception-warning, pointless-statement, pointless-string-statement, print-used, redundant-keyword-arg, - redundant-modulename-xml, reimported, - relative-import, return-in-init, - rst-syntax-error, sql-injection, too-few-format-args, translation-field, translation-required, unreachable, use-vim-comment, - wrong-tabs-instead-of-spaces, - xml-syntax-error, - attribute-string-redundant, character-not-valid-in-resource-link, - consider-merging-classes-inherited, - context-overridden, create-user-wo-reset-password, dangerous-filter-wo-user, dangerous-qweb-replace-wo-priority, deprecated-data-xml-node, deprecated-openerp-xml-node, duplicate-po-message-definition, - except-pass, file-not-used, + missing-newline-extrafiles, + old-api7-method-defined, + po-msgstr-variables, + po-syntax-error, + str-format-used, + unnecessary-utf8-coding-comment, + xml-attribute-translatable, + xml-deprecated-qweb-directive, + xml-deprecated-tree-attribute, + attribute-string-redundant, + consider-merging-classes-inherited, + context-overridden, + except-pass, invalid-commit, manifest-maintainers-list, - missing-newline-extrafiles, missing-readme, missing-return, odoo-addons-relative-import, - old-api7-method-defined, - po-msgstr-variables, - po-syntax-error, renamed-field-parameter, resource-not-exist, - str-format-used, test-folder-imported, translation-contains-variable, translation-positional-used, - unnecessary-utf8-coding-comment, website-manifest-key-not-valid-uri, - xml-attribute-translatable, - xml-deprecated-qweb-directive, - xml-deprecated-tree-attribute, external-request-timeout, - # messages that do not cause the lint step to fail - consider-merging-classes-inherited, + missing-manifest-dependency, + too-complex,, create-user-wo-reset-password, dangerous-filter-wo-user, - deprecated-module, file-not-used, - invalid-commit, - missing-manifest-dependency, missing-newline-extrafiles, - missing-readme, no-utf8-coding-comment, - odoo-addons-relative-import, old-api7-method-defined, + unnecessary-utf8-coding-comment, + # messages that do not cause the lint step to fail + consider-merging-classes-inherited, + deprecated-module, + invalid-commit, + missing-readme, + odoo-addons-relative-import, redefined-builtin, - too-complex, - unnecessary-utf8-coding-comment + manifest-external-assets [REPORTS] diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory index 7a0cd4efefe..098393aadb8 100644 --- a/.pylintrc-mandatory +++ b/.pylintrc-mandatory @@ -17,19 +17,25 @@ disable=all enable=anomalous-backslash-in-string, api-one-deprecated, api-one-multi-together, - assignment-from-none, - attribute-deprecated, class-camelcase, - dangerous-default-value, dangerous-view-replace-wo-priority, - development-status-allowed, duplicate-id-csv, - duplicate-key, duplicate-xml-fields, duplicate-xml-record-id, eval-referenced, - eval-used, incoherent-interpreter-exec-perm, + openerp-exception-warning, + redundant-modulename-xml, + relative-import, + rst-syntax-error, + wrong-tabs-instead-of-spaces, + xml-syntax-error, + assignment-from-none, + attribute-deprecated, + dangerous-default-value, + development-status-allowed, + duplicate-key, + eval-used, license-allowed, manifest-author-string, manifest-deprecated-key, @@ -40,56 +46,50 @@ enable=anomalous-backslash-in-string, method-inverse, method-required-super, method-search, - openerp-exception-warning, pointless-statement, pointless-string-statement, print-used, redundant-keyword-arg, - redundant-modulename-xml, reimported, - relative-import, return-in-init, - rst-syntax-error, sql-injection, too-few-format-args, translation-field, translation-required, unreachable, use-vim-comment, - wrong-tabs-instead-of-spaces, - xml-syntax-error, - attribute-string-redundant, character-not-valid-in-resource-link, - consider-merging-classes-inherited, - context-overridden, create-user-wo-reset-password, dangerous-filter-wo-user, dangerous-qweb-replace-wo-priority, deprecated-data-xml-node, deprecated-openerp-xml-node, duplicate-po-message-definition, - except-pass, file-not-used, + missing-newline-extrafiles, + old-api7-method-defined, + po-msgstr-variables, + po-syntax-error, + str-format-used, + unnecessary-utf8-coding-comment, + xml-attribute-translatable, + xml-deprecated-qweb-directive, + xml-deprecated-tree-attribute, + attribute-string-redundant, + consider-merging-classes-inherited, + context-overridden, + except-pass, invalid-commit, manifest-maintainers-list, - missing-newline-extrafiles, missing-readme, missing-return, odoo-addons-relative-import, - old-api7-method-defined, - po-msgstr-variables, - po-syntax-error, renamed-field-parameter, resource-not-exist, - str-format-used, test-folder-imported, translation-contains-variable, translation-positional-used, - unnecessary-utf8-coding-comment, website-manifest-key-not-valid-uri, - xml-attribute-translatable, - xml-deprecated-qweb-directive, - xml-deprecated-tree-attribute, external-request-timeout [REPORTS] From 36b9f8509f843991e9d938576a9d716b8de1605d Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 19 Feb 2026 16:37:18 +0000 Subject: [PATCH 324/357] [BOT] post-merge updates --- README.md | 4 +-- stock_release_channel/README.rst | 8 +++-- stock_release_channel/__manifest__.py | 2 +- .../static/description/index.html | 34 +++++++++++-------- .../README.rst | 2 +- .../__manifest__.py | 2 +- .../static/description/index.html | 2 +- 7 files changed, 32 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index f6fafb8f61e..4eecc5b722d 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ addon | version | maintainers | summary [stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.2.1.0 | lmignon | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type -[stock_release_channel](stock_release_channel/) | 16.0.3.1.0 | sebalix jbaudoux mt-software-de | Manage workload in WMS with release channels +[stock_release_channel](stock_release_channel/) | 16.0.3.1.1 | sebalix jbaudoux mt-software-de | Manage workload in WMS with release channels [stock_release_channel_auto_release](stock_release_channel_auto_release/) | 16.0.1.1.0 | | Add an automatic release mode to the release channel [stock_release_channel_batch_mode_commercial_partner](stock_release_channel_batch_mode_commercial_partner/) | 16.0.1.0.2 | | Release pickings into channels by batch of same commercial entity [stock_release_channel_cutoff](stock_release_channel_cutoff/) | 16.0.1.1.0 | jbaudoux | Add the cutoff time to the release channel @@ -69,7 +69,7 @@ addon | version | maintainers | summary [stock_release_channel_process_end_time](stock_release_channel_process_end_time/) | 16.0.1.7.0 | rousseldenis jbaudoux | Allows to define an end date (and time) on a release channel and propagate it to the concerned pickings [stock_release_channel_propagate_channel_picking](stock_release_channel_propagate_channel_picking/) | 16.0.1.2.0 | | Allows to propagate the channel to every picking that is created from the original one. [stock_release_channel_shipment_advice](stock_release_channel_shipment_advice/) | 16.0.1.2.0 | jbaudoux | Plan shipment advices for ready and released pickings -[stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.1 | | This module adds an action to the release channel to automate the delivery of its shippings. +[stock_release_channel_shipment_advice_deliver](stock_release_channel_shipment_advice_deliver/) | 16.0.2.0.2 | | This module adds an action to the release channel to automate the delivery of its shippings. [stock_release_channel_shipment_advice_process_end_time](stock_release_channel_shipment_advice_process_end_time/) | 16.0.1.0.0 | | This module allows to set a delay time (in minutes) between the release channel process end time and the shipment advice arrival to the dock time. [stock_release_channel_shipment_advice_toursolver](stock_release_channel_shipment_advice_toursolver/) | 16.0.1.1.0 | | Use TourSolver to plan shipment advices for ready and released pickings [stock_release_channel_shipment_lead_time](stock_release_channel_shipment_lead_time/) | 16.0.2.1.0 | jbaudoux | Release channel with shipment lead time diff --git a/stock_release_channel/README.rst b/stock_release_channel/README.rst index a8c2b83541c..4af06749de6 100644 --- a/stock_release_channel/README.rst +++ b/stock_release_channel/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ====================== Stock Release Channels ====================== @@ -7,13 +11,13 @@ Stock Release Channels !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:2fad401dca0aa4a4f4b0e8ddcc83fd0010d54cdfe53ed66d8fc01049bdb6d273 + !! source digest: sha256:1f36dd380861d1ccbe9a15b44cc304825d014e2aa40b38296ed78b623940726e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/stock_release_channel/__manifest__.py b/stock_release_channel/__manifest__.py index 4f9cde1b92a..9ef5c166d5b 100644 --- a/stock_release_channel/__manifest__.py +++ b/stock_release_channel/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Stock Release Channels", "summary": "Manage workload in WMS with release channels", - "version": "16.0.3.1.0", + "version": "16.0.3.1.1", "development_status": "Beta", "license": "AGPL-3", "author": "Camptocamp, BCIM, ACSONE SA/NV, Odoo Community Association (OCA)", diff --git a/stock_release_channel/static/description/index.html b/stock_release_channel/static/description/index.html index 3ebd0ec010e..a524dc9d5c1 100644 --- a/stock_release_channel/static/description/index.html +++ b/stock_release_channel/static/description/index.html @@ -3,7 +3,7 @@ -Stock Release Channels +README.rst -

    -

    Stock Release Channels

    +
    + + +Odoo Community Association + +
    +

    Stock Release Channels

    -

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Release channels are:

    • Release channels are created by stock managers (only pallets, only parcels, …)
    • @@ -403,12 +408,12 @@

      Stock Release Channels

    -

    Configuration

    +

    Configuration

    In Inventory > Configuration > Release Channels. Only Stock Managers have write permissions.

    -

    Usage

    +

    Usage

    Use Inventory > Operations > Release Channels to access to the dashboard.

    Each channel has a dashboard with statistics about the number of transfers to release and of the progress of the released transfers.

    @@ -438,7 +443,7 @@

    Usage

    “Open” or “Locked” state.

    -

    Bug Tracker

    +

    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 to smash it by providing a detailed and welcomed @@ -446,9 +451,9 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Camptocamp
    • BCIM
    • @@ -456,7 +461,7 @@

      Authors

    -

    Contributors

    +

    Contributors

    -

    Design

    +

    Design

    -

    Other credits

    +

    Other credits

    Financial support

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -497,5 +502,6 @@

    Maintainers

    +
    diff --git a/stock_release_channel_shipment_advice_deliver/README.rst b/stock_release_channel_shipment_advice_deliver/README.rst index 759a2f738e7..9d57b02e352 100644 --- a/stock_release_channel_shipment_advice_deliver/README.rst +++ b/stock_release_channel_shipment_advice_deliver/README.rst @@ -11,7 +11,7 @@ Stock Release Channel Shipment Advice Deliver !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:39da7fc0bf93470a6fd5bf80c0d5cdfa9422ac87a32eb2d473d47908e568feb3 + !! source digest: sha256:f1e4d9a35298da170efb90de6c3d7779de88b1962bf059970e7a4d9ec4066ea6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_release_channel_shipment_advice_deliver/__manifest__.py b/stock_release_channel_shipment_advice_deliver/__manifest__.py index 935726fe157..b0393fafcda 100644 --- a/stock_release_channel_shipment_advice_deliver/__manifest__.py +++ b/stock_release_channel_shipment_advice_deliver/__manifest__.py @@ -8,7 +8,7 @@ "author": "ACSONE SA/NV, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "16.0.2.0.1", + "version": "16.0.2.0.2", "license": "AGPL-3", "depends": [ "stock_release_channel", diff --git a/stock_release_channel_shipment_advice_deliver/static/description/index.html b/stock_release_channel_shipment_advice_deliver/static/description/index.html index 13e605d4f1c..5ea0e1f9574 100644 --- a/stock_release_channel_shipment_advice_deliver/static/description/index.html +++ b/stock_release_channel_shipment_advice_deliver/static/description/index.html @@ -372,7 +372,7 @@

    Stock Release Channel Shipment Advice Deliver

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:39da7fc0bf93470a6fd5bf80c0d5cdfa9422ac87a32eb2d473d47908e568feb3 +!! source digest: sha256:f1e4d9a35298da170efb90de6c3d7779de88b1962bf059970e7a4d9ec4066ea6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    This module adds an action to the release channel to automate the delivery of From 60cad64d23b3868d19fd4cb45287ac7cc27ec1a2 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Wed, 18 Jun 2025 16:10:13 +0200 Subject: [PATCH 325/357] [FIX] shopfloor: Fetch qty_available only when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several services use `_data_move_line` to prepare stock move line data for the Shopfloor frontend. However, qty_available is not displayed on all pages where stock move lines are handled. Since qty_available is computed from quants, accessing it unnecessarily can lead to useless database queries. In high-concurrency environments, this can even trigger deadlocks when reads and writes occur simultaneously across many Shopfloor users. This fix limits the use of qty_available to cases where it’s strictly needed. --- shopfloor/services/cluster_picking.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/shopfloor/services/cluster_picking.py b/shopfloor/services/cluster_picking.py index d54ef12b9f6..6a7854a503b 100644 --- a/shopfloor/services/cluster_picking.py +++ b/shopfloor/services/cluster_picking.py @@ -97,7 +97,7 @@ def _response_for_start_line( self, move_line, message=None, popup=None, sublocation=None ): kw = {"sublocation": self.data.location(sublocation)} if sublocation else {} - data = self._data_move_line(move_line, **kw) + data = self._data_move_line(move_line, with_qty_available=False, **kw) return self._response( next_state="start_line", data=data, @@ -107,9 +107,14 @@ def _response_for_start_line( def _response_for_scan_destination(self, move_line, message=None, qty_done=None): if qty_done is None: - data = self._data_move_line(move_line) + data = self._data_move_line( + move_line, + with_qty_available=False, + ) else: - data = self._data_move_line(move_line, qty_done=qty_done) + data = self._data_move_line( + move_line, with_qty_available=False, qty_done=qty_done + ) last_picked_line = self._last_picked_line(move_line.picking_id) if last_picked_line: # suggest pack to be used for the next line @@ -393,7 +398,7 @@ def _next_line_for_pick(self, picking_batch): def _response_batch_does_not_exist(self): return self._response_for_start(message=self.msg_store.record_not_found()) - def _data_move_line(self, line, **kw): + def _data_move_line(self, line, with_qty_available=True, **kw): picking = line.picking_id batch = picking.batch_id product = line.product_id @@ -406,9 +411,10 @@ def _data_move_line(self, line, **kw): data["batch"] = self.data.picking_batch(batch) data["picking"] = self.data.picking(picking) data["postponed"] = line.shopfloor_postponed - data["product"]["qty_available"] = product.with_context( - location=line.location_id.id - ).qty_available + if with_qty_available: + data["product"]["qty_available"] = product.with_context( + location=line.location_id.id + ).qty_available data["scan_location_or_pack_first"] = self.work.menu.scan_location_or_pack_first data.update(kw) return data From d97f6411a3f57646e51a3651476262822bc82c7c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 20 Feb 2026 13:04:40 +0000 Subject: [PATCH 326/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4eecc5b722d..90562aa8b4f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.14.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.15.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index 5e2dde5c4fb..dcf8e3a9cdf 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e393dd59712ff8f5ff542bcda9e7405966f33c6dc787ef439d16051a70aaadf0 + !! source digest: sha256:4c221d01eb0d0479500dca6accfc6ba696e95c76f62d5039ead2afb98cf83536 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 36610727298..c369aad32aa 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.14.0", + "version": "16.0.2.15.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index d61019c6cd3..7882e9c25ac 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:e393dd59712ff8f5ff542bcda9e7405966f33c6dc787ef439d16051a70aaadf0 +!! source digest: sha256:4c221d01eb0d0479500dca6accfc6ba696e95c76f62d5039ead2afb98cf83536 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor is a barcode scanner application for internal warehouse operations.

    From 81866903440d08b8352ba45001b54d5d64bd7822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Tue, 19 Aug 2025 12:47:08 -0300 Subject: [PATCH 327/357] [REF] stock_picking_batch_creation: adapt for changes in #2062 --- .../tests/test_clustering_conditions.py | 31 +++++++++++++------ .../wizards/make_picking_batch.py | 23 ++++++++------ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index cb513cfbb3c..23be6612878 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -1,7 +1,12 @@ # Copyright 2021 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from ..exceptions import NoSuitableDeviceError, PickingCandidateNumberLineExceedError +from odoo.tests import RecordCapturer + +from ..exceptions import ( + NoSuitableDeviceError, + PickingCandidateNumberLineExceedError, +) from .common import ClusterPickingCommonFeatures @@ -447,8 +452,10 @@ def test_picking_split_with_maximum_number_of_lines_exceed(self): with self.assertRaises(PickingCandidateNumberLineExceedError): self.make_picking_batch._create_batch(raise_if_not_possible=True) self.make_picking_batch.split_picking_exceeding_limits = True - batch = self.make_picking_batch._create_batch() - self.assertEqual(self.pick3, batch.picking_ids) + with RecordCapturer(self.env["stock.picking"], []) as rc: + batch = self.make_picking_batch._create_batch() + new_pickings = rc.records + self.assertEqual(new_pickings, batch.picking_ids) self.assertEqual(len(batch.move_line_ids), 1) def test_picking_split_with_weight_exceed(self): @@ -484,8 +491,10 @@ def test_picking_split_with_weight_exceed(self): with self.assertRaises(NoSuitableDeviceError): self.make_picking_batch._create_batch(raise_if_not_possible=True) self.make_picking_batch.split_picking_exceeding_limits = True - batch = self.make_picking_batch._create_batch() - self.assertEqual(self.pick3, batch.picking_ids) + with RecordCapturer(self.env["stock.picking"], []) as rc: + batch = self.make_picking_batch._create_batch() + new_pickings = rc.records + self.assertEqual(new_pickings, batch.picking_ids) self.assertEqual(len(batch.move_line_ids), 1) def test_picking_split_with_volume_exceed(self): @@ -529,8 +538,10 @@ def test_picking_split_with_volume_exceed(self): with self.assertRaises(NoSuitableDeviceError): self.make_picking_batch._create_batch(raise_if_not_possible=True) self.make_picking_batch.split_picking_exceeding_limits = True - batch = self.make_picking_batch._create_batch() - self.assertEqual(self.pick3, batch.picking_ids) + with RecordCapturer(self.env["stock.picking"], []) as rc: + batch = self.make_picking_batch._create_batch() + new_pickings = rc.records + self.assertEqual(new_pickings, batch.picking_ids) self.assertEqual(len(batch.move_line_ids), 1) def test_picking_split_priority(self): @@ -580,5 +591,7 @@ def test_picking_split_priority(self): # if the split_picking_exceeding_limits is set to True. # then pick3 should be split and processed first self.make_picking_batch.split_picking_exceeding_limits = True - batch = self.make_picking_batch._create_batch() - self.assertEqual(self.pick3, batch.picking_ids) + with RecordCapturer(self.env["stock.picking"], []) as rc: + batch = self.make_picking_batch._create_batch() + new_pickings = rc.records + self.assertEqual(new_pickings, batch.picking_ids) diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 94653aaf17a..e99763f037c 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -271,16 +271,19 @@ def _get_picking_max_dimensions(self): def _split_first_picking_for_limit(self, picking): nbr_lines, volume, weight = self._get_picking_max_dimensions() - wizard = self.env["stock.split.picking"].with_context(active_ids=picking.ids) - wizard.create( - { - "mode": "dimensions", - "max_nbr_lines": nbr_lines, - "max_volume": volume, - "max_weight": weight, - } - ).action_apply() - return picking + return ( + self.env["stock.split.picking"] + .with_context(active_ids=picking.ids) + .create( + { + "mode": "dimensions", + "max_nbr_lines": nbr_lines, + "max_volume": volume, + "max_weight": weight, + } + ) + ._action_apply() + ) def _is_picking_exceeding_limits(self, picking): """Check if the picking exceeds the limits of the available devices. From 5155aef0009a49761713da30d5154e69938433f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Tue, 19 Aug 2025 14:34:29 -0300 Subject: [PATCH 328/357] [IMP] stock_picking_batch_creation: _create_product test helper Make it easier to pass custom vals for the created product. --- stock_picking_batch_creation/tests/common.py | 38 +++++++++----------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/stock_picking_batch_creation/tests/common.py b/stock_picking_batch_creation/tests/common.py index d5bdca02cb4..b19d3a50a24 100644 --- a/stock_picking_batch_creation/tests/common.py +++ b/stock_picking_batch_creation/tests/common.py @@ -145,27 +145,23 @@ def _create_partner(cls, name, ref): return cls.env["res.partner"].create({"name": name, "ref": ref}) @classmethod - def _create_product( - cls, name, weight, length, height, width, uom_id=None, product_type=None - ): - if not uom_id: - uom_id = cls.uom_id - if not product_type: - product_type = "product" - volume = length * height * width - return cls.env["product.product"].create( - { - "name": name, - "uom_id": uom_id, - "type": product_type, - "weight": weight, - "product_length": length, - "product_height": height, - "product_width": width, - "volume": volume, - "dimensional_uom_id": cls.uom_m.id, - } - ) + def _create_product(cls, name, weight, length, height, width, **kwargs): + vals = { + "name": name, + "weight": weight, + "product_length": length, + "product_height": height, + "product_width": width, + "dimensional_uom_id": cls.uom_m.id, + **kwargs, + } + if vals.get("type", "consu") == "consu" and "is_storable" not in vals: + vals["is_storable"] = True + if "uom_id" not in vals: + vals["uom_id"] = cls.uom_id + if "volume" not in vals: + vals["volume"] = length * height * width + return cls.env["product.product"].create(vals) @classmethod def _create_device( From da143d36b546855f130f416cc3f36505bd66b175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Tue, 19 Aug 2025 14:38:42 -0300 Subject: [PATCH 329/357] [IMP] stock_picking_batch_creation: respect product order in test helper --- stock_picking_batch_creation/tests/common.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stock_picking_batch_creation/tests/common.py b/stock_picking_batch_creation/tests/common.py index b19d3a50a24..c43308e8970 100644 --- a/stock_picking_batch_creation/tests/common.py +++ b/stock_picking_batch_creation/tests/common.py @@ -208,9 +208,10 @@ def _create_picking_pick_and_assign( "product_uom": p.uom_id.id, "location_id": cls.env.ref("stock.stock_location_stock").id, "location_dest_id": warehouse.wh_output_stock_loc_id.id, + "sequence": sequence, }, ) - for p in products + for sequence, p in enumerate(products) ], } picking = cls.env["stock.picking"].create(picking_values) From c7e9f8c4276cc22777ec96acf4e1ef20b489f266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Mon, 25 Aug 2025 15:04:58 -0300 Subject: [PATCH 330/357] [IMP] stock_picking_batch_creation: implement configurable split_mode --- .../models/stock_device_type.py | 5 ++ .../views/stock_device_type.xml | 2 + .../wizards/make_picking_batch.py | 49 +++++++++---------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/stock_picking_batch_creation/models/stock_device_type.py b/stock_picking_batch_creation/models/stock_device_type.py index dfe870544a7..98a84882f19 100644 --- a/stock_picking_batch_creation/models/stock_device_type.py +++ b/stock_picking_batch_creation/models/stock_device_type.py @@ -42,6 +42,11 @@ class StockDeviceType(models.Model): readonly=False, ) nbr_bins = fields.Integer(string="Number of compartments") + split_mode = fields.Selection( + selection=[("dimension", "Dimension")], + default="dimension", + required=True, + ) volume_per_bin = fields.Float( string="Max volume per bin", compute="_compute_volume_per_bin" diff --git a/stock_picking_batch_creation/views/stock_device_type.xml b/stock_picking_batch_creation/views/stock_device_type.xml index a3207f9dd59..c53c8765e98 100644 --- a/stock_picking_batch_creation/views/stock_device_type.xml +++ b/stock_picking_batch_creation/views/stock_device_type.xml @@ -15,6 +15,7 @@ + @@ -55,6 +56,7 @@
    + diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index e99763f037c..49bc8430c59 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -261,41 +261,36 @@ def _execute_search_pickings(self, domain, limit=None): domain, order=self._get_picking_order_by(), limit=limit ) - def _get_picking_max_dimensions(self): - self.ensure_one() - nbr_lines = self.maximum_number_of_preparation_lines - last_device = self.stock_device_type_ids[-1] - volume = last_device.max_volume - weight = last_device.max_weight - return nbr_lines, volume, weight - def _split_first_picking_for_limit(self, picking): - nbr_lines, volume, weight = self._get_picking_max_dimensions() - return ( - self.env["stock.split.picking"] - .with_context(active_ids=picking.ids) - .create( - { - "mode": "dimensions", - "max_nbr_lines": nbr_lines, - "max_volume": volume, - "max_weight": weight, - } + last_device = self.stock_device_type_ids[-1] + if last_device.split_mode == "dimension": + return ( + self.env["stock.split.picking"] + .with_context(active_ids=picking.ids) + .create( + { + "mode": "dimensions", + "max_nbr_lines": self.maximum_number_of_preparation_lines, + "max_volume": last_device.max_volume, + "max_weight": last_device.max_weight, + } + ) + ._action_apply() ) - ._action_apply() - ) def _is_picking_exceeding_limits(self, picking): """Check if the picking exceeds the limits of the available devices. :param picking: the picking to check """ - nbr_lines, volume, weight = self._get_picking_max_dimensions() - return ( - picking.nbr_picking_lines > nbr_lines - or picking.volume > volume - or picking.weight > weight - ) + last_device = self.stock_device_type_ids[-1] + if last_device.split_mode == "dimension": + return ( + picking.nbr_picking_lines > self.maximum_number_of_preparation_lines + or picking.volume > last_device.max_volume + or picking.weight > last_device.max_weight + ) + return False def _get_first_picking(self, raise_if_not_found=False): """Get the first picking to add to the batch. From 1c1305694a1ebda098e3423f2e89bea9c082ee09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Thu, 4 Sep 2025 11:47:08 -0300 Subject: [PATCH 331/357] [FIX] stock_picking_batch_creation: support devices without max volume/weight --- .../models/stock_picking.py | 3 +- .../tests/test_get_device_to_use.py | 119 ++++++++++++++++++ .../wizards/make_picking_batch.py | 65 +++++----- 3 files changed, 151 insertions(+), 36 deletions(-) diff --git a/stock_picking_batch_creation/models/stock_picking.py b/stock_picking_batch_creation/models/stock_picking.py index 181e01dcf9a..f22a8ec2b80 100644 --- a/stock_picking_batch_creation/models/stock_picking.py +++ b/stock_picking_batch_creation/models/stock_picking.py @@ -9,6 +9,7 @@ class StockPicking(models.Model): _inherit = "stock.picking" + picking_device_id = fields.Many2one( "stock.device.type", string="Device for the picking", @@ -26,7 +27,7 @@ def _get_nbr_bins_for_device(self, device): self.ensure_one() if not device: return 0 - if not self.volume: + if not self.volume or not device.volume_per_bin: return 1 return math.ceil(self.volume / device.volume_per_bin) diff --git a/stock_picking_batch_creation/tests/test_get_device_to_use.py b/stock_picking_batch_creation/tests/test_get_device_to_use.py index de18fc1c61e..63ea2aa7bfb 100644 --- a/stock_picking_batch_creation/tests/test_get_device_to_use.py +++ b/stock_picking_batch_creation/tests/test_get_device_to_use.py @@ -1,6 +1,8 @@ # Copyright 2021 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import Command + from .common import ClusterPickingCommonFeatures @@ -65,6 +67,123 @@ def test_get_device_to_use_01(self): device = make_picking_batch._compute_device_to_use(first_picking) self.assertEqual(device, self.device2) + def test_get_device_to_use_no_matching_device(self): + """Use case: There's no device that can handle the picking + + Data: + We create a new product with a really big and heavy product in zone 1. + + Test case: + We have 3 devices possibles (device1, device2, device3), ordered following + sequence: device3, device2, device1. + + Expected Result: + No device can be used to handle it, so another picking is selected. + """ + product_big_1 = self._create_product("Unittest P1 big & heavy", 800, 80, 80, 80) + self._set_quantity_in_stock(self.stock_location, product_big_1) + self._add_product_to_picking(self.pick3, product_big_1) + + make_picking_batch = self.make_picking_batch.create( + { + "user_id": self.env.user.id, + "picking_type_ids": [ + Command.set(self.picking_type_1.ids), + ], + "stock_device_type_ids": [ + Command.link(self.device1.id), + Command.link(self.device2.id), + Command.link(self.device3.id), + ], + } + ) + + self.assertFalse( + make_picking_batch._compute_device_to_use(self.pick3), + "No device can hold this picking", + ) + + first_picking = make_picking_batch._get_first_picking() + self.assertEqual(first_picking, self.pick1) + + def test_get_device_to_use_without_max_volume(self): + """Use case: There's no max volume set, so it's unlimited + + Data: + We create a new product with a really big volume in zone 1. + We remove the max volume from device1. + + Test case: + We have 3 devices possibles (device1, device2, device3), ordered following + sequence: device3, device2, device1. + + Expected Result: + device1 should be the device to use since it's the one with no max volume, + effectively unlimited. + """ + self.device1.max_volume = 0 # Effectively unlimited + product_big_1 = self._create_product("Unittest P1 voluminous", 10, 800, 1, 1) + self._set_quantity_in_stock(self.stock_location, product_big_1) + self._add_product_to_picking(self.pick3, product_big_1) + + make_picking_batch = self.make_picking_batch.create( + { + "user_id": self.env.user.id, + "picking_type_ids": [ + Command.set(self.picking_type_1.ids), + ], + "stock_device_type_ids": [ + Command.link(self.device1.id), + Command.link(self.device2.id), + Command.link(self.device3.id), + ], + } + ) + first_picking = make_picking_batch._get_first_picking() + self.assertEqual(first_picking, self.pick3) + device = make_picking_batch._compute_device_to_use(first_picking) + self.assertEqual(device, self.device1) + + def test_get_device_to_use_without_max_weight(self): + """Use case: There's no max weight set, so it's unlimited + + Data: + We create a new product with a really big weight in zone 1. + We remove the max weight from device2. + We remove the min volume from device2 to not interfere (previously 70). + + Test case: + We have 3 devices possibles (device1, device2, device3), ordered following + sequence: device3, device2, device1. + + Expected Result: + device2 should be the device to use since it's the one with no max weight, + effectively unlimited. + """ + self.device2.max_weight = 0 # Effectively unlimited + self.device2.min_volume = 0 # No min_volume to not interfere + product_big_1 = self._create_product("Unittest P1 heavy", 800, 1, 1, 1) + self._set_quantity_in_stock(self.stock_location, product_big_1) + self._add_product_to_picking(self.pick3, product_big_1) + + make_picking_batch = self.make_picking_batch.create( + { + "user_id": self.env.user.id, + "picking_type_ids": [ + Command.set(self.picking_type_1.ids), + ], + "stock_device_type_ids": [ + Command.link(self.device1.id), + Command.link(self.device2.id), + Command.link(self.device3.id), + ], + } + ) + first_picking = make_picking_batch._get_first_picking() + self.assertEqual(first_picking, self.pick3) + device = make_picking_batch._compute_device_to_use(first_picking) + self.assertEqual(device, self.device2) + def test_get_device_to_use_filter_pickings(self): """ Data: we create 1 new product with big volume in zone 1 diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 49bc8430c59..9c45ee01a8a 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -137,7 +137,7 @@ def create_batch(self): def _reset_counters(self): self._volume_by_partners = defaultdict(lambda: 0) self._device = None - self._remaining_weight = 0 + self._remaining_weight = None # None means unlimited self._remaining_nbr_picking_lines = 0 self._selected_picking_ids = [] self._first_picking = None @@ -181,11 +181,14 @@ def _get_picking_domain_for_first(self, no_nbr_lines_limit=False): return AND([picking_domain_common, picking_domain_first]) def _get_picking_domain_for_device(self, device): - return [ - ("volume", ">=", device.min_volume), - ("volume", "<=", device.max_volume), - ("weight", "<=", device.max_weight), - ] + domain = [] + if device.min_volume: + domain.append(("volume", ">=", device.min_volume)) + if device.max_volume: + domain.append(("volume", "<=", device.max_volume)) + if device.max_weight: + domain.append(("weight", "<=", device.max_weight)) + return domain def _get_picking_domain_for_additional(self): """Provides the domain expressing the additional constraints to apply to @@ -199,9 +202,10 @@ def _get_picking_domain_for_additional(self): self._remaining_nbr_picking_lines, ), ("id", "not in", excluded_ids), - ("weight", "<=", self._remaining_weight), ("picking_type_id", "=", self._first_picking.picking_type_id.id), ] + if self._remaining_weight is not None: # None means unlimited + domain.append(("weight", "<=", self._remaining_weight)) previous_picking = self._previous_selected_picking if self.restrict_to_same_priority: domain.append(("priority", "=", previous_picking.priority)) @@ -283,13 +287,19 @@ def _is_picking_exceeding_limits(self, picking): :param picking: the picking to check """ + # First check the number of lines + if ( + self.maximum_number_of_preparation_lines + and picking.nbr_picking_lines > self.maximum_number_of_preparation_lines + ): + return True + # Then, check the device limits last_device = self.stock_device_type_ids[-1] if last_device.split_mode == "dimension": - return ( - picking.nbr_picking_lines > self.maximum_number_of_preparation_lines - or picking.volume > last_device.max_volume - or picking.weight > last_device.max_weight - ) + if last_device.max_volume and picking.volume > last_device.max_volume: + return True + if last_device.max_weight and picking.weight > last_device.max_weight: + return True return False def _get_first_picking(self, raise_if_not_found=False): @@ -356,23 +366,10 @@ def _get_remaining_volume(self, partner=False): return remaining_volume def _compute_device_to_use(self, picking): - available_devices = self.stock_device_type_ids.sorted(lambda d: d.sequence) - for device in available_devices: - if ( - self._volume_condition_for_device_choice( - device.min_volume, - picking.volume, - device.max_volume, - ) - and tools.float_compare( - device.max_weight, - picking.weight, - precision_digits=self._precision_volume(), - ) - > 0 - ): + for device in self.stock_device_type_ids.sorted("sequence"): + if picking.filtered_domain(self._get_picking_domain_for_device(device)): return device - return None + return self.env["stock.device.type"] def _volume_condition_for_device_choice( self, min_volume, picking_volume, max_volume @@ -432,12 +429,6 @@ def _create_batch(self, raise_if_not_possible=False): batch = self.env["stock.picking.batch"].create(vals) return batch - def _precision_volume(self): - return max( - 6, - self.env["decimal.precision"].precision_get("Product Unit of Measure") * 2, - ) - def _init_counters(self, first_picking, device): """Initialize the counters used to compute the batch. This method is called at the beginning of the batch creation. It allows @@ -448,7 +439,11 @@ def _init_counters(self, first_picking, device): :param device: the device to use to prepare the batch """ self._device = device - self._remaining_weight = device.max_weight - first_picking.weight + self._remaining_weight = ( + max(device.max_weight - first_picking.weight, 0) + if device.max_weight + else None # None means unlimited + ) self._remaining_nbr_picking_lines = ( self.maximum_number_of_preparation_lines - first_picking.nbr_picking_lines ) From 1d813423ce8f5f4b60efd531e4b31fc62f079629 Mon Sep 17 00:00:00 2001 From: Thierry Ducrest Date: Fri, 14 Nov 2025 16:02:00 +0100 Subject: [PATCH 332/357] stock_picking_batch_creation: Imp first picking slection When trying to create a batch picking only with the first availale transfer, there could be some occurence where that picking does not fit the dimension of the device and can not be split. This can happen when all moves from the transfer are oversize compare to the dimension of the device. After this change, the module will use the next transfer to create a batch until it is successfull. --- .../tests/test_batch_creation_splitting.py | 90 +++++++++++++++++++ .../wizards/make_picking_batch.py | 36 +++++--- 2 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 stock_picking_batch_creation/tests/test_batch_creation_splitting.py diff --git a/stock_picking_batch_creation/tests/test_batch_creation_splitting.py b/stock_picking_batch_creation/tests/test_batch_creation_splitting.py new file mode 100644 index 00000000000..3f403aaf362 --- /dev/null +++ b/stock_picking_batch_creation/tests/test_batch_creation_splitting.py @@ -0,0 +1,90 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from .common import ClusterPickingCommonFeatures + + +class TestBatchCreationSplitting(ClusterPickingCommonFeatures): + @classmethod + def setUpClass(cls): + super().setUpClass() + + def test_batch_creation_one_pick_move_over_the_limit(self): + """Test splitting a picking when the first move exceed the weight limit.""" + self.pick2.action_cancel() + self.pick3.action_cancel() + # Keep the picking 1 with one line and product 1 + move = self.pick1.move_ids + # And the weight of the move can not be accepted by the device + max_weight = 9 + move_weight = move.product_id.weight * move.product_qty + self.assertTrue(move_weight > max_weight) + self.make_picking_batch.write( + { + "maximum_number_of_preparation_lines": 2, + "split_picking_exceeding_limits": True, + } + ) + device = self._create_device( + "Device-A", + min_volume=0, + max_volume=0, + max_weight=max_weight, + nbr_bins=6, + sequence=1, + ) + self.make_picking_batch.stock_device_type_ids = device + batch = self.make_picking_batch._create_batch() + # There is no batch because the only picking could not be split + self.assertFalse(batch) + + def test_batch_creation_move_over_the_limit_take_2nd_picking(self): + """Test splitting a picking when the first move exceed the weight limit.""" + self.pick3.action_cancel() + # Keep the picking 1 with one line and product 1 + move = self.pick1.move_ids + # And the weight of the move can not be accepted by the device + max_weight = 9 + move_weight = move.product_id.weight * move.product_qty + self.assertTrue(move_weight > max_weight) + # Get the picking to fit the limit + self.pick2.move_ids.product_id.weight = 0.2 + # Force recomputation after changing the product weight + self.pick2.move_ids._cal_move_weight() + self.make_picking_batch.write( + { + "maximum_number_of_preparation_lines": 2, + "split_picking_exceeding_limits": True, + } + ) + device = self._create_device( + "Device-A", + min_volume=0, + max_volume=0, + max_weight=max_weight, + nbr_bins=6, + sequence=1, + ) + self.make_picking_batch.stock_device_type_ids = device + batch = self.make_picking_batch._create_batch() + self.assertTrue(batch, "We should have a batch") + self.assertTrue(self.pick2 in batch.picking_ids) + self.assertTrue(batch.picking_ids, "We should have a picking in the batch") + + def test_batch_creation_splitting_by_number_of_lines(self): + """Test splitting a picking when the number of lines exceed the limit.""" + self.pick1.action_cancel() + self.pick2.action_cancel() + # Keep the picking 3 + self._add_product_to_picking(self.pick3, self.p3) + self._add_product_to_picking(self.pick3, self.p4) + # And now it has 4 lines + self.make_picking_batch.write({"maximum_number_of_preparation_lines": 2}) + self.make_picking_batch.write({"split_picking_exceeding_limits": True}) + device = self._create_device("Test", 0.0, 0.0, 0.0, 20, 1) + self.make_picking_batch.stock_device_type_ids = device + batch = self.make_picking_batch._create_batch() + self.assertFalse(self.pick3 in batch.picking_ids) + self.assertTrue(batch, "We should have a batch") + self.assertTrue(batch.picking_ids, "We should have a picking in the batch") + self.assertEqual(len(batch.picking_ids.move_line_ids), 2) diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 9c45ee01a8a..098b8bfde1f 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -1,5 +1,6 @@ # Copyright 2021 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + import logging import math import threading @@ -319,23 +320,32 @@ def _get_first_picking(self, raise_if_not_found=False): for device in self.stock_device_type_ids: device_domains.append(self._get_picking_domain_for_device(device)) domain = AND([domain, OR(device_domains)]) - picking = self._execute_search_pickings(domain, limit=1) - if not picking and not no_limit and raise_if_not_found: - self._raise_create_batch_not_possible() + picking = self._execute_search_pickings(domain, limit=1) + if not picking and raise_if_not_found: + self._raise_create_batch_not_possible() + return picking + pickings = self._execute_search_pickings(domain) # at this stage we have the first picking to add to the batch but it could # exceed the limits of the available devices. In this case we split the # picking and return the picking to add to the batch. The split is done only # if the split_picking_exceeding_limits is set to True. - if ( - picking - and self.split_picking_exceeding_limits - and self._is_picking_exceeding_limits(picking) - ): - split_picking = self._split_first_picking_for_limit(picking) - if not split_picking and raise_if_not_found: - raise PickingSplitNotPossibleError(picking) - picking = split_picking - return picking + selected_picking = self.env["stock.picking"] + for picking in pickings: + if self._is_picking_exceeding_limits(picking): + split_picking = self._split_first_picking_for_limit(picking) + if not split_picking: + if raise_if_not_found: + raise PickingSplitNotPossibleError(picking) + _logger.warning( + f"The picking {picking.name} could not be split " + "for batch creation." + ) + continue + selected_picking = split_picking + else: + selected_picking = picking + break + return selected_picking def _get_additional_picking(self): """Get the next picking to add to the batch.""" From 00ee9488a83346926eb2a0b32e40dc44f70b133b Mon Sep 17 00:00:00 2001 From: Thierry Ducrest Date: Mon, 10 Nov 2025 15:39:14 +0100 Subject: [PATCH 333/357] stock_picking_batch_creation: fix stock device order Before this change when searching for a device to use for the batch, the order of the devices was not guaranteed although important. And it could cause some batch split not happening. Now the possible devices will be sorted by their default order, which is by sequence and name. --- .../tests/test_get_device_to_use.py | 64 +++++++++++++++++++ .../wizards/make_picking_batch.py | 13 +++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/stock_picking_batch_creation/tests/test_get_device_to_use.py b/stock_picking_batch_creation/tests/test_get_device_to_use.py index 63ea2aa7bfb..8f0143b5fa6 100644 --- a/stock_picking_batch_creation/tests/test_get_device_to_use.py +++ b/stock_picking_batch_creation/tests/test_get_device_to_use.py @@ -213,3 +213,67 @@ def test_get_device_to_use_filter_pickings(self): self.assertEqual(first_picking, self.pick1) device = make_picking_batch._compute_device_to_use(first_picking) self.assertEqual(device, self.device1) + + def test_device_used_for_first_picking_splitting_00(self): + """Check the last device is used for splitting the first picking. + + Default order is :: device3, device2, device1. + The last device (device1) can not manage the only picking. + So the picking will be split. + + """ + # Keep only one picking and a heavy one + self.pick1.action_cancel() + self.pick2.action_cancel() + product_big_1 = self._create_product("Unittest P1 voluminous", 10, 100, 1, 1) + self._set_quantity_in_stock(self.stock_location, product_big_1) + self._add_product_to_picking(self.pick3, product_big_1) + make_picking_batch = self.make_picking_batch.create( + { + "user_id": self.env.user.id, + "picking_type_ids": [(4, self.picking_type_1.id)], + "split_picking_exceeding_limits": True, + # Add the device not in their default sort order + "stock_device_type_ids": [ + (4, self.device1.id), + (4, self.device2.id), + (4, self.device3.id), + ], + } + ) + first_picking = make_picking_batch._get_first_picking() + # A split picking has been created + self.assertTrue(first_picking != self.pick3) + + def test_device_used_for_first_picking_splitting_01(self): + """Check the last device is used for splitting the first picking. + + The last device (device2) can manage the only picking. + So picking will not be split. + + """ + # Keep only one picking and a heavy one. + self.pick1.action_cancel() + self.pick2.action_cancel() + product_big_1 = self._create_product("Unittest P1 voluminous", 10, 100, 1, 1) + self._set_quantity_in_stock(self.stock_location, product_big_1) + self._add_product_to_picking(self.pick3, product_big_1) + # Set the device order + self.device1.sequence = 10 + self.device3.sequence = 20 + self.device2.sequence = 30 + make_picking_batch = self.make_picking_batch.create( + { + "user_id": self.env.user.id, + "picking_type_ids": [(4, self.picking_type_1.id)], + "split_picking_exceeding_limits": True, + # Add the device not in their default sort order + "stock_device_type_ids": [ + (4, self.device1.id), + (4, self.device2.id), + (4, self.device3.id), + ], + } + ) + first_picking = make_picking_batch._get_first_picking() + self.assertEqual(first_picking, self.pick3) diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 098b8bfde1f..6efbac33aea 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -267,7 +267,7 @@ def _execute_search_pickings(self, domain, limit=None): ) def _split_first_picking_for_limit(self, picking): - last_device = self.stock_device_type_ids[-1] + last_device = self._get_sorted_devices()[-1] if last_device.split_mode == "dimension": return ( self.env["stock.split.picking"] @@ -295,7 +295,7 @@ def _is_picking_exceeding_limits(self, picking): ): return True # Then, check the device limits - last_device = self.stock_device_type_ids[-1] + last_device = self._get_sorted_devices()[-1] if last_device.split_mode == "dimension": if last_device.max_volume and picking.volume > last_device.max_volume: return True @@ -376,11 +376,18 @@ def _get_remaining_volume(self, partner=False): return remaining_volume def _compute_device_to_use(self, picking): - for device in self.stock_device_type_ids.sorted("sequence"): + for device in self._get_sorted_devices(): if picking.filtered_domain(self._get_picking_domain_for_device(device)): return device return self.env["stock.device.type"] + def _get_sorted_devices(self): + """Return the devices sorted in their default order. + + Because it will not be done by default with the Many2many + """ + return self.stock_device_type_ids.sorted() + def _volume_condition_for_device_choice( self, min_volume, picking_volume, max_volume ): From c8afe5a567f00b8723149bd95790bffdd0eb97d4 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Fri, 26 Sep 2025 18:20:56 +0200 Subject: [PATCH 334/357] [FIX] stock_picking_batch_creation: Fix unsupported operand In case device has no attribute max_weight set, _init_counters function will set self._remaining_weight as None, so we need to consider this possibility before decreasing it when adding picking. --- stock_picking_batch_creation/wizards/make_picking_batch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 6efbac33aea..49699f66b65 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -508,7 +508,8 @@ def _add_picking(self, picking): :param picking: picking to add to the batch """ self._selected_picking_ids.append(picking.id) - self._remaining_weight -= picking.weight + if self._remaining_weight is not None: + self._remaining_weight -= picking.weight self._remaining_nbr_picking_lines -= picking.nbr_picking_lines nbr_bins = self._get_nbr_bins_for_picking(picking) self._remaining_nbr_bins -= nbr_bins From 5e697e426b73dd903afb5a2dba169d0c024bbc41 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 Jan 2026 12:28:36 +0100 Subject: [PATCH 335/357] stock_picking_batch_creation: credit, author, readme --- stock_picking_batch_creation/__manifest__.py | 4 ++-- stock_picking_batch_creation/models/stock_device_type.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/stock_picking_batch_creation/__manifest__.py b/stock_picking_batch_creation/__manifest__.py index f81633c5056..228109ac900 100644 --- a/stock_picking_batch_creation/__manifest__.py +++ b/stock_picking_batch_creation/__manifest__.py @@ -7,7 +7,7 @@ Create a batch of pickings to be processed all together""", "version": "16.0.2.1.0", "license": "AGPL-3", - "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "author": "ACSONE SA/NV,BCIM,Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", "application": False, @@ -26,6 +26,6 @@ "security/ir.model.access.csv", ], "development_status": "Beta", - "maintainers": ["lmignon"], + "maintainers": ["lmignon", "jbaudoux"], "pre_init_hook": "pre_init_hook", } diff --git a/stock_picking_batch_creation/models/stock_device_type.py b/stock_picking_batch_creation/models/stock_device_type.py index 98a84882f19..9fff3aec4a9 100644 --- a/stock_picking_batch_creation/models/stock_device_type.py +++ b/stock_picking_batch_creation/models/stock_device_type.py @@ -13,15 +13,15 @@ class StockDeviceType(models.Model): name = fields.Char(required=True) min_volume = fields.Float( string="Minimum total net volume for this device", - help="Volume in default system volume unit of measure", + help="Volume in default system volume unit of measure. Set to 0 to disable.", ) max_volume = fields.Float( string="Maximum total net volume for this device", - help="Volume in default system volume unit of measure", + help="Volume in default system volume unit of measure. Set to 0 to disable.", ) max_weight = fields.Float( string="Maximum total net weight for this device", - help="Weight in default system weight unit of measure", + help="Weight in default system weight unit of measure. Set to 0 to disable.", ) user_min_volume = fields.Float( string="Minimum total net volume for electing this device", From 0375812e7ea03338cedca873bb837572bfaa4a4e Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 3 Sep 2025 12:11:17 +0200 Subject: [PATCH 336/357] [IMP] stock_picking_batch_creation: Hide fields in picking list by default --- stock_picking_batch_creation/views/stock_picking.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock_picking_batch_creation/views/stock_picking.xml b/stock_picking_batch_creation/views/stock_picking.xml index aa2bf1711ea..19931cb7474 100644 --- a/stock_picking_batch_creation/views/stock_picking.xml +++ b/stock_picking_batch_creation/views/stock_picking.xml @@ -24,8 +24,8 @@ - - + + From 99e00f0aaf6940a012ce4c5c56422b5cd22e3453 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 Jan 2026 12:24:42 +0100 Subject: [PATCH 337/357] stock_picking_batch_creation: allow no limit Allow no max nbr lines Allow no max volume Add test --- .../tests/test_clustering_conditions.py | 68 +++++++++++++++- .../wizards/make_picking_batch.py | 77 +++++++++++-------- 2 files changed, 112 insertions(+), 33 deletions(-) diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index 23be6612878..4efd42dc6fa 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -30,7 +30,73 @@ def test_device_with_one_bin(self): self.assertEqual(self.device3, batch.picking_device_id) self.assertEqual(self.pick3, batch.picking_ids) - def test_put_3_pickings_in_one_cluster(self): + + def test_device_with_several_bins_volume_0_group_per_partner(self): + """ + Got a selected picking with volume == 0 + Enable grouping per partner + + Ensure we can create batch + """ + product = self._create_product("Without volume", 0.0, 0.0, 0.0, 0.0) + self._set_quantity_in_stock(self.stock_location, product) + self._create_picking_pick_and_assign(self.picking_type_1.id, 0, product) + device = self._create_device("Test", 0.0, 0.0, 200.0, 20, 1) + self.make_picking_batch.stock_device_type_ids = device + self.make_picking_batch.group_pickings_by_partner = True + self.make_picking_batch._create_batch() + + """ + def test_put_3_pickings_in_one_cluster_no_limit(self): + Data: 3 picks of type 1, total of 4 products for a volume of 60m3 + pick1: 1 line + pick2: 1 line + pick3: 3 lines + Test case: + Disable the maximum number of preparation lines + Create a device without any limit + Expected result: + The device without limit is used + The batch should contain pick3, pick2 and pick1 + """ + self._set_quantity_in_stock(self.stock_location, self.p5) + self.p1.write( + { + "volume": 5.0, + "product_length": 5, + "product_height": 1, + "product_width": 1, + "weight": 1, + } + ) + self.p2.write( + { + "volume": 5.0, + "product_length": 5, + "product_height": 1, + "product_width": 1, + "weight": 1, + } + ) + device = self.env["stock.device.type"].create( + { + "name": "test no limit device", + "min_volume": 0, + "max_volume": 0, + "max_weight": 0, + "nbr_bins": 6, + "sequence": 10, + } + ) + self.make_picking_batch.write({ + "maximum_number_of_preparation_lines": 0, + "stock_device_type_ids": [(4, device.id)], + }) + batch = self.make_picking_batch._create_batch() + self.assertEqual(device, batch.picking_device_id) + self.assertEqual(self.pick3 | self.pick2 | self.pick1, batch.picking_ids) + + def test_put_3_pickings_in_one_cluster_max_lines(self): """ Data: 3 picks of type 1, total of 4 products for a volume of 60m3 pick1: 1 line diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 49699f66b65..aebe0e365c8 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -1,4 +1,5 @@ # Copyright 2021 ACSONE SA/NV +# Copyright 2026 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging @@ -46,7 +47,8 @@ class MakePickingBatch(models.TransientModel): ) maximum_number_of_preparation_lines = fields.Integer( default=20, - string="Maximum number of preparation lines for the batch", + string="Maximum number of preparation lines for the batch.", + help="Set to 0 to disable.", required=True, ) group_pickings_by_partner = fields.Boolean( @@ -139,7 +141,7 @@ def _reset_counters(self): self._volume_by_partners = defaultdict(lambda: 0) self._device = None self._remaining_weight = None # None means unlimited - self._remaining_nbr_picking_lines = 0 + self._remaining_nbr_picking_lines = None # None means unlimited self._selected_picking_ids = [] self._first_picking = None self._remaining_nbr_bins = None @@ -171,7 +173,7 @@ def _get_picking_domain_for_first(self, no_nbr_lines_limit=False): picking_domain_first = [ ("picking_type_id", "in", self.picking_type_ids.ids), ] - if apply_limit_on_nbr_lines: + if apply_limit_on_nbr_lines and self.maximum_number_of_preparation_lines: picking_domain_first.append( ( "nbr_picking_lines", @@ -197,14 +199,13 @@ def _get_picking_domain_for_additional(self): """ excluded_ids = self._selected_picking_ids domain = [ - ( - "nbr_picking_lines", - "<=", - self._remaining_nbr_picking_lines, - ), ("id", "not in", excluded_ids), ("picking_type_id", "=", self._first_picking.picking_type_id.id), ] + if self._remaining_nbr_picking_lines is not None: # None means unlimited + domain.append( + ("nbr_picking_lines", "<=", self._remaining_nbr_picking_lines) + ) if self._remaining_weight is not None: # None means unlimited domain.append(("weight", "<=", self._remaining_weight)) previous_picking = self._previous_selected_picking @@ -212,30 +213,33 @@ def _get_picking_domain_for_additional(self): domain.append(("priority", "=", previous_picking.priority)) if self.restrict_to_same_partner: domain.append(("partner_id", "=", previous_picking.partner_id.id)) - volume_domains = [ - [ - ("volume", "<=", self._get_remaining_volume()), - ] - ] - if self.group_pickings_by_partner: - # in case of grouping by partner, we allow to group picking into - # the same bins. That means that the volume available for the - # partner does not depend on the volume of remaining bins only - # but also on the remaining volume into the bins already used by - # the partner. Since results are sorted by partner, the search - # takes as partner the partner of the previous picking. - previous_partner = previous_picking.partner_id - volume_domains.append( + remaining_volume = self._get_remaining_volume() + if remaining_volume is not None: # None means unlimited + volume_domains = [ [ - ("partner_id", "=", previous_partner.id), - ( - "volume", - "<=", - self._get_remaining_volume(previous_partner), - ), + ("volume", "<=", remaining_volume), ] - ) - return AND([domain, OR(volume_domains)]) + ] + if self.group_pickings_by_partner: + # in case of grouping by partner, we allow to group picking into + # the same bins. That means that the volume available for the + # partner does not depend on the volume of remaining bins only + # but also on the remaining volume into the bins already used by + # the partner. Since results are sorted by partner, the search + # takes as partner the partner of the previous picking. + previous_partner = previous_picking.partner_id + volume_domains.append( + [ + ("partner_id", "=", previous_partner.id), + ( + "volume", + "<=", + self._get_remaining_volume(previous_partner), + ), + ] + ) + domain = AND([domain, OR(volume_domains)]) + return domain def _execute_search_pickings(self, domain, limit=None): """Hook to allow to override the search of pickings @@ -360,6 +364,8 @@ def _get_remaining_volume(self, partner=False): :param partner: if set, the remaining volume will add to the volume available if free bins the volume remaining in the bins already used by the partner """ + if not self._device.volume_per_bin: + return None remaining_volume = self._remaining_nbr_bins * self._device.volume_per_bin if partner: # for a partner we must take into account the remaining volume in @@ -462,7 +468,13 @@ def _init_counters(self, first_picking, device): else None # None means unlimited ) self._remaining_nbr_picking_lines = ( - self.maximum_number_of_preparation_lines - first_picking.nbr_picking_lines + max( + self.maximum_number_of_preparation_lines + - first_picking.nbr_picking_lines, + 0, + ) + if self.maximum_number_of_preparation_lines + else None # None means unlimited ) self._selected_picking_ids = [first_picking.id] self._first_picking = first_picking @@ -510,7 +522,8 @@ def _add_picking(self, picking): self._selected_picking_ids.append(picking.id) if self._remaining_weight is not None: self._remaining_weight -= picking.weight - self._remaining_nbr_picking_lines -= picking.nbr_picking_lines + if self._remaining_nbr_picking_lines is not None: + self._remaining_nbr_picking_lines -= picking.nbr_picking_lines nbr_bins = self._get_nbr_bins_for_picking(picking) self._remaining_nbr_bins -= nbr_bins self._previous_selected_picking = picking From 320a382d488882ce600ea7d1fae3c37932ff24b8 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 Jan 2026 15:41:03 +0100 Subject: [PATCH 338/357] [FIX] stock_picking_batch_creation: add non declared tests --- stock_picking_batch_creation/tests/__init__.py | 1 + .../tests/test_clustering_conditions.py | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/stock_picking_batch_creation/tests/__init__.py b/stock_picking_batch_creation/tests/__init__.py index 92afefe8492..ddf283a47cd 100644 --- a/stock_picking_batch_creation/tests/__init__.py +++ b/stock_picking_batch_creation/tests/__init__.py @@ -2,3 +2,4 @@ from . import test_picking_lock from . import test_get_device_to_use from . import test_clustering_conditions +from . import test_batch_creation_splitting diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index 4efd42dc6fa..a7d96dce144 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -1,4 +1,5 @@ # Copyright 2021 ACSONE SA/NV +# Copyright 2026 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo.tests import RecordCapturer @@ -88,10 +89,12 @@ def test_put_3_pickings_in_one_cluster_no_limit(self): "sequence": 10, } ) - self.make_picking_batch.write({ - "maximum_number_of_preparation_lines": 0, - "stock_device_type_ids": [(4, device.id)], - }) + self.make_picking_batch.write( + { + "maximum_number_of_preparation_lines": 0, + "stock_device_type_ids": [(4, device.id)], + } + ) batch = self.make_picking_batch._create_batch() self.assertEqual(device, batch.picking_device_id) self.assertEqual(self.pick3 | self.pick2 | self.pick1, batch.picking_ids) From ac9b6d7018958b20e3e203cde1850b36244d7632 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Tue, 13 Jan 2026 17:01:16 +0100 Subject: [PATCH 339/357] stock_picking_batch_creation: replace warning by debug --- stock_picking_batch_creation/wizards/make_picking_batch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index aebe0e365c8..8426f417609 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -340,7 +340,7 @@ def _get_first_picking(self, raise_if_not_found=False): if not split_picking: if raise_if_not_found: raise PickingSplitNotPossibleError(picking) - _logger.warning( + _logger.debug( f"The picking {picking.name} could not be split " "for batch creation." ) From 24081179cbfbf9f3990eec01fec7f95bbefeb4cb Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 28 May 2025 11:43:14 +0200 Subject: [PATCH 340/357] [IMP] stock_picking_batch_creation: raise specific exceptions + tests As specific exceptions inherit from UserError, there is no need to do such change. --- .../tests/test_clustering_conditions.py | 28 ++++++++++++++++++- .../wizards/make_picking_batch.py | 16 +++++------ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index a7d96dce144..00972bb5eca 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -5,6 +5,7 @@ from odoo.tests import RecordCapturer from ..exceptions import ( + NoPickingCandidateError, NoSuitableDeviceError, PickingCandidateNumberLineExceedError, ) @@ -47,8 +48,8 @@ def test_device_with_several_bins_volume_0_group_per_partner(self): self.make_picking_batch.group_pickings_by_partner = True self.make_picking_batch._create_batch() - """ def test_put_3_pickings_in_one_cluster_no_limit(self): + """ Data: 3 picks of type 1, total of 4 products for a volume of 60m3 pick1: 1 line pick2: 1 line @@ -527,6 +528,31 @@ def test_picking_split_with_maximum_number_of_lines_exceed(self): self.assertEqual(new_pickings, batch.picking_ids) self.assertEqual(len(batch.move_line_ids), 1) + def test_device_with_one_bin_create_action(self): + """ + Data: 3 picks of type 1, total of 4 products for a volume of 60m3 + Test case: We have 3 devices possibles (device1, device2, device3), + ordered following sequence: device3, device2, device1. + The first picking will be pick3 (higher priority) and its volume is + is 30m3. -> device3 is the device to use (min 30m3, max 100m3) + + Device3 has 1 bin -> the batch should only contain pick3 + """ + batch_action = self.make_picking_batch.create_batch() + batch = self.env["stock.picking.batch"].browse(batch_action.get("res_id")) + self.assertEqual(self.device3, batch.picking_device_id) + self.assertEqual(self.pick3, batch.picking_ids) + + def test_device_with_one_bin_create_action_no_picking(self): + """ + Cancel all pickings + + No picking candidate error should be raised + """ + self.picks.action_cancel() + with self.assertRaises(NoPickingCandidateError): + self.make_picking_batch.create_batch() + def test_picking_split_with_weight_exceed(self): # pick 3 has 2 lines # we will set a weight by line under the maximum weight of the device diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 8426f417609..4af9fa73f64 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -8,7 +8,6 @@ from collections import defaultdict from odoo import api, fields, models, tools -from odoo.exceptions import UserError from odoo.osv.expression import AND, OR, expression from ..exceptions import ( @@ -59,7 +58,8 @@ class MakePickingBatch(models.TransientModel): restrict_to_same_priority = fields.Boolean( default=False, string="Restrict to the same priority", - help="Only the pickings with the same priority will be selected for this batch.", + help="Only the pickings with the same priority will be selected " + "for this batch.", ) restrict_to_same_partner = fields.Boolean( default=False, @@ -121,12 +121,9 @@ def _get_default_picking_locking_mode(self): return None return "sql_for_update_skip_locked" - def create_batch(self): + def create_batch(self) -> dict: self.ensure_one() - try: - batch = self._create_batch(raise_if_not_possible=True) - except (NoPickingCandidateError, NoSuitableDeviceError) as error: - raise UserError(error.name) from error + batch = self._create_batch(raise_if_not_possible=True) action = { "type": "ir.actions.act_window", "name": batch.name, @@ -156,7 +153,10 @@ def _get_picking_order_by(self): # https://www.postgresql.org/docs/current/queries-order.html # so we need to sort user_id asc to have NULLS LAST if self.group_pickings_by_partner: - return "user_id asc, priority desc, scheduled_date asc, partner_id desc, id asc" + return ( + "user_id asc, priority desc, scheduled_date asc, " + "partner_id desc, id asc" + ) return "user_id asc, priority desc, scheduled_date asc, id asc" def _get_picking_domain_common(self): From f86c4e5acbf5e5fbf2d9a6e1ed36fa6254d356ee Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 28 May 2025 13:34:35 +0200 Subject: [PATCH 341/357] [IMP] stock_picking_batch_creation: Add tests for device types measures --- .../tests/test_clustering_conditions.py | 104 +++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index 00972bb5eca..1a178e20452 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -2,7 +2,7 @@ # Copyright 2026 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo.tests import RecordCapturer +from odoo.tests import Form, RecordCapturer from ..exceptions import ( NoPickingCandidateError, @@ -553,6 +553,108 @@ def test_device_with_one_bin_create_action_no_picking(self): with self.assertRaises(NoPickingCandidateError): self.make_picking_batch.create_batch() + def test_put_2_pickings_with_volume_in_one_cluster(self): + """2 products have a volume : + they should still occupy at least one bin each""" + device = self.env["stock.device.type"].create( + { + "name": "test volume devices", + "min_volume": 0, + "max_volume": 200, + "max_weight": 200, + "nbr_bins": 6, + "sequence": 50, + } + ) + make_picking_batch_volume_zero = self.makePickingBatch.create( + { + "user_id": self.env.user.id, + "picking_type_ids": [(4, self.picking_type_1.id)], + "stock_device_type_ids": [(4, device.id)], + "maximum_number_of_preparation_lines": 6, + } + ) + self.p1.write( + { + "product_length": 1, + "product_height": 1, + "product_width": 1, + "weight": 1, + } + ) + self.p2.write( + { + "product_length": 1, + "product_height": 2, + "product_width": 3, + "weight": 1, + } + ) + self.picks.mapped("move_ids")._compute_volume() + self.assertEqual(1.0, self.pick1.volume) + self.assertEqual(6.0, self.pick2.volume) + self.assertEqual(7.0, self.pick3.volume) + batch = make_picking_batch_volume_zero._create_batch() + self.assertEqual(device, batch.picking_device_id) + self.assertEqual(self.pick3 | self.pick2 | self.pick1, batch.picking_ids) + + # All picks have a volume of 0 : they should each occupy one bin + self.assertEqual(batch.batch_nbr_bins, 3) + + def test_changing_device_constraints(self): + device = self.env["stock.device.type"].create( + { + "name": "test volume devices", + "min_volume": 0, + "max_volume": 200, + "max_weight": 200, + "nbr_bins": 6, + "sequence": 50, + } + ) + self.assertEqual(device.user_max_volume, 200.0) + self.assertEqual(device.user_min_volume, 0.0) + self.assertEqual(device.user_max_weight, 200.0) + + device.write( + { + "min_volume": 100.0, + } + ) + self.assertEqual(device.user_min_volume, 100.0) + self.assertAlmostEqual(device.volume_per_bin, 33.33, places=2) + + # Test user interface + with Form(device) as device_form: + device_form.user_min_volume = 0.0 + device = device_form.save() + self.assertEqual(device.min_volume, 0.0) + + with Form(device) as device_form: + device_form.user_min_volume = 10.0 + device = device_form.save() + self.assertEqual(device.min_volume, 10.0) + + with Form(device) as device_form: + device_form.user_max_volume = 300.0 + device = device_form.save() + self.assertEqual(device.max_volume, 300.0) + + with Form(device) as device_form: + device_form.user_max_volume = 0.0 + device = device_form.save() + self.assertEqual(device.max_volume, 0.0) + + with Form(device) as device_form: + device_form.user_max_weight = 0.0 + device = device_form.save() + self.assertEqual(device.max_weight, 0.0) + + with Form(device) as device_form: + device_form.user_max_weight = 100.0 + device = device_form.save() + self.assertEqual(device.max_weight, 100.0) + def test_picking_split_with_weight_exceed(self): # pick 3 has 2 lines # we will set a weight by line under the maximum weight of the device From 53a6418ad8b376173e1953d9c0a9609ebb24b56e Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Mon, 9 Mar 2026 14:09:06 +0100 Subject: [PATCH 342/357] [FIX] stock_picking_batch_creation: Fix backport from 18.0 up to d610d38 --- stock_picking_batch_creation/tests/common.py | 4 ++-- .../tests/test_clustering_conditions.py | 3 +-- .../wizards/make_picking_batch.py | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/stock_picking_batch_creation/tests/common.py b/stock_picking_batch_creation/tests/common.py index c43308e8970..8e31db951e4 100644 --- a/stock_picking_batch_creation/tests/common.py +++ b/stock_picking_batch_creation/tests/common.py @@ -155,8 +155,8 @@ def _create_product(cls, name, weight, length, height, width, **kwargs): "dimensional_uom_id": cls.uom_m.id, **kwargs, } - if vals.get("type", "consu") == "consu" and "is_storable" not in vals: - vals["is_storable"] = True + if not vals.get("type"): + vals["type"] = "product" if "uom_id" not in vals: vals["uom_id"] = cls.uom_id if "volume" not in vals: diff --git a/stock_picking_batch_creation/tests/test_clustering_conditions.py b/stock_picking_batch_creation/tests/test_clustering_conditions.py index 1a178e20452..cc4c0e293cf 100644 --- a/stock_picking_batch_creation/tests/test_clustering_conditions.py +++ b/stock_picking_batch_creation/tests/test_clustering_conditions.py @@ -32,7 +32,6 @@ def test_device_with_one_bin(self): self.assertEqual(self.device3, batch.picking_device_id) self.assertEqual(self.pick3, batch.picking_ids) - def test_device_with_several_bins_volume_0_group_per_partner(self): """ Got a selected picking with volume == 0 @@ -551,7 +550,7 @@ def test_device_with_one_bin_create_action_no_picking(self): """ self.picks.action_cancel() with self.assertRaises(NoPickingCandidateError): - self.make_picking_batch.create_batch() + self.make_picking_batch._create_batch(raise_if_not_possible=True) def test_put_2_pickings_with_volume_in_one_cluster(self): """2 products have a volume : diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index 4af9fa73f64..a8af5fcb903 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -8,6 +8,7 @@ from collections import defaultdict from odoo import api, fields, models, tools +from odoo.exceptions import UserError from odoo.osv.expression import AND, OR, expression from ..exceptions import ( @@ -123,7 +124,16 @@ def _get_default_picking_locking_mode(self): def create_batch(self) -> dict: self.ensure_one() - batch = self._create_batch(raise_if_not_possible=True) + try: + batch = self._create_batch(raise_if_not_possible=True) + except UserError as error: + # We catch specific batch picking creation errors to display + # them as user errors in the UI. They are declared as + # subclass of UserError to be able to catch them + # as UserError and display the message in the UI + # but also to be able to catch them specifically into + # the tests + raise UserError(error.name) from error action = { "type": "ir.actions.act_window", "name": batch.name, @@ -504,6 +514,9 @@ def _get_nbr_bins_for_picking(self, picking): # of the device by convention a picking without volume fill a complete # bin picking_volume = self._device.volume_per_bin + if not self._device.volume_per_bin: + # We should return current result to avoid division per 0 + return nbr_bins old_volume = self._volume_by_partners[picking.partner_id] new_volume = picking_volume + old_volume nbr_bins = math.ceil(new_volume / self._device.volume_per_bin) - math.ceil( From 756abb3c397d882300c63b80ea73d3888fba7072 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Tue, 17 Feb 2026 14:27:29 +0100 Subject: [PATCH 343/357] [IMP] shopfloor: Single pack transfer create package level for company of picking type --- shopfloor/services/single_pack_transfer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopfloor/services/single_pack_transfer.py b/shopfloor/services/single_pack_transfer.py index e3e98c72354..efe5844409c 100644 --- a/shopfloor/services/single_pack_transfer.py +++ b/shopfloor/services/single_pack_transfer.py @@ -192,7 +192,7 @@ def _create_package_level(self, package): "picking_id": picking.id, "package_id": package.id, "location_dest_id": picking.location_dest_id.id, - "company_id": self.env.company.id, + "company_id": picking.company_id.id, } ) picking.action_confirm() From 17bbcf0f2bb38adef8864eb404a214c1537e2dc1 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 12 Mar 2026 17:10:04 +0000 Subject: [PATCH 344/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 90562aa8b4f..8b177decd06 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.15.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.16.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index dcf8e3a9cdf..c7dc1e8ff36 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:4c221d01eb0d0479500dca6accfc6ba696e95c76f62d5039ead2afb98cf83536 + !! source digest: sha256:8775bde18eb05cb1feb84336aec2ec97cf39d328f5b9c0dde785ac4f73f7f950 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index c369aad32aa..4961f4158b1 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.15.0", + "version": "16.0.2.16.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index 7882e9c25ac..948145d696d 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:4c221d01eb0d0479500dca6accfc6ba696e95c76f62d5039ead2afb98cf83536 +!! source digest: sha256:8775bde18eb05cb1feb84336aec2ec97cf39d328f5b9c0dde785ac4f73f7f950 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor is a barcode scanner application for internal warehouse operations.

    From 0619927ec1c4167f58220d47b6ab09c052a69325 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Wed, 18 Mar 2026 18:33:22 +0100 Subject: [PATCH 345/357] [FIX] stock_picking_batch_creation: splitting When splitting is enabled, an over limit picking can be elected as first picking. In that case, the last device should be used. An over limit picking must be excluded only when splitting is disabled. When a trying to split a picking with a single move, there will be no split order as there is only one move. In this case, the picking must be used. --- .../tests/test_batch_creation_splitting.py | 10 ++++----- .../wizards/make_picking_batch.py | 21 ++++++++----------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/stock_picking_batch_creation/tests/test_batch_creation_splitting.py b/stock_picking_batch_creation/tests/test_batch_creation_splitting.py index 3f403aaf362..7622ebb64a5 100644 --- a/stock_picking_batch_creation/tests/test_batch_creation_splitting.py +++ b/stock_picking_batch_creation/tests/test_batch_creation_splitting.py @@ -1,4 +1,5 @@ # Copyright 2025 Camptocamp SA +# Copyright 2026 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from .common import ClusterPickingCommonFeatures @@ -10,7 +11,7 @@ def setUpClass(cls): super().setUpClass() def test_batch_creation_one_pick_move_over_the_limit(self): - """Test splitting a picking when the first move exceed the weight limit.""" + """Test splitting a picking when the first move exceeds a limit.""" self.pick2.action_cancel() self.pick3.action_cancel() # Keep the picking 1 with one line and product 1 @@ -35,11 +36,10 @@ def test_batch_creation_one_pick_move_over_the_limit(self): ) self.make_picking_batch.stock_device_type_ids = device batch = self.make_picking_batch._create_batch() - # There is no batch because the only picking could not be split - self.assertFalse(batch) + self.assertTrue(batch, "There should always be a batch") def test_batch_creation_move_over_the_limit_take_2nd_picking(self): - """Test splitting a picking when the first move exceed the weight limit.""" + """Splitting is disabled, the first picking exceeding a limit is excluded.""" self.pick3.action_cancel() # Keep the picking 1 with one line and product 1 move = self.pick1.move_ids @@ -54,7 +54,7 @@ def test_batch_creation_move_over_the_limit_take_2nd_picking(self): self.make_picking_batch.write( { "maximum_number_of_preparation_lines": 2, - "split_picking_exceeding_limits": True, + "split_picking_exceeding_limits": False, } ) device = self._create_device( diff --git a/stock_picking_batch_creation/wizards/make_picking_batch.py b/stock_picking_batch_creation/wizards/make_picking_batch.py index a8af5fcb903..b429203997e 100644 --- a/stock_picking_batch_creation/wizards/make_picking_batch.py +++ b/stock_picking_batch_creation/wizards/make_picking_batch.py @@ -15,7 +15,6 @@ NoPickingCandidateError, NoSuitableDeviceError, PickingCandidateNumberLineExceedError, - PickingSplitNotPossibleError, ) _logger = logging.getLogger(__name__) @@ -348,14 +347,10 @@ def _get_first_picking(self, raise_if_not_found=False): if self._is_picking_exceeding_limits(picking): split_picking = self._split_first_picking_for_limit(picking) if not split_picking: - if raise_if_not_found: - raise PickingSplitNotPossibleError(picking) - _logger.debug( - f"The picking {picking.name} could not be split " - "for batch creation." - ) - continue - selected_picking = split_picking + # If the picking has only one move, it won't be split + selected_picking = picking + else: + selected_picking = split_picking else: selected_picking = picking break @@ -453,9 +448,11 @@ def _create_batch(self, raise_if_not_possible=False): return self.env["stock.picking.batch"].browse() device = self._compute_device_to_use(first_picking) if not device: - if raise_if_not_possible: - raise NoSuitableDeviceError(self.env, pickings=first_picking) - return self.env["stock.picking.batch"].browse() + # A picking has been elected. If no device is suitable, use the + # last device. This can happen when the picking still exceeds the + # limits. Then the best device to use is the last done (that should + # be the biggest one). + device = self._get_sorted_devices()[-1] self._init_counters(first_picking, device) self._apply_limits() vals = self._create_batch_values() From 2c4877e981d4dd8b5c228e73a0a4ca51d576581d Mon Sep 17 00:00:00 2001 From: oca-ci Date: Fri, 20 Mar 2026 15:42:00 +0000 Subject: [PATCH 346/357] [UPD] Update stock_picking_batch_creation.pot --- .../i18n/stock_picking_batch_creation.pot | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot b/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot index 5cb3a7fdddd..f2c960d5e0b 100644 --- a/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot +++ b/stock_picking_batch_creation/i18n/stock_picking_batch_creation.pot @@ -132,6 +132,11 @@ msgstr "" msgid "Diagnostic" msgstr "" +#. module: stock_picking_batch_creation +#: model:ir.model.fields.selection,name:stock_picking_batch_creation.selection__stock_device_type__split_mode__dimension +msgid "Dimension" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__display_name #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__display_name @@ -225,7 +230,7 @@ msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines -msgid "Maximum number of preparation lines for the batch" +msgid "Maximum number of preparation lines for the batch." msgstr "" #. module: stock_picking_batch_creation @@ -340,6 +345,16 @@ msgstr "" msgid "SQL FOR UPDATE SKIP LOCKED" msgstr "" +#. module: stock_picking_batch_creation +#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines +msgid "Set to 0 to disable." +msgstr "" + +#. module: stock_picking_batch_creation +#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__split_mode +msgid "Split Mode" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits msgid "Split pickings exceeding limits" @@ -385,7 +400,7 @@ msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__max_volume #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__min_volume -msgid "Volume in default system volume unit of measure" +msgid "Volume in default system volume unit of measure. Set to 0 to disable." msgstr "" #. module: stock_picking_batch_creation @@ -400,7 +415,7 @@ msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__max_weight -msgid "Weight in default system weight unit of measure" +msgid "Weight in default system weight unit of measure. Set to 0 to disable." msgstr "" #. module: stock_picking_batch_creation From 5b64d3a7fd8c26c340afa6dbaf7f08fe2c76a1ce Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 20 Mar 2026 15:54:37 +0000 Subject: [PATCH 347/357] [BOT] post-merge updates --- README.md | 2 +- stock_picking_batch_creation/README.rst | 10 +++++++--- stock_picking_batch_creation/__manifest__.py | 2 +- .../static/description/index.html | 7 ++++--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8b177decd06..1f260044587 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ addon | version | maintainers | summary [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock [stock_dynamic_routing](stock_dynamic_routing/) | 16.0.1.0.4 | | Dynamic routing of stock moves [stock_full_location_reservation](stock_full_location_reservation/) | 16.0.1.0.0 | mt-software-de | Extend reservation to full content of location -[stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.2.1.0 | lmignon | Create a batch of pickings to be processed all together +[stock_picking_batch_creation](stock_picking_batch_creation/) | 16.0.2.2.0 | lmignon jbaudoux | Create a batch of pickings to be processed all together [stock_picking_completion_info](stock_picking_completion_info/) | 16.0.1.0.1 | | Display on current document completion information according to next operations [stock_picking_type_shipping_policy](stock_picking_type_shipping_policy/) | 16.0.1.0.0 | | Define different shipping policies according to picking type [stock_release_channel](stock_release_channel/) | 16.0.3.1.1 | sebalix jbaudoux mt-software-de | Manage workload in WMS with release channels diff --git a/stock_picking_batch_creation/README.rst b/stock_picking_batch_creation/README.rst index da35af542be..fde7ac36d13 100644 --- a/stock_picking_batch_creation/README.rst +++ b/stock_picking_batch_creation/README.rst @@ -11,7 +11,7 @@ Stock Picking Batch Creation !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:af42f7a43dd7eff1c265bcf1ee896c20a5de4226c3c313fd6251d8c94fae1cad + !! source digest: sha256:5776c02d9d60b438c67755c970d68145bd2112f5378cf09f73ae26ec7f1efd72 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -178,6 +178,7 @@ Authors ~~~~~~~ * ACSONE SA/NV +* BCIM Contributors ~~~~~~~~~~~~ @@ -209,10 +210,13 @@ promote its widespread use. .. |maintainer-lmignon| image:: https://github.com/lmignon.png?size=40px :target: https://github.com/lmignon :alt: lmignon +.. |maintainer-jbaudoux| image:: https://github.com/jbaudoux.png?size=40px + :target: https://github.com/jbaudoux + :alt: jbaudoux -Current `maintainer `__: +Current `maintainers `__: -|maintainer-lmignon| +|maintainer-lmignon| |maintainer-jbaudoux| This module is part of the `OCA/wms `_ project on GitHub. diff --git a/stock_picking_batch_creation/__manifest__.py b/stock_picking_batch_creation/__manifest__.py index 228109ac900..056b94f6e4a 100644 --- a/stock_picking_batch_creation/__manifest__.py +++ b/stock_picking_batch_creation/__manifest__.py @@ -5,7 +5,7 @@ "name": "Stock Picking Batch Creation", "summary": """ Create a batch of pickings to be processed all together""", - "version": "16.0.2.1.0", + "version": "16.0.2.2.0", "license": "AGPL-3", "author": "ACSONE SA/NV,BCIM,Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_picking_batch_creation/static/description/index.html b/stock_picking_batch_creation/static/description/index.html index 1022bbc0f1b..441ae9a6716 100644 --- a/stock_picking_batch_creation/static/description/index.html +++ b/stock_picking_batch_creation/static/description/index.html @@ -372,7 +372,7 @@

    Stock Picking Batch Creation

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:af42f7a43dd7eff1c265bcf1ee896c20a5de4226c3c313fd6251d8c94fae1cad +!! source digest: sha256:5776c02d9d60b438c67755c970d68145bd2112f5378cf09f73ae26ec7f1efd72 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Odoo allows you to create batches of pickings by hand or automatically by @@ -520,6 +520,7 @@

    Credits

    Authors

    • ACSONE SA/NV
    • +
    • BCIM
    @@ -546,8 +547,8 @@

    Maintainers

    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.

    -

    Current maintainer:

    -

    lmignon

    +

    Current maintainers:

    +

    lmignon jbaudoux

    This module is part of the OCA/wms project on GitHub.

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

    From 3356b6a2146d618997d4abe9e48acf00150ea04e Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Thu, 26 Mar 2026 14:39:09 +0100 Subject: [PATCH 348/357] [FIX] shopfloor: fix test broken after dependent module update Tests broke because of this commit in a dependent module: https://github.com/OCA/delivery-carrier/commit/9c8bd5c110e413b127eaa10dd02240ccfbadca60 See this PR: https://github.com/OCA/delivery-carrier/pull/1142 An outgoing picking is now considered its own "ship_picking_id" (which was not the case before) leading to more data than previously expected in the tests. --- shopfloor/tests/test_actions_data.py | 10 ++++++++-- shopfloor/tests/test_actions_data_detail.py | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/shopfloor/tests/test_actions_data.py b/shopfloor/tests/test_actions_data.py index b3979103635..22717b1d36a 100644 --- a/shopfloor/tests/test_actions_data.py +++ b/shopfloor/tests/test_actions_data.py @@ -153,7 +153,10 @@ def test_data_picking(self): "weight": 110.0, "partner": {"id": self.customer.id, "name": self.customer.name}, "carrier": {"id": carrier.id, "name": carrier.name}, - "ship_carrier": None, + "ship_carrier": { + "id": self.picking.ship_carrier_id.id, + "name": self.picking.ship_carrier_id.name, + }, "priority": "0", } self.assertEqual(data.pop("scheduled_date").split("T")[0], "2020-08-03") @@ -177,7 +180,10 @@ def test_data_picking_with_progress(self): "weight": 110.0, "partner": {"id": self.customer.id, "name": self.customer.name}, "carrier": {"id": carrier.id, "name": carrier.name}, - "ship_carrier": None, + "ship_carrier": { + "id": self.picking.ship_carrier_id.id, + "name": self.picking.ship_carrier_id.name, + }, "progress": 0.0, "priority": "0", } diff --git a/shopfloor/tests/test_actions_data_detail.py b/shopfloor/tests/test_actions_data_detail.py index 9cda26bbd70..d149640a286 100644 --- a/shopfloor/tests/test_actions_data_detail.py +++ b/shopfloor/tests/test_actions_data_detail.py @@ -122,7 +122,10 @@ def test_data_picking(self): "name": picking.name, "note": Markup("

    read me

    "), "origin": "created by test", - "ship_carrier": None, + "ship_carrier": { + "id": picking.ship_carrier_id.id, + "name": picking.ship_carrier_id.name, + }, "weight": 110.0, "partner": {"id": self.customer.id, "name": self.customer.name}, "carrier": {"id": picking.carrier_id.id, "name": picking.carrier_id.name}, @@ -159,7 +162,10 @@ def test_data_picking_with_progress(self): "name": picking.name, "note": Markup("

    read me

    "), "origin": "created by test", - "ship_carrier": None, + "ship_carrier": { + "id": picking.ship_carrier_id.id, + "name": picking.ship_carrier_id.name, + }, "weight": 110.0, "partner": {"id": self.customer.id, "name": self.customer.name}, "carrier": {"id": picking.carrier_id.id, "name": picking.carrier_id.name}, From 0bffe1c7f8da1d3e03615179134fbfe866c44d6f Mon Sep 17 00:00:00 2001 From: oca-ci Date: Mon, 30 Mar 2026 16:17:10 +0000 Subject: [PATCH 349/357] [UPD] Update stock_available_to_promise_release.pot --- .../i18n/stock_available_to_promise_release.pot | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot b/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot index 493952fe07c..434de62722b 100644 --- a/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot +++ b/stock_available_to_promise_release/i18n/stock_available_to_promise_release.pot @@ -26,6 +26,7 @@ msgstr "" #. module: stock_available_to_promise_release #. odoo-python #: code:addons/stock_available_to_promise_release/models/stock_move.py:0 +#: code:addons/stock_available_to_promise_release/models/stock_move.py:0 #, python-format msgid "- blocking transfer(s): %(picking_names)s" msgstr "" @@ -366,6 +367,7 @@ msgstr "" #. module: stock_available_to_promise_release #. odoo-python #: code:addons/stock_available_to_promise_release/models/stock_picking.py:0 +#: code:addons/stock_available_to_promise_release/models/stock_picking.py:0 #, python-format msgid "" "The backorder Date: Mon, 30 Mar 2026 16:29:26 +0000 Subject: [PATCH 350/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1f260044587..908dc64d6b7 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.16.0 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.16.1 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app diff --git a/shopfloor/README.rst b/shopfloor/README.rst index c7dc1e8ff36..16df3b9d278 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:8775bde18eb05cb1feb84336aec2ec97cf39d328f5b9c0dde785ac4f73f7f950 + !! source digest: sha256:9f90d6a5968a33846a7f00f6daac7c54a3097b54e13d308bdc964d8115207c58 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 4961f4158b1..1aefbb909cb 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.16.0", + "version": "16.0.2.16.1", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index 948145d696d..86a779984fb 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:8775bde18eb05cb1feb84336aec2ec97cf39d328f5b9c0dde785ac4f73f7f950 +!! source digest: sha256:9f90d6a5968a33846a7f00f6daac7c54a3097b54e13d308bdc964d8115207c58 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor is a barcode scanner application for internal warehouse operations.

    From d0f3cd6fcd1c4ffdf2b54f0f2ef3480fd0fb5684 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 30 Mar 2026 16:29:39 +0000 Subject: [PATCH 351/357] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: wms-16.0/wms-16.0-stock_picking_batch_creation Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_picking_batch_creation/ --- stock_picking_batch_creation/i18n/fr.po | 36 ++++++++++++++++++++----- stock_picking_batch_creation/i18n/it.po | 36 ++++++++++++++++++++----- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/stock_picking_batch_creation/i18n/fr.po b/stock_picking_batch_creation/i18n/fr.po index 92c64904dcc..0d7c2ceab43 100644 --- a/stock_picking_batch_creation/i18n/fr.po +++ b/stock_picking_batch_creation/i18n/fr.po @@ -145,6 +145,11 @@ msgstr "Matériel de préparation pour le transfert" msgid "Diagnostic" msgstr "Diagnostic" +#. module: stock_picking_batch_creation +#: model:ir.model.fields.selection,name:stock_picking_batch_creation.selection__stock_device_type__split_mode__dimension +msgid "Dimension" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__display_name #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__display_name @@ -244,8 +249,8 @@ msgstr "Volume max par bac" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines -msgid "Maximum number of preparation lines for the batch" -msgstr "Nombre maximum de lignes de préparation pour la vague" +msgid "Maximum number of preparation lines for the batch." +msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__user_max_volume @@ -361,6 +366,16 @@ msgstr "" msgid "SQL FOR UPDATE SKIP LOCKED" msgstr "SQL FOR UPDATE SKIP LOCKED" +#. module: stock_picking_batch_creation +#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines +msgid "Set to 0 to disable." +msgstr "" + +#. module: stock_picking_batch_creation +#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__split_mode +msgid "Split Mode" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits msgid "Split pickings exceeding limits" @@ -406,8 +421,8 @@ msgstr "Unités de mesure de volume" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__max_volume #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__min_volume -msgid "Volume in default system volume unit of measure" -msgstr "Volume dans l'unité de mesure de volume par défaut du système" +msgid "Volume in default system volume unit of measure. Set to 0 to disable." +msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__user_weight_uom_id @@ -421,8 +436,8 @@ msgstr "Unités de mesure de poids" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__max_weight -msgid "Weight in default system weight unit of measure" -msgstr "Poids dans l'unité de mesure de poids par défaut du système" +msgid "Weight in default system weight unit of measure. Set to 0 to disable." +msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__user_weight_uom_name @@ -441,6 +456,15 @@ msgstr "ex: Transpalette" msgid "no candidate pickings to batch" msgstr "aucun transfert candidat à la création de la vague de préparation" +#~ msgid "Maximum number of preparation lines for the batch" +#~ msgstr "Nombre maximum de lignes de préparation pour la vague" + +#~ msgid "Volume in default system volume unit of measure" +#~ msgstr "Volume dans l'unité de mesure de volume par défaut du système" + +#~ msgid "Weight in default system weight unit of measure" +#~ msgstr "Poids dans l'unité de mesure de poids par défaut du système" + #~ msgid "Indicates the bins occupied by the picking on the device." #~ msgstr "" #~ "Indique le nombre de bacs occupées par le transfert sur le matériel de " diff --git a/stock_picking_batch_creation/i18n/it.po b/stock_picking_batch_creation/i18n/it.po index 57346a6d3f5..bc38fc6b020 100644 --- a/stock_picking_batch_creation/i18n/it.po +++ b/stock_picking_batch_creation/i18n/it.po @@ -146,6 +146,11 @@ msgstr "Dispositivi per il prelievo" msgid "Diagnostic" msgstr "Diagnostica" +#. module: stock_picking_batch_creation +#: model:ir.model.fields.selection,name:stock_picking_batch_creation.selection__stock_device_type__split_mode__dimension +msgid "Dimension" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__display_name #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__display_name @@ -248,8 +253,8 @@ msgstr "Volume massimo per contenitore" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines -msgid "Maximum number of preparation lines for the batch" -msgstr "Numero massimo di righe di preparazione per il gruppo" +msgid "Maximum number of preparation lines for the batch." +msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__user_max_volume @@ -366,6 +371,16 @@ msgstr "Restringi alla stessa priorità" msgid "SQL FOR UPDATE SKIP LOCKED" msgstr "SQL PER SALTO AGGIORNAMENTO BLOCCATO" +#. module: stock_picking_batch_creation +#: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines +msgid "Set to 0 to disable." +msgstr "" + +#. module: stock_picking_batch_creation +#: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__split_mode +msgid "Split Mode" +msgstr "" + #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits msgid "Split pickings exceeding limits" @@ -411,8 +426,8 @@ msgstr "Unità di misura del volume" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__max_volume #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__min_volume -msgid "Volume in default system volume unit of measure" -msgstr "Volume nell'unità di misura del volume predefinita del sistema" +msgid "Volume in default system volume unit of measure. Set to 0 to disable." +msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__user_weight_uom_id @@ -426,8 +441,8 @@ msgstr "Unità di misura del peso" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__max_weight -msgid "Weight in default system weight unit of measure" -msgstr "Peso nell'unità di misura del peso predefinita del sistema" +msgid "Weight in default system weight unit of measure. Set to 0 to disable." +msgstr "" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__user_weight_uom_name @@ -446,6 +461,15 @@ msgstr "es. muletto" msgid "no candidate pickings to batch" msgstr "nessun prelievo candidato da raggruppare" +#~ msgid "Maximum number of preparation lines for the batch" +#~ msgstr "Numero massimo di righe di preparazione per il gruppo" + +#~ msgid "Volume in default system volume unit of measure" +#~ msgstr "Volume nell'unità di misura del volume predefinita del sistema" + +#~ msgid "Weight in default system weight unit of measure" +#~ msgstr "Peso nell'unità di misura del peso predefinita del sistema" + #~ msgid "" #~ "If checked, the maximum number of lines will not be applied if there is " #~ "no candidate to add to the batch with a number of lines less than the " From c8c7ba602a8af99f507865ee6d1bde1f2a33c70e Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Fri, 27 Mar 2026 16:38:30 +0100 Subject: [PATCH 352/357] [FIX] stock_available_to_promise_release: fix Kanban counter layout The "Need Release" counter on the Picking Type Kanban view was inconsistent with standard Odoo counters. Additionally, the layout broke when the count reached 1,000 or more, causing the number to overflow the card boundaries. --- .../views/stock_picking_type_views.xml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/stock_available_to_promise_release/views/stock_picking_type_views.xml b/stock_available_to_promise_release/views/stock_picking_type_views.xml index 7ddb53aa7d7..50cded2a034 100644 --- a/stock_available_to_promise_release/views/stock_picking_type_views.xml +++ b/stock_available_to_promise_release/views/stock_picking_type_views.xml @@ -13,13 +13,11 @@ position="before" >
    -
    + -
    - + Need Release
    From 1c73f31001e65df33cc30abebf9bd02888402a0f Mon Sep 17 00:00:00 2001 From: Nicolas Delbovier Date: Tue, 31 Mar 2026 09:14:21 +0200 Subject: [PATCH 353/357] [FIX] shopfloor_reception: fix UTC boundaries for "Today" filters The `_get_today_start_end_datetime` function returned naive datetimes without accounting for the user's local timezone. Since Odoo stores datetimes in UTC, this caused incorrect filtering on the "Pickings to Process Today" screen for users in non-UTC timezones. Now, the function correctly calculates the start and end of the local day and converts those boundaries to UTC . --- shopfloor_reception/services/reception.py | 41 ++++++++++++------- .../tests/test_select_document.py | 19 ++++++--- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index 349de78804a..c52f778b948 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -4,6 +4,8 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from datetime import datetime, time + import pytz from decorator import contextmanager @@ -86,31 +88,40 @@ def _move_line_by_lot(self, lot): def _scheduled_date_today_domain(self): domain = [] - today_start, today_end = self._get_today_start_end_datetime() + today_start, today_end = self._get_today_start_end_datetime_utc() domain.append(("scheduled_date", ">=", today_start)) domain.append(("scheduled_date", "<=", today_end)) return domain - def _get_today_start_end_datetime(self, naive=True): + def _get_today_start_end_datetime_utc(self): + """ + Returns the start and end of the current day for the warehouse/company + timezone, converted to UTC naive datetimes. + """ # TODO: Put warehouse tz retrieval in shopfloor module? company = self.env.company warehouse = self.picking_types.warehouse_id - tz = ( + + tz_name = ( warehouse.partner_id.tz if (len(warehouse) == 1 and warehouse.partner_id.tz) else company.partner_id.tz or "UTC" ) - today = fields.Datetime.today() - today_start = today_start_localized = fields.Datetime.start_of(today, "day") - today_end = today_end_localized = fields.Datetime.end_of(today, "day") - if not naive: - today_start_localized = ( - pytz.timezone(tz).localize(today_start).astimezone(pytz.utc) - ) - today_end_localized = ( - pytz.timezone(tz).localize(today_end).astimezone(pytz.utc) - ) - return (today_start_localized, today_end_localized) + tz = pytz.timezone(tz_name) + + now_local = pytz.utc.localize(datetime.now()).astimezone(tz) + + local_start = datetime.combine( + now_local.date(), time.min, tzinfo=now_local.tzinfo + ) + local_end = datetime.combine( + now_local.date(), time.max, tzinfo=now_local.tzinfo + ) + + utc_start = local_start.astimezone(pytz.utc).replace(tzinfo=None) + utc_end = local_end.astimezone(pytz.utc).replace(tzinfo=None) + + return utc_start, utc_end @property def filter_today_scheduled_pickings(self): @@ -384,7 +395,7 @@ def _scan_document__by_picking(self, pickings, barcode): # could return more than one picking. # If there's only one picking due today, we go to the next screen. # Otherwise, we ask the user to scan a package instead. - today_start, today_end = self._get_today_start_end_datetime() + today_start, today_end = self._get_today_start_end_datetime_utc() picking_filter_result_due_today = picking_filter_result.filtered( lambda p: today_start <= p.scheduled_date < today_end ) diff --git a/shopfloor_reception/tests/test_select_document.py b/shopfloor_reception/tests/test_select_document.py index 7de580e35b4..d9a2aadb669 100644 --- a/shopfloor_reception/tests/test_select_document.py +++ b/shopfloor_reception/tests/test_select_document.py @@ -1,6 +1,8 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) # pylint: disable=missing-return +from datetime import datetime, timedelta + from freezegun import freeze_time from odoo import fields @@ -9,7 +11,6 @@ _TODAY = "2022-12-07" _TOMORROW = "2022-12-08" -_TODAY_ELEVEN = "2022-12-07 23:30:00" class TestSelectDocument(CommonCase): @@ -82,15 +83,21 @@ def test_scan_picking_origin_multiple_pickings_one_today(self): data=self._data_for_select_move(picking_today), ) - @freeze_time(_TODAY_ELEVEN, tz_offset=0) + # Since we use "Europe/Brussels" tz and _TODAY is in winter + # the shift is UTC+1 + @freeze_time(_TODAY, tz_offset=-1) def test_scan_picking_origin_multiple_pickings_one_today_tz(self): # freezed today is UTC time, set warehouse user to Brussels - self.wh.partner_id.sudo().tz = "Europe/Brussels" + tz_name = "Europe/Brussels" + self.wh.partner_id.sudo().tz = tz_name # Create a picking with the UTC hour - picking_today = self._create_picking(scheduled_date=_TODAY_ELEVEN) - - picking_tomorrow = self._create_picking(scheduled_date=_TOMORROW) + picking_today = self._create_picking( + scheduled_date=datetime.now() + timedelta(hours=23, minutes=30) + ) + picking_tomorrow = self._create_picking( + scheduled_date=datetime.now() + timedelta(days=1), + ) pickings = picking_today | picking_tomorrow pickings = pickings.sorted(lambda p: (p.scheduled_date, p.id), reverse=False) pickings.write({"origin": "Somewhere together"}) From c943870187ef6c05ac4af5ab6d4f5dde348576ea Mon Sep 17 00:00:00 2001 From: mymage Date: Tue, 31 Mar 2026 08:25:21 +0000 Subject: [PATCH 354/357] Translated using Weblate (Italian) Currently translated at 100.0% (76 of 76 strings) Translation: wms-16.0/wms-16.0-stock_picking_batch_creation Translate-URL: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-stock_picking_batch_creation/it/ --- stock_picking_batch_creation/i18n/it.po | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/stock_picking_batch_creation/i18n/it.po b/stock_picking_batch_creation/i18n/it.po index bc38fc6b020..fa71045b768 100644 --- a/stock_picking_batch_creation/i18n/it.po +++ b/stock_picking_batch_creation/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2026-01-28 18:09+0000\n" +"PO-Revision-Date: 2026-03-31 10:07+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -149,7 +149,7 @@ msgstr "Diagnostica" #. module: stock_picking_batch_creation #: model:ir.model.fields.selection,name:stock_picking_batch_creation.selection__stock_device_type__split_mode__dimension msgid "Dimension" -msgstr "" +msgstr "Dimensione" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__display_name @@ -254,7 +254,7 @@ msgstr "Volume massimo per contenitore" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines msgid "Maximum number of preparation lines for the batch." -msgstr "" +msgstr "Numero massimo di righe di preparazione per il gruppo." #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__user_max_volume @@ -374,12 +374,12 @@ msgstr "SQL PER SALTO AGGIORNAMENTO BLOCCATO" #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_make_picking_batch__maximum_number_of_preparation_lines msgid "Set to 0 to disable." -msgstr "" +msgstr "Impostare a 0 per disabilitare." #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__split_mode msgid "Split Mode" -msgstr "" +msgstr "Metodo di divisione" #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_make_picking_batch__split_picking_exceeding_limits @@ -428,6 +428,8 @@ msgstr "Unità di misura del volume" #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__min_volume msgid "Volume in default system volume unit of measure. Set to 0 to disable." msgstr "" +"Volume nell'unità di misura predefinita del volume del sistema. Impostare a " +"zero per disabilitare." #. module: stock_picking_batch_creation #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__user_weight_uom_id @@ -443,6 +445,8 @@ msgstr "Unità di misura del peso" #: model:ir.model.fields,help:stock_picking_batch_creation.field_stock_device_type__max_weight msgid "Weight in default system weight unit of measure. Set to 0 to disable." msgstr "" +"Peso nell'unità di misura predefinita del peso del sistema. Impostare a zero " +"per disabilitare." #. module: stock_picking_batch_creation #: model:ir.model.fields,field_description:stock_picking_batch_creation.field_stock_device_type__user_weight_uom_name From 5b8d9eebc3b7a02487a10d5ce895fc7a85756a72 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 2 Apr 2026 10:32:31 +0000 Subject: [PATCH 355/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_reception/README.rst | 2 +- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 908dc64d6b7..386dd19d096 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ addon | version | maintainers | summary [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.5 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.6 | mmequignon JuMiSanAr | Reception scenario for shopfloor [shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 6e0fdc30774..d6f1ddb0f96 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:40ba81ab584552fe151e2a4d6021706cb34380a9bdc9ed7f08963394a45030b9 + !! source digest: sha256:f8d87b75abf2f07115fe503fe887e2266295e7bc6e9e86e9818ff85ed88bff85 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 2346cf0deca..3cd79d28e16 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.6.5", + "version": "16.0.1.6.6", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index a1af0acb72a..6a9251b2515 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

    Shopfloor Reception

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:40ba81ab584552fe151e2a4d6021706cb34380a9bdc9ed7f08963394a45030b9 +!! source digest: sha256:f8d87b75abf2f07115fe503fe887e2266295e7bc6e9e86e9818ff85ed88bff85 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Shopfloor implementation of the reception scenario. From ea4c71100a388c17db1763283400e3f47e8987e0 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 9 Apr 2026 07:58:39 +0000 Subject: [PATCH 356/357] [BOT] post-merge updates --- README.md | 2 +- shopfloor_mobile/README.rst | 8 ++- shopfloor_mobile/__manifest__.py | 2 +- .../static/description/index.html | 50 +++++++++++-------- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 386dd19d096..fe079fb8b45 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ addon | version | maintainers | summary [shopfloor](shopfloor/) | 16.0.2.16.1 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.0 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking -[shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.0 | simahawk | Mobile frontend for WMS Shopfloor app +[shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.1 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.1.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app [shopfloor_reception](shopfloor_reception/) | 16.0.1.6.6 | mmequignon JuMiSanAr | Reception scenario for shopfloor diff --git a/shopfloor_mobile/README.rst b/shopfloor_mobile/README.rst index 988e1881b27..420cb24069e 100644 --- a/shopfloor_mobile/README.rst +++ b/shopfloor_mobile/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================ Shopfloor mobile ================ @@ -7,13 +11,13 @@ Shopfloor mobile !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e2e8c5dda324092d44eb40ecd4e2bfd44696c59cdc3af9ded861ef7401f7d971 + !! source digest: sha256:f07e5aafb87420fa19f88d904f3718cfd8877b4730a036b454a4feb9d70900a8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fwms-lightgray.png?logo=github diff --git a/shopfloor_mobile/__manifest__.py b/shopfloor_mobile/__manifest__.py index cce3b38b0a1..b7aaa54e73a 100644 --- a/shopfloor_mobile/__manifest__.py +++ b/shopfloor_mobile/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Shopfloor mobile", "summary": "Mobile frontend for WMS Shopfloor app", - "version": "16.0.1.4.0", + "version": "16.0.1.4.1", "depends": ["shopfloor", "shopfloor_mobile_base"], "author": "Camptocamp, BCIM, Akretion, Odoo Community Association (OCA)", "maintainers": ["simahawk"], diff --git a/shopfloor_mobile/static/description/index.html b/shopfloor_mobile/static/description/index.html index f437eee30bc..3b1e1642ee8 100644 --- a/shopfloor_mobile/static/description/index.html +++ b/shopfloor_mobile/static/description/index.html @@ -3,7 +3,7 @@ -Shopfloor mobile +README.rst -

    -

    Shopfloor mobile

    +
    + + +Odoo Community Association + +
    +

    Shopfloor mobile

    -

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Frontend for Shopfloor app.

    The work is organized in scenario. A scenario represents a process in the warehouse (eg: receive, deliver). @@ -377,7 +382,7 @@

    Shopfloor mobile

    Each scenario is linked to a specific menu item which can be configured in the backend. Each scenario drives you through the work to do.

    -

    Tech details

    +

    Tech details

    • This frontend is built on top of VueJS and VuetifyJS and relies on shopfloor module that exposes REST API in Odoo @@ -404,18 +409,18 @@

      Tech details

    -

    Pre-requisites

    +

    Pre-requisites

    • Your Odoo instance is accessible via mobile device
    • You have an API Key configured
    -

    Start the app

    +

    Start the app

    • Go to “Inventory -> Configuration -> Shopfloor -> Shopfloor App”
    • In the login screen fill in your API key
    • @@ -423,7 +428,7 @@

      Start the app

    -

    Select a profile

    +

    Select a profile

    Several profiles can be configured in the backend, you must choose one before starting.

      @@ -433,17 +438,17 @@

      Select a profile

      This will load all available menu items for the selected profile.

    -

    Change language

    +

    Change language

    • Go to “Settings -> Language”
    • Select a language
    -

    Customization

    +

    Customization

    Please refer to shopfloor_mobile_custom_example.

    -

    Known issues / Roadmap

    +

    Known issues / Roadmap

    • Split module by scenario

    • @@ -483,14 +488,14 @@

      Known issues / Roadmap

    -

    Changelog

    +

    Changelog

    -

    13.0.1.0.0

    +

    13.0.1.0.0

    First official version.

    -

    Bug Tracker

    +

    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 to smash it by providing a detailed and welcomed @@ -498,11 +503,11 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Camptocamp
    • BCIM
    • @@ -510,7 +515,7 @@

      Authors

    -

    Contributors

    +

    Contributors

    -

    Design

    +

    Design

    -

    Other credits

    +

    Other credits

    Financial support

    • Cosanum
    • @@ -537,7 +542,7 @@

      Other credits

    +
    From f46298a907a1275a4c15bf587a82a3b0dad9ae4c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 9 Apr 2026 08:20:14 +0000 Subject: [PATCH 357/357] [BOT] post-merge updates --- README.md | 2 +- stock_available_to_promise_release/README.rst | 2 +- stock_available_to_promise_release/__manifest__.py | 2 +- .../static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fe079fb8b45..321bf111763 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ addon | version | maintainers | summary [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners [shopfloor_workstation_mobile](shopfloor_workstation_mobile/) | 16.0.1.0.0 | | Shopfloor mobile app integration for workstation -[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.8.2 | | Release Operations based on available to promise +[stock_available_to_promise_release](stock_available_to_promise_release/) | 16.0.3.8.3 | | Release Operations based on available to promise [stock_available_to_promise_release_block](stock_available_to_promise_release_block/) | 16.0.1.1.1 | | Block Release of Operations [stock_available_to_promise_release_dynamic_routing](stock_available_to_promise_release_dynamic_routing/) | 16.0.1.0.0 | jbaudoux | Glue between moves release and dynamic routing [stock_available_to_promise_release_exclude_location](stock_available_to_promise_release_exclude_location/) | 16.0.1.0.0 | | Exclude locations from available stock diff --git a/stock_available_to_promise_release/README.rst b/stock_available_to_promise_release/README.rst index 48b48bf8f91..0041f828642 100644 --- a/stock_available_to_promise_release/README.rst +++ b/stock_available_to_promise_release/README.rst @@ -11,7 +11,7 @@ Stock Available to Promise Release !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:a2c7d3a98fbb4bc85708fd746ece6b40695d865ff74d05fccbb4622ac019fe93 + !! source digest: sha256:543c66e12c249c9e0f83d9e4a5449c6915eea33005a226e38e78f54dedcda8da !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/stock_available_to_promise_release/__manifest__.py b/stock_available_to_promise_release/__manifest__.py index a6022e9dbf8..7dc337724e0 100644 --- a/stock_available_to_promise_release/__manifest__.py +++ b/stock_available_to_promise_release/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Stock Available to Promise Release", - "version": "16.0.3.8.2", + "version": "16.0.3.8.3", "summary": "Release Operations based on available to promise", "author": "Camptocamp, BCIM, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", diff --git a/stock_available_to_promise_release/static/description/index.html b/stock_available_to_promise_release/static/description/index.html index 3619102b694..56ad583b27e 100644 --- a/stock_available_to_promise_release/static/description/index.html +++ b/stock_available_to_promise_release/static/description/index.html @@ -372,7 +372,7 @@

    Stock Available to Promise Release

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:a2c7d3a98fbb4bc85708fd746ece6b40695d865ff74d05fccbb4622ac019fe93 +!! source digest: sha256:543c66e12c249c9e0f83d9e4a5449c6915eea33005a226e38e78f54dedcda8da !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: LGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

    Currently the reservation is performed by adding reserved quantities on quants,