[FIX] stock: auto batch of internal transfers

Steps to reproduce the bug:
- Enable “batch transfers” in the inventory settings
- Create a new warehouse “WH2”:
    - Enable “Resupply From” option
    - Enable “3steps”

- Go to the operation type “internal transfers” of WH2:
    - Enable “Automatic Batches”
        - “Destination Location”

- Create two storable product “P1” and “P2”:
    - Route: warehouse # 2: Supply Product from YourCompany
    - update the Qty to 10 in wh/stock

- Create a replenishment for “P1” and “p2”:
    - Location: WH2/stock
    - Preferred route: warehouse # 2: Supply Product from YourCompany
    - Procurement Group: select two different procurement
    - min qty: 1

Problem:
Two internal pickings are created for “P1” and two others for “P2”,
because two different procurement:
    - from “input” to “quality control”
    - from “quality control” to “wh/stock2”

But as the pickings have the same location destination, two batches
are supposed to be created to group the pickings.

The `_find_auto_batch` function is triggered when the picking is
confirmed:
https://github.com/odoo/odoo/blob/16.0/addons/stock_picking_batch/models/stock_picking.py#L120
but since the pickings are not confirmed, the function is not called:

opw-3076077

closes odoo/odoo#111716

X-original-commit: 324298967cb63d7de1144c8aee2039119443e60c
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
Touati Djamel (otd)
2023-02-03 06:06:10 +01:00
parent ae32bfea53
commit 28e1fdce4e
2 changed files with 69 additions and 0 deletions
@@ -21,3 +21,7 @@ class StockMove(models.Model):
if picking.state == 'cancel' and picking.batch_id and any(p.state != 'cancel' for p in picking.batch_id.picking_ids):
picking.batch_id = None
return res
def _assign_picking_post_process(self, new=False):
super(StockMove, self)._assign_picking_post_process(new=new)
self.picking_id.action_confirm()
@@ -460,6 +460,71 @@ class TestBatchPicking(TransactionCase):
self.assertFalse(picking_out_1.batch_id)
self.assertEqual(len(picking_out_3.batch_id.picking_ids), 1)
def test_auto_batch_02(self):
""" Test that the auto batch works correctly in internal transfers
when they are created from an order point:
* WH1: 1 steps outgoing transfers:
- Delivery orders: auto batch - source location
* WH2: 3 steps incoming transfers, ressuply from WH1
- internal transfert/ WH2 : auto batch - destination location
* orderpoint:
- Product A - Location: WH2 - Route: WH2/supply from WH1 - procurement: P1 - min_qty: 1
- Product B - Location: WH2 - Route: WH2/supply from >H1 - procurement: P2 - min_qty: 1
* Result: 6 pickings and 3 batchs
"""
warehouse_1 = self.env['stock.warehouse'].search([], limit=1)
warehouse_2 = self.env['stock.warehouse'].create({
'name': 'WH 2',
'code': 'WH2',
'company_id': warehouse_1.company_id.id,
'resupply_wh_ids': [(6, 0, [warehouse_1.id])],
'reception_steps': 'three_steps',
})
warehouse_1.int_type_id.write({
'auto_batch': True,
'batch_group_by_src_loc': True,
})
warehouse_2.int_type_id.write({
'auto_batch': True,
'batch_group_by_dest_loc': True,
})
self.env['stock.quant']._update_available_quantity(self.productA, warehouse_1.lot_stock_id, 10)
self.env['stock.quant']._update_available_quantity(self.productB, warehouse_1.lot_stock_id, 10)
procurement_1 = self.env['procurement.group'].create({
'move_type': 'direct',
'partner_id': self.client_1.id
})
procurement_2 = self.env['procurement.group'].create({
'move_type': 'direct',
'partner_id': self.client_1.id
})
op1 = self.env['stock.warehouse.orderpoint'].create({
'name': 'Product A',
'location_id': warehouse_2.lot_stock_id.id,
'product_id': self.productA.id,
'product_min_qty': 1,
'product_max_qty': 1,
'group_id': procurement_1.id,
'route_id': warehouse_2.route_ids[0].id,
})
op2 = self.env['stock.warehouse.orderpoint'].create({
'name': 'Product B',
'location_id': warehouse_2.lot_stock_id.id,
'product_id': self.productB.id,
'product_min_qty': 1,
'product_max_qty': 1,
'group_id': procurement_2.id,
'route_id': warehouse_2.route_ids[0].id,
})
self.productA.route_ids = warehouse_2.resupply_route_ids
self.productB.route_ids = warehouse_2.resupply_route_ids
(op1 | op2)._procure_orderpoint_confirm()
self.assertEqual(len(procurement_1.stock_move_ids.picking_id.batch_id), 3)
self.assertEqual(procurement_1.stock_move_ids.picking_id[0].batch_id, procurement_2.stock_move_ids.picking_id[0].batch_id)
self.assertEqual(procurement_1.stock_move_ids.picking_id[1].batch_id, procurement_2.stock_move_ids.picking_id[1].batch_id)
self.assertEqual(procurement_1.stock_move_ids.picking_id[2].batch_id, procurement_2.stock_move_ids.picking_id[2].batch_id)
def test_remove_all_transfers_from_confirmed_batch(self):
"""
Check that the batch is canceled when all transfers are deleted