# Copyright 2025 Criptomart # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) from datetime import datetime, timedelta from odoo.tests.common import TransactionCase from odoo.exceptions import ValidationError from psycopg2 import IntegrityError from odoo import fields 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')