[FIX] website_sale_aplicoop: harden group order cron

This commit is contained in:
snt 2026-03-31 19:36:20 +02:00
parent 813c8071d9
commit 331a2e8944
4 changed files with 126 additions and 70 deletions

View file

@ -907,6 +907,10 @@ msgid ""
"orders" "orders"
msgstr "" msgstr ""
#. module: website_sale_aplicoop
#. odoo-python
#: code:addons/website_sale_aplicoop/controllers/website_sale.py:0
#: code:addons/website_sale_aplicoop/models/js_translations.py:0
msgid "No draft orders found for the current order period" msgid "No draft orders found for the current order period"
msgstr "No se encontraron borradores para el período actual del pedido" msgstr "No se encontraron borradores para el período actual del pedido"
@ -1441,46 +1445,16 @@ msgstr "con el borrador guardado."
msgid "{{ product.name }}" msgid "{{ product.name }}"
msgstr "{{ product.name }}" msgstr "{{ product.name }}"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Consumer Group"
msgstr "Grupo de Consumidores"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Delivery Information"
msgstr "Información de Envío"
#. module: website_sale_aplicoop #. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Delivery Date" msgid "Delivery Date"
msgstr "Fecha de Entrega" msgstr "Fecha de Entrega"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Pickup Date"
msgstr "Fecha de Recogida"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Delivery Notice"
msgstr "Aviso de Envío"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "No special delivery instructions"
msgstr "Sin instrucciones especiales de entrega"
#. module: website_sale_aplicoop #. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Pickup Location" msgid "Pickup Location"
msgstr "Lugar de Recogida" msgstr "Lugar de Recogida"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.portal_order_page_sidebar_button
msgid "Load in Cart"
msgstr "Recargar Carrito"
#. module: website_sale_aplicoop #. module: website_sale_aplicoop
#: model:product.ribbon,name:website_sale_aplicoop.out_of_stock_ribbon #: model:product.ribbon,name:website_sale_aplicoop.out_of_stock_ribbon
msgid "Out of Stock" msgid "Out of Stock"

View file

@ -906,6 +906,10 @@ msgid ""
"orders" "orders"
msgstr "" msgstr ""
#. module: website_sale_aplicoop
#. odoo-python
#: code:addons/website_sale_aplicoop/controllers/website_sale.py:0
#: code:addons/website_sale_aplicoop/models/js_translations.py:0
msgid "No draft orders found for the current order period" msgid "No draft orders found for the current order period"
msgstr "Ez da zirriborrorik aurkitu uneko eskaera-aldirako" msgstr "Ez da zirriborrorik aurkitu uneko eskaera-aldirako"
@ -1441,46 +1445,16 @@ msgstr "gordetako zirriborroarekin."
msgid "{{ product.name }}" msgid "{{ product.name }}"
msgstr "{{ product.name }}" msgstr "{{ product.name }}"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Consumer Group"
msgstr "Kontsumo Taldea"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Delivery Information"
msgstr "Delibatua Informazioa"
#. module: website_sale_aplicoop #. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Delivery Date" msgid "Delivery Date"
msgstr "Entrega Data" msgstr "Entrega Data"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Pickup Date"
msgstr "Biltzea Data"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Delivery Notice"
msgstr "Delibatua Oharra"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "No special delivery instructions"
msgstr "Ez dago entregaren instrukzio bereziak"
#. module: website_sale_aplicoop #. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop
msgid "Pickup Location" msgid "Pickup Location"
msgstr "Biltzeko Lekua" msgstr "Biltzeko Lekua"
#. module: website_sale_aplicoop
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.portal_order_page_sidebar_button
msgid "Load in Cart"
msgstr "Saskia Berrkargatu"
#. module: website_sale_aplicoop #. module: website_sale_aplicoop
#: model:product.ribbon,name:website_sale_aplicoop.out_of_stock_ribbon #: model:product.ribbon,name:website_sale_aplicoop.out_of_stock_ribbon
msgid "Out of Stock" msgid "Out of Stock"

View file

@ -645,8 +645,35 @@ class GroupOrder(models.Model):
Only updates orders in 'draft' or 'open' states. Only updates orders in 'draft' or 'open' states.
""" """
orders = self.search([("state", "in", ["draft", "open"])]) orders = self.search([("state", "in", ["draft", "open"])])
_logger.info("Cron: Updating dates for %d active group orders", len(orders)) cron_started_at = fields.Datetime.now()
_logger.info(
"Cron: Starting group.order date update at %s for %d active orders (ids=%s)",
cron_started_at,
len(orders),
orders.ids,
)
processed_orders = 0
failed_orders = []
for order in orders: for order in orders:
before_values = {
"state": order.state,
"period": order.period,
"start_date": order.start_date,
"end_date": order.end_date,
"cutoff_day": order.cutoff_day,
"pickup_day": order.pickup_day,
"cutoff_date": order.cutoff_date,
"pickup_date": order.pickup_date,
"delivery_date": order.delivery_date,
"home_delivery": order.home_delivery,
}
_logger.info(
"Cron: Processing group order %s (%s) with values before recompute: %s",
order.id,
order.name,
before_values,
)
try:
# Confirm BEFORE recomputing dates: cutoff_date still points to the # Confirm BEFORE recomputing dates: cutoff_date still points to the
# current cycle's cutoff (today or past), so the check works correctly. # current cycle's cutoff (today or past), so the check works correctly.
# After confirmation, recompute dates so they advance to the next cycle. # After confirmation, recompute dates so they advance to the next cycle.
@ -654,7 +681,29 @@ class GroupOrder(models.Model):
order._compute_cutoff_date() order._compute_cutoff_date()
order._compute_pickup_date() order._compute_pickup_date()
order._compute_delivery_date() order._compute_delivery_date()
_logger.info("Cron: Date update completed") processed_orders += 1
_logger.info(
"Cron: Finished group order %s (%s). Dates after recompute: cutoff=%s, pickup=%s, delivery=%s",
order.id,
order.name,
order.cutoff_date,
order.pickup_date,
order.delivery_date,
)
except Exception:
failed_orders.append(order.id)
_logger.exception(
"Cron: Error while processing group order %s (%s). Initial values were: %s",
order.id,
order.name,
before_values,
)
_logger.info(
"Cron: Date update completed. processed=%d failed=%d failed_ids=%s",
processed_orders,
len(failed_orders),
failed_orders,
)
def _confirm_linked_sale_orders(self): def _confirm_linked_sale_orders(self):
"""Confirm draft/sent sale orders linked to this group order. """Confirm draft/sent sale orders linked to this group order.
@ -669,13 +718,26 @@ class GroupOrder(models.Model):
today = fields.Date.today() today = fields.Date.today()
if not self.cutoff_date:
_logger.warning(
"Cron: Group order %s (%s) has no cutoff_date (state=%s, period=%s, cutoff_day=%s, start_date=%s). Skipping sale order confirmation for this cycle.",
self.id,
self.name,
self.state,
self.period,
self.cutoff_day,
self.start_date,
)
return
# Skip if cutoff hasn't passed yet (the cycle is still open for orders) # Skip if cutoff hasn't passed yet (the cycle is still open for orders)
if self.cutoff_date >= today: if self.cutoff_date >= today:
_logger.info( _logger.info(
"Cron: Skipping group order %s (%s) - cutoff date %s not yet passed", "Cron: Skipping group order %s (%s) - cutoff date %s not yet passed (today=%s)",
self.id, self.id,
self.name, self.name,
self.cutoff_date, self.cutoff_date,
today,
) )
return return

View file

@ -566,3 +566,49 @@ class TestDateCalculations(TransactionCase):
order.pickup_date, order.pickup_date,
f"Pickup date should be set for active order {order.name}", f"Pickup date should be set for active order {order.name}",
) )
def test_cron_update_dates_skips_orders_without_cutoff_date(self):
"""Cron should not crash if an active order lacks cutoff_date.
A malformed or partially configured active group order should be logged
and skipped for sale-order confirmation, but must not block recomputing
the rest of active orders.
"""
today = fields.Date.today()
valid_order = self.env["group.order"].create(
{
"name": "Valid Cron Order",
"group_ids": [(6, 0, [self.group.id])],
"start_date": today,
"pickup_day": "2", # Wednesday
"cutoff_day": "0", # Monday
"period": "weekly",
"state": "open",
}
)
invalid_order = self.env["group.order"].create(
{
"name": "Invalid Cron Order Without Cutoff",
"group_ids": [(6, 0, [self.group.id])],
"start_date": today,
"pickup_day": "2", # Wednesday
"cutoff_day": False,
"period": "weekly",
"state": "open",
}
)
self.assertFalse(
invalid_order.cutoff_date,
"Precondition failed: invalid order should not have cutoff_date",
)
self.env["group.order"]._cron_update_dates()
valid_order.invalidate_recordset()
invalid_order.invalidate_recordset()
self.assertTrue(valid_order.cutoff_date)
self.assertTrue(valid_order.pickup_date)
self.assertFalse(invalid_order.cutoff_date)