[FIX] website_sale_aplicoop: Critical date calculation fixes (v18.0.1.3.1)
- Fixed _compute_cutoff_date logic: Changed days_ahead <= 0 to days_ahead < 0 to allow cutoff_date same day as today
- Enabled store=True for delivery_date field to persist calculated values and enable database filtering
- Added constraint _check_cutoff_before_pickup to validate pickup_day >= cutoff_day in weekly orders
- Added @api.onchange methods for immediate UI feedback when changing cutoff_day or pickup_day
- Created daily cron job _cron_update_dates to automatically recalculate dates for active orders
- Added 'Calculated Dates' section in form view showing readonly cutoff_date, pickup_date, delivery_date
- Added 6 regression tests with @tagged('post_install', 'date_calculations')
- Updated documentation with comprehensive changelog
This is a more robust fix than v18.0.1.2.0, addressing edge cases in date calculations.
This commit is contained in:
parent
c70de71cff
commit
8b0a402ccf
6 changed files with 489 additions and 120 deletions
|
|
@ -154,7 +154,7 @@ class GroupOrder(models.Model):
|
|||
delivery_date = fields.Date(
|
||||
string="Delivery Date",
|
||||
compute="_compute_delivery_date",
|
||||
store=False,
|
||||
store=True,
|
||||
readonly=True,
|
||||
help="Calculated delivery date (pickup date + 1 day)",
|
||||
)
|
||||
|
|
@ -503,10 +503,11 @@ class GroupOrder(models.Model):
|
|||
# Calculate days to NEXT occurrence of cutoff_day
|
||||
days_ahead = target_weekday - current_weekday
|
||||
|
||||
if days_ahead <= 0:
|
||||
# Target day already passed this week or is today
|
||||
if days_ahead < 0:
|
||||
# Target day already passed this week
|
||||
# Jump to next week's occurrence
|
||||
days_ahead += 7
|
||||
# If days_ahead == 0, cutoff is today (allowed)
|
||||
|
||||
record.cutoff_date = reference_date + timedelta(days=days_ahead)
|
||||
_logger.info(
|
||||
|
|
@ -534,3 +535,64 @@ class GroupOrder(models.Model):
|
|||
)
|
||||
else:
|
||||
record.delivery_date = None
|
||||
|
||||
# === Constraints ===
|
||||
|
||||
@api.constrains("cutoff_day", "pickup_day", "period")
|
||||
def _check_cutoff_before_pickup(self):
|
||||
"""Validate that pickup_day comes after or equals cutoff_day in weekly orders.
|
||||
|
||||
For weekly orders, if pickup_day < cutoff_day numerically, it means pickup
|
||||
would be scheduled BEFORE cutoff in the same week cycle, which is illogical.
|
||||
|
||||
Example:
|
||||
- cutoff_day=3 (Thursday), pickup_day=1 (Tuesday): INVALID
|
||||
(pickup Tuesday would be before cutoff Thursday)
|
||||
- cutoff_day=1 (Tuesday), pickup_day=5 (Saturday): VALID
|
||||
(pickup Saturday is after cutoff Tuesday)
|
||||
- cutoff_day=5 (Saturday), pickup_day=5 (Saturday): VALID
|
||||
(same day allowed)
|
||||
"""
|
||||
for record in self:
|
||||
if record.cutoff_day and record.pickup_day and record.period == "weekly":
|
||||
cutoff = int(record.cutoff_day)
|
||||
pickup = int(record.pickup_day)
|
||||
if pickup < cutoff:
|
||||
pickup_name = dict(self._get_day_selection())[str(pickup)]
|
||||
cutoff_name = dict(self._get_day_selection())[str(cutoff)]
|
||||
raise ValidationError(
|
||||
_(
|
||||
"For weekly orders, pickup day ({pickup}) must be after or equal to "
|
||||
"cutoff day ({cutoff}) in the same week. Current configuration would "
|
||||
"put pickup before cutoff, which is illogical."
|
||||
).format(pickup=pickup_name, cutoff=cutoff_name)
|
||||
)
|
||||
|
||||
# === Onchange Methods ===
|
||||
|
||||
@api.onchange("cutoff_day", "start_date")
|
||||
def _onchange_cutoff_day(self):
|
||||
"""Force recompute cutoff_date on UI change for immediate feedback."""
|
||||
self._compute_cutoff_date()
|
||||
|
||||
@api.onchange("pickup_day", "cutoff_day", "start_date")
|
||||
def _onchange_pickup_day(self):
|
||||
"""Force recompute pickup_date on UI change for immediate feedback."""
|
||||
self._compute_pickup_date()
|
||||
|
||||
# === Cron Methods ===
|
||||
|
||||
@api.model
|
||||
def _cron_update_dates(self):
|
||||
"""Cron job to recalculate dates for active orders daily.
|
||||
|
||||
This ensures that computed dates stay up-to-date as time passes.
|
||||
Only updates orders in 'draft' or 'open' states.
|
||||
"""
|
||||
orders = self.search([("state", "in", ["draft", "open"])])
|
||||
_logger.info("Cron: Updating dates for %d active group orders", len(orders))
|
||||
for order in orders:
|
||||
order._compute_cutoff_date()
|
||||
order._compute_pickup_date()
|
||||
order._compute_delivery_date()
|
||||
_logger.info("Cron: Date update completed")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue