- Add mypy.ini configuration to exclude migration scripts - Rename migration files to proper snake_case (post-migration.py → post_migration.py) - Add __init__.py to migration directories for proper Python package structure - Add new portal access tests for website_sale_aplicoop - Code formatting improvements (black, isort) - Update copilot instructions and project configuration Related to previous code quality refactoring work.
354 lines
12 KiB
Python
354 lines
12 KiB
Python
# 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")
|