From 813c8071d92e21c6841dde74effaae57678836b8 Mon Sep 17 00:00:00 2001 From: snt Date: Tue, 31 Mar 2026 19:07:43 +0200 Subject: [PATCH 1/2] [I18N] website_sale_aplicoop: remove legacy week draft strings --- .../controllers/website_sale.py | 94 +++++++++---------- website_sale_aplicoop/i18n/es.po | 20 +--- website_sale_aplicoop/i18n/eu.po | 20 +--- .../models/js_translations.py | 4 +- .../static/src/js/website_sale.js | 2 +- .../tests/test_phase3_confirm_eskaera.py | 51 ++++++++++ 6 files changed, 106 insertions(+), 85 deletions(-) diff --git a/website_sale_aplicoop/controllers/website_sale.py b/website_sale_aplicoop/controllers/website_sale.py index 9a8794d..2f9de17 100644 --- a/website_sale_aplicoop/controllers/website_sale.py +++ b/website_sale_aplicoop/controllers/website_sale.py @@ -188,7 +188,9 @@ class AplicoopWebsiteSale(WebsiteSale): "error_unknown": env_lang._("Unknown error"), "error_invalid_data": env_lang._("Invalid data provided"), "error_order_not_found": env_lang._("Order not found"), - "error_no_draft_orders": env_lang._("No draft orders found for this week"), + "error_no_draft_orders": env_lang._( + "No draft orders found for the current order period" + ), "invalid_quantity": env_lang._("Please enter a valid quantity"), # ============ CONFIRMATION MESSAGES ============ "save_draft_confirm": env_lang._( @@ -207,7 +209,7 @@ class AplicoopWebsiteSale(WebsiteSale): # ============ DRAFT MODAL LABELS ============ "draft_already_exists": env_lang._("Draft Already Exists"), "draft_exists_message": env_lang._( - "A saved draft already exists for this week." + "A saved draft already exists for the current order period." ), "draft_two_options": env_lang._("You have two options:"), "draft_option1_title": env_lang._("Option 1: Merge with Existing Draft"), @@ -1428,34 +1430,41 @@ class AplicoopWebsiteSale(WebsiteSale): status=status, ) - def _find_recent_draft_order(self, partner_id, order_id): - """Find most recent draft sale.order for partner and group_order in current week. + def _find_recent_draft_order(self, partner_id, group_order): + """Find most recent draft sale.order for partner in the active order period. - Returns the record or empty recordset. + Priority for period matching: + 1) If group_order.pickup_date is set, match that exact pickup_date + (prevents reusing stale drafts from previous cycles of same group.order). + 2) Fallback to current-week create_date bounds when pickup_date is not set. + + Returns the recordset (limit=1) or empty recordset. """ - from datetime import datetime - from datetime import timedelta - today = datetime.now().date() start_of_week = today - timedelta(days=today.weekday()) end_of_week = start_of_week + timedelta(days=6) - drafts = ( - request.env["sale.order"] - .sudo() - .search( + domain = [ + ("partner_id", "=", partner_id), + ("group_order_id", "=", group_order.id), + ("state", "=", "draft"), + ] + + if group_order.pickup_date: + domain.append(("pickup_date", "=", group_order.pickup_date)) + else: + domain.extend( [ - ("partner_id", "=", partner_id), - ("group_order_id", "=", order_id), - ("state", "=", "draft"), ("create_date", ">=", f"{start_of_week} 00:00:00"), ("create_date", "<=", f"{end_of_week} 23:59:59"), - ], - order="create_date desc", - limit=1, + ] ) + + return ( + request.env["sale.order"] + .sudo() + .search(domain, order="create_date desc", limit=1) ) - return drafts @http.route(["/eskaera/"], type="http", auth="user", website=True) def eskaera_shop(self, order_id, **post): @@ -2258,7 +2267,7 @@ class AplicoopWebsiteSale(WebsiteSale): csrf=False, ) def load_draft_cart(self, **post): - """Load items from the most recent draft sale.order for this week.""" + """Load items from the most recent draft sale.order for current period.""" import json try: @@ -2318,16 +2327,18 @@ class AplicoopWebsiteSale(WebsiteSale): status=400, ) - # Find the most recent draft sale.order for this partner from this week - # The helper _find_recent_draft_order computes the week bounds itself, + # Find the most recent draft sale.order for this partner in active period + # The helper _find_recent_draft_order computes the period criteria itself, # so we only need to call it here. # Find the most recent matching draft order using helper draft_orders = self._find_recent_draft_order( - current_user.partner_id.id, order_id + current_user.partner_id.id, group_order ) if not draft_orders: - error_msg = request.env._("No draft orders found for this week") + error_msg = request.env._( + "No draft orders found for the current order period" + ) return request.make_response( json.dumps({"error": error_msg}), [("Content-Type", "application/json")], @@ -2496,17 +2507,9 @@ class AplicoopWebsiteSale(WebsiteSale): status=400, ) - # Check if a draft already exists for this group order and user - existing_drafts = ( - request.env["sale.order"] - .sudo() - .search( - [ - ("group_order_id", "=", order_id), - ("partner_id", "=", current_user.partner_id.id), - ("state", "=", "draft"), - ] - ) + # Check if a draft already exists for this user in current order period + existing_drafts = self._find_recent_draft_order( + current_user.partner_id.id, group_order ) _logger.info( @@ -2633,18 +2636,9 @@ class AplicoopWebsiteSale(WebsiteSale): status=400, ) - # First, check if there's already a draft sale.order for this user in this group order - existing_order = ( - request.env["sale.order"] - .sudo() - .search( - [ - ("partner_id", "=", current_user.partner_id.id), - ("group_order_id", "=", group_order.id), - ("state", "=", "draft"), - ], - limit=1, - ) + # Reuse only draft from the current group_order cycle (not stale ones) + existing_order = self._find_recent_draft_order( + current_user.partner_id.id, group_order ) if existing_order: @@ -2934,7 +2928,7 @@ class AplicoopWebsiteSale(WebsiteSale): translations = { "es_ES": { "Draft Already Exists": "El Borrador Ya Existe", - "A saved draft already exists for this week.": "Un borrador guardado ya existe para esta semana.", + "A saved draft already exists for the current order period.": "Un borrador guardado ya existe para el período actual del pedido.", "You have two options:": "Tienes dos opciones:", "Option 1: Merge with Existing Draft": "Opción 1: Fusionar con Borrador Existente", "Combine your current cart with the existing draft.": "Combina tu carrito actual con el borrador existente.", @@ -2957,7 +2951,7 @@ class AplicoopWebsiteSale(WebsiteSale): }, "eu_ES": { "Draft Already Exists": "Zirriborro Dagoeneko Badago", - "A saved draft already exists for this week.": "Gordetako zirriborro bat dagoeneko badago asteburu honetarako.", + "A saved draft already exists for the current order period.": "Gordetako zirriborro bat dagoeneko badago uneko eskaera-aldirako.", "You have two options:": "Bi aukera dituzu:", "Option 1: Merge with Existing Draft": "1. Aukera: Existentea Duen Zirriborroarekin Batu", "Combine your current cart with the existing draft.": "Batu zure gaur-oraingo saskia existentea duen zirriborroarekin.", @@ -2981,7 +2975,7 @@ class AplicoopWebsiteSale(WebsiteSale): # Also support 'eu' as a variant "eu": { "Draft Already Exists": "Zirriborro Dagoeneko Badago", - "A saved draft already exists for this week.": "Gordetako zirriborro bat dagoeneko badago asteburu honetarako.", + "A saved draft already exists for the current order period.": "Gordetako zirriborro bat dagoeneko badago uneko eskaera-aldirako.", "You have two options:": "Bi aukera dituzu:", "Option 1: Merge with Existing Draft": "1. Aukera: Existentea Duen Zirriborroarekin Batu", "Combine your current cart with the existing draft.": "Batu zure gaur-oraingo saskia existentea duen zirriborroarekin.", diff --git a/website_sale_aplicoop/i18n/es.po b/website_sale_aplicoop/i18n/es.po index 1c8479c..d4c7361 100644 --- a/website_sale_aplicoop/i18n/es.po +++ b/website_sale_aplicoop/i18n/es.po @@ -240,15 +240,8 @@ msgstr "Día de Recogida" #. module: website_sale_aplicoop #. odoo-python #: code:addons/website_sale_aplicoop/controllers/website_sale.py:0 -msgid "A draft already exists for this week." -msgstr "Ya existe un borrador para esta semana." - -#. 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 "A saved draft already exists for this week." -msgstr "Ya existe un borrador guardado para esta semana." +msgid "A saved draft already exists for the current order period." +msgstr "Ya existe un borrador guardado para el período actual del pedido." #. module: website_sale_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_shop @@ -914,13 +907,8 @@ msgid "" "orders" 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 -#, fuzzy -msgid "No draft orders found for this week" -msgstr "Ya existe un borrador para esta semana." +msgid "No draft orders found for the current order period" +msgstr "No se encontraron borradores para el período actual del pedido" #. module: website_sale_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_page diff --git a/website_sale_aplicoop/i18n/eu.po b/website_sale_aplicoop/i18n/eu.po index 20e8355..eb56ceb 100644 --- a/website_sale_aplicoop/i18n/eu.po +++ b/website_sale_aplicoop/i18n/eu.po @@ -241,15 +241,8 @@ msgstr "Biltzeko Lekua:" #. module: website_sale_aplicoop #. odoo-python #: code:addons/website_sale_aplicoop/controllers/website_sale.py:0 -msgid "A draft already exists for this week." -msgstr "Zirriborro bat dagoeneko existitzen da astean honetan." - -#. 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 "A saved draft already exists for this week." -msgstr "Gordetako zirriborro bat dagoeneko existitzen da astean honetan." +msgid "A saved draft already exists for the current order period." +msgstr "Gordetako zirriborro bat dagoeneko badago uneko eskaera-aldirako." #. module: website_sale_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_shop @@ -913,13 +906,8 @@ msgid "" "orders" 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 -#, fuzzy -msgid "No draft orders found for this week" -msgstr "Zirriborro bat dagoeneko existitzen da astean honetan." +msgid "No draft orders found for the current order period" +msgstr "Ez da zirriborrorik aurkitu uneko eskaera-aldirako" #. module: website_sale_aplicoop #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_page diff --git a/website_sale_aplicoop/models/js_translations.py b/website_sale_aplicoop/models/js_translations.py index 01e24ad..a7edf65 100644 --- a/website_sale_aplicoop/models/js_translations.py +++ b/website_sale_aplicoop/models/js_translations.py @@ -42,7 +42,7 @@ def _register_translations(): # Draft Modal Labels # ======================== _("Draft Already Exists") - _("A saved draft already exists for this week.") + _("A saved draft already exists for the current order period.") _("You have two options:") _("Option 1: Merge with Existing Draft") _("Combine your current cart with the existing draft.") @@ -89,7 +89,7 @@ def _register_translations(): # Error Messages # ======================== _("Error: Order ID not found") - _("No draft orders found for this week") + _("No draft orders found for the current order period") _("Connection error") _("Error loading order") _("Error loading draft") diff --git a/website_sale_aplicoop/static/src/js/website_sale.js b/website_sale_aplicoop/static/src/js/website_sale.js index 0682e33..cb7ad3b 100644 --- a/website_sale_aplicoop/static/src/js/website_sale.js +++ b/website_sale_aplicoop/static/src/js/website_sale.js @@ -1015,7 +1015,7 @@ all_categories: "All categories", // Draft modal labels draft_already_exists: "Draft Already Exists", - draft_exists_message: "A saved draft already exists for this week.", + draft_exists_message: "A saved draft already exists for the current order period.", draft_two_options: "You have two options:", draft_option1_title: "Option 1: Merge with Existing Draft", draft_option1_desc: "Combine your current cart with the existing draft.", diff --git a/website_sale_aplicoop/tests/test_phase3_confirm_eskaera.py b/website_sale_aplicoop/tests/test_phase3_confirm_eskaera.py index 1614ab2..3562c90 100644 --- a/website_sale_aplicoop/tests/test_phase3_confirm_eskaera.py +++ b/website_sale_aplicoop/tests/test_phase3_confirm_eskaera.py @@ -667,3 +667,54 @@ class TestConfirmEskaera_Integration(TransactionCase): existing_order.invalidate_recordset() self.assertEqual(len(existing_order.order_line), 1) self.assertEqual(existing_order.order_line[0].product_uom_qty, 5) + + @patch("odoo.http.request") + def test_confirm_eskaera_ignores_old_period_draft(self, mock_request): + """Old draft from previous pickup_date must not be reused.""" + mock_request.env = self.env.with_user(self.user) + mock_request.env.lang = "es_ES" + mock_request.httprequest = Mock() + + old_draft = self.env["sale.order"].create( + { + "partner_id": self.partner.id, + "group_order_id": self.group_order.id, + "state": "draft", + "pickup_date": date.today() - timedelta(days=7), + "order_line": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_qty": 1, + "price_unit": 20.0, + }, + ) + ], + } + ) + + data = { + "order_id": self.group_order.id, + "items": [ + { + "product_id": self.product.id, + "quantity": 4, + "product_price": 20.0, + } + ], + "is_delivery": False, + } + + mock_request.httprequest.data = json.dumps(data).encode("utf-8") + + response = self.controller.confirm_eskaera() + response_data = json.loads(response.data.decode("utf-8")) + + self.assertTrue(response_data.get("success")) + self.assertNotEqual(response_data["sale_order_id"], old_draft.id) + + old_draft.invalidate_recordset() + self.assertEqual(old_draft.state, "draft") + self.assertEqual(old_draft.order_line[0].product_uom_qty, 1) From 331a2e89442d17c871db8347a07e73cb95979566 Mon Sep 17 00:00:00 2001 From: snt Date: Tue, 31 Mar 2026 19:36:20 +0200 Subject: [PATCH 2/2] [FIX] website_sale_aplicoop: harden group order cron --- website_sale_aplicoop/i18n/es.po | 34 +------- website_sale_aplicoop/i18n/eu.po | 34 +------- website_sale_aplicoop/models/group_order.py | 82 ++++++++++++++++--- .../tests/test_date_calculations.py | 46 +++++++++++ 4 files changed, 126 insertions(+), 70 deletions(-) diff --git a/website_sale_aplicoop/i18n/es.po b/website_sale_aplicoop/i18n/es.po index d4c7361..b9901a8 100644 --- a/website_sale_aplicoop/i18n/es.po +++ b/website_sale_aplicoop/i18n/es.po @@ -907,6 +907,10 @@ msgid "" "orders" 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" msgstr "No se encontraron borradores para el período actual del pedido" @@ -1441,46 +1445,16 @@ msgstr "con el borrador guardado." msgid "{{ 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 #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop msgid "Delivery Date" 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 #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop msgid "Pickup Location" 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 #: model:product.ribbon,name:website_sale_aplicoop.out_of_stock_ribbon msgid "Out of Stock" diff --git a/website_sale_aplicoop/i18n/eu.po b/website_sale_aplicoop/i18n/eu.po index eb56ceb..e6886d9 100644 --- a/website_sale_aplicoop/i18n/eu.po +++ b/website_sale_aplicoop/i18n/eu.po @@ -906,6 +906,10 @@ msgid "" "orders" 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" msgstr "Ez da zirriborrorik aurkitu uneko eskaera-aldirako" @@ -1441,46 +1445,16 @@ msgstr "gordetako zirriborroarekin." msgid "{{ 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 #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop msgid "Delivery Date" 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 #: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.sale_order_portal_content_aplicoop msgid "Pickup Location" 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 #: model:product.ribbon,name:website_sale_aplicoop.out_of_stock_ribbon msgid "Out of Stock" diff --git a/website_sale_aplicoop/models/group_order.py b/website_sale_aplicoop/models/group_order.py index 487b882..8165b8e 100644 --- a/website_sale_aplicoop/models/group_order.py +++ b/website_sale_aplicoop/models/group_order.py @@ -645,16 +645,65 @@ class GroupOrder(models.Model): 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)) + 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: - # Confirm BEFORE recomputing dates: cutoff_date still points to the - # current cycle's cutoff (today or past), so the check works correctly. - # After confirmation, recompute dates so they advance to the next cycle. - order._confirm_linked_sale_orders() - order._compute_cutoff_date() - order._compute_pickup_date() - order._compute_delivery_date() - _logger.info("Cron: Date update completed") + 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 + # current cycle's cutoff (today or past), so the check works correctly. + # After confirmation, recompute dates so they advance to the next cycle. + order._confirm_linked_sale_orders() + order._compute_cutoff_date() + order._compute_pickup_date() + order._compute_delivery_date() + 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): """Confirm draft/sent sale orders linked to this group order. @@ -669,13 +718,26 @@ class GroupOrder(models.Model): 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) if self.cutoff_date >= today: _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.name, self.cutoff_date, + today, ) return diff --git a/website_sale_aplicoop/tests/test_date_calculations.py b/website_sale_aplicoop/tests/test_date_calculations.py index 50d2cee..e6d66a1 100644 --- a/website_sale_aplicoop/tests/test_date_calculations.py +++ b/website_sale_aplicoop/tests/test_date_calculations.py @@ -566,3 +566,49 @@ class TestDateCalculations(TransactionCase): order.pickup_date, 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)