[IMP] website_sale_aplicoop: automate non-weekly group order cycles

One-time, biweekly and monthly group orders now follow the same cron
confirmation flow as weekly ones (confirm sale orders + batch pickings
when the cycle cutoff passes):

- Biweekly/monthly keep the cutoff_day/pickup_day weekday scheme on a
  recurrence grid anchored at start_date (creation date as fallback):
  cutoffs advance +14 days / +1 month snapped to cutoff_day, with
  catch-up after cron downtime. Previously they behaved as weekly.
- One-time orders (specials/promotions) are driven by end_date
  (cutoff_date = end_date); once passed, the cron confirms, batches
  and closes the group order.
- end_date keeps its "empty = permanent" meaning for recurring orders.
- Website draft-cart lookup window is now period-aware instead of
  assuming a 6-day weekly cycle.
- New cron tests for once/biweekly/monthly cycles; i18n es/eu updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
GitHub Copilot 2026-07-15 14:14:03 +02:00
parent d8cd83bdaf
commit aba22fd230
8 changed files with 510 additions and 74 deletions

View file

@ -65,27 +65,39 @@ def _get_salesperson_for_order(self, partner):
def _find_recent_draft_order(self, partner_id, group_order, request_obj=None):
"""Return the active-cycle draft sale.order for the partner, or empty.
The active ordering period ends at group_order.cutoff_date and begins
6 days earlier (weekly cycle). Drafts created outside this window belong
to a previous cycle and must not be reused otherwise stale carts come
back when the user re-enters the order page.
The active ordering period ends at group_order.cutoff_date and its length
depends on the order period: 7 days (weekly), 14 days (biweekly), one
month (monthly). One-time orders have a single cycle starting at
start_date (or unbounded when start_date is empty). Drafts created
outside this window belong to a previous cycle and must not be reused
otherwise stale carts come back when the user re-enters the order page.
"""
req = request_obj or request
from datetime import timedelta
from dateutil.relativedelta import relativedelta
if not group_order or not group_order.cutoff_date:
return req.env["sale.order"]
period_start = group_order.cutoff_date - timedelta(days=6)
period_end = group_order.cutoff_date
if group_order.period == "weekly":
period_start = period_end - timedelta(days=6)
elif group_order.period == "biweekly":
period_start = period_end - timedelta(days=13)
elif group_order.period == "monthly":
period_start = period_end - relativedelta(months=1) + timedelta(days=1)
else: # once: single cycle, bounded by start_date when set
period_start = group_order.start_date
domain = [
("partner_id", "=", partner_id),
("group_order_id", "=", group_order.id),
("state", "=", "draft"),
("create_date", ">=", f"{period_start} 00:00:00"),
("create_date", "<=", f"{period_end} 23:59:59"),
]
if period_start:
domain.append(("create_date", ">=", f"{period_start} 00:00:00"))
return (
req.env["sale.order"].sudo().search(domain, order="create_date desc", limit=1)