diff --git a/stock_move_location/README.rst b/stock_move_location/README.rst
index 197dc5ffd..78619f4c5 100644
--- a/stock_move_location/README.rst
+++ b/stock_move_location/README.rst
@@ -62,8 +62,8 @@ If you want to transfer a full quant:
- Select the quantities which you want move to another location
If you go to the Inventory Dashboard you can see the button "Move from
-location" in each of the picking types (only applicable to internal
-transfers). Press it and you will be directed to the wizard.
+location" in each of the picking types (only applicable to internal and
+outgoing transfers). Press it and you will be directed to the wizard.
|image1|
@@ -143,6 +143,8 @@ Contributors
- Aung Ko Ko Lin
+- Laurent Mignon
+
Maintainers
-----------
diff --git a/stock_move_location/readme/CONTRIBUTORS.md b/stock_move_location/readme/CONTRIBUTORS.md
index fece6339c..7bb7732a3 100644
--- a/stock_move_location/readme/CONTRIBUTORS.md
+++ b/stock_move_location/readme/CONTRIBUTORS.md
@@ -13,3 +13,4 @@
- Abraham Anes \<\>
- Quartile \<\>
- Aung Ko Ko Lin
+- Laurent Mignon \<\>
diff --git a/stock_move_location/readme/USAGE.md b/stock_move_location/readme/USAGE.md
index a772a0a56..a61d944cb 100644
--- a/stock_move_location/readme/USAGE.md
+++ b/stock_move_location/readme/USAGE.md
@@ -1,43 +1,37 @@
-- A new menu item Operations \> Move from location... opens a wizard
- where 2 locations can be specified.
-- Select origin and destination locations and press "IMMEDIATE TRANSFER"
- or "PLANNED TRANSFER"
+- A new menu item Operations \> Move from location... opens a wizard where 2 locations
+ can be specified.
+- Select origin and destination locations and press "IMMEDIATE TRANSFER" or "PLANNED
+ TRANSFER"
- Press ADD ALL button to add all products available
-- Those lines can be edited. Move quantity can't be more than a max
- available quantity
+- Those lines can be edited. Move quantity can't be more than a max available quantity
- Move doesn't care about the reservations and will move stuff anyway
-- If during your operation with the wizard the real quantity will change
- it will move only the available quantity at the button press
-- Products will be moved and a form view of picking that did that will
- show up
-- If "PLANNED TRANSFER" is used - the picking won't be validated
- automatically
+- If during your operation with the wizard the real quantity will change it will move
+ only the available quantity at the button press
+- Products will be moved and a form view of picking that did that will show up
+- If "PLANNED TRANSFER" is used - the picking won't be validated automatically
If you want to transfer a full quant:
-- Go to Inventory \> Products \> Products and click "On hand" smart
- button or Inventory \> Reporting \> Inventory, the quants view will be
- opened.
+- Go to Inventory \> Products \> Products and click "On hand" smart button or Inventory
+ \> Reporting \> Inventory, the quants view will be opened.
- Select the quantities which you want move to another location
-If you go to the Inventory Dashboard you can see the button "Move from
-location" in each of the picking types (only applicable to internal
-transfers). Press it and you will be directed to the wizard.
+If you go to the Inventory Dashboard you can see the button "Move from location" in each
+of the picking types (only applicable to internal and outgoing transfers). Press it and
+you will be directed to the wizard.

-To enable this option, check "Show Move On Hand Stock" in the Picking Type configuration.
+To enable this option, check "Show Move On Hand Stock" in the Picking Type
+configuration.

If you want transfer everything from stock.location
-On a draft picking, add a button to fill with moves lines for all
-products in the source destination. This allows to create a picking to
-move all the content of a location. The Origin Location must have stock.
-The Destination Location has to be a final location.
-If some quants are not available
-(i.e. reserved) the picking will be in partially available state and
-reserved moves won't be listed in the operations. Use barcode interface
-to scan a location and create an empty picking. Then use the fill with
-stock button.
+On a draft picking, add a button to fill with moves lines for all products in the source
+destination. This allows to create a picking to move all the content of a location. The
+Origin Location must have stock. The Destination Location has to be a final location. If
+some quants are not available (i.e. reserved) the picking will be in partially available
+state and reserved moves won't be listed in the operations. Use barcode interface to
+scan a location and create an empty picking. Then use the fill with stock button.
diff --git a/stock_move_location/static/description/index.html b/stock_move_location/static/description/index.html
index bcd253d49..6a5f342df 100644
--- a/stock_move_location/static/description/index.html
+++ b/stock_move_location/static/description/index.html
@@ -412,8 +412,8 @@ opened.
Select the quantities which you want move to another location
If you go to the Inventory Dashboard you can see the button “Move from
-location” in each of the picking types (only applicable to internal
-transfers). Press it and you will be directed to the wizard.
+location” in each of the picking types (only applicable to internal and
+outgoing transfers). Press it and you will be directed to the wizard.
To enable this option, check “Show Move On Hand Stock” in the Picking
Type configuration.
@@ -483,6 +483,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
diff --git a/stock_move_location/tests/test_common.py b/stock_move_location/tests/test_common.py
index e476f7281..761cd07ce 100644
--- a/stock_move_location/tests/test_common.py
+++ b/stock_move_location/tests/test_common.py
@@ -92,46 +92,49 @@ class TestsCommon(common.TransactionCase):
)
cls.package = cls.env["stock.quant.package"].create({})
cls.package1 = cls.env["stock.quant.package"].create({})
+
cls.package2 = cls.env["stock.quant.package"].create({})
- def setup_product_amounts(self):
- self.set_product_amount(self.product_no_lots, self.internal_loc_1, 123)
- self.set_product_amount(
- self.product_lots, self.internal_loc_1, 1.0, lot_id=self.lot1
+ @classmethod
+ def setup_product_amounts(cls):
+ cls.set_product_amount(cls.product_no_lots, cls.internal_loc_1, 123)
+ cls.set_product_amount(
+ cls.product_lots, cls.internal_loc_1, 1.0, lot_id=cls.lot1
)
- self.set_product_amount(
- self.product_lots, self.internal_loc_1, 1.0, lot_id=self.lot2
+ cls.set_product_amount(
+ cls.product_lots, cls.internal_loc_1, 1.0, lot_id=cls.lot2
)
- self.set_product_amount(
- self.product_lots, self.internal_loc_1, 1.0, lot_id=self.lot3
+ cls.set_product_amount(
+ cls.product_lots, cls.internal_loc_1, 1.0, lot_id=cls.lot3
)
- self.set_product_amount(
- self.product_package,
- self.internal_loc_1,
+ cls.set_product_amount(
+ cls.product_package,
+ cls.internal_loc_1,
1.0,
- lot_id=self.lot4,
- package_id=self.package,
+ lot_id=cls.lot4,
+ package_id=cls.package,
)
- self.set_product_amount(
- self.product_package,
- self.internal_loc_1,
+ cls.set_product_amount(
+ cls.product_package,
+ cls.internal_loc_1,
1.0,
- lot_id=self.lot4,
- package_id=self.package1,
+ lot_id=cls.lot4,
+ package_id=cls.package1,
)
- self.set_product_amount(
- self.product_package,
- self.internal_loc_1,
+ cls.set_product_amount(
+ cls.product_package,
+ cls.internal_loc_1,
1.0,
- lot_id=self.lot5,
- package_id=self.package2,
- owner_id=self.partner,
+ lot_id=cls.lot5,
+ package_id=cls.package2,
+ owner_id=cls.partner,
)
+ @classmethod
def set_product_amount(
- self, product, location, amount, lot_id=None, package_id=None, owner_id=None
+ cls, product, location, amount, lot_id=None, package_id=None, owner_id=None
):
- self.env["stock.quant"]._update_available_quantity(
+ cls.env["stock.quant"]._update_available_quantity(
product,
location,
amount,
diff --git a/stock_move_location/tests/test_move_location.py b/stock_move_location/tests/test_move_location.py
index 87de962f9..0421134eb 100644
--- a/stock_move_location/tests/test_move_location.py
+++ b/stock_move_location/tests/test_move_location.py
@@ -8,9 +8,10 @@ from .test_common import TestsCommon
class TestMoveLocation(TestsCommon):
- def setUp(self):
- super().setUp()
- self.setup_product_amounts()
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.setup_product_amounts()
def test_move_location_wizard(self):
"""Test a simple move."""
diff --git a/stock_move_location/views/stock_picking_type_views.xml b/stock_move_location/views/stock_picking_type_views.xml
index ed0a6d6db..1f3045b74 100644
--- a/stock_move_location/views/stock_picking_type_views.xml
+++ b/stock_move_location/views/stock_picking_type_views.xml
@@ -8,7 +8,7 @@
diff --git a/stock_move_location/wizard/stock_move_location.py b/stock_move_location/wizard/stock_move_location.py
index ac2854f99..e04201e1d 100644
--- a/stock_move_location/wizard/stock_move_location.py
+++ b/stock_move_location/wizard/stock_move_location.py
@@ -71,7 +71,7 @@ class StockMoveLocationWizard(models.TransientModel):
for rec in self:
picking_type = self.env["stock.picking.type"]
base_domain = [
- ("code", "=", "internal"),
+ ("code", "in", ("internal", "outgoing")),
("warehouse_id.company_id", "=", company_id),
]
if rec.origin_location_id:
@@ -303,25 +303,32 @@ class StockMoveLocationWizard(models.TransientModel):
)
return action
+ def _get_quants_domain(self):
+ return [("location_id", "=", self.origin_location_id.id)]
+
def _get_group_quants(self):
- location_id = self.origin_location_id
- # Using sql as search_group doesn't support aggregation functions
- # leading to overhead in queries to DB
- query = """
- SELECT product_id, lot_id, package_id, owner_id, SUM(quantity) AS quantity,
- SUM(reserved_quantity) AS reserved_quantity
- FROM stock_quant
- WHERE location_id = %s
- GROUP BY product_id, lot_id, package_id, owner_id
- """
- self.env.cr.execute(query, (location_id.id,))
- return self.env.cr.dictfetchall()
+ domain = self._get_quants_domain()
+ result = self.env["stock.quant"].read_group(
+ domain=domain,
+ fields=[
+ "product_id",
+ "lot_id",
+ "package_id",
+ "owner_id",
+ "quantity:sum",
+ "reserved_quantity:sum",
+ ],
+ groupby=["product_id", "lot_id", "package_id", "owner_id"],
+ orderby="id",
+ lazy=False,
+ )
+ return result
def _get_stock_move_location_lines_values(self):
product_obj = self.env["product.product"]
product_data = []
for group in self._get_group_quants():
- product = product_obj.browse(group.get("product_id")).exists()
+ product = product_obj.browse(group["product_id"][0]).exists()
# Apply the putaway strategy
location_dest_id = (
self.apply_putaway_strategy
@@ -337,15 +344,33 @@ class StockMoveLocationWizard(models.TransientModel):
"origin_location_id": self.origin_location_id.id,
"destination_location_id": location_dest_id,
# cursor returns None instead of False
- "lot_id": group.get("lot_id") or False,
- "package_id": group.get("package_id") or False,
- "owner_id": group.get("owner_id") or False,
+ "lot_id": group["lot_id"][0] if group.get("lot_id") else False,
+ "package_id": group["package_id"][0]
+ if group.get("package_id")
+ else False,
+ "owner_id": group["owner_id"][0]
+ if group.get("owner_id")
+ else False,
"product_uom_id": product.uom_id.id,
"custom": False,
}
)
return product_data
+ def _reset_stock_move_location_lines(self):
+ lines = []
+ line_model = self.env["wiz.stock.move.location.line"]
+ for line_val in self._get_stock_move_location_lines_values():
+ if line_val.get("max_quantity") <= 0:
+ continue
+ line = line_model.create(line_val)
+ line.max_quantity = line.get_max_quantity()
+ line.reserved_quantity = line.reserved_quantity
+ lines.append(line)
+ self.update(
+ {"stock_move_location_line_ids": [(6, 0, [line.id for line in lines])]}
+ )
+
@api.onchange("origin_location_id")
def onchange_origin_location(self):
# Get origin_location_disable context key to prevent load all origin
@@ -355,18 +380,7 @@ class StockMoveLocationWizard(models.TransientModel):
not self.env.context.get("origin_location_disable")
and self.origin_location_id
):
- lines = []
- line_model = self.env["wiz.stock.move.location.line"]
- for line_val in self._get_stock_move_location_lines_values():
- if line_val.get("max_quantity") <= 0:
- continue
- line = line_model.create(line_val)
- line.max_quantity = line.get_max_quantity()
- line.reserved_quantity = line.reserved_quantity
- lines.append(line)
- self.update(
- {"stock_move_location_line_ids": [(6, 0, [line.id for line in lines])]}
- )
+ self._reset_stock_move_location_lines()
def clear_lines(self):
self._clear_lines()
diff --git a/stock_move_location/wizard/stock_move_location.xml b/stock_move_location/wizard/stock_move_location.xml
index 060504d38..30101eceb 100644
--- a/stock_move_location/wizard/stock_move_location.xml
+++ b/stock_move_location/wizard/stock_move_location.xml
@@ -10,18 +10,15 @@