diff --git a/CHANGELOG b/CHANGELOG
index 53c3289af6..d71e28c569 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,4 @@
+* Define one lost and found location per warehouse
* Show warehouse in user status if not unique
* Add cost price revision
* Add wizard to modify product cost price
diff --git a/doc/index.rst b/doc/index.rst
index b0dd2f95b1..f7a89f4db2 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -18,13 +18,14 @@ virtually stored. The following location types are defined:
* Warehouse
- Warehouses are meta-locations which define input, storage, picking and output
- locations. These locations are all of type Storage. Input and Output are
- locations where incoming an outgoing product are temporally stored awaiting
- transportation. The storage location is often the biggest location where
- products are stored for middle or long periods of time. The picking location
- is optionally where the products are picked by the customer shipment
- otherwise the storage location is used.
+ Warehouses are meta-locations which define input, storage, picking, output
+ and lost and found locations. These locations are all of type Storage. Input
+ and Output are locations where incoming an outgoing product are temporally
+ stored awaiting transportation. The storage location is often the biggest
+ location where products are stored for middle or long periods of time. The
+ picking location is optionally where the products are picked by the customer
+ shipment otherwise the storage location is used. The lost and found location
+ is the location used by inventories when correcting stock levels.
* Customer
@@ -261,9 +262,8 @@ of moves. It can be in one of these states:
Inventory
*********
-Inventories allow to control and update stock levels. They are mainly
-composed of two locations (a Storage location and a Lost And Found
-location), and a list of inventory lines.
+Inventories allow to control and update stock levels. They are mainly composed
+of the inventoried storage location and a list of inventory lines.
Inventory lines consist of a product and it's default unit of measure, an
expected quantity and the real quantity (the real products on the shelves).
diff --git a/inventory.py b/inventory.py
index 4ddaf8ba41..1713a24930 100644
--- a/inventory.py
+++ b/inventory.py
@@ -37,11 +37,6 @@ class Inventory(Workflow, ModelSQL, ModelView):
},
depends=['state'],
help="The date of the stock count.")
- lost_found = fields.Many2One(
- 'stock.location', 'Lost and Found', required=True,
- domain=[('type', '=', 'lost_found')], states=_states, depends=_depends,
- help="Used for the balancing entries needed when the stock is "
- "corrected.")
lines = fields.One2Many(
'stock.inventory.line', 'inventory', 'Lines',
states={
@@ -106,6 +101,9 @@ class Inventory(Workflow, ModelSQL, ModelView):
# Add index on create_date
table.index_action('create_date', action='add')
+ # Migration from 5.4: remove lost_found
+ table.not_null_action('lost_found', 'remove')
+
@staticmethod
def default_state():
return 'draft'
@@ -119,13 +117,6 @@ class Inventory(Workflow, ModelSQL, ModelView):
def default_company():
return Transaction().context.get('company')
- @classmethod
- def default_lost_found(cls):
- Location = Pool().get('stock.location')
- locations = Location.search(cls.lost_found.domain)
- if len(locations) == 1:
- return locations[0].id
-
@classmethod
def view_attributes(cls):
return [
@@ -446,7 +437,12 @@ class InventoryLine(ModelSQL, ModelView):
if delta_qty == 0.0:
return
from_location = self.inventory.location
- to_location = self.inventory.lost_found
+ to_location = self.inventory.location.lost_found_used
+ if not to_location:
+ raise InventoryValidationError(
+ gettext('stock.msg_inventory_location_missing_lost_found',
+ inventory=self.inventory.rec_name,
+ location=self.inventory.location.rec_name))
if delta_qty < 0:
(from_location, to_location, delta_qty) = \
(to_location, from_location, -delta_qty)
diff --git a/location.py b/location.py
index 6768952d42..aee68eb76d 100644
--- a/location.py
+++ b/location.py
@@ -112,6 +112,18 @@ class Location(DeactivableMixin, tree(), ModelSQL, ModelView):
depends=['type', 'storage_location'],
help="Where stock is picked from.\n"
"Leave empty to use the storage location.")
+ lost_found_location = fields.Many2One(
+ 'stock.location', "Lost and Found",
+ states={
+ 'invisible': Eval('type') != 'warehouse',
+ 'readonly': ~Eval('active'),
+ },
+ domain=[
+ ('type', '=', 'lost_found'),
+ ],
+ depends=['type', 'active'],
+ help="Used, by inventories, when correcting stock levels "
+ "in the warehouse.")
quantity = fields.Function(
fields.Float('Quantity',
help="The amount of stock in the location."),
@@ -304,6 +316,11 @@ class Location(DeactivableMixin, tree(), ModelSQL, ModelView):
cls._default_warehouse_cache.set(None, warehouse)
return warehouse
+ @property
+ def lost_found_used(self):
+ if self.warehouse:
+ return self.warehouse.lost_found_location
+
@classmethod
def search_rec_name(cls, name, clause):
if clause[1].startswith('!') or clause[1].startswith('not '):
diff --git a/location.xml b/location.xml
index 9e8a91563d..e60ad7c2f9 100644
--- a/location.xml
+++ b/location.xml
@@ -194,6 +194,10 @@ this repository contains the full copyright notices and license terms. -->
STOstorage
+
+ Lost and Found
+ lost_found
+ WarehouseWH
@@ -201,6 +205,7 @@ this repository contains the full copyright notices and license terms. -->
+ Supplier
@@ -212,10 +217,6 @@ this repository contains the full copyright notices and license terms. -->
CUScustomer
-
- Lost and Found
- lost_found
- Transitstorage
diff --git a/message.xml b/message.xml
index 423ba029b2..ff6d8fa822 100644
--- a/message.xml
+++ b/message.xml
@@ -41,6 +41,9 @@ because the type does not support moves and location has existing moves.
To confirm the inventory "%(inventory)s" you must select an option for empty quantity.
+
+ To confirm the inventory "%(inventory)s" you must set a lost and found on a parent of location "%(location)s".
+ Inventory line "%(line)s" is not unique on inventory "%(inventory)s".
diff --git a/tests/scenario_stock_inventory.rst b/tests/scenario_stock_inventory.rst
index 4a0773ff0f..0c809a0f24 100644
--- a/tests/scenario_stock_inventory.rst
+++ b/tests/scenario_stock_inventory.rst
@@ -28,6 +28,7 @@ Get stock locations::
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
>>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> lost_found_loc, = Location.find([('type', '=', 'lost_found')])
Create products::
@@ -170,7 +171,7 @@ Confirm the inventory::
>>> move, = line_p1.moves
>>> move.quantity
1.0
- >>> move.from_location == inventory.lost_found
+ >>> move.from_location == lost_found_loc
True
>>> move.to_location == inventory.location
True
@@ -230,7 +231,7 @@ Add quantity of consumable product::
>>> move, = line.moves
>>> move.quantity
5.0
- >>> move.from_location == inventory.lost_found
+ >>> move.from_location == lost_found_loc
True
>>> move.to_location == inventory.location
True
diff --git a/tests/scenario_stock_inventory_empty_quantity.rst b/tests/scenario_stock_inventory_empty_quantity.rst
index efd941e450..ab1f8e40b6 100644
--- a/tests/scenario_stock_inventory_empty_quantity.rst
+++ b/tests/scenario_stock_inventory_empty_quantity.rst
@@ -28,6 +28,7 @@ Get stock locations::
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
>>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> lost_found_loc, = Location.find([('type', '=', 'lost_found')])
Create product::
@@ -83,5 +84,5 @@ Creating an inventory with empty quantities creates and empty move::
1.0
>>> move.from_location == inventory.location
True
- >>> move.to_location == inventory.lost_found
+ >>> move.to_location == lost_found_loc
True
diff --git a/view/inventory_form.xml b/view/inventory_form.xml
index 3dae6e5f2f..b4d7daa110 100644
--- a/view/inventory_form.xml
+++ b/view/inventory_form.xml
@@ -6,15 +6,17 @@ this repository contains the full copyright notices and license terms. -->
+
-
-
+
+
+
diff --git a/view/location_form.xml b/view/location_form.xml
index db027f81d2..c2571b96cc 100644
--- a/view/location_form.xml
+++ b/view/location_form.xml
@@ -28,5 +28,10 @@ this repository contains the full copyright notices and license terms. -->
+
+
+
+
+