[ADD] website_sale_aplicoop: create picking batches after cutoff

- Add stock_picking_batch dependency to manifest
- Add cutoff date validation in _confirm_linked_sale_orders()
- Create _create_picking_batches_for_sale_orders() method
- Group pickings by consumer_group_id into separate batches
- Set batch scheduled_date from group order pickup_date
- Add test_cron_picking_batch.py with 7 tests covering:
  - Skip orders before cutoff
  - Confirm orders after cutoff
  - Separate batches per consumer group
  - Same group orders in same batch
  - Batch has scheduled_date
  - No duplicate batches on re-run
  - Closed group orders not processed
This commit is contained in:
snt 2026-03-06 15:45:12 +01:00
parent c3173a32c9
commit e2ced75ecd
4 changed files with 455 additions and 11 deletions

View file

@ -688,8 +688,23 @@ class GroupOrder(models.Model):
This is triggered by the daily cron so that weekly orders generated
from the website are confirmed automatically once dates are refreshed.
After confirmation, creates picking batches grouped by consumer group.
Only confirms orders if the cutoff date has already passed.
"""
self.ensure_one()
# Only confirm if cutoff date has passed
today = fields.Date.today()
if self.cutoff_date and self.cutoff_date >= today:
_logger.info(
"Cron: Skipping group order %s (%s) - cutoff date %s not yet passed",
self.id,
self.name,
self.cutoff_date,
)
return
SaleOrder = self.env["sale.order"].sudo()
sale_orders = SaleOrder.search(
[
@ -715,9 +730,65 @@ class GroupOrder(models.Model):
try:
sale_orders.action_confirm()
# Create picking batches after confirmation
self._create_picking_batches_for_sale_orders(sale_orders)
except Exception:
_logger.exception(
"Cron: Error confirming sale orders for group order %s (%s)",
self.id,
self.name,
)
def _create_picking_batches_for_sale_orders(self, sale_orders):
"""Create stock.picking.batch grouped by consumer_group_id.
Args:
sale_orders: Recordset of confirmed sale.order
"""
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(
lambda p: p.state not in ("done", "cancel") and not p.batch_id
)
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 = 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,
}
)
# 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",
batch.name,
len(pickings),
self.name,
consumer_group.name if consumer_group else "N/A",
)