Fix stock picking batch date and does not split batchs by consumer group
This commit is contained in:
parent
b73f031dfb
commit
828278573d
2 changed files with 48 additions and 59 deletions
|
|
@ -890,47 +890,41 @@ class GroupOrder(models.Model):
|
|||
self.ensure_one()
|
||||
StockPickingBatch = self.env["stock.picking.batch"].sudo()
|
||||
|
||||
# Group sale orders by consumer_group_id
|
||||
groups = {}
|
||||
for so in sale_orders:
|
||||
group_id = so.consumer_group_id.id or False
|
||||
if group_id not in groups:
|
||||
groups[group_id] = self.env["sale.order"]
|
||||
groups[group_id] |= so
|
||||
|
||||
for consumer_group_id, group_sale_orders in groups.items():
|
||||
# Get pickings without batch
|
||||
pickings = group_sale_orders.picking_ids.filtered(
|
||||
# Create batches per group order, not per consumer group.
|
||||
# If multiple picking types exist, keep one batch per picking type.
|
||||
grouped_pickings = {}
|
||||
pickings = sale_orders.picking_ids.filtered(
|
||||
lambda p: p.state not in ("done", "cancel") and not p.batch_id
|
||||
)
|
||||
for picking in pickings:
|
||||
grouped_pickings.setdefault(
|
||||
picking.picking_type_id.id, self.env["stock.picking"]
|
||||
)
|
||||
grouped_pickings[picking.picking_type_id.id] |= picking
|
||||
|
||||
scheduled_date = self.pickup_date
|
||||
if not scheduled_date and self.delivery_date:
|
||||
scheduled_date = self.delivery_date - timedelta(days=1)
|
||||
|
||||
for picking_type_id, pickings in grouped_pickings.items():
|
||||
if not pickings:
|
||||
continue
|
||||
|
||||
# Get consumer group name for batch description
|
||||
consumer_group = self.env["res.partner"].browse(consumer_group_id)
|
||||
batch_desc = (
|
||||
f"{self.name} - {consumer_group.name}" if consumer_group else self.name
|
||||
)
|
||||
|
||||
# Create the batch
|
||||
batch_desc = self.name
|
||||
batch = StockPickingBatch.create(
|
||||
{
|
||||
"description": batch_desc,
|
||||
"company_id": self.company_id.id,
|
||||
"picking_type_id": pickings[0].picking_type_id.id,
|
||||
"scheduled_date": self.pickup_date,
|
||||
"picking_type_id": picking_type_id,
|
||||
"scheduled_date": scheduled_date,
|
||||
}
|
||||
)
|
||||
|
||||
# Assign pickings to the batch
|
||||
pickings.write({"batch_id": batch.id})
|
||||
|
||||
_logger.info(
|
||||
"Cron: Created batch %s with %d pickings for group order %s, "
|
||||
"consumer group %s",
|
||||
"Cron: Created batch %s with %d pickings for group order %s",
|
||||
batch.name,
|
||||
len(pickings),
|
||||
self.name,
|
||||
consumer_group.name if consumer_group else "N/A",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -227,8 +227,8 @@ class TestCronPickingBatch(TransactionCase):
|
|||
"Cron should snapshot and preserve the current cycle pickup_date when confirming",
|
||||
)
|
||||
|
||||
def test_cron_creates_picking_batch_per_consumer_group(self):
|
||||
"""Test that cron creates separate picking batches per consumer group."""
|
||||
def test_cron_creates_single_picking_batch_for_group_order(self):
|
||||
"""Test that cron creates a single picking batch for the whole group order."""
|
||||
# Create group order with cutoff yesterday (past)
|
||||
group_order = self._create_group_order(cutoff_in_past=True)
|
||||
|
||||
|
|
@ -247,39 +247,30 @@ class TestCronPickingBatch(TransactionCase):
|
|||
self.assertTrue(so1.picking_ids, "Sale order 1 should have pickings")
|
||||
self.assertTrue(so2.picking_ids, "Sale order 2 should have pickings")
|
||||
|
||||
# Check that pickings have batch_id assigned
|
||||
for picking in so1.picking_ids:
|
||||
self.assertTrue(
|
||||
picking.batch_id,
|
||||
"Picking from SO1 should be assigned to a batch",
|
||||
)
|
||||
|
||||
for picking in so2.picking_ids:
|
||||
self.assertTrue(
|
||||
picking.batch_id,
|
||||
"Picking from SO2 should be assigned to a batch",
|
||||
)
|
||||
|
||||
# Check that batches are different (one per consumer group)
|
||||
# Check that all pickings share the same batch
|
||||
batch_1 = so1.picking_ids[0].batch_id
|
||||
batch_2 = so2.picking_ids[0].batch_id
|
||||
|
||||
self.assertNotEqual(
|
||||
self.assertEqual(
|
||||
batch_1.id,
|
||||
batch_2.id,
|
||||
"Different consumer groups should have different batches",
|
||||
"Different consumer groups in the same group order should share one batch",
|
||||
)
|
||||
|
||||
# Check batch descriptions contain consumer group names
|
||||
self.assertIn(
|
||||
self.consumer_group_1.name,
|
||||
batch_1.description,
|
||||
"Batch 1 description should include consumer group 1 name",
|
||||
# Check that there is only one batch record created
|
||||
self.assertEqual(
|
||||
self.env["stock.picking.batch"].search_count(
|
||||
[("description", "=", group_order.name)]
|
||||
),
|
||||
1,
|
||||
"Only one batch should be created for a single group order",
|
||||
)
|
||||
self.assertIn(
|
||||
self.consumer_group_2.name,
|
||||
batch_2.description,
|
||||
"Batch 2 description should include consumer group 2 name",
|
||||
|
||||
# Check batch description uses the group order name only
|
||||
self.assertEqual(
|
||||
batch_1.description,
|
||||
group_order.name,
|
||||
"Batch description should be the group order name",
|
||||
)
|
||||
|
||||
def test_cron_same_consumer_group_same_batch(self):
|
||||
|
|
@ -342,10 +333,10 @@ class TestCronPickingBatch(TransactionCase):
|
|||
self.assertTrue(so.picking_ids, "Sale order should have pickings")
|
||||
batch = so.picking_ids[0].batch_id
|
||||
self.assertTrue(batch, "Picking should have a batch")
|
||||
# scheduled_date should be set (not False/None)
|
||||
self.assertTrue(
|
||||
batch.scheduled_date,
|
||||
"Batch should have a scheduled_date set",
|
||||
self.assertEqual(
|
||||
batch.scheduled_date.date(),
|
||||
group_order.pickup_date,
|
||||
"Batch scheduled_date should be the pickup date (day before delivery)",
|
||||
)
|
||||
|
||||
def test_cron_does_not_duplicate_batches(self):
|
||||
|
|
@ -364,13 +355,17 @@ class TestCronPickingBatch(TransactionCase):
|
|||
|
||||
self.assertTrue(so.picking_ids, "Sale order should have pickings")
|
||||
batch_first = so.picking_ids[0].batch_id
|
||||
batch_count_first = self.env["stock.picking.batch"].search_count([])
|
||||
batch_count_first = self.env["stock.picking.batch"].search_count(
|
||||
[("description", "=", group_order.name)]
|
||||
)
|
||||
|
||||
# Call second time
|
||||
group_order._confirm_linked_sale_orders()
|
||||
|
||||
batch_second = so.picking_ids[0].batch_id
|
||||
batch_count_second = self.env["stock.picking.batch"].search_count([])
|
||||
batch_count_second = self.env["stock.picking.batch"].search_count(
|
||||
[("description", "=", group_order.name)]
|
||||
)
|
||||
|
||||
# Should be same batch, no duplicates
|
||||
self.assertEqual(
|
||||
|
|
@ -427,7 +422,7 @@ class TestCronPickingBatch(TransactionCase):
|
|||
def _patched_action_confirm(recordset):
|
||||
should_fail = any(so.name == "SO-FAIL" for so in recordset)
|
||||
if should_fail and not recordset.env.context.get("from_orderpoint"):
|
||||
raise UserError("Simulated stock route error")
|
||||
raise UserError()
|
||||
return original_action_confirm(recordset)
|
||||
|
||||
with patch.object(SaleOrderClass, "action_confirm", _patched_action_confirm):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue