From 218e34946c26e22942c82e728f288d0540bffb52 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 25 Nov 2024 13:49:53 +0100 Subject: [PATCH] [16.0][MIG] shopfloor_reception --- .../odoo/addons/shopfloor_reception | 1 + setup/shopfloor_reception/setup.py | 6 ++ shopfloor/actions/stock.py | 6 +- shopfloor_reception/README.rst | 11 ++-- shopfloor_reception/__manifest__.py | 2 +- shopfloor_reception/readme/CONTRIBUTORS.rst | 1 + shopfloor_reception/services/reception.py | 20 +++--- .../static/description/index.html | 18 +++-- shopfloor_reception/tests/common.py | 6 +- .../tests/reception_return_common.py | 13 ++-- .../tests/test_return_reception_done.py | 4 +- .../tests/test_return_scan_document.py | 2 +- .../tests/test_select_dest_package.py | 9 +-- .../tests/test_select_document.py | 2 +- shopfloor_reception/tests/test_select_move.py | 10 +-- .../tests/test_set_destination.py | 6 +- shopfloor_reception/tests/test_set_lot.py | 2 +- .../tests/test_set_lot_confirm.py | 2 +- .../tests/test_set_quantity.py | 65 ++++++++----------- .../tests/test_set_quantity_action.py | 13 ++-- 20 files changed, 94 insertions(+), 105 deletions(-) create mode 120000 setup/shopfloor_reception/odoo/addons/shopfloor_reception create mode 100644 setup/shopfloor_reception/setup.py diff --git a/setup/shopfloor_reception/odoo/addons/shopfloor_reception b/setup/shopfloor_reception/odoo/addons/shopfloor_reception new file mode 120000 index 0000000000..6fbfe38b04 --- /dev/null +++ b/setup/shopfloor_reception/odoo/addons/shopfloor_reception @@ -0,0 +1 @@ +../../../../shopfloor_reception \ No newline at end of file diff --git a/setup/shopfloor_reception/setup.py b/setup/shopfloor_reception/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/shopfloor_reception/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopfloor/actions/stock.py b/shopfloor/actions/stock.py index ba34b36ab9..ee4a810b6c 100644 --- a/shopfloor/actions/stock.py +++ b/shopfloor/actions/stock.py @@ -18,7 +18,7 @@ class StockAction(Component): def _create_return_move__get_max_qty(self, origin_move): """Returns the max returneable qty.""" # The max returnable qty is the sent qty minus the already returned qties - quantity = origin_move.reserved_qty + quantity = origin_move.product_uom_qty for move in origin_move.move_dest_ids: if ( move.origin_returned_move_id @@ -28,7 +28,7 @@ def _create_return_move__get_max_qty(self, origin_move): if move.state in ("partially_available", "assigned"): quantity -= sum(move.move_line_ids.mapped("reserved_qty")) elif move.state in ("done"): - quantity -= move.reserved_qty + quantity -= move.product_uom_qty return float_round( quantity, precision_rounding=origin_move.product_id.uom_id.rounding ) @@ -92,7 +92,7 @@ def create_return_move(self, return_picking, origin_moves): def _create_return_picking__get_vals(self, return_types, origin): return_type = fields.first(return_types) return { - "move_lines": [], + "move_ids": [], "picking_type_id": return_type.id, "state": "draft", "origin": origin, diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index 73942e270e..e1b5c54486 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -17,13 +17,13 @@ Shopfloor Reception :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 + :target: https://github.com/OCA/wms/tree/16.0/shopfloor_reception :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 + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_reception :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| @@ -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 to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -66,6 +66,7 @@ Contributors * Juan Miguel Sánchez Arce * Jacques-Etienne Baudoux (BCIM) * Michael Tietz (MT Software) +* Souheil Bejaoui Maintainers ~~~~~~~~~~~ @@ -91,6 +92,6 @@ Current `maintainers `__: |maintainer-mmequignon| |maintainer-JuMiSanAr| -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/__manifest__.py b/shopfloor_reception/__manifest__.py index 4d209f92ad..afbe051d4f 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "14.0.2.10.0", + "version": "16.0.1.0.0", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/readme/CONTRIBUTORS.rst b/shopfloor_reception/readme/CONTRIBUTORS.rst index 02b86acf88..331a33b7cc 100644 --- a/shopfloor_reception/readme/CONTRIBUTORS.rst +++ b/shopfloor_reception/readme/CONTRIBUTORS.rst @@ -2,3 +2,4 @@ * Juan Miguel Sánchez Arce * Jacques-Etienne Baudoux (BCIM) * Michael Tietz (MT Software) +* Souheil Bejaoui \ No newline at end of file diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index bf5262c321..212711d5e0 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -429,7 +429,7 @@ def _scan_line__by_product__return(self, picking, product): return self._scan_line__find_or_create_line(picking, return_move) def _scan_line__by_product(self, picking, product): - moves = picking.move_lines.filtered(lambda m: m.product_id == 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: response = self._scan_line__by_product__return(picking, product) @@ -471,7 +471,7 @@ def _scan_line__by_packaging__return(self, picking, packaging): ) def _scan_line__by_packaging(self, picking, packaging): - move = picking.move_lines.filtered( + move = picking.move_ids.filtered( lambda m: packaging in m.product_id.packaging_ids ) # Only create a return if don't already have a maching reception move @@ -708,7 +708,7 @@ def _data_for_stock_picking(self, picking, with_lines=False, **kw): kw["with_progress"] = True data = self.data.picking(picking, **kw) if with_lines: - data.update({"moves": self._data_for_moves(picking.move_lines)}) + data.update({"moves": self._data_for_moves(picking.move_ids)}) return data def _data_for_stock_pickings(self, pickings, with_lines=False): @@ -1040,7 +1040,7 @@ def set_lot( product = selected_line.product_id lot = search.lot_from_scan(lot_name, products=product) if not lot: - lot = self.env["stock.production.lot"].create( + lot = self.env["stock.lot"].create( self._create_lot_values(product, lot_name) ) selected_line.lot_id = lot.id @@ -1180,7 +1180,7 @@ def set_quantity__cancel_action(self, picking_id, selected_line_id): picking, selected_line, message=message ) if selected_line.exists(): - if selected_line.product_uom_qty: + if selected_line.reserved_uom_qty: stock = self._actions_for("stock") stock.unmark_move_line_as_picked(selected_line) else: @@ -1256,7 +1256,7 @@ def process_without_pack(self, picking_id, selected_line_id, quantity): return self._response_for_set_destination(picking, selected_line) def _post_line(self, selected_line): - selected_line.product_uom_qty = selected_line.qty_done + selected_line.reserved_uom_qty = selected_line.qty_done if ( selected_line.picking_id.is_shopfloor_created and self.work.menu.allow_return @@ -1271,7 +1271,7 @@ def _post_line(self, selected_line): self._auto_post_line(selected_line) def _post_shopfloor_created_line(self, selected_line): - selected_line.product_uom_qty = selected_line.qty_done + selected_line.reserved_uom_qty = selected_line.qty_done selected_line.picking_id.with_context(cancel_backorder=True)._action_done() return self._response_for_select_document( message=self.msg_store.transfer_done_success(selected_line.picking_id) @@ -1287,13 +1287,13 @@ def _auto_post_line(self, selected_line): # 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.product_uom_qty > 0 + 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.product_uom_qty = 0 + lines_with_qty_todo.reserved_uom_qty = 0 move_quantity = move.product_uom._compute_quantity( move.product_uom_qty, selected_line.product_uom_id @@ -1317,7 +1317,7 @@ def _auto_post_line(self, selected_line): move_quantity = move.product_uom._compute_quantity( move.product_uom_qty, line[0].product_uom_id ) - line.product_uom_qty = move_quantity + line.reserved_uom_qty = move_quantity move._recompute_state() new_move.extract_and_action_done() diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index de40df6d5a..7661786fbd 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -8,11 +8,10 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ +:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z 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 +274,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: gray; } /* line numbers */ +pre.code .ln { color: grey; } /* 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 +300,7 @@ span.pre { white-space: pre } -span.problematic, pre.problematic { +span.problematic { color: red } span.section-subtitle { @@ -369,7 +368,7 @@

Shopfloor Reception

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:2daa340b0e627a464975665796f422f9792c329d73389a28e995a4a0c11234a2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

@@ -394,7 +393,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.

@@ -412,20 +411,19 @@

Contributors

  • Juan Miguel Sánchez Arce <juan.sanchez@camptocamp.com>
  • Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
  • Michael Tietz (MT Software) <mtietz@mt-software.de>
  • +
  • Souheil Bejaoui <souheil.bejaoui@acsone.eu>
  • 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 maintainers:

    mmequignon JuMiSanAr

    -

    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/tests/common.py b/shopfloor_reception/tests/common.py index 56e812ddb0..90bd62e323 100644 --- a/shopfloor_reception/tests/common.py +++ b/shopfloor_reception/tests/common.py @@ -1,6 +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 @@ -23,7 +23,7 @@ def _create_lot(cls, **kwargs): "company_id": cls.env.company.id, } vals.update(kwargs) - return cls.env["stock.production.lot"].create(vals) + return cls.env["stock.lot"].create(vals) @classmethod def _add_package(cls, picking): @@ -67,7 +67,7 @@ def _data_for_pickings_with_line(self, pickings): def _data_for_picking_with_moves(self, picking, with_progress=True): picking_data = self._data_for_picking(picking, with_progress) - moves_data = self._data_for_moves(picking.move_lines) + moves_data = self._data_for_moves(picking.move_ids) picking_data.update({"moves": moves_data}) return picking_data diff --git a/shopfloor_reception/tests/reception_return_common.py b/shopfloor_reception/tests/reception_return_common.py index b9bddd096d..742d4a32d9 100644 --- a/shopfloor_reception/tests/reception_return_common.py +++ b/shopfloor_reception/tests/reception_return_common.py @@ -13,6 +13,7 @@ def setUpClass(cls): super().setUpClass() # In order to have the `picking_type_reception_demo` picking_type # on returned pickings and moves + cls.stock_manager = cls.env.ref("stock.group_stock_manager").users[0] cls.reception_type = cls.env.ref( "shopfloor_reception.picking_type_reception_demo" ) @@ -74,7 +75,7 @@ def _add_package_to_order(cls, order): for line in order.order_line: product = line.product_id packaging = packagings.filtered(lambda p: p.product_id == product) - line.product_packaging = packaging + line.product_packaging_id = packaging @classmethod def deliver(cls, pickings): @@ -85,7 +86,7 @@ def deliver(cls, pickings): if not ready_picking: break for line in ready_picking.move_line_ids: - line.qty_done = line.product_qty + line.qty_done = line.reserved_uom_qty ready_picking._action_done() @classmethod @@ -95,7 +96,9 @@ def partial_deliver(cls, picking, qty_done): if not action_data or action_data is True: return picking.browse() backorder_wizard = Form( - cls.env["stock.backorder.confirmation"].with_context(action_data["context"]) + cls.env["stock.backorder.confirmation"].with_context( + **action_data["context"] + ) ).save() backorder_wizard.process() return cls.env["stock.picking"].search([("backorder_id", "=", picking.id)]) @@ -141,7 +144,9 @@ def _add_stock_to_product(cls, product, location, qty): "location_id": location.id, "inventory_quantity": qty, } - cls.env["stock.quant"].sudo().with_context(inventory_mode=True).create(values) + cls.env["stock.quant"].with_user(cls.stock_manager).with_context( + inventory_mode=True + ).create(values)._apply_inventory() cls.cache_existing_record_ids() @classmethod diff --git a/shopfloor_reception/tests/test_return_reception_done.py b/shopfloor_reception/tests/test_return_reception_done.py index 895a7ca7f7..ee44be8f45 100644 --- a/shopfloor_reception/tests/test_return_reception_done.py +++ b/shopfloor_reception/tests/test_return_reception_done.py @@ -57,7 +57,7 @@ def test_set_done_full_qty_done(self): ) def test_set_done_partial_qty_done(self): - self.assertEqual(self.selected_move_line.product_uom_qty, 20.0) + self.assertEqual(self.selected_move_line.reserved_uom_qty, 20.0) self._set_quantity_done(qty_done=10.0) response = self._dispatch() # As this is a return created by the app, no backorder is created, @@ -85,7 +85,7 @@ def test_set_done_partial_qty_done(self): ) selected_line_2 = self.get_new_move_lines() # Ensure that the max qty to return is 10.0 - self.assertEqual(selected_line_2.product_uom_qty, 10.0) + self.assertEqual(selected_line_2.reserved_uom_qty, 10.0) # Set qty done == 10.0 params = { "picking_id": return_picking_2.id, diff --git a/shopfloor_reception/tests/test_return_scan_document.py b/shopfloor_reception/tests/test_return_scan_document.py index bab1a66f0e..dc086447c7 100644 --- a/shopfloor_reception/tests/test_return_scan_document.py +++ b/shopfloor_reception/tests/test_return_scan_document.py @@ -102,7 +102,7 @@ def test_scan_partial_delivered_order(self): self._enable_allow_return() delivery = self.create_delivery() backorder = self.partial_deliver(delivery, 10) - self.assertEqual(backorder.move_lines.product_qty, 10) + self.assertEqual(backorder.move_ids.product_qty, 10) response = self.service.dispatch( "scan_document", params={"barcode": self.order.name} ) diff --git a/shopfloor_reception/tests/test_select_dest_package.py b/shopfloor_reception/tests/test_select_dest_package.py index 672692ab8e..c2cd05052b 100644 --- a/shopfloor_reception/tests/test_select_dest_package.py +++ b/shopfloor_reception/tests/test_select_dest_package.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from .common import CommonCase @@ -9,12 +9,7 @@ class TestSelectDestPackage(CommonCase): def setUpClassBaseData(cls): super().setUpClassBaseData() package_model = cls.env["stock.quant.package"] - cls.package = package_model.create( - { - "name": "FOO", - "packaging_id": cls.product_a_packaging.id, - } - ) + cls.package = package_model.create({"name": "FOO"}) cls.input_sublocation = ( cls.env["stock.location"] .sudo() diff --git a/shopfloor_reception/tests/test_select_document.py b/shopfloor_reception/tests/test_select_document.py index 58ba78d12f..8ab5386a0b 100644 --- a/shopfloor_reception/tests/test_select_document.py +++ b/shopfloor_reception/tests/test_select_document.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from freezegun import freeze_time from odoo import fields diff --git a/shopfloor_reception/tests/test_select_move.py b/shopfloor_reception/tests/test_select_move.py index 091ae3f60c..5e9b9cf153 100644 --- a/shopfloor_reception/tests/test_select_move.py +++ b/shopfloor_reception/tests/test_select_move.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from odoo import fields from .common import CommonCase @@ -200,7 +200,7 @@ def test_create_new_line_none_available(self): # If there's already a move line for a given incoming move, # we assigned the whole move's product_uom_qty to it. # The reason for that is that when recomputing states for a given move - # if sum(move.move_line_ids.product_uom_qty) != move.product_uom_qty, + # if sum(move.move_line_ids.reserved_uom_qty) != move.product_uom_qty, # then it's state won't be assigned. # For instance: # - user 1 selects line1 @@ -236,7 +236,7 @@ def test_create_new_line_none_available(self): self.assertEqual(len(picking.move_line_ids), 3) created_line = picking.move_line_ids[2] # And its product_uom_qty is 0 - self.assertEqual(created_line.product_uom_qty, 0.0) + self.assertEqual(created_line.reserved_uom_qty, 0.0) self.assertEqual(created_line.shopfloor_user_id.id, self.env.uid) def test_done_action(self): @@ -252,7 +252,7 @@ def test_done_action(self): ) for line in picking.move_line_ids: - line.qty_done = line.product_uom_qty + line.qty_done = line.reserved_uom_qty lot = (self._create_lot(product_id=line.product_id.id),) line.lot_id = lot # Ask for confirmation to mark the package as done. @@ -296,7 +296,7 @@ def test_done_action(self): def test_manual_select_move(self): picking = self._create_picking() - selected_move = picking.move_lines.filtered( + selected_move = picking.move_ids.filtered( lambda m: m.product_id == self.product_a ) response = self.service.dispatch( diff --git a/shopfloor_reception/tests/test_set_destination.py b/shopfloor_reception/tests/test_set_destination.py index 802f6d4b02..2c730360ce 100644 --- a/shopfloor_reception/tests/test_set_destination.py +++ b/shopfloor_reception/tests/test_set_destination.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from .common import CommonCase @@ -148,7 +148,7 @@ def test_auto_posting(self): line_in_picking = picking.move_line_ids.filtered( lambda l: l.product_id == selected_move_line.product_id ) - self.assertEqual(line_in_picking.product_uom_qty, 7) + self.assertEqual(line_in_picking.reserved_uom_qty, 7) self.assertEqual(line_in_picking.qty_done, 0) self.assertEqual(picking.state, "assigned") @@ -160,7 +160,7 @@ def test_auto_posting_concurent_work(self): """ self.menu.sudo().auto_post_line = True picking = self._create_picking(lines=[(self.product_a, 10)]) - move = picking.move_lines + move = picking.move_ids # User 1 starts working service_u1 = self.service res_u1 = service_u1.dispatch( diff --git a/shopfloor_reception/tests/test_set_lot.py b/shopfloor_reception/tests/test_set_lot.py index 016f023d5d..c605aa20eb 100644 --- a/shopfloor_reception/tests/test_set_lot.py +++ b/shopfloor_reception/tests/test_set_lot.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from .common import CommonCase diff --git a/shopfloor_reception/tests/test_set_lot_confirm.py b/shopfloor_reception/tests/test_set_lot_confirm.py index 21fe675814..e8d4f6efe5 100644 --- a/shopfloor_reception/tests/test_set_lot_confirm.py +++ b/shopfloor_reception/tests/test_set_lot_confirm.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from .common import CommonCase diff --git a/shopfloor_reception/tests/test_set_quantity.py b/shopfloor_reception/tests/test_set_quantity.py index 2c50385543..8cd1396200 100644 --- a/shopfloor_reception/tests/test_set_quantity.py +++ b/shopfloor_reception/tests/test_set_quantity.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from .common import CommonCase @@ -11,23 +11,10 @@ def setUpClassBaseData(cls): cls.product_a_packaging.qty = 5.0 cls.packing_location.sudo().active = True package_model = cls.env["stock.quant.package"] - cls.package_without_location = package_model.create( - { - "name": "PKG_WO_LOCATION", - "packaging_id": cls.product_a_packaging.id, - } - ) - cls.package_with_location = package_model.create( - { - "name": "PKG_W_LOCATION", - "packaging_id": cls.product_a_packaging.id, - } - ) + cls.package_without_location = package_model.create({"name": "PKG_WO_LOCATION"}) + cls.package_with_location = package_model.create({"name": "PKG_W_LOCATION"}) cls.package_with_location_child_of_dest = package_model.create( - { - "name": "PKG_W_LOCATION_CHILD", - "packaging_id": cls.product_a_packaging.id, - } + {"name": "PKG_W_LOCATION_CHILD"} ) cls._update_qty_in_location( cls.packing_location, cls.product_a, 10, package=cls.package_with_location @@ -455,7 +442,7 @@ def test_concurrent_update(self): self.assertEqual(len(selected_move_line), 1) self.assertEqual(selected_move_line.qty_done, 1.0) self.assertEqual( - selected_move_line.product_uom_qty, + selected_move_line.reserved_uom_qty, selected_move_line.move_id.product_uom_qty, ) @@ -471,7 +458,7 @@ def test_concurrent_update(self): }, ) self.assertEqual(selected_move_line.qty_done, 5.0) - self.assertEqual(selected_move_line.product_uom_qty, 10.0) + self.assertEqual(selected_move_line.reserved_uom_qty, 10.0) # Now, concurrently pick products with another user for the same move manager_user = self.shopfloor_manager @@ -487,7 +474,7 @@ def test_concurrent_update(self): lambda l: l.product_id == self.product_a and l.shopfloor_user_id == manager_user ) - self.assertEqual(new_line.product_uom_qty, 0.0) + self.assertEqual(new_line.reserved_uom_qty, 0.0) move_lines = selected_move_line | new_line line_service_mapping = [ @@ -519,15 +506,15 @@ def test_concurrent_update(self): self.assertEqual(lines_qty_done, 10.0) self.assertEqual(lines_qty_done, move_lines.move_id.quantity_done) - # However, product_uom_qty hasn't changed - self.assertEqual(selected_move_line.product_uom_qty, 10.0) - self.assertEqual(new_line.product_uom_qty, 0.0) - # And what's important is that the sum of lines's product_uom_qty is + # However, reserved_uom_qty hasn't changed + self.assertEqual(selected_move_line.reserved_uom_qty, 10.0) + self.assertEqual(new_line.reserved_uom_qty, 0.0) + # And what's important is that the sum of lines's reserved_uom_qty is # always == move's product_uom_qty - self.assertEqual(sum(move_lines.mapped("product_uom_qty")), 10.0) + self.assertEqual(sum(move_lines.mapped("reserved_uom_qty")), 10.0) # However, if we pick more than move's product_uom_qty, then lines - # product_uom_qty isn't updated, in order to be able to display an error + # reserved_uom_qty isn't updated, in order to be able to display an error # in the frontend for __ in range(2): @@ -576,8 +563,8 @@ def test_concurrent_update(self): message=error_msg, ) - # But line's product_uom_qty hasn't changed and is still 10.0 - self.assertEqual(sum(move_lines.mapped("product_uom_qty")), 10.0) + # But line's reserved_uom_qty hasn't changed and is still 10.0 + self.assertEqual(sum(move_lines.mapped("reserved_uom_qty")), 10.0) # If we lower by 2 the first move qty done, qty_todo will be updated correctly self.service.dispatch( @@ -593,9 +580,9 @@ def test_concurrent_update(self): self.assertEqual(selected_move_line.qty_done, 3.0) self.assertEqual(new_line.qty_done, 7.0) - self.assertEqual(selected_move_line.product_uom_qty, 10.0) - self.assertEqual(new_line.product_uom_qty, 0.0) - self.assertEqual(sum(move_lines.mapped("product_uom_qty")), 10.0) + self.assertEqual(selected_move_line.reserved_uom_qty, 10.0) + self.assertEqual(new_line.reserved_uom_qty, 0.0) + self.assertEqual(sum(move_lines.mapped("reserved_uom_qty")), 10.0) # And everything's fine on the move move = move_lines.move_id @@ -661,7 +648,7 @@ def test_concurrent_update_2(self): # Creating the picking, selecting the move line. picking = self._create_picking() - move = picking.move_lines.filtered(lambda l: l.product_id == self.product_a) + move = picking.move_ids.filtered(lambda l: l.product_id == self.product_a) service_user_1 = self.service service_user_1.dispatch("scan_document", params={"barcode": picking.name}) service_user_1.dispatch( @@ -671,7 +658,7 @@ def test_concurrent_update_2(self): move_line_user_1 = move.move_line_ids # The only move line should have qty_done = 1 self.assertEqual(move_line_user_1.qty_done, 1.0) - self.assertEqual(move_line_user_1.product_uom_qty, 10.0) + self.assertEqual(move_line_user_1.reserved_uom_qty, 10.0) # Now, concurrently pick products with another user for the same move manager_user = self.shopfloor_manager @@ -687,7 +674,7 @@ def test_concurrent_update_2(self): lambda l: l.product_id == self.product_a and l.shopfloor_user_id == manager_user ) - self.assertEqual(move_line_user_2.product_uom_qty, 0.0) + self.assertEqual(move_line_user_2.reserved_uom_qty, 0.0) self.assertEqual(move_line_user_2.qty_done, 1.0) # At this point, both lines are referencing the same move @@ -735,15 +722,15 @@ def test_concurrent_update_2(self): # As well as the new one self.assertEqual(len(lines_after), 1) # The quantity to do is set on 1 of the lines - self.assertEqual(lines_after.product_uom_qty, 0) - self.assertEqual(move_line_user_2.product_uom_qty, 9) + self.assertEqual(lines_after.reserved_uom_qty, 0) + self.assertEqual(move_line_user_2.reserved_uom_qty, 9) def test_move_states(self): # as only assigned moves can be posted, we need to ensure that # we got the right states in any case, especially when users are working # concurrently picking = self._create_picking() - move_product_a = picking.move_lines.filtered( + move_product_a = picking.move_ids.filtered( lambda l: l.product_id == self.product_a ) # user1 processes 10 units @@ -828,8 +815,8 @@ def test_move_states(self): "location_name": self.dispatch_location.name, }, ) - # When posted, the move line product_uom_qty has been set to qty_done - self.assertEqual(move_line_user_2.qty_done, move_line_user_2.product_qty) + # When posted, the move line reserved_uom_qty has been set to qty_done + self.assertEqual(move_line_user_2.qty_done, move_line_user_2.reserved_uom_qty) self.assert_response( response, next_state="select_move", data=self._data_for_select_move(picking) ) diff --git a/shopfloor_reception/tests/test_set_quantity_action.py b/shopfloor_reception/tests/test_set_quantity_action.py index 8881e64a5f..a7bf4b4b89 100644 --- a/shopfloor_reception/tests/test_set_quantity_action.py +++ b/shopfloor_reception/tests/test_set_quantity_action.py @@ -1,6 +1,6 @@ # Copyright 2022 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - +# pylint: disable=missing-return from .common import CommonCase @@ -14,12 +14,7 @@ def setUpClassBaseData(cls): ) def test_process_with_existing_package(self): - package = self.env["stock.quant.package"].create( - { - "name": "FOO", - "packaging_id": self.product_a_packaging.id, - } - ) + package = self.env["stock.quant.package"].create({"name": "FOO"}) self.selected_move_line.result_package_id = package response = self.service.dispatch( "process_with_existing_pack", @@ -87,7 +82,7 @@ def test_process_without_package(self): def test_cancel_action(self): picking = self._create_picking() - move_product_a = picking.move_lines.filtered( + move_product_a = picking.move_ids.filtered( lambda l: l.product_id == self.product_a ) # User 1 and 2 selects the same picking @@ -163,7 +158,7 @@ def test_cancel_action(self): self.assertTrue(move_line_user_1.exists()) self.assertFalse(move_line_user_1.shopfloor_user_id) self.assertEqual(move_line_user_1.qty_done, 0) - self.assertEqual(move_line_user_1.product_uom_qty, 10) + self.assertEqual(move_line_user_1.reserved_uom_qty, 10) # make user cancel service_user_2.dispatch( "set_quantity__cancel_action",