From 42595dcce01517855129a50cde04f0cc5ac0200b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 10 May 2018 20:19:23 +0200 Subject: [PATCH] Manage same input and storage location in customer return shipment issue7401 review51261002 --- CHANGELOG | 2 + shipment.py | 22 ++++- ...shipment_out_return_same_storage_input.rst | 85 +++++++++++++++++++ tests/test_stock.py | 5 ++ view/shipment_out_return_form.xml | 4 +- 5 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 tests/scenario_stock_shipment_out_return_same_storage_input.rst diff --git a/CHANGELOG b/CHANGELOG index 866190d89a..362627d6c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Manage same input and storage location in customer return shipment + Version 4.8.0 - 2018-04-23 * Bug fixes (see mercurial logs for details) * Add _stock_move_split context keyword when copying move for split diff --git a/shipment.py b/shipment.py index c745c2d782..f72144f94d 100644 --- a/shipment.py +++ b/shipment.py @@ -1547,7 +1547,10 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): 'Incoming Moves', domain=[ ('from_location', '=', Eval('customer_location')), - ('to_location', '=', Eval('warehouse_input')), + If(Eval('warehouse_input') == Eval('warehouse_storage'), + ('to_location', 'child_of', + [Eval('warehouse_input', -1)], 'parent'), + ('to_location', '=', Eval('warehouse_input'))), ('company', '=', Eval('company')), ], states={ @@ -1555,7 +1558,7 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): | ~Eval('warehouse') | ~Eval('customer')), }, depends=['state', 'warehouse', 'customer', 'customer_location', - 'warehouse_input', 'company']), + 'warehouse_input', 'warehouse_storage', 'company']), 'get_incoming_moves', setter='set_incoming_moves') inventory_moves = fields.Function(fields.One2Many('stock.move', 'shipment', 'Inventory Moves', @@ -1569,9 +1572,11 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): ], states={ 'readonly': Eval('state').in_(['draft', 'cancel', 'done']), + 'invisible': ( + Eval('warehouse_input') == Eval('warehouse_storage')), }, depends=['state', 'warehouse', 'warehouse_input', - 'warehouse_storage', 'company']), + 'warehouse_storage', 'warehouse_input', 'company']), 'get_inventory_moves', setter='set_inventory_moves') moves = fields.One2Many('stock.move', 'shipment', 'Moves', domain=[('company', '=', Eval('company'))], depends=['company'], @@ -1724,6 +1729,8 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): def get_incoming_moves(self, name): moves = [] + if self.warehouse_input == self.warehouse_storage: + return [m.id for m in self.moves] for move in self.moves: if move.to_location == self.warehouse_input: moves.append(move.id) @@ -1844,6 +1851,12 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): Move = Pool().get('stock.move') Move.do([m for s in shipments for m in s.incoming_moves]) cls.create_inventory_moves(shipments) + # Set received state to allow done transition + cls.write(shipments, {'state': 'received'}) + to_do = [s for s in shipments + if s.warehouse_storage == s.warehouse_input] + if to_do: + cls.done(to_do) @classmethod @ModelView.button @@ -1888,6 +1901,9 @@ class ShipmentOutReturn(Workflow, ModelSQL, ModelView): @classmethod def create_inventory_moves(cls, shipments): for shipment in shipments: + if shipment.warehouse_storage == shipment.warehouse_input: + # Do not create inventory moves + continue # Use moves instead of inventory_moves because save reset before # adding new records and as set_inventory_moves is just a proxy to # moves, it will reset also the incoming_moves diff --git a/tests/scenario_stock_shipment_out_return_same_storage_input.rst b/tests/scenario_stock_shipment_out_return_same_storage_input.rst new file mode 100644 index 0000000000..329e06c420 --- /dev/null +++ b/tests/scenario_stock_shipment_out_return_same_storage_input.rst @@ -0,0 +1,85 @@ +========================================================= +Stock Shipment Out Return Same Storage and Input Scenario +========================================================= + +Imports:: + + >>> from decimal import Decimal + >>> from proteus import Model + >>> from trytond.tests.tools import activate_modules + >>> from trytond.modules.company.tests.tools import create_company, \ + ... get_company + +Install stock Module:: + + >>> config = activate_modules('stock') + +Create company:: + + >>> _ = create_company() + >>> company = get_company() + +Create customer:: + + >>> Party = Model.get('party.party') + >>> customer = Party(name='Customer') + >>> customer.save() + +Create product:: + + >>> ProductUom = Model.get('product.uom') + >>> ProductTemplate = Model.get('product.template') + >>> Product = Model.get('product.product') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> template = ProductTemplate() + >>> template.name = 'Product' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.list_price = Decimal('20') + >>> template.save() + >>> product, = template.products + +Get stock locations:: + + >>> Location = Model.get('stock.location') + >>> warehouse_loc, = Location.find([('code', '=', 'WH')]) + >>> customer_loc, = Location.find([('code', '=', 'CUS')]) + >>> storage_loc, = Location.find([('code', '=', 'STO')]) + >>> storage1 = Location(name="Storage 1", parent=storage_loc) + >>> storage1.save() + +Use storage location as input location:: + + >>> warehouse_loc.input_location = storage_loc + >>> warehouse_loc.save() + +Create Shipment Out Return:: + + >>> ShipmentOutReturn = Model.get('stock.shipment.out.return') + >>> shipment = ShipmentOutReturn() + >>> shipment.customer = customer + >>> shipment.warehouse = warehouse_loc + >>> shipment.company = company + >>> move = shipment.incoming_moves.new() + >>> move.product = product + >>> move.uom = unit + >>> move.quantity = 1 + >>> move.from_location = customer_loc + >>> move.to_location = storage1 + >>> shipment.save() + + >>> len(shipment.incoming_moves) + 1 + >>> len(shipment.inventory_moves) + 0 + +Shipment is done when receiving:: + + >>> shipment.click('receive') + >>> shipment.state + u'done' + >>> move, = shipment.incoming_moves + >>> move.state + u'done' + >>> len(shipment.inventory_moves) + 0 diff --git a/tests/test_stock.py b/tests/test_stock.py index d89d3ae819..2696ef713d 100644 --- a/tests/test_stock.py +++ b/tests/test_stock.py @@ -1309,4 +1309,9 @@ def suite(): tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite( + 'scenario_stock_shipment_out_return_same_storage_input.rst', + tearDown=doctest_teardown, encoding='utf-8', + checker=doctest_checker, + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) return suite diff --git a/view/shipment_out_return_form.xml b/view/shipment_out_return_form.xml index 82c6f63050..0a1a1ddbbf 100644 --- a/view/shipment_out_return_form.xml +++ b/view/shipment_out_return_form.xml @@ -19,10 +19,10 @@ this repository contains the full copyright notices and license terms. -->