diff --git a/delivery_package_type_number_parcels/README.rst b/delivery_package_type_number_parcels/README.rst new file mode 100644 index 0000000000..8262a57719 --- /dev/null +++ b/delivery_package_type_number_parcels/README.rst @@ -0,0 +1,93 @@ +==================================== +Delivery Package Type Number Parcels +==================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:b89957d7d07f4d3269e752c71675921b863468114cfd1c19987f589d0c3227fd + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fdelivery--carrier-lightgray.png?logo=github + :target: https://github.com/OCA/delivery-carrier/tree/18.0/delivery_package_type_number_parcels + :alt: OCA/delivery-carrier +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/delivery-carrier-18-0/delivery-carrier-18-0-delivery_package_type_number_parcels + :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/delivery-carrier&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to pre-configure a number of parcels on the delivery +package type. When creating a delivery package and associating a package +type, the number of parcels of the package will be initialized from the +delivery package type. You can create one package type per possible +number of parcels, like "1 parcel", "2 parcels", "3 parcels"... When +packing, select or scan the package type barcode to make a package for +all picked lines with the right declared amount of parcels. This +prevents you to declare which picked line and corresponding quantity is +in which parcel. + +The number of parcels is also displayed in the delivery package wizard +when selecting a package type, giving users immediate visibility of the +parcel count during the delivery process. + +**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 +------- + +* ACSONE SA/NV +* BCIM + +Contributors +------------ + +- Hughes Damry +- Jacques-Etienne Baudoux (BCIM) je@bcim.be +- `Heliconia Solutions Pvt. Ltd. `__ + + - Bhavesh Heliconia + +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/delivery-carrier `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/delivery_package_type_number_parcels/__init__.py b/delivery_package_type_number_parcels/__init__.py new file mode 100644 index 0000000000..aee8895e7a --- /dev/null +++ b/delivery_package_type_number_parcels/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/delivery_package_type_number_parcels/__manifest__.py b/delivery_package_type_number_parcels/__manifest__.py new file mode 100644 index 0000000000..c164206c90 --- /dev/null +++ b/delivery_package_type_number_parcels/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Delivery Package Type Number Parcels", + "summary": "Number of parcels in a package type", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,BCIM,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/delivery-carrier", + "depends": ["stock_delivery"], + "data": [ + "views/stock_quant_package_views.xml", + "views/stock_package_type_views.xml", + "wizards/choose_delivery_package_views.xml", + ], + "installable": True, +} diff --git a/delivery_package_type_number_parcels/i18n/delivery_package_type_number_parcels.pot b/delivery_package_type_number_parcels/i18n/delivery_package_type_number_parcels.pot new file mode 100644 index 0000000000..8fba40dd41 --- /dev/null +++ b/delivery_package_type_number_parcels/i18n/delivery_package_type_number_parcels.pot @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * delivery_package_type_number_parcels +# +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: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_choose_delivery_package +msgid "Delivery Package Selection Wizard" +msgstr "" + +#. module: delivery_package_type_number_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_stock_quant_package__number_of_parcels +msgid "Number Of Parcels" +msgstr "" + +#. module: delivery_package_type_number_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_choose_delivery_package__number_of_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_stock_package_type__number_of_parcels +msgid "Number of parcels" +msgstr "" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_stock_quant_package +msgid "Packages" +msgstr "" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_stock_package_type +msgid "Stock package type" +msgstr "" diff --git a/delivery_package_type_number_parcels/i18n/es.po b/delivery_package_type_number_parcels/i18n/es.po new file mode 100644 index 0000000000..3736202e47 --- /dev/null +++ b/delivery_package_type_number_parcels/i18n/es.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * delivery_package_type_number_parcels +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-08-03 15:09+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\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 4.17\n" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_choose_delivery_package +msgid "Delivery Package Selection Wizard" +msgstr "Asistente de selección de paquetes de entrega" + +#. module: delivery_package_type_number_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_stock_quant_package__number_of_parcels +msgid "Number Of Parcels" +msgstr "" + +#. module: delivery_package_type_number_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_choose_delivery_package__number_of_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_stock_package_type__number_of_parcels +msgid "Number of parcels" +msgstr "Número de parcelas" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_stock_quant_package +msgid "Packages" +msgstr "Paquetes" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_stock_package_type +msgid "Stock package type" +msgstr "Tipo de empaquetado de existencias" diff --git a/delivery_package_type_number_parcels/i18n/it.po b/delivery_package_type_number_parcels/i18n/it.po new file mode 100644 index 0000000000..d59871c99e --- /dev/null +++ b/delivery_package_type_number_parcels/i18n/it.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * delivery_package_type_number_parcels +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-09-02 12:06+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.6.2\n" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_choose_delivery_package +msgid "Delivery Package Selection Wizard" +msgstr "Procedura guidata selezione collo consegna" + +#. module: delivery_package_type_number_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_stock_quant_package__number_of_parcels +msgid "Number Of Parcels" +msgstr "Numero di pacchetti" + +#. module: delivery_package_type_number_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_choose_delivery_package__number_of_parcels +#: model:ir.model.fields,field_description:delivery_package_type_number_parcels.field_stock_package_type__number_of_parcels +msgid "Number of parcels" +msgstr "Numero di pacchetti" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_stock_quant_package +msgid "Packages" +msgstr "Colli" + +#. module: delivery_package_type_number_parcels +#: model:ir.model,name:delivery_package_type_number_parcels.model_stock_package_type +msgid "Stock package type" +msgstr "Tipo collo magazzino" diff --git a/delivery_package_type_number_parcels/models/__init__.py b/delivery_package_type_number_parcels/models/__init__.py new file mode 100644 index 0000000000..1c4368248c --- /dev/null +++ b/delivery_package_type_number_parcels/models/__init__.py @@ -0,0 +1,2 @@ +from . import stock_package_type +from . import stock_quant_package diff --git a/delivery_package_type_number_parcels/models/stock_package_type.py b/delivery_package_type_number_parcels/models/stock_package_type.py new file mode 100644 index 0000000000..327d8aaec5 --- /dev/null +++ b/delivery_package_type_number_parcels/models/stock_package_type.py @@ -0,0 +1,10 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PackageType(models.Model): + _inherit = "stock.package.type" + + number_of_parcels = fields.Integer("Number of parcels") diff --git a/delivery_package_type_number_parcels/models/stock_quant_package.py b/delivery_package_type_number_parcels/models/stock_quant_package.py new file mode 100644 index 0000000000..f472a2bcb0 --- /dev/null +++ b/delivery_package_type_number_parcels/models/stock_quant_package.py @@ -0,0 +1,17 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class StockQuantPackage(models.Model): + _inherit = "stock.quant.package" + + number_of_parcels = fields.Integer( + compute="_compute_number_of_parcels", store=True, readonly=False + ) + + @api.depends("package_type_id") + def _compute_number_of_parcels(self): + for rec in self: + rec.number_of_parcels = rec.package_type_id.number_of_parcels diff --git a/delivery_package_type_number_parcels/pyproject.toml b/delivery_package_type_number_parcels/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/delivery_package_type_number_parcels/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/delivery_package_type_number_parcels/readme/CONTRIBUTORS.md b/delivery_package_type_number_parcels/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..648943b428 --- /dev/null +++ b/delivery_package_type_number_parcels/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Hughes Damry \<\> +- Jacques-Etienne Baudoux (BCIM) +- [Heliconia Solutions Pvt. Ltd.](https://www.heliconia.io) + - Bhavesh Heliconia diff --git a/delivery_package_type_number_parcels/readme/DESCRIPTION.md b/delivery_package_type_number_parcels/readme/DESCRIPTION.md new file mode 100644 index 0000000000..4f62ef971f --- /dev/null +++ b/delivery_package_type_number_parcels/readme/DESCRIPTION.md @@ -0,0 +1,9 @@ +This module allows to pre-configure a number of parcels on the delivery package type. +When creating a delivery package and associating a package type, the number of parcels of the package will be initialized from the delivery package type. +You can create one package type per possible number of parcels, like "1 parcel", "2 parcels", "3 parcels"... +When packing, select or scan the package type barcode to make a package for all picked lines with the right declared amount of parcels. +This prevents you to declare which picked line and corresponding quantity is in which parcel. + +The number of parcels is also displayed in the delivery package +wizard when selecting a package type, giving users immediate +visibility of the parcel count during the delivery process. diff --git a/delivery_package_type_number_parcels/static/description/icon.png b/delivery_package_type_number_parcels/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/delivery_package_type_number_parcels/static/description/icon.png differ diff --git a/delivery_package_type_number_parcels/static/description/index.html b/delivery_package_type_number_parcels/static/description/index.html new file mode 100644 index 0000000000..5c3ed40f7d --- /dev/null +++ b/delivery_package_type_number_parcels/static/description/index.html @@ -0,0 +1,440 @@ + + + + + +Delivery Package Type Number Parcels + + + +
+

Delivery Package Type Number Parcels

+ + +

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

+

This module allows to pre-configure a number of parcels on the delivery +package type. When creating a delivery package and associating a package +type, the number of parcels of the package will be initialized from the +delivery package type. You can create one package type per possible +number of parcels, like “1 parcel”, “2 parcels”, “3 parcels”… When +packing, select or scan the package type barcode to make a package for +all picked lines with the right declared amount of parcels. This +prevents you to declare which picked line and corresponding quantity is +in which parcel.

+

The number of parcels is also displayed in the delivery package wizard +when selecting a package type, giving users immediate visibility of the +parcel count during the delivery process.

+

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

+
    +
  • ACSONE SA/NV
  • +
  • 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/delivery-carrier project on GitHub.

+

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

+
+
+
+ + diff --git a/delivery_package_type_number_parcels/tests/__init__.py b/delivery_package_type_number_parcels/tests/__init__.py new file mode 100644 index 0000000000..377ee6294b --- /dev/null +++ b/delivery_package_type_number_parcels/tests/__init__.py @@ -0,0 +1 @@ +from . import test_package_type_number_parcels diff --git a/delivery_package_type_number_parcels/tests/test_package_type_number_parcels.py b/delivery_package_type_number_parcels/tests/test_package_type_number_parcels.py new file mode 100644 index 0000000000..143300360d --- /dev/null +++ b/delivery_package_type_number_parcels/tests/test_package_type_number_parcels.py @@ -0,0 +1,114 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.addons.stock.tests.test_packing import TestPackingCommon + + +class TestStockQuantPackageDelivery(TestPackingCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.uom_kg = cls.env.ref("uom.product_uom_kgm") + cls.product_test = cls.env["product.product"].create( + { + "name": "Product TEST", + "type": "consu", + "weight": 0.1, + "is_storable": True, + "uom_id": cls.uom_kg.id, + "uom_po_id": cls.uom_kg.id, + } + ) + test_carrier_product = cls.env["product.product"].create( + { + "name": "Test carrier product", + "type": "service", + } + ) + cls.test_carrier = cls.env["delivery.carrier"].create( + { + "name": "Test carrier", + "delivery_type": "fixed", + "product_id": test_carrier_product.id, + } + ) + cls.package_type = cls.env["stock.package.type"].create( + { + "name": "package type", + "number_of_parcels": 7, + } + ) + + def test_put_in_pack_choose_carrier_wizard(self): + """ + Trigger the 'choose.delivery.package' wizard and choose a package type with + a number of parcels > 0. + - check the related has the right value in the wizard + - check the related has the right value in the created package + """ + self.env["stock.quant"]._update_available_quantity( + self.product_test, self.stock_location, 20.0 + ) + picking_ship = self.env["stock.picking"].create( + { + "partner_id": self.env["res.partner"].create({"name": "A partner"}).id, + "picking_type_id": self.warehouse.out_type_id.id, + "location_id": self.stock_location.id, + "location_dest_id": self.customer_location.id, + "carrier_id": self.test_carrier.id, + } + ) + picking_ship.action_confirm() + # create a move line for the picking + self.env["stock.move.line"].create( + { + "product_id": self.product_test.id, + "product_uom_id": self.uom_kg.id, + "picking_id": picking_ship.id, + "quantity": 5, + "location_id": self.stock_location.id, + "location_dest_id": self.customer_location.id, + } + ) + pack_action = picking_ship.action_put_in_pack() + pack_action_ctx = pack_action["context"] + pack_action_model = pack_action["res_model"] + # We make sure the correct action was returned + self.assertEqual(pack_action_model, "choose.delivery.package") + # check there is no package yet for the picking + self.assertEqual(len(picking_ship.package_level_ids), 0) + # We instanciate the wizard with the context of the action + pack_wiz = ( + self.env["choose.delivery.package"] + .with_context(**pack_action_ctx) + .create({}) + ) + # set the package type + pack_wiz.delivery_package_type_id = self.package_type + # check the related number_of_parcels is ok + self.assertEqual( + pack_wiz.number_of_parcels, self.package_type.number_of_parcels + ) + pack_wiz.action_put_in_pack() + # check that one package has been created with the same number of packages + self.assertEqual(len(picking_ship.package_level_ids), 1) + package1 = picking_ship.package_level_ids[0] + # check the related number_of_parcels is ok in the package + self.assertEqual( + package1.package_id.number_of_parcels, self.package_type.number_of_parcels + ) + return package1 + + def test_manual_number_of_parcels(self): + package = self.test_put_in_pack_choose_carrier_wizard() + self.assertEqual(package.package_id.number_of_parcels, 7) + self.package_type.number_of_parcels = 8 + self.assertEqual(package.package_id.number_of_parcels, 7) + package.package_id.number_of_parcels = 9 + self.assertEqual(package.package_id.number_of_parcels, 9) + self.assertEqual(self.package_type.number_of_parcels, 8) + package.package_id.package_type_id = self.package_type.copy( + {"number_of_parcels": 10} + ) + self.assertEqual(package.package_id.number_of_parcels, 10) diff --git a/delivery_package_type_number_parcels/views/stock_package_type_views.xml b/delivery_package_type_number_parcels/views/stock_package_type_views.xml new file mode 100644 index 0000000000..5568608d9e --- /dev/null +++ b/delivery_package_type_number_parcels/views/stock_package_type_views.xml @@ -0,0 +1,34 @@ + + + + + stock.package.type.form.delivery (in delivery_package_type_number_parcels) + stock.package.type + + + + + + + + + + stock.package.type.tree.delivery (in delivery_package_type_number_parcels) + stock.package.type + + + + + + + + diff --git a/delivery_package_type_number_parcels/views/stock_quant_package_views.xml b/delivery_package_type_number_parcels/views/stock_quant_package_views.xml new file mode 100644 index 0000000000..939cd772ed --- /dev/null +++ b/delivery_package_type_number_parcels/views/stock_quant_package_views.xml @@ -0,0 +1,34 @@ + + + + + stock.quant.package.form (in delivery_package_type_number_parcels) + stock.quant.package + + + + + + + + + + stock.quant.package.tree (in delivery_package_type_number_parcels) + stock.quant.package + + + + + + + + diff --git a/delivery_package_type_number_parcels/wizards/__init__.py b/delivery_package_type_number_parcels/wizards/__init__.py new file mode 100644 index 0000000000..7ed42a5080 --- /dev/null +++ b/delivery_package_type_number_parcels/wizards/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import choose_delivery_package diff --git a/delivery_package_type_number_parcels/wizards/choose_delivery_package.py b/delivery_package_type_number_parcels/wizards/choose_delivery_package.py new file mode 100644 index 0000000000..b19ff4d20a --- /dev/null +++ b/delivery_package_type_number_parcels/wizards/choose_delivery_package.py @@ -0,0 +1,12 @@ +# Copyright 2023 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ChooseDeliveryPackage(models.TransientModel): + _inherit = "choose.delivery.package" + + number_of_parcels = fields.Integer( + related="delivery_package_type_id.number_of_parcels", + ) diff --git a/delivery_package_type_number_parcels/wizards/choose_delivery_package_views.xml b/delivery_package_type_number_parcels/wizards/choose_delivery_package_views.xml new file mode 100644 index 0000000000..8e90dbd2b1 --- /dev/null +++ b/delivery_package_type_number_parcels/wizards/choose_delivery_package_views.xml @@ -0,0 +1,18 @@ + + + + choose.delivery.package.form (in delivery_package_type_number_parcels) + choose.delivery.package + + + + + + + +