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