# Copyright 2025 Criptomart # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) from datetime import datetime from datetime import timedelta from psycopg2 import IntegrityError # noqa: F401 from odoo import fields from odoo.exceptions import ValidationError from odoo.tests.common import TransactionCase class TestGroupOrder(TransactionCase): """Test suite para el modelo group.order.""" def setUp(self): super().setUp() # Crear un grupo (res.partner) self.group = self.env["res.partner"].create( { "name": "Grupo Test", "is_company": True, "email": "grupo@test.com", } ) # Crear productos self.product1 = self.env["product.product"].create( { "name": "Producto Test 1", "type": "consu", "list_price": 10.0, } ) self.product2 = self.env["product.product"].create( { "name": "Producto Test 2", "type": "consu", "list_price": 20.0, } ) def test_create_group_order(self): """Test crear un pedido de grupo.""" order = self.env["group.order"].create( { "name": "Pedido Semanal Test", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": (datetime.now() + timedelta(days=7)).date(), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) self.assertTrue(order.exists()) self.assertEqual(order.state, "draft") self.assertIn(self.group, order.group_ids) def test_group_order_dates_validation(self): """Test that start_date must be before end_date""" with self.assertRaises(ValidationError): self.env["group.order"].create( { "name": "Pedido Invalid", "start_date": fields.Date.today() + timedelta(days=7), "end_date": fields.Date.today(), } ) def test_group_order_state_transitions(self): """Test transiciones de estado.""" order = self.env["group.order"].create( { "name": "Pedido State Test", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": (datetime.now() + timedelta(days=7)).date(), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) # Draft -> Open order.action_open() self.assertEqual(order.state, "open") # Open -> Closed order.action_close() self.assertEqual(order.state, "closed") def test_group_order_action_cancel(self): """Test cancelar un pedido.""" order = self.env["group.order"].create( { "name": "Pedido Cancel Test", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": (datetime.now() + timedelta(days=7)).date(), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) order.action_cancel() self.assertEqual(order.state, "cancelled") def test_get_active_orders_for_week(self): """Test obtener pedidos activos para la semana.""" today = datetime.now().date() week_start = today - timedelta(days=today.weekday()) week_end = week_start + timedelta(days=6) # Crear pedido activo esta semana active_order = self.env["group.order"].create( { "name": "Pedido Activo", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": week_start, "end_date": week_end, "period": "weekly", "pickup_day": "5", "cutoff_day": "0", "state": "open", } ) # Crear pedido inactivo (futuro) future_order = self.env["group.order"].create( { "name": "Pedido Futuro", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": week_end + timedelta(days=1), "end_date": week_end + timedelta(days=8), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", "state": "open", } ) active_orders = self.env["group.order"].search( [ ("state", "=", "open"), "|", ("end_date", ">=", week_start), ("end_date", "=", False), ("start_date", "<=", week_end), ] ) self.assertIn(active_order, active_orders) self.assertNotIn(future_order, active_orders) def test_permanent_group_order(self): """Test crear un pedido permanente (sin end_date).""" order = self.env["group.order"].create( { "name": "Pedido Permanente", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": False, "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) self.assertTrue(order.exists()) self.assertFalse(order.end_date) def test_get_active_orders_excludes_draft(self): """Test que get_active_orders_for_week NO incluye pedidos en draft.""" today = datetime.now().date() # Crear pedido en draft (no abierto) draft_order = self.env["group.order"].create( { "name": "Pedido Draft", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": today, "end_date": today + timedelta(days=7), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", "state": "draft", } ) today = datetime.now().date() week_start = today - timedelta(days=today.weekday()) week_end = week_start + timedelta(days=6) active_orders = self.env["group.order"].search( [ ("state", "=", "open"), "|", ("end_date", ">=", week_start), ("end_date", "=", False), ("start_date", "<=", week_end), ] ) self.assertNotIn(draft_order, active_orders) def test_get_active_orders_excludes_closed(self): """Test que get_active_orders_for_week NO incluye pedidos cerrados.""" today = datetime.now().date() closed_order = self.env["group.order"].create( { "name": "Pedido Cerrado", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": today, "end_date": today + timedelta(days=7), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", "state": "closed", } ) today = datetime.now().date() week_start = today - timedelta(days=today.weekday()) week_end = week_start + timedelta(days=6) active_orders = self.env["group.order"].search( [ ("state", "=", "open"), "|", ("end_date", ">=", week_start), ("end_date", "=", False), ("start_date", "<=", week_end), ] ) self.assertNotIn(closed_order, active_orders) def test_get_active_orders_excludes_cancelled(self): """Test que get_active_orders_for_week NO incluye pedidos cancelados.""" today = datetime.now().date() cancelled_order = self.env["group.order"].create( { "name": "Pedido Cancelado", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": today, "end_date": today + timedelta(days=7), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", "state": "cancelled", } ) today = datetime.now().date() week_start = today - timedelta(days=today.weekday()) week_end = week_start + timedelta(days=6) active_orders = self.env["group.order"].search( [ ("state", "=", "open"), "|", ("end_date", ">=", week_start), ("end_date", "=", False), ("start_date", "<=", week_end), ] ) self.assertNotIn(cancelled_order, active_orders) def test_state_transition_draft_to_open(self): """Test que un pedido pasa de draft a open.""" order = self.env["group.order"].create( { "name": "Pedido Estado Test", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": datetime.now().date() + timedelta(days=7), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) self.assertEqual(order.state, "draft") order.action_open() self.assertEqual(order.state, "open") def test_state_transition_open_to_closed(self): """Test transición válida open -> closed.""" order = self.env["group.order"].create( { "name": "Pedido Estado Test", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": datetime.now().date() + timedelta(days=7), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) order.action_open() self.assertEqual(order.state, "open") order.action_close() self.assertEqual(order.state, "closed") def test_state_transition_any_to_cancelled(self): """Test cancelar desde cualquier estado.""" order = self.env["group.order"].create( { "name": "Pedido Estado Test", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": datetime.now().date() + timedelta(days=7), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) # Desde draft order.action_cancel() self.assertEqual(order.state, "cancelled") # Crear otro desde open order2 = self.env["group.order"].create( { "name": "Pedido Estado Test 2", "group_ids": [(6, 0, [self.group.id])], "type": "regular", "start_date": datetime.now().date(), "end_date": datetime.now().date() + timedelta(days=7), "period": "weekly", "pickup_day": "5", "cutoff_day": "0", } ) order2.action_open() order2.action_cancel() self.assertEqual(order2.state, "cancelled")