diff --git a/setup/stock_release_channel_show_volume/odoo/addons/stock_release_channel_show_volume b/setup/stock_release_channel_show_volume/odoo/addons/stock_release_channel_show_volume new file mode 120000 index 0000000000..53d9e64b01 --- /dev/null +++ b/setup/stock_release_channel_show_volume/odoo/addons/stock_release_channel_show_volume @@ -0,0 +1 @@ +../../../../stock_release_channel_show_volume \ No newline at end of file diff --git a/setup/stock_release_channel_show_volume/setup.py b/setup/stock_release_channel_show_volume/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/stock_release_channel_show_volume/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_release_channel_show_volume/README.rst b/stock_release_channel_show_volume/README.rst new file mode 100644 index 0000000000..a4861d0c84 --- /dev/null +++ b/stock_release_channel_show_volume/README.rst @@ -0,0 +1,78 @@ +=================================== +Stock Release Channels show Volumes +=================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:6d21986b669c172ec403d968cfeaf164789c75dc3e6e73553e2f49dd5c1ca26d + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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_show_volume + :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_show_volume + :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| + +Show the volume on the release channels + +**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 +~~~~~~~ + +* 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. + +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_show_volume/__init__.py b/stock_release_channel_show_volume/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/stock_release_channel_show_volume/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_release_channel_show_volume/__manifest__.py b/stock_release_channel_show_volume/__manifest__.py new file mode 100644 index 0000000000..bdc78ac37e --- /dev/null +++ b/stock_release_channel_show_volume/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{ + "name": "Stock Release Channels show Volumes", + "summary": "Displays volumes of stock release channels", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "MT-Software, BCIM, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/wms", + "depends": [ + "stock_picking_volume", + "stock_release_channel", + ], + "data": [ + "views/release_channel.xml", + ], + "installable": True, +} diff --git a/stock_release_channel_show_volume/models/__init__.py b/stock_release_channel_show_volume/models/__init__.py new file mode 100644 index 0000000000..a0504e8407 --- /dev/null +++ b/stock_release_channel_show_volume/models/__init__.py @@ -0,0 +1 @@ +from . import stock_release_channel diff --git a/stock_release_channel_show_volume/models/stock_release_channel.py b/stock_release_channel_show_volume/models/stock_release_channel.py new file mode 100644 index 0000000000..f8755dfa72 --- /dev/null +++ b/stock_release_channel_show_volume/models/stock_release_channel.py @@ -0,0 +1,119 @@ +# Copyright 2023 Michael Tietz (MT Software) +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import api, fields, models + + +class StockReleaseChannel(models.Model): + _inherit = "stock.release.channel" + + volume_picking_all = fields.Float( + string="All Transfers Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_release_ready = fields.Float( + string="Release Ready Transfers Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_released = fields.Float( + string="Released Transfers Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_assigned = fields.Float( + string="Available Transfers Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_waiting = fields.Float( + string="Waiting Transfers Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_late = fields.Float( + string="Late Transfers Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_priority = fields.Float( + string="Priority Transfers Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_done = fields.Float( + string="Transfers Done VolumeToday", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_picking_full_progress = fields.Float( + string="Full Progress Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_all = fields.Float( + string="All Moves (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_release_ready = fields.Float( + string="Release Ready Moves (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_released = fields.Float( + string="Released Moves (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_assigned = fields.Float( + string="Available Moves (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_waiting = fields.Float( + string="Waiting Moves (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_late = fields.Float( + string="Late Moves (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_priority = fields.Float( + string="Priority Moves (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + volume_move_done = fields.Float( + string="Moves Done Today (Estimate) Volume", + compute="_compute_picking_count", + digits="Release Channel Volume", + ) + + @api.model + def _get_picking_read_group_fields(self): + res = super()._get_picking_read_group_fields() + res += ["volume"] + return res + + @api.model + def _get_move_read_group_fields(self): + res = super()._get_move_read_group_fields() + res += ["volume"] + return res + + @api.model + def _get_picking_compute_fields(self): + res = super()._get_picking_compute_fields() + res += [("volume", "volume")] + return res + + @api.model + def _get_move_compute_fields(self): + res = super()._get_move_compute_fields() + res += [("volume", "volume")] + return res diff --git a/stock_release_channel_show_volume/readme/CONTRIBUTORS.rst b/stock_release_channel_show_volume/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..03c3145a2b --- /dev/null +++ b/stock_release_channel_show_volume/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Michael Tietz (MT Software) +* Jacques-Etienne Baudoux (BCIM) diff --git a/stock_release_channel_show_volume/readme/DESCRIPTION.rst b/stock_release_channel_show_volume/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..5af17e2758 --- /dev/null +++ b/stock_release_channel_show_volume/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Show the volume on the release channels diff --git a/stock_release_channel_show_volume/static/description/index.html b/stock_release_channel_show_volume/static/description/index.html new file mode 100644 index 0000000000..8f57f74655 --- /dev/null +++ b/stock_release_channel_show_volume/static/description/index.html @@ -0,0 +1,423 @@ + + + + + + +Stock Release Channels show Volumes + + + +
+

Stock Release Channels show Volumes

+ + +

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

+

Show the volume on the release channels

+

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

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

+

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_show_volume/tests/__init__.py b/stock_release_channel_show_volume/tests/__init__.py new file mode 100644 index 0000000000..b6ca01fad1 --- /dev/null +++ b/stock_release_channel_show_volume/tests/__init__.py @@ -0,0 +1 @@ +from . import test_channel_computed_fields diff --git a/stock_release_channel_show_volume/tests/test_channel_computed_fields.py b/stock_release_channel_show_volume/tests/test_channel_computed_fields.py new file mode 100644 index 0000000000..460fdf0901 --- /dev/null +++ b/stock_release_channel_show_volume/tests/test_channel_computed_fields.py @@ -0,0 +1,131 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from datetime import timedelta + +from odoo import fields + +from odoo.addons.stock_release_channel.tests.common import ChannelReleaseCase + + +class TestChannelComputedFields(ChannelReleaseCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.product1.volume = 1 + cls.product2.volume = 3 + cls.channel.picking_ids.move_lines._compute_volume() + cls.channel.picking_ids._compute_volume() + + def assertVolume(self, suffix, product_qties): + volume = sum([product.volume * qty for product, qty in product_qties]) + for prefix in ["volume_picking", "volume_move"]: + field = f"{prefix}_{suffix}" + value = getattr(self.channel, field) + self.assertEqual( + volume, + value, + f"The value of {field} is {value} and not like expected {volume}", + ) + + def assertVolumeFullProgress(self): + self.assertEqual( + self.channel.volume_picking_full_progress, + sum( + [ + self.channel.volume_picking_release_ready, + self.channel.volume_picking_released, + self.channel.volume_picking_done, + ] + ), + ) + + def test_computed_fields_counts(self): + picking = self.picking + + self.channel.invalidate_cache() + self.assertVolume("all", [(self.product1, 5 * 3), (self.product2, 5 * 3)]) + self.assertVolume("release_ready", []) + self.assertVolume("released", []) + self.assertVolume("assigned", []) + self.assertVolume("waiting", []) + self.assertVolume("late", []) + self.assertVolume("priority", []) + self.assertVolume("done", []) + self.assertVolumeFullProgress() + + self._update_qty_in_location(self.loc_bin1, self.product1, 20.0) + self._update_qty_in_location(self.loc_bin1, self.product2, 20.0) + + self.channel.invalidate_cache() + self.assertVolume("all", [(self.product1, 5 * 3), (self.product2, 5 * 3)]) + self.assertVolume( + "release_ready", [(self.product1, 5 * 3), (self.product2, 5 * 3)] + ) + self.assertVolume("released", []) + self.assertVolume("assigned", []) + self.assertVolume("waiting", []) + self.assertVolume("late", []) + self.assertVolume("priority", []) + self.assertVolume("done", []) + self.assertVolumeFullProgress() + + picking.release_available_to_promise() + pick_picking = picking.move_lines.move_orig_ids.picking_id + + self.channel.invalidate_cache() + self.assertVolume("all", [(self.product1, 5 * 3), (self.product2, 5 * 3)]) + self.assertVolume( + "release_ready", [(self.product1, 5 * 2), (self.product2, 5 * 2)] + ) + self.assertVolume("released", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("assigned", []) + self.assertVolume("waiting", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("late", []) + self.assertVolume("priority", []) + self.assertVolume("done", []) + self.assertVolumeFullProgress() + + picking.scheduled_date = fields.Datetime.now() - timedelta(hours=1) + self.channel.invalidate_cache() + self.assertVolume("all", [(self.product1, 5 * 3), (self.product2, 5 * 3)]) + self.assertVolume( + "release_ready", [(self.product1, 5 * 2), (self.product2, 5 * 2)] + ) + self.assertVolume("released", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("assigned", []) + self.assertVolume("waiting", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("late", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("priority", []) + self.assertVolume("done", []) + self.assertVolumeFullProgress() + + self._action_done_picking(pick_picking) + + self.channel.invalidate_cache() + self.assertVolume("all", [(self.product1, 5 * 3), (self.product2, 5 * 3)]) + self.assertVolume( + "release_ready", [(self.product1, 5 * 2), (self.product2, 5 * 2)] + ) + self.assertVolume("released", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("assigned", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("waiting", []) + self.assertVolume("late", [(self.product1, 5), (self.product2, 5)]) + self.assertVolume("priority", []) + self.assertVolume("done", []) + self.assertVolumeFullProgress() + + self._action_done_picking(picking) + + self.channel.invalidate_cache() + self.assertVolume("all", [(self.product1, 5 * 3), (self.product2, 5 * 3)]) + self.assertVolume( + "release_ready", [(self.product1, 5 * 2), (self.product2, 5 * 2)] + ) + self.assertVolume("released", []) + self.assertVolume("assigned", []) + self.assertVolume("waiting", []) + self.assertVolume("late", []) + self.assertVolume("priority", []) + self.assertVolume("done", [(self.product1, 5), (self.product2, 5)]) + self.assertVolumeFullProgress() diff --git a/stock_release_channel_show_volume/views/release_channel.xml b/stock_release_channel_show_volume/views/release_channel.xml new file mode 100644 index 0000000000..c2e0ec15bb --- /dev/null +++ b/stock_release_channel_show_volume/views/release_channel.xml @@ -0,0 +1,124 @@ + + + stock.release.channel + + + + + + + + + + + + + + + + + + + + + + + + + + stock.release.channel + kanban + + + + + + + + + + + + + col-4 + + +
+ + m3 + +
+
+ + col-4 + + +
+ + m3 + +
+
+ + col-4 + + +
+ + m3 + +
+
+ + + + m3 + + + + + m3 + + + + + m3 + + +
+
+