[FIX] website_sale_aplicoop: Remove redundant string= attributes and fix OCA linting warnings
- Remove redundant string= from 17 field definitions where name matches string value (W8113) - Convert @staticmethod to instance methods in selection methods for proper self.env._() access - Fix W8161 (prefer-env-translation) by using self.env._() instead of standalone _() - Fix W8301/W8115 (translation-not-lazy) by proper placement of % interpolation outside self.env._() - Remove unused imports of odoo._ from group_order.py and sale_order_extension.py - All OCA linting warnings in website_sale_aplicoop main models are now resolved Changes: - website_sale_aplicoop/models/group_order.py: 21 field definitions cleaned - website_sale_aplicoop/models/sale_order_extension.py: 5 field definitions cleaned + @staticmethod conversion - Consistent with OCA standards for addon submission
This commit is contained in:
parent
5c89795e30
commit
6fbc7b9456
73 changed files with 5386 additions and 4354 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Análisis de Cobertura de Tests - website_sale_aplicoop
|
||||
|
||||
**Fecha**: 11 de febrero de 2026
|
||||
**Estado**: ✅ **ACTUALIZADO** - Tests de pricing agregados
|
||||
**Fecha**: 11 de febrero de 2026
|
||||
**Estado**: ✅ **ACTUALIZADO** - Tests de pricing agregados
|
||||
**Última actualización**: Sistema de precios completamente cubierto (16 nuevos tests)
|
||||
|
||||
---
|
||||
|
|
@ -310,7 +310,7 @@ Sistema de precios: 0% coverage (CRÍTICO)
|
|||
Sistema de precios: ~95% coverage (✅ RESUELTO)
|
||||
```
|
||||
|
||||
**Tiempo invertido**: ~2 horas
|
||||
**Tiempo invertido**: ~2 horas
|
||||
**ROI**: Alto - Se cubrió funcionalidad crítica de cálculo de precios
|
||||
|
||||
---
|
||||
|
|
@ -343,7 +343,7 @@ Si se necesita más cobertura, priorizar en este orden:
|
|||
|
||||
---
|
||||
|
||||
**Conclusión Final**:
|
||||
**Conclusión Final**:
|
||||
|
||||
✅ **El sistema de precios está completamente testeado y producción-ready.**
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ Coverage:
|
|||
- Draft timeline (very old draft, recent draft)
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
|
@ -23,91 +24,117 @@ class TestSaveDraftOrder(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Test Category',
|
||||
})
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category",
|
||||
}
|
||||
)
|
||||
|
||||
self.product1 = self.env['product.product'].create({
|
||||
'name': 'Product 1',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'categ_id': self.category.id,
|
||||
})
|
||||
self.product1 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product 1",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"categ_id": self.category.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.product2 = self.env['product.product'].create({
|
||||
'name': 'Product 2',
|
||||
'type': 'consu',
|
||||
'list_price': 20.0,
|
||||
'categ_id': self.category.id,
|
||||
})
|
||||
self.product2 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product 2",
|
||||
"type": "consu",
|
||||
"list_price": 20.0,
|
||||
"categ_id": self.category.id,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'pickup_date': start_date + timedelta(days=3),
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"pickup_date": start_date + timedelta(days=3),
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
self.group_order.product_ids = [(4, self.product1.id), (4, self.product2.id)]
|
||||
|
||||
def test_save_draft_with_items(self):
|
||||
"""Test saving draft order with products."""
|
||||
draft_order = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
'order_line': [
|
||||
(0, 0, {
|
||||
'product_id': self.product1.id,
|
||||
'product_qty': 2,
|
||||
'price_unit': self.product1.list_price,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': self.product2.id,
|
||||
'product_qty': 1,
|
||||
'price_unit': self.product2.list_price,
|
||||
}),
|
||||
],
|
||||
})
|
||||
draft_order = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
"order_line": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product1.id,
|
||||
"product_qty": 2,
|
||||
"price_unit": self.product1.list_price,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product2.id,
|
||||
"product_qty": 1,
|
||||
"price_unit": self.product2.list_price,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(draft_order.exists())
|
||||
self.assertEqual(draft_order.state, 'draft')
|
||||
self.assertEqual(draft_order.state, "draft")
|
||||
self.assertEqual(len(draft_order.order_line), 2)
|
||||
|
||||
def test_save_draft_empty_order(self):
|
||||
"""Test saving draft order without items."""
|
||||
# Edge case: empty draft
|
||||
empty_draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
'order_line': [],
|
||||
})
|
||||
empty_draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
"order_line": [],
|
||||
}
|
||||
)
|
||||
|
||||
# Should be valid (user hasn't added products yet)
|
||||
self.assertTrue(empty_draft.exists())
|
||||
|
|
@ -116,15 +143,23 @@ class TestSaveDraftOrder(TransactionCase):
|
|||
def test_save_draft_updates_existing(self):
|
||||
"""Test that saving draft updates existing draft, not creates new."""
|
||||
# Create initial draft
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
'order_line': [(0, 0, {
|
||||
'product_id': self.product1.id,
|
||||
'product_qty': 1,
|
||||
})],
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
"order_line": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product1.id,
|
||||
"product_qty": 1,
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
draft_id = draft.id
|
||||
|
||||
|
|
@ -132,29 +167,33 @@ class TestSaveDraftOrder(TransactionCase):
|
|||
draft.order_line[0].product_qty = 5
|
||||
|
||||
# Should be same draft, not new one
|
||||
updated_draft = self.env['sale.order'].browse(draft_id)
|
||||
updated_draft = self.env["sale.order"].browse(draft_id)
|
||||
self.assertTrue(updated_draft.exists())
|
||||
self.assertEqual(updated_draft.order_line[0].product_qty, 5)
|
||||
|
||||
def test_save_draft_preserves_group_order_reference(self):
|
||||
"""Test that group_order_id is preserved when saving."""
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Link must be preserved
|
||||
self.assertEqual(draft.group_order_id, self.group_order)
|
||||
|
||||
def test_save_draft_preserves_pickup_date(self):
|
||||
"""Test that pickup_date is preserved in draft."""
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'state': 'draft',
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(draft.pickup_date, self.group_order.pickup_date)
|
||||
|
||||
|
|
@ -164,63 +203,83 @@ class TestLoadDraftOrder(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
|
||||
def test_load_existing_draft(self):
|
||||
"""Test loading an existing draft order."""
|
||||
# Create draft
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
'order_line': [(0, 0, {
|
||||
'product_id': self.product.id,
|
||||
'product_qty': 3,
|
||||
})],
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
"order_line": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product.id,
|
||||
"product_qty": 3,
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
# Load it
|
||||
loaded = self.env['sale.order'].search([
|
||||
('id', '=', draft.id),
|
||||
('partner_id', '=', self.member_partner.id),
|
||||
('state', '=', 'draft'),
|
||||
])
|
||||
loaded = self.env["sale.order"].search(
|
||||
[
|
||||
("id", "=", draft.id),
|
||||
("partner_id", "=", self.member_partner.id),
|
||||
("state", "=", "draft"),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(len(loaded), 1)
|
||||
self.assertEqual(loaded[0].order_line[0].product_qty, 3)
|
||||
|
|
@ -228,29 +287,37 @@ class TestLoadDraftOrder(TransactionCase):
|
|||
def test_load_draft_not_visible_to_other_user(self):
|
||||
"""Test that draft from one user not accessible to another."""
|
||||
# Create draft for member_partner
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Create another user/partner
|
||||
other_partner = self.env['res.partner'].create({
|
||||
'name': 'Other Member',
|
||||
'email': 'other@test.com',
|
||||
})
|
||||
other_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Other Member",
|
||||
"email": "other@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
other_user = self.env['res.users'].create({
|
||||
'name': 'Other User',
|
||||
'login': 'other@test.com',
|
||||
'partner_id': other_partner.id,
|
||||
})
|
||||
other_user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Other User",
|
||||
"login": "other@test.com",
|
||||
"partner_id": other_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Other user should not see original draft
|
||||
other_drafts = self.env['sale.order'].search([
|
||||
('id', '=', draft.id),
|
||||
('partner_id', '=', other_partner.id),
|
||||
])
|
||||
other_drafts = self.env["sale.order"].search(
|
||||
[
|
||||
("id", "=", draft.id),
|
||||
("partner_id", "=", other_partner.id),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(len(other_drafts), 0)
|
||||
|
||||
|
|
@ -260,14 +327,16 @@ class TestLoadDraftOrder(TransactionCase):
|
|||
self.group_order.action_close()
|
||||
|
||||
# Create draft before closure (simulated)
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Draft should still be loadable (but should warn)
|
||||
loaded = self.env['sale.order'].browse(draft.id)
|
||||
loaded = self.env["sale.order"].browse(draft.id)
|
||||
self.assertTrue(loaded.exists())
|
||||
# Controller should check: group_order.state and warn if closed
|
||||
|
||||
|
|
@ -277,41 +346,51 @@ class TestDraftConsistency(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 100.0,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 100.0,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
|
||||
def test_draft_price_snapshot(self):
|
||||
|
|
@ -319,16 +398,24 @@ class TestDraftConsistency(TransactionCase):
|
|||
original_price = self.product.list_price
|
||||
|
||||
# Save draft with current price
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
'order_line': [(0, 0, {
|
||||
'product_id': self.product.id,
|
||||
'product_qty': 1,
|
||||
'price_unit': original_price,
|
||||
})],
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
"order_line": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product.id,
|
||||
"product_qty": 1,
|
||||
"price_unit": original_price,
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
saved_price = draft.order_line[0].price_unit
|
||||
|
||||
|
|
@ -342,18 +429,26 @@ class TestDraftConsistency(TransactionCase):
|
|||
def test_draft_quantity_consistency(self):
|
||||
"""Test that quantities are preserved across saves."""
|
||||
# Save draft
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
'order_line': [(0, 0, {
|
||||
'product_id': self.product.id,
|
||||
'product_qty': 5,
|
||||
})],
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
"order_line": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product.id,
|
||||
"product_qty": 5,
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
# Re-load draft
|
||||
reloaded = self.env['sale.order'].browse(draft.id)
|
||||
reloaded = self.env["sale.order"].browse(draft.id)
|
||||
self.assertEqual(reloaded.order_line[0].product_qty, 5)
|
||||
|
||||
|
||||
|
|
@ -362,62 +457,80 @@ class TestProductArchivedInDraft(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'active': True,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"active": True,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
|
||||
def test_load_draft_with_archived_product(self):
|
||||
"""Test loading draft when product has been archived."""
|
||||
# Create draft with active product
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
'order_line': [(0, 0, {
|
||||
'product_id': self.product.id,
|
||||
'product_qty': 2,
|
||||
})],
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
"order_line": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": self.product.id,
|
||||
"product_qty": 2,
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
# Archive the product
|
||||
self.product.active = False
|
||||
|
||||
# Load draft - should still work (historical data)
|
||||
loaded = self.env['sale.order'].browse(draft.id)
|
||||
loaded = self.env["sale.order"].browse(draft.id)
|
||||
self.assertTrue(loaded.exists())
|
||||
# But product may not be editable/accessible
|
||||
|
||||
|
|
@ -427,108 +540,128 @@ class TestDraftTimeline(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
}
|
||||
)
|
||||
|
||||
def test_draft_from_current_week(self):
|
||||
"""Test draft from current/open group order."""
|
||||
start_date = datetime.now().date()
|
||||
current_order = self.env['group.order'].create({
|
||||
'name': 'Current Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
current_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Current Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
current_order.action_open()
|
||||
|
||||
draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': current_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": current_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Should be accessible and valid
|
||||
self.assertTrue(draft.exists())
|
||||
self.assertEqual(draft.group_order_id.state, 'open')
|
||||
self.assertEqual(draft.group_order_id.state, "open")
|
||||
|
||||
def test_draft_from_old_order_6_months_ago(self):
|
||||
"""Test draft from order that was 6 months ago."""
|
||||
old_start = datetime.now().date() - timedelta(days=180)
|
||||
old_end = old_start + timedelta(days=7)
|
||||
|
||||
old_order = self.env['group.order'].create({
|
||||
'name': 'Old Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': old_start,
|
||||
'end_date': old_end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
old_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Old Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": old_start,
|
||||
"end_date": old_end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
old_order.action_open()
|
||||
old_order.action_close()
|
||||
|
||||
old_draft = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': old_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
old_draft = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": old_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Should still exist but be inaccessible (order closed)
|
||||
self.assertTrue(old_draft.exists())
|
||||
self.assertEqual(old_order.state, 'closed')
|
||||
self.assertEqual(old_order.state, "closed")
|
||||
|
||||
def test_draft_order_count_for_user(self):
|
||||
"""Test counting total drafts for a user."""
|
||||
# Create multiple orders and drafts
|
||||
orders = []
|
||||
for i in range(3):
|
||||
start = datetime.now().date() + timedelta(days=i*7)
|
||||
order = self.env['group.order'].create({
|
||||
'name': f'Order {i}',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': start + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
start = datetime.now().date() + timedelta(days=i * 7)
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": f"Order {i}",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": start + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
order.action_open()
|
||||
orders.append(order)
|
||||
|
||||
# Create draft for each
|
||||
for order in orders:
|
||||
self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Count drafts for user
|
||||
user_drafts = self.env['sale.order'].search([
|
||||
('partner_id', '=', self.member_partner.id),
|
||||
('state', '=', 'draft'),
|
||||
])
|
||||
user_drafts = self.env["sale.order"].search(
|
||||
[
|
||||
("partner_id", "=", self.member_partner.id),
|
||||
("state", "=", "draft"),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(len(user_drafts), 3)
|
||||
|
|
|
|||
|
|
@ -13,11 +13,13 @@ Coverage:
|
|||
- Extreme dates (year 1900, year 2099)
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta, date
|
||||
from datetime import date
|
||||
from datetime import timedelta
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestLeapYearHandling(TransactionCase):
|
||||
|
|
@ -25,10 +27,12 @@ class TestLeapYearHandling(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_order_spans_leap_day(self):
|
||||
"""Test order that includes Feb 29 (leap year)."""
|
||||
|
|
@ -36,16 +40,18 @@ class TestLeapYearHandling(TransactionCase):
|
|||
start = date(2024, 2, 25)
|
||||
end = date(2024, 3, 3) # Spans Feb 29
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Leap Year Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '2', # Wednesday (Feb 28 or 29 depending on week)
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Leap Year Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "2", # Wednesday (Feb 28 or 29 depending on week)
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# Should correctly calculate pickup date
|
||||
|
|
@ -57,16 +63,18 @@ class TestLeapYearHandling(TransactionCase):
|
|||
start = date(2024, 2, 26) # Monday
|
||||
end = date(2024, 3, 3)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Feb 29 Pickup',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3', # Thursday = Feb 29
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Feb 29 Pickup",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3", # Thursday = Feb 29
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(order.pickup_date, date(2024, 2, 29))
|
||||
|
||||
|
|
@ -76,16 +84,18 @@ class TestLeapYearHandling(TransactionCase):
|
|||
start = date(2023, 2, 25)
|
||||
end = date(2023, 3, 3)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Non-Leap Year Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '2',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Non-Leap Year Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "2",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# Pickup should be Feb 28 (last day of Feb)
|
||||
|
|
@ -97,26 +107,30 @@ class TestLongDurationOrders(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_order_spans_entire_year(self):
|
||||
"""Test order running for 365 days."""
|
||||
start = date(2024, 1, 1)
|
||||
end = date(2024, 12, 31)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Year-Long Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3', # Same day each week
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Year-Long Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3", # Same day each week
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# Should handle 52+ weeks correctly
|
||||
|
|
@ -128,16 +142,18 @@ class TestLongDurationOrders(TransactionCase):
|
|||
start = date(2024, 1, 1)
|
||||
end = date(2026, 12, 31) # 3 years
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Multi-Year Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'monthly',
|
||||
'pickup_day': '15',
|
||||
'cutoff_day': '10',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Multi-Year Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "monthly",
|
||||
"pickup_day": "15",
|
||||
"cutoff_day": "10",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
days_diff = (end - start).days
|
||||
|
|
@ -147,16 +163,18 @@ class TestLongDurationOrders(TransactionCase):
|
|||
"""Test order with start_date == end_date (single day)."""
|
||||
same_day = date(2024, 2, 15)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'One-Day Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'once',
|
||||
'start_date': same_day,
|
||||
'end_date': same_day,
|
||||
'period': 'once',
|
||||
'pickup_day': '0',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "One-Day Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "once",
|
||||
"start_date": same_day,
|
||||
"end_date": same_day,
|
||||
"period": "once",
|
||||
"pickup_day": "0",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
|
||||
|
|
@ -166,10 +184,12 @@ class TestPickupDayBoundary(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_pickup_day_same_as_start_date(self):
|
||||
"""Test when pickup_day equals start date (today)."""
|
||||
|
|
@ -177,16 +197,18 @@ class TestPickupDayBoundary(TransactionCase):
|
|||
start = today
|
||||
end = today + timedelta(days=7)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Today Pickup',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': str(start.weekday()), # Same as start
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Today Pickup",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": str(start.weekday()), # Same as start
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# Pickup should be today
|
||||
|
|
@ -198,16 +220,18 @@ class TestPickupDayBoundary(TransactionCase):
|
|||
start = date(2024, 1, 24)
|
||||
end = date(2024, 2, 1)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Month-End Pickup',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'once',
|
||||
'pickup_day': '2', # Wednesday = Jan 31
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Month-End Pickup",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "once",
|
||||
"pickup_day": "2", # Wednesday = Jan 31
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
|
||||
|
|
@ -217,16 +241,18 @@ class TestPickupDayBoundary(TransactionCase):
|
|||
start = date(2024, 1, 28)
|
||||
end = date(2024, 2, 5)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Month Boundary Pickup',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '4', # Friday (Feb 2)
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Month Boundary Pickup",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "4", # Friday (Feb 2)
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# Pickup should be in Feb
|
||||
|
|
@ -238,16 +264,18 @@ class TestPickupDayBoundary(TransactionCase):
|
|||
end = date(2024, 1, 8)
|
||||
|
||||
for day_num in range(7):
|
||||
order = self.env['group.order'].create({
|
||||
'name': f'Pickup Day {day_num}',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': str(day_num),
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": f"Pickup Day {day_num}",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": str(day_num),
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# Each should have valid pickup_date
|
||||
|
|
@ -259,10 +287,12 @@ class TestFutureStartDateOrders(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_order_starts_tomorrow(self):
|
||||
"""Test order starting tomorrow."""
|
||||
|
|
@ -270,16 +300,18 @@ class TestFutureStartDateOrders(TransactionCase):
|
|||
start = today + timedelta(days=1)
|
||||
end = start + timedelta(days=7)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Future Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Future Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
self.assertGreater(order.start_date, today)
|
||||
|
|
@ -290,16 +322,18 @@ class TestFutureStartDateOrders(TransactionCase):
|
|||
start = today + relativedelta(months=6)
|
||||
end = start + timedelta(days=30)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Far Future Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'monthly',
|
||||
'pickup_day': '15',
|
||||
'cutoff_day': '10',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Far Future Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "monthly",
|
||||
"pickup_day": "15",
|
||||
"cutoff_day": "10",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
|
||||
|
|
@ -309,26 +343,30 @@ class TestExtremeDate(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_order_year_2000(self):
|
||||
"""Test order in year 2000 (Y2K edge case)."""
|
||||
start = date(2000, 1, 1)
|
||||
end = date(2000, 12, 31)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Y2K Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Y2K Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
|
||||
|
|
@ -337,16 +375,18 @@ class TestExtremeDate(TransactionCase):
|
|||
start = date(2099, 1, 1)
|
||||
end = date(2099, 12, 31)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Far Future Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Far Future Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
|
||||
|
|
@ -355,16 +395,18 @@ class TestExtremeDate(TransactionCase):
|
|||
start = date(1999, 12, 26)
|
||||
end = date(2000, 1, 2)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Century Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '6', # Saturday
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Century Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "6", # Saturday
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# Should handle date arithmetic correctly across years
|
||||
|
|
@ -377,25 +419,29 @@ class TestOrderWithoutEndDate(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_permanent_order_with_null_end_date(self):
|
||||
"""Test order with end_date = NULL (ongoing order)."""
|
||||
start = date.today()
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Permanent Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': False, # No end date
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Permanent Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": False, # No end date
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
# If supported, should handle gracefully
|
||||
# Otherwise, may be optional validation
|
||||
|
|
@ -406,10 +452,12 @@ class TestPickupCalculationAccuracy(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_pickup_date_calculation_multiple_weeks(self):
|
||||
"""Test pickup_date calculation over multiple weeks."""
|
||||
|
|
@ -417,16 +465,18 @@ class TestPickupCalculationAccuracy(TransactionCase):
|
|||
start = date(2024, 1, 1)
|
||||
end = date(2024, 1, 22)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Multi-Week Pickup',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3', # Thursday
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Multi-Week Pickup",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3", # Thursday
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# First pickup should be first Thursday on or after start
|
||||
|
|
@ -438,16 +488,18 @@ class TestPickupCalculationAccuracy(TransactionCase):
|
|||
start = date(2024, 2, 1)
|
||||
end = date(2024, 3, 31)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Monthly Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start,
|
||||
'end_date': end,
|
||||
'period': 'monthly',
|
||||
'pickup_day': '15',
|
||||
'cutoff_day': '10',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Monthly Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start,
|
||||
"end_date": end,
|
||||
"period": "monthly",
|
||||
"pickup_day": "15",
|
||||
"cutoff_day": "10",
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(order.exists())
|
||||
# First pickup should be Feb 15
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@ Coverage:
|
|||
- /eskaera/labels (GET) - Get translated labels
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
import json
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase, HttpCase
|
||||
from odoo.exceptions import ValidationError, AccessError
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import HttpCase
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestEskaearaListEndpoint(TransactionCase):
|
||||
|
|
@ -28,63 +30,75 @@ class TestEskaearaListEndpoint(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
'email': 'group@test.com',
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
"email": "group@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create multiple group orders (some open, some closed)
|
||||
start_date = datetime.now().date()
|
||||
|
||||
self.open_order = self.env['group.order'].create({
|
||||
'name': 'Open Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.open_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Open Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.open_order.action_open()
|
||||
|
||||
self.draft_order = self.env['group.order'].create({
|
||||
'name': 'Draft Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date - timedelta(days=14),
|
||||
'end_date': start_date - timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.draft_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Draft Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date - timedelta(days=14),
|
||||
"end_date": start_date - timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
# Stay in draft
|
||||
|
||||
self.closed_order = self.env['group.order'].create({
|
||||
'name': 'Closed Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date - timedelta(days=21),
|
||||
'end_date': start_date - timedelta(days=14),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.closed_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Closed Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date - timedelta(days=21),
|
||||
"end_date": start_date - timedelta(days=14),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.closed_order.action_open()
|
||||
self.closed_order.action_close()
|
||||
|
||||
|
|
@ -92,10 +106,12 @@ class TestEskaearaListEndpoint(TransactionCase):
|
|||
"""Test that /eskaera shows only open/draft orders, not closed."""
|
||||
# In controller context, only open and draft should be visible to members
|
||||
# This is business logic: closed orders are historical
|
||||
visible_orders = self.env['group.order'].search([
|
||||
('state', 'in', ['open', 'draft']),
|
||||
('group_ids', 'in', self.group.id),
|
||||
])
|
||||
visible_orders = self.env["group.order"].search(
|
||||
[
|
||||
("state", "in", ["open", "draft"]),
|
||||
("group_ids", "in", self.group.id),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertIn(self.open_order, visible_orders)
|
||||
self.assertIn(self.draft_order, visible_orders)
|
||||
|
|
@ -103,30 +119,36 @@ class TestEskaearaListEndpoint(TransactionCase):
|
|||
|
||||
def test_eskaera_list_filters_by_user_groups(self):
|
||||
"""Test that user only sees orders from their groups."""
|
||||
other_group = self.env['res.partner'].create({
|
||||
'name': 'Other Group',
|
||||
'is_company': True,
|
||||
'email': 'other@test.com',
|
||||
})
|
||||
other_group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Other Group",
|
||||
"is_company": True,
|
||||
"email": "other@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
other_order = self.env['group.order'].create({
|
||||
'name': 'Other Group Order',
|
||||
'group_ids': [(6, 0, [other_group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': datetime.now().date(),
|
||||
'end_date': datetime.now().date() + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
other_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Other Group Order",
|
||||
"group_ids": [(6, 0, [other_group.id])],
|
||||
"type": "regular",
|
||||
"start_date": datetime.now().date(),
|
||||
"end_date": datetime.now().date() + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
other_order.action_open()
|
||||
|
||||
# User should not see orders from groups they're not in
|
||||
user_groups = self.member_partner.group_ids
|
||||
visible_orders = self.env['group.order'].search([
|
||||
('state', 'in', ['open', 'draft']),
|
||||
('group_ids', 'in', user_groups.ids),
|
||||
])
|
||||
visible_orders = self.env["group.order"].search(
|
||||
[
|
||||
("state", "in", ["open", "draft"]),
|
||||
("group_ids", "in", user_groups.ids),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertNotIn(other_order, visible_orders)
|
||||
|
||||
|
|
@ -136,61 +158,75 @@ class TestAddToCartEndpoint(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
'email': 'group@test.com',
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
"email": "group@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Test Category',
|
||||
})
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category",
|
||||
}
|
||||
)
|
||||
|
||||
# Published product
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'categ_id': self.category.id,
|
||||
'sale_ok': True,
|
||||
'is_published': True,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"categ_id": self.category.id,
|
||||
"sale_ok": True,
|
||||
"is_published": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Unpublished product (should not be available)
|
||||
self.unpublished_product = self.env['product.product'].create({
|
||||
'name': 'Unpublished Product',
|
||||
'type': 'consu',
|
||||
'list_price': 15.0,
|
||||
'categ_id': self.category.id,
|
||||
'sale_ok': False,
|
||||
'is_published': False,
|
||||
})
|
||||
self.unpublished_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Unpublished Product",
|
||||
"type": "consu",
|
||||
"list_price": 15.0,
|
||||
"categ_id": self.category.id,
|
||||
"sale_ok": False,
|
||||
"is_published": False,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
self.group_order.product_ids = [(4, self.product.id)]
|
||||
|
||||
|
|
@ -198,13 +234,13 @@ class TestAddToCartEndpoint(TransactionCase):
|
|||
"""Test adding published product to cart."""
|
||||
# Simulate controller logic
|
||||
cart_line = {
|
||||
'product_id': self.product.id,
|
||||
'quantity': 2,
|
||||
'group_order_id': self.group_order.id,
|
||||
'partner_id': self.member_partner.id,
|
||||
"product_id": self.product.id,
|
||||
"quantity": 2,
|
||||
"group_order_id": self.group_order.id,
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
# Should succeed
|
||||
self.assertTrue(cart_line['product_id'])
|
||||
self.assertTrue(cart_line["product_id"])
|
||||
|
||||
def test_add_to_cart_zero_quantity(self):
|
||||
"""Test that adding zero quantity is rejected."""
|
||||
|
|
@ -228,11 +264,13 @@ class TestAddToCartEndpoint(TransactionCase):
|
|||
def test_add_to_cart_product_not_in_order(self):
|
||||
"""Test that products not in the order cannot be added."""
|
||||
# Create a product NOT associated with group_order
|
||||
other_product = self.env['product.product'].create({
|
||||
'name': 'Other Product',
|
||||
'type': 'consu',
|
||||
'list_price': 25.0,
|
||||
})
|
||||
other_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Other Product",
|
||||
"type": "consu",
|
||||
"list_price": 25.0,
|
||||
}
|
||||
)
|
||||
|
||||
# Controller should check: product in group_order.product_ids
|
||||
self.assertNotIn(other_product, self.group_order.product_ids)
|
||||
|
|
@ -241,7 +279,7 @@ class TestAddToCartEndpoint(TransactionCase):
|
|||
"""Test that adding to closed order is rejected."""
|
||||
self.group_order.action_close()
|
||||
# Controller should check: order.state == 'open'
|
||||
self.assertEqual(self.group_order.state, 'closed')
|
||||
self.assertEqual(self.group_order.state, "closed")
|
||||
|
||||
|
||||
class TestCheckoutEndpoint(TransactionCase):
|
||||
|
|
@ -249,38 +287,46 @@ class TestCheckoutEndpoint(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
'email': 'group@test.com',
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
"email": "group@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'pickup_date': start_date + timedelta(days=3),
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"pickup_date": start_date + timedelta(days=3),
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
|
||||
def test_checkout_page_loads(self):
|
||||
|
|
@ -301,16 +347,18 @@ class TestCheckoutEndpoint(TransactionCase):
|
|||
def test_checkout_order_without_products(self):
|
||||
"""Test checkout when no products available."""
|
||||
# Order with empty product_ids
|
||||
empty_order = self.env['group.order'].create({
|
||||
'name': 'Empty Order',
|
||||
'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': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
empty_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Empty Order",
|
||||
"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": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
empty_order.action_open()
|
||||
|
||||
# Should handle gracefully
|
||||
|
|
@ -322,95 +370,115 @@ class TestConfirmOrderEndpoint(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
'email': 'group@test.com',
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
"email": "group@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Test Category',
|
||||
})
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category",
|
||||
}
|
||||
)
|
||||
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'categ_id': self.category.id,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"categ_id": self.category.id,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'pickup_date': start_date + timedelta(days=3),
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"pickup_date": start_date + timedelta(days=3),
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
self.group_order.product_ids = [(4, self.product.id)]
|
||||
|
||||
# Create a draft sale order
|
||||
self.draft_sale = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'state': 'draft',
|
||||
})
|
||||
self.draft_sale = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
def test_confirm_order_creates_sale_order(self):
|
||||
"""Test that confirming creates a confirmed sale.order."""
|
||||
# Controller should change state from draft to sale
|
||||
self.draft_sale.action_confirm()
|
||||
self.assertEqual(self.draft_sale.state, 'sale')
|
||||
self.assertEqual(self.draft_sale.state, "sale")
|
||||
|
||||
def test_confirm_empty_order(self):
|
||||
"""Test confirming order without items fails."""
|
||||
# Order with no order_lines should fail
|
||||
empty_sale = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
empty_sale = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Should validate: must have at least one line
|
||||
self.assertEqual(len(empty_sale.order_line), 0)
|
||||
|
||||
def test_confirm_order_wrong_group(self):
|
||||
"""Test that user cannot confirm order from different group."""
|
||||
other_group = self.env['res.partner'].create({
|
||||
'name': 'Other Group',
|
||||
'is_company': True,
|
||||
})
|
||||
other_group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Other Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
other_order = self.env['group.order'].create({
|
||||
'name': 'Other Order',
|
||||
'group_ids': [(6, 0, [other_group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': datetime.now().date(),
|
||||
'end_date': datetime.now().date() + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
other_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Other Order",
|
||||
"group_ids": [(6, 0, [other_group.id])],
|
||||
"type": "regular",
|
||||
"start_date": datetime.now().date(),
|
||||
"end_date": datetime.now().date() + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
# User should not be in other_group
|
||||
self.assertNotIn(self.member_partner, other_group.member_ids)
|
||||
|
|
@ -421,76 +489,94 @@ class TestLoadDraftEndpoint(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
'email': 'group@test.com',
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
"email": "group@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Test Category',
|
||||
})
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category",
|
||||
}
|
||||
)
|
||||
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'categ_id': self.category.id,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"categ_id": self.category.id,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'pickup_date': start_date + timedelta(days=3),
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"pickup_date": start_date + timedelta(days=3),
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.group_order.action_open()
|
||||
self.group_order.product_ids = [(4, self.product.id)]
|
||||
|
||||
def test_load_draft_from_history(self):
|
||||
"""Test loading a previous draft order."""
|
||||
# Create old draft sale
|
||||
old_sale = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
old_sale = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Should be able to load
|
||||
self.assertTrue(old_sale.exists())
|
||||
|
||||
def test_load_draft_not_owned_by_user(self):
|
||||
"""Test that user cannot load draft from other user."""
|
||||
other_partner = self.env['res.partner'].create({
|
||||
'name': 'Other Member',
|
||||
'email': 'other@test.com',
|
||||
})
|
||||
other_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Other Member",
|
||||
"email": "other@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
other_sale = self.env['sale.order'].create({
|
||||
'partner_id': other_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
other_sale = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": other_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# User should not be able to load other's draft
|
||||
self.assertNotEqual(other_sale.partner_id, self.member_partner)
|
||||
|
|
@ -500,24 +586,28 @@ class TestLoadDraftEndpoint(TransactionCase):
|
|||
old_start = datetime.now().date() - timedelta(days=30)
|
||||
old_end = datetime.now().date() - timedelta(days=23)
|
||||
|
||||
expired_order = self.env['group.order'].create({
|
||||
'name': 'Expired Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': old_start,
|
||||
'end_date': old_end,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
expired_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Expired Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": old_start,
|
||||
"end_date": old_end,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
expired_order.action_open()
|
||||
expired_order.action_close()
|
||||
|
||||
old_sale = self.env['sale.order'].create({
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': expired_order.id,
|
||||
'state': 'draft',
|
||||
})
|
||||
old_sale = self.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": expired_order.id,
|
||||
"state": "draft",
|
||||
}
|
||||
)
|
||||
|
||||
# Should warn: order expired
|
||||
self.assertEqual(expired_order.state, 'closed')
|
||||
self.assertEqual(expired_order.state, "closed")
|
||||
|
|
|
|||
|
|
@ -1,127 +1,158 @@
|
|||
# Copyright 2025 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestEskaerShop(TransactionCase):
|
||||
'''Test suite para la lógica de eskaera_shop (descubrimiento de productos).'''
|
||||
"""Test suite para la lógica de eskaera_shop (descubrimiento de productos)."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Crear un grupo (res.partner)
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Grupo Test Eskaera',
|
||||
'is_company': True,
|
||||
'email': 'grupo@test.com',
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Grupo Test Eskaera",
|
||||
"is_company": True,
|
||||
"email": "grupo@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
# Crear usuario miembro del grupo
|
||||
user_partner = self.env['res.partner'].create({
|
||||
'name': 'Usuario Test Partner',
|
||||
'email': 'usuario_test@test.com',
|
||||
})
|
||||
user_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Usuario Test Partner",
|
||||
"email": "usuario_test@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Usuario Test',
|
||||
'login': 'usuario_test@test.com',
|
||||
'email': 'usuario_test@test.com',
|
||||
'partner_id': user_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Usuario Test",
|
||||
"login": "usuario_test@test.com",
|
||||
"email": "usuario_test@test.com",
|
||||
"partner_id": user_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Añadir el partner del usuario como miembro del grupo
|
||||
self.group.member_ids = [(4, user_partner.id)]
|
||||
|
||||
# Crear categorías de producto
|
||||
self.category1 = self.env['product.category'].create({
|
||||
'name': 'Categoría Test 1',
|
||||
})
|
||||
self.category1 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Categoría Test 1",
|
||||
}
|
||||
)
|
||||
|
||||
self.category2 = self.env['product.category'].create({
|
||||
'name': 'Categoría Test 2',
|
||||
})
|
||||
self.category2 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Categoría Test 2",
|
||||
}
|
||||
)
|
||||
|
||||
# Crear proveedor
|
||||
self.supplier = self.env['res.partner'].create({
|
||||
'name': 'Proveedor Test',
|
||||
'is_company': True,
|
||||
'supplier_rank': 1,
|
||||
'email': 'proveedor@test.com',
|
||||
})
|
||||
self.supplier = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Proveedor Test",
|
||||
"is_company": True,
|
||||
"supplier_rank": 1,
|
||||
"email": "proveedor@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
# Crear productos
|
||||
self.product_cat1 = self.env['product.product'].create({
|
||||
'name': 'Producto Categoría 1',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'categ_id': self.category1.id,
|
||||
'active': True,
|
||||
})
|
||||
self.product_cat1.product_tmpl_id.write({
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.product_cat1 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Producto Categoría 1",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"categ_id": self.category1.id,
|
||||
"active": True,
|
||||
}
|
||||
)
|
||||
self.product_cat1.product_tmpl_id.write(
|
||||
{
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_cat2 = self.env['product.product'].create({
|
||||
'name': 'Producto Categoría 2',
|
||||
'type': 'consu',
|
||||
'list_price': 20.0,
|
||||
'categ_id': self.category2.id,
|
||||
'active': True,
|
||||
})
|
||||
self.product_cat2.product_tmpl_id.write({
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.product_cat2 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Producto Categoría 2",
|
||||
"type": "consu",
|
||||
"list_price": 20.0,
|
||||
"categ_id": self.category2.id,
|
||||
"active": True,
|
||||
}
|
||||
)
|
||||
self.product_cat2.product_tmpl_id.write(
|
||||
{
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Crear producto con relación a proveedor
|
||||
self.product_supplier_template = self.env['product.template'].create({
|
||||
'name': 'Producto Proveedor',
|
||||
'type': 'consu',
|
||||
'list_price': 30.0,
|
||||
'categ_id': self.category1.id,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.product_supplier_template = self.env["product.template"].create(
|
||||
{
|
||||
"name": "Producto Proveedor",
|
||||
"type": "consu",
|
||||
"list_price": 30.0,
|
||||
"categ_id": self.category1.id,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_supplier = self.product_supplier_template.product_variant_ids[0]
|
||||
self.product_supplier.active = True
|
||||
|
||||
# Crear relación con proveedor
|
||||
self.env['product.supplierinfo'].create({
|
||||
'product_tmpl_id': self.product_supplier_template.id,
|
||||
'partner_id': self.supplier.id,
|
||||
'min_qty': 1.0,
|
||||
})
|
||||
self.env["product.supplierinfo"].create(
|
||||
{
|
||||
"product_tmpl_id": self.product_supplier_template.id,
|
||||
"partner_id": self.supplier.id,
|
||||
"min_qty": 1.0,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_direct = self.env['product.product'].create({
|
||||
'name': 'Producto Directo',
|
||||
'type': 'consu',
|
||||
'list_price': 40.0,
|
||||
'categ_id': self.category1.id,
|
||||
'active': True,
|
||||
})
|
||||
self.product_direct.product_tmpl_id.write({
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.product_direct = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Producto Directo",
|
||||
"type": "consu",
|
||||
"list_price": 40.0,
|
||||
"categ_id": self.category1.id,
|
||||
"active": True,
|
||||
}
|
||||
)
|
||||
self.product_direct.product_tmpl_id.write(
|
||||
{
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_product_discovery_direct(self):
|
||||
'''Test que los productos directos se descubren correctamente.'''
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido Directo',
|
||||
'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',
|
||||
'product_ids': [(6, 0, [self.product_direct.id])],
|
||||
})
|
||||
"""Test que los productos directos se descubren correctamente."""
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Directo",
|
||||
"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",
|
||||
"product_ids": [(6, 0, [self.product_direct.id])],
|
||||
}
|
||||
)
|
||||
|
||||
order.action_open()
|
||||
|
||||
|
|
@ -131,96 +162,124 @@ class TestEskaerShop(TransactionCase):
|
|||
self.assertEqual(len(products), 1)
|
||||
self.assertIn(self.product_direct, products)
|
||||
|
||||
products = self.env['product.product']._get_products_for_group_order(order.id)
|
||||
self.assertIn(self.product_direct.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
products = self.env["product.product"]._get_products_for_group_order(order.id)
|
||||
self.assertIn(
|
||||
self.product_direct.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
def test_product_discovery_by_category(self):
|
||||
'''Test que los productos se descubren por categoría cuando no hay directos.'''
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido por Categoría',
|
||||
'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',
|
||||
'category_ids': [(6, 0, [self.category1.id])],
|
||||
})
|
||||
"""Test que los productos se descubren por categoría cuando no hay directos."""
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido por Categoría",
|
||||
"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",
|
||||
"category_ids": [(6, 0, [self.category1.id])],
|
||||
}
|
||||
)
|
||||
|
||||
order.action_open()
|
||||
|
||||
# Simular lo que hace eskaera_shop (fallback a categorías)
|
||||
products = order.product_ids
|
||||
if not products:
|
||||
products = self.env['product.product'].search([
|
||||
('categ_id', 'in', order.category_ids.ids),
|
||||
])
|
||||
products = self.env["product.product"].search(
|
||||
[
|
||||
("categ_id", "in", order.category_ids.ids),
|
||||
]
|
||||
)
|
||||
|
||||
# Debe incluir todos los productos de la categoría 1
|
||||
self.assertGreaterEqual(len(products), 2)
|
||||
self.assertIn(self.product_cat1.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertIn(self.product_supplier.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertIn(self.product_direct.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertIn(
|
||||
self.product_cat1.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
self.assertIn(
|
||||
self.product_supplier.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
self.assertIn(
|
||||
self.product_direct.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
order.write({'category_ids': [(4, self.category1.id)]})
|
||||
products = self.env['product.product']._get_products_for_group_order(order.id)
|
||||
self.assertIn(self.product_cat1.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertNotIn(self.product_cat2.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
order.write({"category_ids": [(4, self.category1.id)]})
|
||||
products = self.env["product.product"]._get_products_for_group_order(order.id)
|
||||
self.assertIn(
|
||||
self.product_cat1.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
self.assertNotIn(
|
||||
self.product_cat2.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
def test_product_discovery_by_supplier(self):
|
||||
'''Test que los productos se descubren por proveedor cuando no hay directos ni categorías.'''
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido por Proveedor',
|
||||
'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',
|
||||
'supplier_ids': [(6, 0, [self.supplier.id])],
|
||||
})
|
||||
"""Test que los productos se descubren por proveedor cuando no hay directos ni categorías."""
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido por Proveedor",
|
||||
"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",
|
||||
"supplier_ids": [(6, 0, [self.supplier.id])],
|
||||
}
|
||||
)
|
||||
|
||||
order.action_open()
|
||||
|
||||
# Simular lo que hace eskaera_shop (fallback a proveedores)
|
||||
products = order.product_ids
|
||||
if not products and order.category_ids:
|
||||
products = self.env['product.product'].search([
|
||||
('categ_id', 'in', order.category_ids.ids),
|
||||
])
|
||||
products = self.env["product.product"].search(
|
||||
[
|
||||
("categ_id", "in", order.category_ids.ids),
|
||||
]
|
||||
)
|
||||
|
||||
if not products and order.supplier_ids:
|
||||
# Buscar productos que tienen estos proveedores en seller_ids
|
||||
product_templates = self.env['product.template'].search([
|
||||
('seller_ids.partner_id', 'in', order.supplier_ids.ids),
|
||||
])
|
||||
products = product_templates.mapped('product_variant_ids')
|
||||
product_templates = self.env["product.template"].search(
|
||||
[
|
||||
("seller_ids.partner_id", "in", order.supplier_ids.ids),
|
||||
]
|
||||
)
|
||||
products = product_templates.mapped("product_variant_ids")
|
||||
|
||||
# Debe incluir el producto del proveedor
|
||||
self.assertEqual(len(products), 1)
|
||||
self.assertIn(self.product_supplier.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertIn(
|
||||
self.product_supplier.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
order.write({'supplier_ids': [(4, self.supplier.id)]})
|
||||
products = self.env['product.product']._get_products_for_group_order(order.id)
|
||||
self.assertIn(self.product_supplier.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
order.write({"supplier_ids": [(4, self.supplier.id)]})
|
||||
products = self.env["product.product"]._get_products_for_group_order(order.id)
|
||||
self.assertIn(
|
||||
self.product_supplier.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
def test_product_discovery_priority(self):
|
||||
'''Test que la prioridad de descubrimiento es: directos > categorías > proveedores.'''
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido con Todos',
|
||||
'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',
|
||||
'product_ids': [(6, 0, [self.product_direct.id])],
|
||||
'category_ids': [(6, 0, [self.category1.id, self.category2.id])],
|
||||
'supplier_ids': [(6, 0, [self.supplier.id])],
|
||||
})
|
||||
"""Test que la prioridad de descubrimiento es: directos > categorías > proveedores."""
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido con Todos",
|
||||
"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",
|
||||
"product_ids": [(6, 0, [self.product_direct.id])],
|
||||
"category_ids": [(6, 0, [self.category1.id, self.category2.id])],
|
||||
"supplier_ids": [(6, 0, [self.supplier.id])],
|
||||
}
|
||||
)
|
||||
|
||||
order.action_open()
|
||||
|
||||
|
|
@ -229,94 +288,122 @@ class TestEskaerShop(TransactionCase):
|
|||
|
||||
# Debe retornar los productos directos, no los de categoría/proveedor
|
||||
self.assertEqual(len(products), 1)
|
||||
self.assertIn(self.product_direct.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertNotIn(self.product_cat1.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertNotIn(self.product_cat2.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertNotIn(self.product_supplier.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertIn(
|
||||
self.product_direct.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
self.assertNotIn(
|
||||
self.product_cat1.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
self.assertNotIn(
|
||||
self.product_cat2.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
self.assertNotIn(
|
||||
self.product_supplier.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
# 2. The canonical helper now returns the UNION of all association
|
||||
# sources (direct products, categories, suppliers). Assert all are
|
||||
# present to reflect the new behaviour.
|
||||
products = self.env['product.product']._get_products_for_group_order(order.id)
|
||||
tmpl_ids = products.mapped('product_tmpl_id')
|
||||
products = self.env["product.product"]._get_products_for_group_order(order.id)
|
||||
tmpl_ids = products.mapped("product_tmpl_id")
|
||||
self.assertIn(self.product_direct.product_tmpl_id, tmpl_ids)
|
||||
self.assertIn(self.product_cat1.product_tmpl_id, tmpl_ids)
|
||||
self.assertIn(self.product_supplier.product_tmpl_id, tmpl_ids)
|
||||
|
||||
def test_product_discovery_fallback_from_category_to_supplier(self):
|
||||
'''Test que si no hay directos ni categorías, usa proveedores.'''
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido Fallback',
|
||||
'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',
|
||||
# Sin product_ids
|
||||
# Sin category_ids
|
||||
'supplier_ids': [(6, 0, [self.supplier.id])],
|
||||
})
|
||||
"""Test que si no hay directos ni categorías, usa proveedores."""
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Fallback",
|
||||
"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",
|
||||
# Sin product_ids
|
||||
# Sin category_ids
|
||||
"supplier_ids": [(6, 0, [self.supplier.id])],
|
||||
}
|
||||
)
|
||||
|
||||
order.action_open()
|
||||
|
||||
# Simular lo que hace eskaera_shop
|
||||
products = order.product_ids
|
||||
if not products and order.category_ids:
|
||||
products = self.env['product.product'].search([
|
||||
('categ_id', 'in', order.category_ids.ids),
|
||||
])
|
||||
products = self.env["product.product"].search(
|
||||
[
|
||||
("categ_id", "in", order.category_ids.ids),
|
||||
]
|
||||
)
|
||||
|
||||
if not products and order.supplier_ids:
|
||||
# Buscar productos que tienen estos proveedores en seller_ids
|
||||
product_templates = self.env['product.template'].search([
|
||||
('seller_ids.partner_id', 'in', order.supplier_ids.ids),
|
||||
])
|
||||
products = product_templates.mapped('product_variant_ids')
|
||||
product_templates = self.env["product.template"].search(
|
||||
[
|
||||
("seller_ids.partner_id", "in", order.supplier_ids.ids),
|
||||
]
|
||||
)
|
||||
products = product_templates.mapped("product_variant_ids")
|
||||
|
||||
# Debe retornar productos del proveedor
|
||||
self.assertEqual(len(products), 1)
|
||||
self.assertIn(self.product_supplier.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertIn(
|
||||
self.product_supplier.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
# Clear categories so supplier-only fallback remains active
|
||||
order.write({
|
||||
'category_ids': [(5, 0, 0)],
|
||||
'supplier_ids': [(4, self.supplier.id)],
|
||||
})
|
||||
products = self.env['product.product']._get_products_for_group_order(order.id)
|
||||
self.assertIn(self.product_supplier.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
self.assertNotIn(self.product_direct.product_tmpl_id, products.mapped('product_tmpl_id'))
|
||||
order.write(
|
||||
{
|
||||
"category_ids": [(5, 0, 0)],
|
||||
"supplier_ids": [(4, self.supplier.id)],
|
||||
}
|
||||
)
|
||||
products = self.env["product.product"]._get_products_for_group_order(order.id)
|
||||
self.assertIn(
|
||||
self.product_supplier.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
self.assertNotIn(
|
||||
self.product_direct.product_tmpl_id, products.mapped("product_tmpl_id")
|
||||
)
|
||||
|
||||
def test_no_products_available(self):
|
||||
'''Test que retorna vacío si no hay productos definidos de ninguna forma.'''
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido Sin Productos',
|
||||
'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',
|
||||
# Sin product_ids, category_ids, supplier_ids
|
||||
})
|
||||
"""Test que retorna vacío si no hay productos definidos de ninguna forma."""
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Sin Productos",
|
||||
"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",
|
||||
# Sin product_ids, category_ids, supplier_ids
|
||||
}
|
||||
)
|
||||
|
||||
order.action_open()
|
||||
|
||||
# Simular lo que hace eskaera_shop
|
||||
products = order.product_ids
|
||||
if not products and order.category_ids:
|
||||
products = self.env['product.product'].search([
|
||||
('categ_id', 'in', order.category_ids.ids),
|
||||
])
|
||||
products = self.env["product.product"].search(
|
||||
[
|
||||
("categ_id", "in", order.category_ids.ids),
|
||||
]
|
||||
)
|
||||
|
||||
if not products and order.supplier_ids:
|
||||
# Buscar productos que tienen estos proveedores en seller_ids
|
||||
product_templates = self.env['product.template'].search([
|
||||
('seller_ids.partner_id', 'in', order.supplier_ids.ids),
|
||||
])
|
||||
products = product_templates.mapped('product_variant_ids')
|
||||
product_templates = self.env["product.template"].search(
|
||||
[
|
||||
("seller_ids.partner_id", "in", order.supplier_ids.ids),
|
||||
]
|
||||
)
|
||||
products = product_templates.mapped("product_variant_ids")
|
||||
|
||||
# Debe estar vacío
|
||||
self.assertEqual(len(products), 0)
|
||||
|
|
|
|||
|
|
@ -1,310 +1,354 @@
|
|||
# Copyright 2025 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError
|
||||
from psycopg2 import IntegrityError
|
||||
|
||||
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.'''
|
||||
"""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',
|
||||
})
|
||||
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.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,
|
||||
})
|
||||
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',
|
||||
})
|
||||
"""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.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 """
|
||||
"""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(),
|
||||
})
|
||||
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',
|
||||
})
|
||||
"""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')
|
||||
self.assertEqual(order.state, "open")
|
||||
|
||||
# Open -> Closed
|
||||
order.action_close()
|
||||
self.assertEqual(order.state, 'closed')
|
||||
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',
|
||||
})
|
||||
"""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')
|
||||
self.assertEqual(order.state, "cancelled")
|
||||
|
||||
def test_get_active_orders_for_week(self):
|
||||
'''Test obtener pedidos activos para la semana.'''
|
||||
"""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',
|
||||
})
|
||||
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',
|
||||
})
|
||||
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),
|
||||
])
|
||||
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',
|
||||
})
|
||||
"""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.'''
|
||||
"""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',
|
||||
})
|
||||
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),
|
||||
])
|
||||
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.'''
|
||||
"""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',
|
||||
})
|
||||
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),
|
||||
])
|
||||
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.'''
|
||||
"""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',
|
||||
})
|
||||
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),
|
||||
])
|
||||
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',
|
||||
})
|
||||
"""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')
|
||||
self.assertEqual(order.state, "draft")
|
||||
order.action_open()
|
||||
self.assertEqual(order.state, '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',
|
||||
})
|
||||
"""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')
|
||||
self.assertEqual(order.state, "open")
|
||||
|
||||
order.action_close()
|
||||
self.assertEqual(order.state, 'closed')
|
||||
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',
|
||||
})
|
||||
"""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')
|
||||
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 = 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')
|
||||
self.assertEqual(order2.state, "cancelled")
|
||||
|
|
|
|||
|
|
@ -1,147 +1,178 @@
|
|||
# Copyright 2025 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestMultiCompanyGroupOrder(TransactionCase):
|
||||
'''Test suite para el soporte multicompañía en group.order.'''
|
||||
"""Test suite para el soporte multicompañía en group.order."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Crear dos compañías
|
||||
self.company1 = self.env['res.company'].create({
|
||||
'name': 'Company 1',
|
||||
})
|
||||
self.company2 = self.env['res.company'].create({
|
||||
'name': 'Company 2',
|
||||
})
|
||||
self.company1 = self.env["res.company"].create(
|
||||
{
|
||||
"name": "Company 1",
|
||||
}
|
||||
)
|
||||
self.company2 = self.env["res.company"].create(
|
||||
{
|
||||
"name": "Company 2",
|
||||
}
|
||||
)
|
||||
|
||||
# Crear grupos en diferentes compañías
|
||||
self.group1 = self.env['res.partner'].create({
|
||||
'name': 'Grupo Company 1',
|
||||
'is_company': True,
|
||||
'email': 'grupo1@test.com',
|
||||
'company_id': self.company1.id,
|
||||
})
|
||||
self.group1 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Grupo Company 1",
|
||||
"is_company": True,
|
||||
"email": "grupo1@test.com",
|
||||
"company_id": self.company1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.group2 = self.env['res.partner'].create({
|
||||
'name': 'Grupo Company 2',
|
||||
'is_company': True,
|
||||
'email': 'grupo2@test.com',
|
||||
'company_id': self.company2.id,
|
||||
})
|
||||
self.group2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Grupo Company 2",
|
||||
"is_company": True,
|
||||
"email": "grupo2@test.com",
|
||||
"company_id": self.company2.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Crear productos en cada compañía
|
||||
self.product1 = self.env['product.product'].create({
|
||||
'name': 'Producto Company 1',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'company_id': self.company1.id,
|
||||
})
|
||||
self.product1 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Producto Company 1",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"company_id": self.company1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.product2 = self.env['product.product'].create({
|
||||
'name': 'Producto Company 2',
|
||||
'type': 'consu',
|
||||
'list_price': 20.0,
|
||||
'company_id': self.company2.id,
|
||||
})
|
||||
self.product2 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Producto Company 2",
|
||||
"type": "consu",
|
||||
"list_price": 20.0,
|
||||
"company_id": self.company2.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_group_order_has_company_id(self):
|
||||
'''Test que group.order tenga el campo company_id.'''
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido Company 1',
|
||||
'group_ids': [(6, 0, [self.group1.id])],
|
||||
'company_id': self.company1.id,
|
||||
'type': 'regular',
|
||||
'start_date': datetime.now().date(),
|
||||
'end_date': (datetime.now() + timedelta(days=7)).date(),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '5',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
"""Test que group.order tenga el campo company_id."""
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Company 1",
|
||||
"group_ids": [(6, 0, [self.group1.id])],
|
||||
"company_id": self.company1.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.company_id, self.company1)
|
||||
|
||||
def test_group_order_default_company(self):
|
||||
'''Test que company_id por defecto sea la compañía del usuario.'''
|
||||
"""Test que company_id por defecto sea la compañía del usuario."""
|
||||
# Crear usuario con compañía específica
|
||||
user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser',
|
||||
'password': 'test123',
|
||||
'company_id': self.company1.id,
|
||||
'company_ids': [(6, 0, [self.company1.id])],
|
||||
})
|
||||
user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser",
|
||||
"password": "test123",
|
||||
"company_id": self.company1.id,
|
||||
"company_ids": [(6, 0, [self.company1.id])],
|
||||
}
|
||||
)
|
||||
|
||||
order = self.env['group.order'].with_user(user).create({
|
||||
'name': 'Pedido Default Company',
|
||||
'group_ids': [(6, 0, [self.group1.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 = (
|
||||
self.env["group.order"]
|
||||
.with_user(user)
|
||||
.create(
|
||||
{
|
||||
"name": "Pedido Default Company",
|
||||
"group_ids": [(6, 0, [self.group1.id])],
|
||||
"type": "regular",
|
||||
"start_date": datetime.now().date(),
|
||||
"end_date": (datetime.now() + timedelta(days=7)).date(),
|
||||
"period": "weekly",
|
||||
"pickup_day": "5",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
# Verificar que se asignó la compañía del usuario
|
||||
self.assertEqual(order.company_id, self.company1)
|
||||
|
||||
def test_group_order_company_constraint(self):
|
||||
'''Test que solo grupos de la misma compañía se puedan asignar.'''
|
||||
"""Test que solo grupos de la misma compañía se puedan asignar."""
|
||||
# Intentar asignar un grupo de otra compañía
|
||||
with self.assertRaises(ValidationError):
|
||||
self.env['group.order'].create({
|
||||
'name': 'Pedido Mixed Companies',
|
||||
'group_ids': [(6, 0, [self.group1.id, self.group2.id])],
|
||||
'company_id': self.company1.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.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Mixed Companies",
|
||||
"group_ids": [(6, 0, [self.group1.id, self.group2.id])],
|
||||
"company_id": self.company1.id,
|
||||
"type": "regular",
|
||||
"start_date": datetime.now().date(),
|
||||
"end_date": (datetime.now() + timedelta(days=7)).date(),
|
||||
"period": "weekly",
|
||||
"pickup_day": "5",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_group_order_multi_company_filter(self):
|
||||
'''Test que get_active_orders_for_week() respete company_id.'''
|
||||
"""Test que get_active_orders_for_week() respete company_id."""
|
||||
# Crear órdenes en diferentes compañías
|
||||
order1 = self.env['group.order'].create({
|
||||
'name': 'Pedido Company 1',
|
||||
'group_ids': [(6, 0, [self.group1.id])],
|
||||
'company_id': self.company1.id,
|
||||
'type': 'regular',
|
||||
'state': 'open',
|
||||
'start_date': datetime.now().date(),
|
||||
'end_date': (datetime.now() + timedelta(days=7)).date(),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '5',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order1 = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Company 1",
|
||||
"group_ids": [(6, 0, [self.group1.id])],
|
||||
"company_id": self.company1.id,
|
||||
"type": "regular",
|
||||
"state": "open",
|
||||
"start_date": datetime.now().date(),
|
||||
"end_date": (datetime.now() + timedelta(days=7)).date(),
|
||||
"period": "weekly",
|
||||
"pickup_day": "5",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
order2 = self.env['group.order'].create({
|
||||
'name': 'Pedido Company 2',
|
||||
'group_ids': [(6, 0, [self.group2.id])],
|
||||
'company_id': self.company2.id,
|
||||
'type': 'regular',
|
||||
'state': 'open',
|
||||
'start_date': datetime.now().date(),
|
||||
'end_date': (datetime.now() + timedelta(days=7)).date(),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '5',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order2 = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Company 2",
|
||||
"group_ids": [(6, 0, [self.group2.id])],
|
||||
"company_id": self.company2.id,
|
||||
"type": "regular",
|
||||
"state": "open",
|
||||
"start_date": datetime.now().date(),
|
||||
"end_date": (datetime.now() + timedelta(days=7)).date(),
|
||||
"period": "weekly",
|
||||
"pickup_day": "5",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
# Obtener órdenes activas de company1
|
||||
active_orders = self.env['group.order'].with_context(
|
||||
allowed_company_ids=[self.company1.id]
|
||||
).get_active_orders_for_week()
|
||||
active_orders = (
|
||||
self.env["group.order"]
|
||||
.with_context(allowed_company_ids=[self.company1.id])
|
||||
.get_active_orders_for_week()
|
||||
)
|
||||
|
||||
# Debería contener solo order1
|
||||
self.assertIn(order1, active_orders)
|
||||
|
|
@ -149,24 +180,28 @@ class TestMultiCompanyGroupOrder(TransactionCase):
|
|||
# el filtro de compañía correctamente
|
||||
|
||||
def test_product_company_isolation(self):
|
||||
'''Test que los productos de diferentes compañías estén aislados.'''
|
||||
"""Test que los productos de diferentes compañías estén aislados."""
|
||||
# Crear categoría para products
|
||||
category = self.env['product.category'].create({
|
||||
'name': 'Test Category',
|
||||
})
|
||||
category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category",
|
||||
}
|
||||
)
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Pedido con Categoría',
|
||||
'group_ids': [(6, 0, [self.group1.id])],
|
||||
'category_ids': [(6, 0, [category.id])],
|
||||
'company_id': self.company1.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 = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido con Categoría",
|
||||
"group_ids": [(6, 0, [self.group1.id])],
|
||||
"category_ids": [(6, 0, [category.id])],
|
||||
"company_id": self.company1.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.company_id, self.company1)
|
||||
|
|
|
|||
|
|
@ -13,131 +13,166 @@ Coverage:
|
|||
- Product price info structure in eskaera_shop
|
||||
"""
|
||||
|
||||
import json
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestPricingWithPricelist(TransactionCase):
|
||||
"""Test pricing calculations using OCA product_get_price_helper addon."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
|
||||
# Create test company
|
||||
self.company = self.env['res.company'].create({
|
||||
'name': 'Test Company Pricing',
|
||||
})
|
||||
|
||||
self.company = self.env["res.company"].create(
|
||||
{
|
||||
"name": "Test Company Pricing",
|
||||
}
|
||||
)
|
||||
|
||||
# Create test group
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group Pricing',
|
||||
'is_company': True,
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group Pricing",
|
||||
"is_company": True,
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create test user
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User Pricing',
|
||||
'login': 'testpricing@example.com',
|
||||
'company_id': self.company.id,
|
||||
'company_ids': [(6, 0, [self.company.id])],
|
||||
})
|
||||
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User Pricing",
|
||||
"login": "testpricing@example.com",
|
||||
"company_id": self.company.id,
|
||||
"company_ids": [(6, 0, [self.company.id])],
|
||||
}
|
||||
)
|
||||
|
||||
# Get or create default tax group
|
||||
tax_group = self.env['account.tax.group'].search([
|
||||
('company_id', '=', self.company.id)
|
||||
], limit=1)
|
||||
tax_group = self.env["account.tax.group"].search(
|
||||
[("company_id", "=", self.company.id)], limit=1
|
||||
)
|
||||
if not tax_group:
|
||||
tax_group = self.env['account.tax.group'].create({
|
||||
'name': 'IVA',
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
tax_group = self.env["account.tax.group"].create(
|
||||
{
|
||||
"name": "IVA",
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Get default country (Spain)
|
||||
country_es = self.env.ref('base.es')
|
||||
|
||||
country_es = self.env.ref("base.es")
|
||||
|
||||
# Create tax (21% IVA)
|
||||
self.tax_21 = self.env['account.tax'].create({
|
||||
'name': 'IVA 21%',
|
||||
'amount': 21.0,
|
||||
'amount_type': 'percent',
|
||||
'type_tax_use': 'sale',
|
||||
'company_id': self.company.id,
|
||||
'country_id': country_es.id,
|
||||
'tax_group_id': tax_group.id,
|
||||
})
|
||||
|
||||
self.tax_21 = self.env["account.tax"].create(
|
||||
{
|
||||
"name": "IVA 21%",
|
||||
"amount": 21.0,
|
||||
"amount_type": "percent",
|
||||
"type_tax_use": "sale",
|
||||
"company_id": self.company.id,
|
||||
"country_id": country_es.id,
|
||||
"tax_group_id": tax_group.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create tax (10% IVA reducido)
|
||||
self.tax_10 = self.env['account.tax'].create({
|
||||
'name': 'IVA 10%',
|
||||
'amount': 10.0,
|
||||
'amount_type': 'percent',
|
||||
'type_tax_use': 'sale',
|
||||
'company_id': self.company.id,
|
||||
'country_id': country_es.id,
|
||||
'tax_group_id': tax_group.id,
|
||||
})
|
||||
|
||||
self.tax_10 = self.env["account.tax"].create(
|
||||
{
|
||||
"name": "IVA 10%",
|
||||
"amount": 10.0,
|
||||
"amount_type": "percent",
|
||||
"type_tax_use": "sale",
|
||||
"company_id": self.company.id,
|
||||
"country_id": country_es.id,
|
||||
"tax_group_id": tax_group.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create fiscal position (maps 21% to 10%)
|
||||
self.fiscal_position = self.env['account.fiscal.position'].create({
|
||||
'name': 'Test Fiscal Position',
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
self.env['account.fiscal.position.tax'].create({
|
||||
'position_id': self.fiscal_position.id,
|
||||
'tax_src_id': self.tax_21.id,
|
||||
'tax_dest_id': self.tax_10.id,
|
||||
})
|
||||
|
||||
self.fiscal_position = self.env["account.fiscal.position"].create(
|
||||
{
|
||||
"name": "Test Fiscal Position",
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
self.env["account.fiscal.position.tax"].create(
|
||||
{
|
||||
"position_id": self.fiscal_position.id,
|
||||
"tax_src_id": self.tax_21.id,
|
||||
"tax_dest_id": self.tax_10.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create product category
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Test Category Pricing',
|
||||
})
|
||||
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category Pricing",
|
||||
}
|
||||
)
|
||||
|
||||
# Create test products with different tax configurations
|
||||
self.product_with_tax = self.env['product.product'].create({
|
||||
'name': 'Product With 21% Tax',
|
||||
'list_price': 100.0,
|
||||
'categ_id': self.category.id,
|
||||
'taxes_id': [(6, 0, [self.tax_21.id])],
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
self.product_without_tax = self.env['product.product'].create({
|
||||
'name': 'Product Without Tax',
|
||||
'list_price': 50.0,
|
||||
'categ_id': self.category.id,
|
||||
'taxes_id': False,
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
self.product_with_tax = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product With 21% Tax",
|
||||
"list_price": 100.0,
|
||||
"categ_id": self.category.id,
|
||||
"taxes_id": [(6, 0, [self.tax_21.id])],
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_without_tax = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product Without Tax",
|
||||
"list_price": 50.0,
|
||||
"categ_id": self.category.id,
|
||||
"taxes_id": False,
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create pricelist with discount
|
||||
self.pricelist_with_discount = self.env['product.pricelist'].create({
|
||||
'name': 'Test Pricelist 10% Discount',
|
||||
'company_id': self.company.id,
|
||||
'item_ids': [(0, 0, {
|
||||
'compute_price': 'percentage',
|
||||
'percent_price': 10.0, # 10% discount
|
||||
'applied_on': '3_global',
|
||||
})],
|
||||
})
|
||||
|
||||
self.pricelist_with_discount = self.env["product.pricelist"].create(
|
||||
{
|
||||
"name": "Test Pricelist 10% Discount",
|
||||
"company_id": self.company.id,
|
||||
"item_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"compute_price": "percentage",
|
||||
"percent_price": 10.0, # 10% discount
|
||||
"applied_on": "3_global",
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
# Create pricelist without discount
|
||||
self.pricelist_no_discount = self.env['product.pricelist'].create({
|
||||
'name': 'Test Pricelist No Discount',
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
self.pricelist_no_discount = self.env["product.pricelist"].create(
|
||||
{
|
||||
"name": "Test Pricelist No Discount",
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create group order
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order Pricing',
|
||||
'state': 'open',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'product_ids': [(6, 0, [self.product_with_tax.id, self.product_without_tax.id])],
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order Pricing",
|
||||
"state": "open",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"product_ids": [
|
||||
(6, 0, [self.product_with_tax.id, self.product_without_tax.id])
|
||||
],
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_add_to_cart_basic_price_without_tax(self):
|
||||
"""Test basic price calculation for product without taxes."""
|
||||
|
|
@ -147,11 +182,15 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=self.pricelist_no_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
self.assertEqual(result['value'], 50.0,
|
||||
"Product without tax should have price = list_price")
|
||||
self.assertEqual(result.get('discount', 0), 0,
|
||||
"No discount pricelist should have 0% discount")
|
||||
|
||||
self.assertEqual(
|
||||
result["value"], 50.0, "Product without tax should have price = list_price"
|
||||
)
|
||||
self.assertEqual(
|
||||
result.get("discount", 0),
|
||||
0,
|
||||
"No discount pricelist should have 0% discount",
|
||||
)
|
||||
|
||||
def test_add_to_cart_with_pricelist_discount(self):
|
||||
"""Test that discounted prices are calculated correctly."""
|
||||
|
|
@ -161,14 +200,18 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=self.pricelist_with_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# OCA addon returns price without taxes by default
|
||||
expected_price = 100.0 * 0.9 # 90.0
|
||||
|
||||
self.assertIn('value', result, "Result must contain 'value' key")
|
||||
self.assertIn('tax_included', result, "Result must contain 'tax_included' key")
|
||||
self.assertAlmostEqual(result['value'], expected_price, places=2,
|
||||
msg=f"Expected {expected_price}, got {result['value']}")
|
||||
|
||||
self.assertIn("value", result, "Result must contain 'value' key")
|
||||
self.assertIn("tax_included", result, "Result must contain 'tax_included' key")
|
||||
self.assertAlmostEqual(
|
||||
result["value"],
|
||||
expected_price,
|
||||
places=2,
|
||||
msg=f"Expected {expected_price}, got {result['value']}",
|
||||
)
|
||||
|
||||
def test_add_to_cart_with_fiscal_position(self):
|
||||
"""Test fiscal position maps taxes correctly (21% -> 10%)."""
|
||||
|
|
@ -178,19 +221,19 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=self.pricelist_no_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
result_with_fp = self.product_with_tax._get_price(
|
||||
qty=1.0,
|
||||
pricelist=self.pricelist_no_discount,
|
||||
fposition=self.fiscal_position,
|
||||
)
|
||||
|
||||
|
||||
# Both should return base price (100.0) without tax by default
|
||||
# Tax mapping only affects tax calculation, not the base price returned
|
||||
self.assertIn('value', result_without_fp, "Result must contain 'value'")
|
||||
self.assertIn('value', result_with_fp, "Result must contain 'value'")
|
||||
self.assertEqual(result_without_fp['value'], 100.0)
|
||||
self.assertEqual(result_with_fp['value'], 100.0)
|
||||
self.assertIn("value", result_without_fp, "Result must contain 'value'")
|
||||
self.assertIn("value", result_with_fp, "Result must contain 'value'")
|
||||
self.assertEqual(result_without_fp["value"], 100.0)
|
||||
self.assertEqual(result_with_fp["value"], 100.0)
|
||||
|
||||
def test_add_to_cart_with_tax_included(self):
|
||||
"""Test price calculation returns tax_included flag correctly."""
|
||||
|
|
@ -200,43 +243,53 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=self.pricelist_no_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# By default, tax is not included in price
|
||||
self.assertIn('tax_included', result)
|
||||
self.assertEqual(result['value'], 100.0, "Price should be base price without tax")
|
||||
self.assertIn("tax_included", result)
|
||||
self.assertEqual(
|
||||
result["value"], 100.0, "Price should be base price without tax"
|
||||
)
|
||||
|
||||
def test_add_to_cart_with_quantity_discount(self):
|
||||
"""Test quantity-based discounts if applicable."""
|
||||
# Create pricelist with quantity-based rule
|
||||
pricelist_qty = self.env['product.pricelist'].create({
|
||||
'name': 'Quantity Discount Pricelist',
|
||||
'company_id': self.company.id,
|
||||
'item_ids': [(0, 0, {
|
||||
'compute_price': 'percentage',
|
||||
'percent_price': 20.0, # 20% discount
|
||||
'min_quantity': 5.0,
|
||||
'applied_on': '3_global',
|
||||
})],
|
||||
})
|
||||
|
||||
pricelist_qty = self.env["product.pricelist"].create(
|
||||
{
|
||||
"name": "Quantity Discount Pricelist",
|
||||
"company_id": self.company.id,
|
||||
"item_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"compute_price": "percentage",
|
||||
"percent_price": 20.0, # 20% discount
|
||||
"min_quantity": 5.0,
|
||||
"applied_on": "3_global",
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
# Quantity 1: No discount
|
||||
result_qty_1 = self.product_with_tax._get_price(
|
||||
qty=1.0,
|
||||
pricelist=pricelist_qty,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# Quantity 5: 20% discount
|
||||
result_qty_5 = self.product_with_tax._get_price(
|
||||
qty=5.0,
|
||||
pricelist=pricelist_qty,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# Qty 1: 100.0 (no discount, no tax in value)
|
||||
# Qty 5: 100 * 0.8 = 80.0 (with 20% discount, no tax in value)
|
||||
self.assertAlmostEqual(result_qty_1['value'], 100.0, places=2)
|
||||
self.assertAlmostEqual(result_qty_5['value'], 80.0, places=2)
|
||||
self.assertAlmostEqual(result_qty_1["value"], 100.0, places=2)
|
||||
self.assertAlmostEqual(result_qty_5["value"], 80.0, places=2)
|
||||
|
||||
def test_add_to_cart_price_fallback_no_pricelist(self):
|
||||
"""Test fallback to list_price when pricelist is not available."""
|
||||
|
|
@ -247,35 +300,39 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=False,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# Should return list_price with taxes (fallback behavior)
|
||||
# This depends on OCA addon implementation
|
||||
self.assertIsNotNone(result, "Should not fail when pricelist is False")
|
||||
self.assertIn('value', result, "Result should contain 'value' key")
|
||||
self.assertIn("value", result, "Result should contain 'value' key")
|
||||
|
||||
def test_add_to_cart_price_fallback_no_variant(self):
|
||||
"""Test handling when product has no variants."""
|
||||
# Create product template without variants
|
||||
product_template = self.env['product.template'].create({
|
||||
'name': 'Product Without Variant',
|
||||
'list_price': 75.0,
|
||||
'categ_id': self.category.id,
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
product_template = self.env["product.template"].create(
|
||||
{
|
||||
"name": "Product Without Variant",
|
||||
"list_price": 75.0,
|
||||
"categ_id": self.category.id,
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Should have auto-created variant
|
||||
self.assertTrue(product_template.product_variant_ids,
|
||||
"Product template should have at least one variant")
|
||||
|
||||
self.assertTrue(
|
||||
product_template.product_variant_ids,
|
||||
"Product template should have at least one variant",
|
||||
)
|
||||
|
||||
variant = product_template.product_variant_ids[0]
|
||||
result = variant._get_price(
|
||||
qty=1.0,
|
||||
pricelist=self.pricelist_no_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
self.assertIsNotNone(result, "Should handle product with auto-created variant")
|
||||
self.assertAlmostEqual(result['value'], 75.0, places=2)
|
||||
self.assertAlmostEqual(result["value"], 75.0, places=2)
|
||||
|
||||
def test_product_price_info_structure(self):
|
||||
"""Test product_price_info dict structure returned by _get_price."""
|
||||
|
|
@ -284,18 +341,19 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=self.pricelist_with_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# Verify structure
|
||||
self.assertIn('value', result, "Result must contain 'value' key")
|
||||
self.assertIsInstance(result['value'], (int, float),
|
||||
"Price value must be numeric")
|
||||
|
||||
self.assertIn("value", result, "Result must contain 'value' key")
|
||||
self.assertIsInstance(
|
||||
result["value"], (int, float), "Price value must be numeric"
|
||||
)
|
||||
|
||||
# Optional keys (depends on OCA addon version)
|
||||
if 'discount' in result:
|
||||
self.assertIsInstance(result['discount'], (int, float))
|
||||
|
||||
if 'original_value' in result:
|
||||
self.assertIsInstance(result['original_value'], (int, float))
|
||||
if "discount" in result:
|
||||
self.assertIsInstance(result["discount"], (int, float))
|
||||
|
||||
if "original_value" in result:
|
||||
self.assertIsInstance(result["original_value"], (int, float))
|
||||
|
||||
def test_discounted_price_visual_comparison(self):
|
||||
"""Test comparison of original vs discounted price for UI display."""
|
||||
|
|
@ -304,71 +362,83 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=self.pricelist_with_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# When there's a discount, original_value should be higher than value
|
||||
if result.get('discount', 0) > 0:
|
||||
original = result.get('original_value', result['value'])
|
||||
discounted = result['value']
|
||||
self.assertGreater(original, discounted,
|
||||
"Original price should be higher than discounted price")
|
||||
if result.get("discount", 0) > 0:
|
||||
original = result.get("original_value", result["value"])
|
||||
discounted = result["value"]
|
||||
self.assertGreater(
|
||||
original,
|
||||
discounted,
|
||||
"Original price should be higher than discounted price",
|
||||
)
|
||||
|
||||
def test_price_calculation_with_multiple_taxes(self):
|
||||
"""Test product with multiple taxes applied."""
|
||||
# Get tax group and country from existing tax
|
||||
tax_group = self.tax_21.tax_group_id
|
||||
country = self.tax_21.country_id
|
||||
|
||||
|
||||
# Create additional tax
|
||||
tax_extra = self.env['account.tax'].create({
|
||||
'name': 'Extra Tax 5%',
|
||||
'amount': 5.0,
|
||||
'amount_type': 'percent',
|
||||
'type_tax_use': 'sale',
|
||||
'company_id': self.company.id,
|
||||
'country_id': country.id,
|
||||
'tax_group_id': tax_group.id,
|
||||
})
|
||||
|
||||
product_multi_tax = self.env['product.product'].create({
|
||||
'name': 'Product With Multiple Taxes',
|
||||
'list_price': 100.0,
|
||||
'categ_id': self.category.id,
|
||||
'taxes_id': [(6, 0, [self.tax_21.id, tax_extra.id])],
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
tax_extra = self.env["account.tax"].create(
|
||||
{
|
||||
"name": "Extra Tax 5%",
|
||||
"amount": 5.0,
|
||||
"amount_type": "percent",
|
||||
"type_tax_use": "sale",
|
||||
"company_id": self.company.id,
|
||||
"country_id": country.id,
|
||||
"tax_group_id": tax_group.id,
|
||||
}
|
||||
)
|
||||
|
||||
product_multi_tax = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product With Multiple Taxes",
|
||||
"list_price": 100.0,
|
||||
"categ_id": self.category.id,
|
||||
"taxes_id": [(6, 0, [self.tax_21.id, tax_extra.id])],
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
result = product_multi_tax._get_price(
|
||||
qty=1.0,
|
||||
pricelist=self.pricelist_no_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
# Base price 100.0 (taxes not included in value by default)
|
||||
self.assertEqual(result['value'], 100.0,
|
||||
msg="Should return base price (taxes applied separately)")
|
||||
self.assertEqual(
|
||||
result["value"],
|
||||
100.0,
|
||||
msg="Should return base price (taxes applied separately)",
|
||||
)
|
||||
|
||||
def test_price_currency_handling(self):
|
||||
"""Test price calculation with different currencies."""
|
||||
# Get or use existing EUR currency
|
||||
eur = self.env['res.currency'].search([('name', '=', 'EUR')], limit=1)
|
||||
eur = self.env["res.currency"].search([("name", "=", "EUR")], limit=1)
|
||||
if not eur:
|
||||
self.skipTest("EUR currency not available in test database")
|
||||
|
||||
|
||||
# Create pricelist with EUR
|
||||
pricelist_eur = self.env['product.pricelist'].create({
|
||||
'name': 'EUR Pricelist',
|
||||
'currency_id': eur.id,
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
pricelist_eur = self.env["product.pricelist"].create(
|
||||
{
|
||||
"name": "EUR Pricelist",
|
||||
"currency_id": eur.id,
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
result = self.product_with_tax._get_price(
|
||||
qty=1.0,
|
||||
pricelist=pricelist_eur,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
self.assertIsNotNone(result, "Should handle different currency pricelist")
|
||||
self.assertIn('value', result)
|
||||
self.assertIn("value", result)
|
||||
|
||||
def test_price_consistency_across_calls(self):
|
||||
"""Test that multiple calls with same params return same price."""
|
||||
|
|
@ -377,33 +447,37 @@ class TestPricingWithPricelist(TransactionCase):
|
|||
pricelist=self.pricelist_with_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
|
||||
result2 = self.product_with_tax._get_price(
|
||||
qty=1.0,
|
||||
pricelist=self.pricelist_with_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
self.assertEqual(result1['value'], result2['value'],
|
||||
"Price calculation should be deterministic")
|
||||
|
||||
self.assertEqual(
|
||||
result1["value"],
|
||||
result2["value"],
|
||||
"Price calculation should be deterministic",
|
||||
)
|
||||
|
||||
def test_zero_price_product(self):
|
||||
"""Test handling of free products (price = 0)."""
|
||||
free_product = self.env['product.product'].create({
|
||||
'name': 'Free Product',
|
||||
'list_price': 0.0,
|
||||
'categ_id': self.category.id,
|
||||
'company_id': self.company.id,
|
||||
})
|
||||
|
||||
free_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Free Product",
|
||||
"list_price": 0.0,
|
||||
"categ_id": self.category.id,
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
|
||||
result = free_product._get_price(
|
||||
qty=1.0,
|
||||
pricelist=self.pricelist_no_discount,
|
||||
fposition=False,
|
||||
)
|
||||
|
||||
self.assertEqual(result['value'], 0.0,
|
||||
"Free product should have price = 0")
|
||||
|
||||
self.assertEqual(result["value"], 0.0, "Free product should have price = 0")
|
||||
|
||||
def test_negative_quantity_handling(self):
|
||||
"""Test that negative quantities are handled properly."""
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ Coverage:
|
|||
- Ordering and deduplication
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
|
@ -27,81 +28,105 @@ class TestProductDiscoveryUnion(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Create a supplier
|
||||
self.supplier = self.env['res.partner'].create({
|
||||
'name': 'Test Supplier',
|
||||
'is_supplier': True,
|
||||
})
|
||||
self.supplier = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Supplier",
|
||||
"is_supplier": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Create categories
|
||||
self.category1 = self.env['product.category'].create({
|
||||
'name': 'Category 1',
|
||||
})
|
||||
self.category1 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Category 1",
|
||||
}
|
||||
)
|
||||
|
||||
self.category2 = self.env['product.category'].create({
|
||||
'name': 'Category 2',
|
||||
})
|
||||
self.category2 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Category 2",
|
||||
}
|
||||
)
|
||||
|
||||
# Create products
|
||||
# Direct product
|
||||
self.direct_product = self.env['product.product'].create({
|
||||
'name': 'Direct Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.direct_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Direct Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Category 1 product
|
||||
self.cat1_product = self.env['product.product'].create({
|
||||
'name': 'Category 1 Product',
|
||||
'type': 'consu',
|
||||
'list_price': 20.0,
|
||||
'categ_id': self.category1.id,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.cat1_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Category 1 Product",
|
||||
"type": "consu",
|
||||
"list_price": 20.0,
|
||||
"categ_id": self.category1.id,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Category 2 product
|
||||
self.cat2_product = self.env['product.product'].create({
|
||||
'name': 'Category 2 Product',
|
||||
'type': 'consu',
|
||||
'list_price': 30.0,
|
||||
'categ_id': self.category2.id,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.cat2_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Category 2 Product",
|
||||
"type": "consu",
|
||||
"list_price": 30.0,
|
||||
"categ_id": self.category2.id,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Supplier product
|
||||
self.supplier_product = self.env['product.product'].create({
|
||||
'name': 'Supplier Product',
|
||||
'type': 'consu',
|
||||
'list_price': 40.0,
|
||||
'categ_id': self.category1.id, # Also in category
|
||||
'seller_ids': [(0, 0, {
|
||||
'partner_id': self.supplier.id,
|
||||
'product_name': 'Supplier Product',
|
||||
})],
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.supplier_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Supplier Product",
|
||||
"type": "consu",
|
||||
"list_price": 40.0,
|
||||
"categ_id": self.category1.id, # Also in category
|
||||
"seller_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"partner_id": self.supplier.id,
|
||||
"product_name": "Supplier Product",
|
||||
},
|
||||
)
|
||||
],
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_discovery_from_direct_products(self):
|
||||
"""Test discovery returns directly linked products."""
|
||||
|
|
@ -145,14 +170,16 @@ class TestProductDiscoveryUnion(TransactionCase):
|
|||
|
||||
def test_discovery_filters_unpublished(self):
|
||||
"""Test that unpublished products are excluded from discovery."""
|
||||
unpublished = self.env['product.product'].create({
|
||||
'name': 'Unpublished Product',
|
||||
'type': 'consu',
|
||||
'list_price': 50.0,
|
||||
'categ_id': self.category1.id,
|
||||
'is_published': False,
|
||||
'sale_ok': True,
|
||||
})
|
||||
unpublished = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Unpublished Product",
|
||||
"type": "consu",
|
||||
"list_price": 50.0,
|
||||
"categ_id": self.category1.id,
|
||||
"is_published": False,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.group_order.category_ids = [(4, self.category1.id)]
|
||||
discovered = self.group_order.product_ids
|
||||
|
|
@ -162,14 +189,16 @@ class TestProductDiscoveryUnion(TransactionCase):
|
|||
|
||||
def test_discovery_filters_not_for_sale(self):
|
||||
"""Test that non-sellable products are excluded."""
|
||||
not_for_sale = self.env['product.product'].create({
|
||||
'name': 'Not For Sale',
|
||||
'type': 'consu',
|
||||
'list_price': 60.0,
|
||||
'categ_id': self.category1.id,
|
||||
'is_published': True,
|
||||
'sale_ok': False,
|
||||
})
|
||||
not_for_sale = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Not For Sale",
|
||||
"type": "consu",
|
||||
"list_price": 60.0,
|
||||
"categ_id": self.category1.id,
|
||||
"is_published": True,
|
||||
"sale_ok": False,
|
||||
}
|
||||
)
|
||||
|
||||
self.group_order.category_ids = [(4, self.category1.id)]
|
||||
discovered = self.group_order.product_ids
|
||||
|
|
@ -183,76 +212,96 @@ class TestDeepCategoryHierarchies(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Create nested category structure:
|
||||
# Root -> L1 -> L2 -> L3 -> L4
|
||||
self.cat_l1 = self.env['product.category'].create({
|
||||
'name': 'Level 1',
|
||||
})
|
||||
self.cat_l1 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Level 1",
|
||||
}
|
||||
)
|
||||
|
||||
self.cat_l2 = self.env['product.category'].create({
|
||||
'name': 'Level 2',
|
||||
'parent_id': self.cat_l1.id,
|
||||
})
|
||||
self.cat_l2 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Level 2",
|
||||
"parent_id": self.cat_l1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.cat_l3 = self.env['product.category'].create({
|
||||
'name': 'Level 3',
|
||||
'parent_id': self.cat_l2.id,
|
||||
})
|
||||
self.cat_l3 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Level 3",
|
||||
"parent_id": self.cat_l2.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.cat_l4 = self.env['product.category'].create({
|
||||
'name': 'Level 4',
|
||||
'parent_id': self.cat_l3.id,
|
||||
})
|
||||
self.cat_l4 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Level 4",
|
||||
"parent_id": self.cat_l3.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.cat_l5 = self.env['product.category'].create({
|
||||
'name': 'Level 5',
|
||||
'parent_id': self.cat_l4.id,
|
||||
})
|
||||
self.cat_l5 = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Level 5",
|
||||
"parent_id": self.cat_l4.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create products at each level
|
||||
self.product_l2 = self.env['product.product'].create({
|
||||
'name': 'Product L2',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'categ_id': self.cat_l2.id,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.product_l2 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product L2",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"categ_id": self.cat_l2.id,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_l4 = self.env['product.product'].create({
|
||||
'name': 'Product L4',
|
||||
'type': 'consu',
|
||||
'list_price': 20.0,
|
||||
'categ_id': self.cat_l4.id,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.product_l4 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product L4",
|
||||
"type": "consu",
|
||||
"list_price": 20.0,
|
||||
"categ_id": self.cat_l4.id,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_l5 = self.env['product.product'].create({
|
||||
'name': 'Product L5',
|
||||
'type': 'consu',
|
||||
'list_price': 30.0,
|
||||
'categ_id': self.cat_l5.id,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
self.product_l5 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product L5",
|
||||
"type": "consu",
|
||||
"list_price": 30.0,
|
||||
"categ_id": self.cat_l5.id,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_discovery_root_category_includes_all_descendants(self):
|
||||
"""Test that linking root category discovers all nested products."""
|
||||
|
|
@ -307,33 +356,41 @@ class TestEmptySourcesDiscovery(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Empty Category',
|
||||
})
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Empty Category",
|
||||
}
|
||||
)
|
||||
# No products in this category
|
||||
|
||||
self.supplier = self.env['res.partner'].create({
|
||||
'name': 'Supplier No Products',
|
||||
'is_supplier': True,
|
||||
})
|
||||
self.supplier = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Supplier No Products",
|
||||
"is_supplier": True,
|
||||
}
|
||||
)
|
||||
# No products from this supplier
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_discovery_empty_category(self):
|
||||
"""Test discovery from empty category."""
|
||||
|
|
@ -371,39 +428,47 @@ class TestProductDiscoveryOrdering(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Test Category',
|
||||
})
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category",
|
||||
}
|
||||
)
|
||||
|
||||
# Create products with specific names
|
||||
self.products = []
|
||||
for i in range(5):
|
||||
product = self.env['product.product'].create({
|
||||
'name': f'Product {chr(65 + i)}', # A, B, C, D, E
|
||||
'type': 'consu',
|
||||
'list_price': (i + 1) * 10.0,
|
||||
'categ_id': self.category.id,
|
||||
'is_published': True,
|
||||
'sale_ok': True,
|
||||
})
|
||||
product = self.env["product.product"].create(
|
||||
{
|
||||
"name": f"Product {chr(65 + i)}", # A, B, C, D, E
|
||||
"type": "consu",
|
||||
"list_price": (i + 1) * 10.0,
|
||||
"categ_id": self.category.id,
|
||||
"is_published": True,
|
||||
"sale_ok": True,
|
||||
}
|
||||
)
|
||||
self.products.append(product)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_discovery_consistent_ordering(self):
|
||||
"""Test that repeated calls return same order."""
|
||||
|
|
@ -413,10 +478,7 @@ class TestProductDiscoveryOrdering(TransactionCase):
|
|||
discovered2 = list(self.group_order.product_ids)
|
||||
|
||||
# Order should be consistent
|
||||
self.assertEqual(
|
||||
[p.id for p in discovered1],
|
||||
[p.id for p in discovered2]
|
||||
)
|
||||
self.assertEqual([p.id for p in discovered1], [p.id for p in discovered2])
|
||||
|
||||
def test_discovery_alphabetical_or_price_order(self):
|
||||
"""Test that products are ordered predictably."""
|
||||
|
|
@ -427,6 +489,6 @@ class TestProductDiscoveryOrdering(TransactionCase):
|
|||
# Should be in some consistent order (name, price, ID, etc)
|
||||
# Verify they're the same products, regardless of order
|
||||
self.assertEqual(len(discovered), 5)
|
||||
discovered_ids = set(p.id for p in discovered)
|
||||
expected_ids = set(p.id for p in self.products)
|
||||
discovered_ids = {p.id for p in discovered}
|
||||
expected_ids = {p.id for p in self.products}
|
||||
self.assertEqual(discovered_ids, expected_ids)
|
||||
|
|
|
|||
|
|
@ -1,91 +1,106 @@
|
|||
# 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
|
||||
|
||||
|
||||
class TestProductExtension(TransactionCase):
|
||||
'''Test suite para las extensiones de product.template.'''
|
||||
"""Test suite para las extensiones de product.template."""
|
||||
|
||||
def setUp(self):
|
||||
super(TestProductExtension, self).setUp()
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
})
|
||||
self.order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'product_ids': [(4, self.product.id)]
|
||||
})
|
||||
super().setUp()
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
}
|
||||
)
|
||||
self.order = self.env["group.order"].create(
|
||||
{"name": "Test Order", "product_ids": [(4, self.product.id)]}
|
||||
)
|
||||
|
||||
def test_product_template_group_order_ids_field_exists(self):
|
||||
'''Test que el campo group_order_ids existe en product.template.'''
|
||||
"""Test que el campo group_order_ids existe en product.template."""
|
||||
product_template = self.product.product_tmpl_id
|
||||
|
||||
# El campo debe existir y ser readonly
|
||||
self.assertTrue(hasattr(product_template, 'group_order_ids'))
|
||||
self.assertTrue(hasattr(product_template, "group_order_ids"))
|
||||
|
||||
def test_product_group_order_ids_readonly(self):
|
||||
""" Test that group_order_ids is a readonly field """
|
||||
field = self.env['product.template']._fields['group_order_ids']
|
||||
"""Test that group_order_ids is a readonly field"""
|
||||
field = self.env["product.template"]._fields["group_order_ids"]
|
||||
self.assertTrue(field.readonly)
|
||||
|
||||
def test_product_group_order_ids_reverse_lookup(self):
|
||||
""" Test that adding a product to an order reflects in group_order_ids """
|
||||
"""Test that adding a product to an order reflects in group_order_ids"""
|
||||
related_orders = self.product.product_tmpl_id.group_order_ids
|
||||
self.assertIn(self.order, related_orders)
|
||||
|
||||
def test_product_group_order_ids_empty_by_default(self):
|
||||
""" Test that a new product has no group orders """
|
||||
new_product = self.env['product.product'].create({'name': 'New Product'})
|
||||
"""Test that a new product has no group orders"""
|
||||
new_product = self.env["product.product"].create({"name": "New Product"})
|
||||
self.assertFalse(new_product.product_tmpl_id.group_order_ids)
|
||||
|
||||
def test_product_group_order_ids_multiple_orders(self):
|
||||
""" Test that group_order_ids can contain multiple orders """
|
||||
order2 = self.env['group.order'].create({
|
||||
'name': 'Test Order 2',
|
||||
'product_ids': [(4, self.product.id)]
|
||||
})
|
||||
"""Test that group_order_ids can contain multiple orders"""
|
||||
order2 = self.env["group.order"].create(
|
||||
{"name": "Test Order 2", "product_ids": [(4, self.product.id)]}
|
||||
)
|
||||
self.assertIn(self.order, self.product.product_tmpl_id.group_order_ids)
|
||||
self.assertIn(order2, self.product.product_tmpl_id.group_order_ids)
|
||||
|
||||
def test_product_group_order_ids_empty_after_remove_from_order(self):
|
||||
""" Test that group_order_ids is empty after removing the product from all orders """
|
||||
self.order.write({'product_ids': [(3, self.product.id)]})
|
||||
"""Test that group_order_ids is empty after removing the product from all orders"""
|
||||
self.order.write({"product_ids": [(3, self.product.id)]})
|
||||
self.assertFalse(self.product.product_tmpl_id.group_order_ids)
|
||||
|
||||
def test_product_group_order_ids_with_multiple_products(self):
|
||||
""" Test group_order_ids with multiple products in one order """
|
||||
product2 = self.env['product.product'].create({'name': 'Test Product 2'})
|
||||
self.order.write({'product_ids': [
|
||||
(4, self.product.id),
|
||||
(4, product2.id)
|
||||
]})
|
||||
"""Test group_order_ids with multiple products in one order"""
|
||||
product2 = self.env["product.product"].create({"name": "Test Product 2"})
|
||||
self.order.write({"product_ids": [(4, self.product.id), (4, product2.id)]})
|
||||
self.assertIn(self.order, self.product.product_tmpl_id.group_order_ids)
|
||||
self.assertIn(self.order, product2.product_tmpl_id.group_order_ids)
|
||||
|
||||
def test_product_with_variants_group_order_ids(self):
|
||||
""" Test that group_order_ids works correctly with product variants """
|
||||
"""Test that group_order_ids works correctly with product variants"""
|
||||
# Create a product template with two variants
|
||||
product_template = self.env['product.template'].create({
|
||||
'name': 'Product with Variants',
|
||||
'attribute_line_ids': [(0, 0, {
|
||||
'attribute_id': self.env.ref('product.product_attribute_1').id,
|
||||
'value_ids': [
|
||||
(4, self.env.ref('product.product_attribute_value_1').id),
|
||||
(4, self.env.ref('product.product_attribute_value_2').id)
|
||||
]
|
||||
})]
|
||||
})
|
||||
product_template = self.env["product.template"].create(
|
||||
{
|
||||
"name": "Product with Variants",
|
||||
"attribute_line_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"attribute_id": self.env.ref(
|
||||
"product.product_attribute_1"
|
||||
).id,
|
||||
"value_ids": [
|
||||
(
|
||||
4,
|
||||
self.env.ref(
|
||||
"product.product_attribute_value_1"
|
||||
).id,
|
||||
),
|
||||
(
|
||||
4,
|
||||
self.env.ref(
|
||||
"product.product_attribute_value_2"
|
||||
).id,
|
||||
),
|
||||
],
|
||||
},
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
variant1 = product_template.product_variant_ids[0]
|
||||
variant2 = product_template.product_variant_ids[1]
|
||||
|
||||
# Add one variant to an order (store variant id, not template id)
|
||||
order_with_variant = self.env['group.order'].create({
|
||||
'name': 'Order with Variant',
|
||||
'product_ids': [(4, variant1.id)]
|
||||
})
|
||||
order_with_variant = self.env["group.order"].create(
|
||||
{"name": "Order with Variant", "product_ids": [(4, variant1.id)]}
|
||||
)
|
||||
|
||||
# Check that the order appears in the group_order_ids of the template
|
||||
self.assertIn(order_with_variant, product_template.group_order_ids)
|
||||
|
|
|
|||
|
|
@ -1,145 +1,170 @@
|
|||
# Copyright 2025 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestGroupOrderRecordRules(TransactionCase):
|
||||
'''Test suite para record rules de multicompañía en group.order.'''
|
||||
"""Test suite para record rules de multicompañía en group.order."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Crear dos compañías
|
||||
self.company1 = self.env['res.company'].create({
|
||||
'name': 'Company 1',
|
||||
})
|
||||
self.company2 = self.env['res.company'].create({
|
||||
'name': 'Company 2',
|
||||
})
|
||||
self.company1 = self.env["res.company"].create(
|
||||
{
|
||||
"name": "Company 1",
|
||||
}
|
||||
)
|
||||
self.company2 = self.env["res.company"].create(
|
||||
{
|
||||
"name": "Company 2",
|
||||
}
|
||||
)
|
||||
|
||||
# Crear usuarios para cada compañía
|
||||
self.user_company1 = self.env['res.users'].create({
|
||||
'name': 'User Company 1',
|
||||
'login': 'user_c1',
|
||||
'password': 'pass123',
|
||||
'company_id': self.company1.id,
|
||||
'company_ids': [(6, 0, [self.company1.id])],
|
||||
})
|
||||
self.user_company1 = self.env["res.users"].create(
|
||||
{
|
||||
"name": "User Company 1",
|
||||
"login": "user_c1",
|
||||
"password": "pass123",
|
||||
"company_id": self.company1.id,
|
||||
"company_ids": [(6, 0, [self.company1.id])],
|
||||
}
|
||||
)
|
||||
|
||||
self.user_company2 = self.env['res.users'].create({
|
||||
'name': 'User Company 2',
|
||||
'login': 'user_c2',
|
||||
'password': 'pass123',
|
||||
'company_id': self.company2.id,
|
||||
'company_ids': [(6, 0, [self.company2.id])],
|
||||
})
|
||||
self.user_company2 = self.env["res.users"].create(
|
||||
{
|
||||
"name": "User Company 2",
|
||||
"login": "user_c2",
|
||||
"password": "pass123",
|
||||
"company_id": self.company2.id,
|
||||
"company_ids": [(6, 0, [self.company2.id])],
|
||||
}
|
||||
)
|
||||
|
||||
# Crear admin con acceso a ambas compañías
|
||||
self.admin_user = self.env['res.users'].create({
|
||||
'name': 'Admin Both',
|
||||
'login': 'admin_both',
|
||||
'password': 'pass123',
|
||||
'company_id': self.company1.id,
|
||||
'company_ids': [(6, 0, [self.company1.id, self.company2.id])],
|
||||
})
|
||||
self.admin_user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Admin Both",
|
||||
"login": "admin_both",
|
||||
"password": "pass123",
|
||||
"company_id": self.company1.id,
|
||||
"company_ids": [(6, 0, [self.company1.id, self.company2.id])],
|
||||
}
|
||||
)
|
||||
|
||||
# Crear grupos en cada compañía
|
||||
self.group1 = self.env['res.partner'].create({
|
||||
'name': 'Grupo Company 1',
|
||||
'is_company': True,
|
||||
'email': 'grupo1@test.com',
|
||||
'company_id': self.company1.id,
|
||||
})
|
||||
self.group1 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Grupo Company 1",
|
||||
"is_company": True,
|
||||
"email": "grupo1@test.com",
|
||||
"company_id": self.company1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.group2 = self.env['res.partner'].create({
|
||||
'name': 'Grupo Company 2',
|
||||
'is_company': True,
|
||||
'email': 'grupo2@test.com',
|
||||
'company_id': self.company2.id,
|
||||
})
|
||||
self.group2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Grupo Company 2",
|
||||
"is_company": True,
|
||||
"email": "grupo2@test.com",
|
||||
"company_id": self.company2.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Crear órdenes en cada compañía
|
||||
self.order1 = self.env['group.order'].create({
|
||||
'name': 'Pedido Company 1',
|
||||
'group_ids': [(6, 0, [self.group1.id])],
|
||||
'company_id': self.company1.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.order1 = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Company 1",
|
||||
"group_ids": [(6, 0, [self.group1.id])],
|
||||
"company_id": self.company1.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.order2 = self.env['group.order'].create({
|
||||
'name': 'Pedido Company 2',
|
||||
'group_ids': [(6, 0, [self.group2.id])],
|
||||
'company_id': self.company2.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.order2 = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Pedido Company 2",
|
||||
"group_ids": [(6, 0, [self.group2.id])],
|
||||
"company_id": self.company2.id,
|
||||
"type": "regular",
|
||||
"start_date": datetime.now().date(),
|
||||
"end_date": (datetime.now() + timedelta(days=7)).date(),
|
||||
"period": "weekly",
|
||||
"pickup_day": "5",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_user_company1_can_read_own_orders(self):
|
||||
'''Test que usuario de Company 1 puede leer sus propias órdenes.'''
|
||||
orders = self.env['group.order'].with_user(
|
||||
self.user_company1
|
||||
).search([('company_id', '=', self.company1.id)])
|
||||
"""Test que usuario de Company 1 puede leer sus propias órdenes."""
|
||||
orders = (
|
||||
self.env["group.order"]
|
||||
.with_user(self.user_company1)
|
||||
.search([("company_id", "=", self.company1.id)])
|
||||
)
|
||||
|
||||
self.assertIn(self.order1, orders)
|
||||
|
||||
def test_user_company1_cannot_read_company2_orders(self):
|
||||
'''Test que usuario de Company 1 NO puede leer órdenes de Company 2.'''
|
||||
orders = self.env['group.order'].with_user(
|
||||
self.user_company1
|
||||
).search([('company_id', '=', self.company2.id)])
|
||||
"""Test que usuario de Company 1 NO puede leer órdenes de Company 2."""
|
||||
orders = (
|
||||
self.env["group.order"]
|
||||
.with_user(self.user_company1)
|
||||
.search([("company_id", "=", self.company2.id)])
|
||||
)
|
||||
|
||||
self.assertNotIn(self.order2, orders)
|
||||
self.assertEqual(len(orders), 0)
|
||||
|
||||
def test_admin_can_read_all_orders(self):
|
||||
'''Test que admin con acceso a ambas compañías ve todas las órdenes.'''
|
||||
orders = self.env['group.order'].with_user(
|
||||
self.admin_user
|
||||
).search([])
|
||||
"""Test que admin con acceso a ambas compañías ve todas las órdenes."""
|
||||
orders = self.env["group.order"].with_user(self.admin_user).search([])
|
||||
|
||||
self.assertIn(self.order1, orders)
|
||||
self.assertIn(self.order2, orders)
|
||||
|
||||
def test_user_cannot_write_other_company_order(self):
|
||||
'''Test que usuario no puede escribir en orden de otra compañía.'''
|
||||
"""Test que usuario no puede escribir en orden de otra compañía."""
|
||||
with self.assertRaises(AccessError):
|
||||
self.order2.with_user(self.user_company1).write({
|
||||
'name': 'Intentando cambiar nombre',
|
||||
})
|
||||
self.order2.with_user(self.user_company1).write(
|
||||
{
|
||||
"name": "Intentando cambiar nombre",
|
||||
}
|
||||
)
|
||||
|
||||
def test_record_rule_filters_search(self):
|
||||
'''Test que búsqueda automáticamente filtra por record rule.'''
|
||||
"""Test que búsqueda automáticamente filtra por record rule."""
|
||||
# Usuario de Company 1 busca todas las órdenes
|
||||
orders_c1 = self.env['group.order'].with_user(
|
||||
self.user_company1
|
||||
).search([('state', '=', 'draft')])
|
||||
orders_c1 = (
|
||||
self.env["group.order"]
|
||||
.with_user(self.user_company1)
|
||||
.search([("state", "=", "draft")])
|
||||
)
|
||||
|
||||
# Solo debe ver su orden
|
||||
self.assertEqual(len(orders_c1), 1)
|
||||
self.assertEqual(orders_c1[0], self.order1)
|
||||
|
||||
def test_cross_company_access_denied(self):
|
||||
'''Test que acceso entre compañías es denegado.'''
|
||||
"""Test que acceso entre compañías es denegado."""
|
||||
# Usuario company1 intenta acceder a orden de company2
|
||||
with self.assertRaises(AccessError):
|
||||
self.order2.with_user(self.user_company1).read()
|
||||
|
||||
def test_admin_can_bypass_company_restriction(self):
|
||||
'''Test que admin puede acceder a órdenes de cualquier compañía.'''
|
||||
"""Test que admin puede acceder a órdenes de cualquier compañía."""
|
||||
# Admin lee orden de company2 sin problema
|
||||
order2_admin = self.order2.with_user(self.admin_user)
|
||||
self.assertEqual(order2_admin.name, 'Pedido Company 2')
|
||||
self.assertEqual(order2_admin.name, "Pedido Company 2")
|
||||
self.assertEqual(order2_admin.company_id, self.company2)
|
||||
|
|
|
|||
|
|
@ -5,34 +5,40 @@ from odoo.tests.common import TransactionCase
|
|||
|
||||
|
||||
class TestResPartnerExtension(TransactionCase):
|
||||
'''Test suite para la extensión res.partner (user-group relationship).'''
|
||||
"""Test suite para la extensión res.partner (user-group relationship)."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# Crear grupos (res.partner with is_company=True)
|
||||
self.group1 = self.env['res.partner'].create({
|
||||
'name': 'Grupo 1',
|
||||
'is_company': True,
|
||||
'email': 'grupo1@test.com',
|
||||
})
|
||||
self.group1 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Grupo 1",
|
||||
"is_company": True,
|
||||
"email": "grupo1@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
self.group2 = self.env['res.partner'].create({
|
||||
'name': 'Grupo 2',
|
||||
'is_company': True,
|
||||
'email': 'grupo2@test.com',
|
||||
})
|
||||
self.group2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Grupo 2",
|
||||
"is_company": True,
|
||||
"email": "grupo2@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
# Crear usuario
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
def test_partner_can_belong_to_groups(self):
|
||||
'''Test que un partner (usuario) puede pertenecer a múltiples grupos.'''
|
||||
"""Test que un partner (usuario) puede pertenecer a múltiples grupos."""
|
||||
partner = self.user.partner_id
|
||||
|
||||
|
||||
# Agregar partner a grupos (usar campo member_ids)
|
||||
partner.member_ids = [(6, 0, [self.group1.id, self.group2.id])]
|
||||
|
||||
|
|
@ -42,12 +48,14 @@ class TestResPartnerExtension(TransactionCase):
|
|||
self.assertEqual(len(partner.member_ids), 2)
|
||||
|
||||
def test_group_can_have_multiple_users(self):
|
||||
'''Test que un grupo puede tener múltiples usuarios.'''
|
||||
user2 = self.env['res.users'].create({
|
||||
'name': 'Test User 2',
|
||||
'login': 'testuser2@test.com',
|
||||
'email': 'testuser2@test.com',
|
||||
})
|
||||
"""Test que un grupo puede tener múltiples usuarios."""
|
||||
user2 = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User 2",
|
||||
"login": "testuser2@test.com",
|
||||
"email": "testuser2@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
# Agregar usuarios al grupo
|
||||
self.group1.user_ids = [(6, 0, [self.user.id, user2.id])]
|
||||
|
|
@ -58,26 +66,28 @@ class TestResPartnerExtension(TransactionCase):
|
|||
self.assertEqual(len(self.group1.user_ids), 2)
|
||||
|
||||
def test_user_group_relationship_is_bidirectional(self):
|
||||
'''Test que se puede modificar la relación desde el lado del partner o el grupo.'''
|
||||
"""Test que se puede modificar la relación desde el lado del partner o el grupo."""
|
||||
partner = self.user.partner_id
|
||||
|
||||
|
||||
# Opción 1: Agregar grupo al usuario (desde el lado del usuario/partner)
|
||||
partner.member_ids = [(6, 0, [self.group1.id])]
|
||||
self.assertIn(self.group1, partner.member_ids)
|
||||
|
||||
# Opción 2: Agregar usuario al grupo (desde el lado del grupo)
|
||||
|
||||
# Opción 2: Agregar usuario al grupo (desde el lado del grupo)
|
||||
# Nota: Esto es una relación Many2many independiente
|
||||
user2 = self.env['res.users'].create({
|
||||
'name': 'Test User 2',
|
||||
'login': 'testuser2@test.com',
|
||||
'email': 'testuser2@test.com',
|
||||
})
|
||||
user2 = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User 2",
|
||||
"login": "testuser2@test.com",
|
||||
"email": "testuser2@test.com",
|
||||
}
|
||||
)
|
||||
self.group2.user_ids = [(6, 0, [user2.id])]
|
||||
self.assertIn(user2, self.group2.user_ids)
|
||||
|
||||
def test_empty_group_ids(self):
|
||||
'''Test que un partner sin grupos tiene group_ids vacío.'''
|
||||
"""Test que un partner sin grupos tiene group_ids vacío."""
|
||||
partner = self.user.partner_id
|
||||
|
||||
|
||||
# Sin agregar a ningún grupo
|
||||
self.assertEqual(len(partner.member_ids), 0)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ draft sale orders.
|
|||
See: website_sale_aplicoop/controllers/website_sale.py
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
|
@ -23,60 +24,72 @@ class TestSaveOrderEndpoints(TransactionCase):
|
|||
super().setUp()
|
||||
|
||||
# Create a consumer group
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
'email': 'group@test.com',
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
"email": "group@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
# Create a group member (user partner)
|
||||
self.member_partner = self.env['res.partner'].create({
|
||||
'name': 'Group Member Partner',
|
||||
'email': 'member@test.com',
|
||||
})
|
||||
self.member_partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Member Partner",
|
||||
"email": "member@test.com",
|
||||
}
|
||||
)
|
||||
|
||||
# Add member to group
|
||||
self.group.member_ids = [(4, self.member_partner.id)]
|
||||
|
||||
# Create test user
|
||||
self.user = self.env['res.users'].create({
|
||||
'name': 'Test User',
|
||||
'login': 'testuser@test.com',
|
||||
'email': 'testuser@test.com',
|
||||
'partner_id': self.member_partner.id,
|
||||
})
|
||||
self.user = self.env["res.users"].create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "testuser@test.com",
|
||||
"email": "testuser@test.com",
|
||||
"partner_id": self.member_partner.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create a group order
|
||||
start_date = datetime.now().date()
|
||||
end_date = start_date + timedelta(days=7)
|
||||
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Group Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3', # Wednesday
|
||||
'pickup_date': start_date + timedelta(days=3),
|
||||
'home_delivery': False,
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Group Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": end_date,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3", # Wednesday
|
||||
"pickup_date": start_date + timedelta(days=3),
|
||||
"home_delivery": False,
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
# Open the group order
|
||||
self.group_order.action_open()
|
||||
|
||||
# Create products for the order
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Test Category',
|
||||
})
|
||||
self.category = self.env["product.category"].create(
|
||||
{
|
||||
"name": "Test Category",
|
||||
}
|
||||
)
|
||||
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
'categ_id': self.category.id,
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
"categ_id": self.category.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Associate product with group order
|
||||
self.group_order.product_ids = [(4, self.product.id)]
|
||||
|
|
@ -84,22 +97,22 @@ class TestSaveOrderEndpoints(TransactionCase):
|
|||
def test_save_eskaera_draft_creates_order_with_group_order_id(self):
|
||||
"""
|
||||
Test that save_eskaera_draft() creates a sale.order with group_order_id.
|
||||
|
||||
|
||||
This is the main fix: ensure that the /eskaera/save-order endpoint
|
||||
correctly links the created sale.order to the group.order.
|
||||
"""
|
||||
# Simulate what the controller does: create order with group_order_id
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_day': self.group_order.pickup_day,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'home_delivery': self.group_order.home_delivery,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_day": self.group_order.pickup_day,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"home_delivery": self.group_order.home_delivery,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify the order was created with group_order_id
|
||||
self.assertIsNotNone(sale_order.id)
|
||||
|
|
@ -109,34 +122,34 @@ class TestSaveOrderEndpoints(TransactionCase):
|
|||
def test_save_eskaera_draft_propagates_pickup_day(self):
|
||||
"""Test that save_eskaera_draft() propagates pickup_day correctly."""
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_day': self.group_order.pickup_day,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'home_delivery': self.group_order.home_delivery,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_day": self.group_order.pickup_day,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"home_delivery": self.group_order.home_delivery,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify pickup_day was propagated
|
||||
self.assertEqual(sale_order.pickup_day, '3')
|
||||
self.assertEqual(sale_order.pickup_day, "3")
|
||||
self.assertEqual(sale_order.pickup_day, self.group_order.pickup_day)
|
||||
|
||||
def test_save_eskaera_draft_propagates_pickup_date(self):
|
||||
"""Test that save_eskaera_draft() propagates pickup_date correctly."""
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_day': self.group_order.pickup_day,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'home_delivery': self.group_order.home_delivery,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_day": self.group_order.pickup_day,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"home_delivery": self.group_order.home_delivery,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify pickup_date was propagated
|
||||
self.assertEqual(sale_order.pickup_date, self.group_order.pickup_date)
|
||||
|
|
@ -144,33 +157,35 @@ class TestSaveOrderEndpoints(TransactionCase):
|
|||
def test_save_eskaera_draft_propagates_home_delivery(self):
|
||||
"""Test that save_eskaera_draft() propagates home_delivery correctly."""
|
||||
# Create a group order with home_delivery=True
|
||||
group_order_home = self.env['group.order'].create({
|
||||
'name': 'Test Group Order with Home Delivery',
|
||||
'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': '3',
|
||||
'pickup_date': datetime.now().date() + timedelta(days=3),
|
||||
'home_delivery': True, # Enable home delivery
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
group_order_home = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Group Order with Home Delivery",
|
||||
"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": "3",
|
||||
"pickup_date": datetime.now().date() + timedelta(days=3),
|
||||
"home_delivery": True, # Enable home delivery
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
group_order_home.action_open()
|
||||
|
||||
# Test with home_delivery=True
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': group_order_home.id,
|
||||
'pickup_day': group_order_home.pickup_day,
|
||||
'pickup_date': group_order_home.pickup_date,
|
||||
'home_delivery': group_order_home.home_delivery,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": group_order_home.id,
|
||||
"pickup_day": group_order_home.pickup_day,
|
||||
"pickup_date": group_order_home.pickup_date,
|
||||
"home_delivery": group_order_home.home_delivery,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify home_delivery was propagated
|
||||
self.assertTrue(sale_order.home_delivery)
|
||||
|
|
@ -179,65 +194,65 @@ class TestSaveOrderEndpoints(TransactionCase):
|
|||
def test_save_eskaera_draft_order_is_draft_state(self):
|
||||
"""Test that save_eskaera_draft() creates order in draft state."""
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_day': self.group_order.pickup_day,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'home_delivery': self.group_order.home_delivery,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_day": self.group_order.pickup_day,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"home_delivery": self.group_order.home_delivery,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify order is in draft state
|
||||
self.assertEqual(sale_order.state, 'draft')
|
||||
self.assertEqual(sale_order.state, "draft")
|
||||
|
||||
def test_save_eskaera_draft_multiple_fields_together(self):
|
||||
"""
|
||||
Test that all fields are saved together correctly.
|
||||
|
||||
|
||||
This test ensures that the fix didn't break any field and that
|
||||
all group_order-related fields are propagated together.
|
||||
"""
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_day': self.group_order.pickup_day,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'home_delivery': self.group_order.home_delivery,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_day": self.group_order.pickup_day,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"home_delivery": self.group_order.home_delivery,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify all fields together
|
||||
self.assertEqual(sale_order.group_order_id.id, self.group_order.id)
|
||||
self.assertEqual(sale_order.pickup_day, self.group_order.pickup_day)
|
||||
self.assertEqual(sale_order.pickup_date, self.group_order.pickup_date)
|
||||
self.assertEqual(sale_order.home_delivery, self.group_order.home_delivery)
|
||||
self.assertEqual(sale_order.state, 'draft')
|
||||
self.assertEqual(sale_order.state, "draft")
|
||||
|
||||
def test_save_cart_draft_also_saves_group_order_id(self):
|
||||
"""
|
||||
Test that save_cart_draft() (the working endpoint) also saves group_order_id.
|
||||
|
||||
|
||||
This is a regression test to ensure that save_cart_draft() continues
|
||||
to work correctly after the fix to save_eskaera_draft().
|
||||
"""
|
||||
# save_cart_draft should also include group_order_id
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_day': self.group_order.pickup_day,
|
||||
'pickup_date': self.group_order.pickup_date,
|
||||
'home_delivery': self.group_order.home_delivery,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_day": self.group_order.pickup_day,
|
||||
"pickup_date": self.group_order.pickup_date,
|
||||
"home_delivery": self.group_order.home_delivery,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify all fields
|
||||
self.assertEqual(sale_order.group_order_id.id, self.group_order.id)
|
||||
|
|
@ -247,18 +262,18 @@ class TestSaveOrderEndpoints(TransactionCase):
|
|||
def test_save_draft_order_without_group_order_id_still_works(self):
|
||||
"""
|
||||
Test that creating a normal sale.order (without group_order_id) still works.
|
||||
|
||||
|
||||
This ensures backward compatibility - you should still be able to create
|
||||
sale orders without associating them to a group order.
|
||||
"""
|
||||
order_vals = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
# No group_order_id
|
||||
}
|
||||
|
||||
sale_order = self.env['sale.order'].create(order_vals)
|
||||
sale_order = self.env["sale.order"].create(order_vals)
|
||||
|
||||
# Verify order was created without group_order_id
|
||||
self.assertIsNotNone(sale_order.id)
|
||||
|
|
@ -267,62 +282,64 @@ class TestSaveOrderEndpoints(TransactionCase):
|
|||
def test_group_order_id_field_exists_and_is_stored(self):
|
||||
"""
|
||||
Test that group_order_id field exists on sale.order and is stored correctly.
|
||||
|
||||
|
||||
This is a sanity check to ensure the field is properly defined in the model.
|
||||
"""
|
||||
# Verify the field exists in the model
|
||||
sale_order_model = self.env['sale.order']
|
||||
self.assertIn('group_order_id', sale_order_model._fields)
|
||||
sale_order_model = self.env["sale.order"]
|
||||
self.assertIn("group_order_id", sale_order_model._fields)
|
||||
|
||||
# Verify it's a Many2one field
|
||||
field = sale_order_model._fields['group_order_id']
|
||||
self.assertEqual(field.type, 'many2one')
|
||||
self.assertEqual(field.comodel_name, 'group.order')
|
||||
field = sale_order_model._fields["group_order_id"]
|
||||
self.assertEqual(field.type, "many2one")
|
||||
self.assertEqual(field.comodel_name, "group.order")
|
||||
|
||||
def test_different_group_orders_map_to_different_sale_orders(self):
|
||||
"""
|
||||
Test that different group orders create separate sale orders.
|
||||
|
||||
|
||||
This ensures that two users buying from different group orders
|
||||
don't accidentally share the same sale.order.
|
||||
"""
|
||||
# Create a second group order
|
||||
group_order_2 = self.env['group.order'].create({
|
||||
'name': 'Test Group Order 2',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': datetime.now().date() + timedelta(days=10),
|
||||
'end_date': datetime.now().date() + timedelta(days=17),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '5',
|
||||
'pickup_date': datetime.now().date() + timedelta(days=12),
|
||||
'home_delivery': True,
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
group_order_2 = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Group Order 2",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": datetime.now().date() + timedelta(days=10),
|
||||
"end_date": datetime.now().date() + timedelta(days=17),
|
||||
"period": "weekly",
|
||||
"pickup_day": "5",
|
||||
"pickup_date": datetime.now().date() + timedelta(days=12),
|
||||
"home_delivery": True,
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
group_order_2.action_open()
|
||||
|
||||
# Create order for first group order
|
||||
order_vals_1 = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': self.group_order.id,
|
||||
'pickup_day': self.group_order.pickup_day,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": self.group_order.id,
|
||||
"pickup_day": self.group_order.pickup_day,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order_1 = self.env['sale.order'].create(order_vals_1)
|
||||
sale_order_1 = self.env["sale.order"].create(order_vals_1)
|
||||
|
||||
# Create order for second group order
|
||||
order_vals_2 = {
|
||||
'partner_id': self.member_partner.id,
|
||||
'group_order_id': group_order_2.id,
|
||||
'pickup_day': group_order_2.pickup_day,
|
||||
'order_line': [],
|
||||
'state': 'draft',
|
||||
"partner_id": self.member_partner.id,
|
||||
"group_order_id": group_order_2.id,
|
||||
"pickup_day": group_order_2.pickup_day,
|
||||
"order_line": [],
|
||||
"state": "draft",
|
||||
}
|
||||
|
||||
sale_order_2 = self.env['sale.order'].create(order_vals_2)
|
||||
sale_order_2 = self.env["sale.order"].create(order_vals_2)
|
||||
|
||||
# Verify they're different orders with different group_order_ids
|
||||
self.assertNotEqual(sale_order_1.id, sale_order_2.id)
|
||||
|
|
|
|||
|
|
@ -1,77 +1,90 @@
|
|||
# Copyright 2025 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from datetime import date, timedelta
|
||||
from odoo.tests.common import TransactionCase, tagged
|
||||
from datetime import date
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import _
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tests.common import tagged
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestTemplatesRendering(TransactionCase):
|
||||
'''Test suite to verify QWeb templates work with day_names context.
|
||||
"""Test suite to verify QWeb templates work with day_names context.
|
||||
|
||||
This test covers the fix for the issue where _() function calls
|
||||
in QWeb t-value attributes caused TypeError: 'NoneType' object is not callable.
|
||||
The fix moves day_names definition to Python controller and passes it as context.
|
||||
'''
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
'''Set up test data: create a test group order.'''
|
||||
"""Set up test data: create a test group order."""
|
||||
super().setUp()
|
||||
|
||||
# Create a test supplier
|
||||
self.supplier = self.env['res.partner'].create({
|
||||
'name': 'Test Supplier',
|
||||
'is_company': True,
|
||||
})
|
||||
self.supplier = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Supplier",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Create test products
|
||||
self.product = self.env['product.product'].create({
|
||||
'name': 'Test Product',
|
||||
'type': 'consu', # consumable (consu), service, or storable
|
||||
})
|
||||
self.product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Test Product",
|
||||
"type": "consu", # consumable (consu), service, or storable
|
||||
}
|
||||
)
|
||||
|
||||
# Create a test group
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Create a group order
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'state': 'open',
|
||||
'supplier_ids': [(6, 0, [self.supplier.id])],
|
||||
'product_ids': [(6, 0, [self.product.id])],
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'start_date': date.today(),
|
||||
'end_date': date.today() + timedelta(days=7),
|
||||
'pickup_day': '5', # Saturday
|
||||
'cutoff_day': '3', # Thursday
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"state": "open",
|
||||
"supplier_ids": [(6, 0, [self.supplier.id])],
|
||||
"product_ids": [(6, 0, [self.product.id])],
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"start_date": date.today(),
|
||||
"end_date": date.today() + timedelta(days=7),
|
||||
"pickup_day": "5", # Saturday
|
||||
"cutoff_day": "3", # Thursday
|
||||
}
|
||||
)
|
||||
|
||||
def test_eskaera_page_template_exists(self):
|
||||
'''Test that eskaera_page template compiles without errors.'''
|
||||
template = self.env.ref('website_sale_aplicoop.eskaera_page')
|
||||
"""Test that eskaera_page template compiles without errors."""
|
||||
template = self.env.ref("website_sale_aplicoop.eskaera_page")
|
||||
self.assertIsNotNone(template)
|
||||
self.assertEqual(template.type, 'qweb')
|
||||
self.assertEqual(template.type, "qweb")
|
||||
|
||||
def test_eskaera_shop_template_exists(self):
|
||||
'''Test that eskaera_shop template compiles without errors.'''
|
||||
template = self.env.ref('website_sale_aplicoop.eskaera_shop')
|
||||
"""Test that eskaera_shop template compiles without errors."""
|
||||
template = self.env.ref("website_sale_aplicoop.eskaera_shop")
|
||||
self.assertIsNotNone(template)
|
||||
self.assertEqual(template.type, 'qweb')
|
||||
self.assertEqual(template.type, "qweb")
|
||||
|
||||
def test_eskaera_checkout_template_exists(self):
|
||||
'''Test that eskaera_checkout template compiles without errors.'''
|
||||
template = self.env.ref('website_sale_aplicoop.eskaera_checkout')
|
||||
"""Test that eskaera_checkout template compiles without errors."""
|
||||
template = self.env.ref("website_sale_aplicoop.eskaera_checkout")
|
||||
self.assertIsNotNone(template)
|
||||
self.assertEqual(template.type, 'qweb')
|
||||
self.assertEqual(template.type, "qweb")
|
||||
|
||||
def test_day_names_context_is_provided(self):
|
||||
'''Test that day_names context is provided by the controller method.'''
|
||||
"""Test that day_names context is provided by the controller method."""
|
||||
# Simulate what the controller does, passing env for test context
|
||||
from odoo.addons.website_sale_aplicoop.controllers.website_sale import AplicoopWebsiteSale
|
||||
from odoo.addons.website_sale_aplicoop.controllers.website_sale import (
|
||||
AplicoopWebsiteSale,
|
||||
)
|
||||
|
||||
controller = AplicoopWebsiteSale()
|
||||
day_names = controller._get_day_names(env=self.env)
|
||||
|
|
@ -86,45 +99,61 @@ class TestTemplatesRendering(TransactionCase):
|
|||
self.assertGreater(len(day_name), 0, f"Day at index {i} is empty string")
|
||||
|
||||
def test_day_names_not_using_inline_underscore(self):
|
||||
'''Test that day_names are defined in Python, not in t-value attributes.
|
||||
"""Test that day_names are defined in Python, not in t-value attributes.
|
||||
|
||||
This test ensures the fix has been applied:
|
||||
- day_names MUST be passed from controller context
|
||||
- day_names MUST NOT be defined with _() inside t-value attributes
|
||||
- Templates use day_names[index] from context, not t-set with _()
|
||||
'''
|
||||
template = self.env.ref('website_sale_aplicoop.eskaera_page')
|
||||
"""
|
||||
template = self.env.ref("website_sale_aplicoop.eskaera_page")
|
||||
# Read the template source to verify it doesn't have inline _() in t-value
|
||||
self.assertIn('day_names', template.arch_db,
|
||||
"Template must reference day_names from context")
|
||||
self.assertIn(
|
||||
"day_names",
|
||||
template.arch_db,
|
||||
"Template must reference day_names from context",
|
||||
)
|
||||
# The fix ensures no <t t-set="day_names" t-value="[_(...)]"/> exists
|
||||
# which was causing the NoneType error
|
||||
|
||||
def test_eskaera_checkout_summary_template_exists(self):
|
||||
'''Test that eskaera_checkout_summary sub-template exists.'''
|
||||
template = self.env.ref('website_sale_aplicoop.eskaera_checkout_summary')
|
||||
"""Test that eskaera_checkout_summary sub-template exists."""
|
||||
template = self.env.ref("website_sale_aplicoop.eskaera_checkout_summary")
|
||||
self.assertIsNotNone(template)
|
||||
self.assertEqual(template.type, 'qweb')
|
||||
self.assertEqual(template.type, "qweb")
|
||||
# Verify it has the expected structure
|
||||
self.assertIn('checkout-summary-table', template.arch_db,
|
||||
"Template must have checkout-summary-table id")
|
||||
self.assertIn('Product', template.arch_db,
|
||||
"Template must have Product label for translation")
|
||||
self.assertIn('Quantity', template.arch_db,
|
||||
"Template must have Quantity label for translation")
|
||||
self.assertIn('Price', template.arch_db,
|
||||
"Template must have Price label for translation")
|
||||
self.assertIn('Subtotal', template.arch_db,
|
||||
"Template must have Subtotal label for translation")
|
||||
self.assertIn(
|
||||
"checkout-summary-table",
|
||||
template.arch_db,
|
||||
"Template must have checkout-summary-table id",
|
||||
)
|
||||
self.assertIn(
|
||||
"Product",
|
||||
template.arch_db,
|
||||
"Template must have Product label for translation",
|
||||
)
|
||||
self.assertIn(
|
||||
"Quantity",
|
||||
template.arch_db,
|
||||
"Template must have Quantity label for translation",
|
||||
)
|
||||
self.assertIn(
|
||||
"Price", template.arch_db, "Template must have Price label for translation"
|
||||
)
|
||||
self.assertIn(
|
||||
"Subtotal",
|
||||
template.arch_db,
|
||||
"Template must have Subtotal label for translation",
|
||||
)
|
||||
|
||||
def test_eskaera_checkout_summary_renders(self):
|
||||
'''Test that eskaera_checkout_summary renders without errors.'''
|
||||
template = self.env.ref('website_sale_aplicoop.eskaera_checkout_summary')
|
||||
"""Test that eskaera_checkout_summary renders without errors."""
|
||||
template = self.env.ref("website_sale_aplicoop.eskaera_checkout_summary")
|
||||
# Render the template with empty context
|
||||
html = template._render_template(template.xml_id, {})
|
||||
# Should contain the basic table structure
|
||||
self.assertIn('<table', html)
|
||||
self.assertIn('checkout-summary-table', html)
|
||||
self.assertIn('Product', html)
|
||||
self.assertIn('Quantity', html)
|
||||
self.assertIn("<table", html)
|
||||
self.assertIn("checkout-summary-table", html)
|
||||
self.assertIn("Product", html)
|
||||
self.assertIn("Quantity", html)
|
||||
self.assertIn("This order's cart is empty", html)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@ Coverage:
|
|||
- group.order state transitions: illegal transitions
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
|
||||
|
||||
class TestGroupOrderValidations(TransactionCase):
|
||||
|
|
@ -25,87 +27,101 @@ class TestGroupOrderValidations(TransactionCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.company1 = self.env.company
|
||||
self.company2 = self.env['res.company'].create({
|
||||
'name': 'Company 2',
|
||||
})
|
||||
self.company2 = self.env["res.company"].create(
|
||||
{
|
||||
"name": "Company 2",
|
||||
}
|
||||
)
|
||||
|
||||
self.group_c1 = self.env['res.partner'].create({
|
||||
'name': 'Group Company 1',
|
||||
'is_company': True,
|
||||
'company_id': self.company1.id,
|
||||
})
|
||||
self.group_c1 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Company 1",
|
||||
"is_company": True,
|
||||
"company_id": self.company1.id,
|
||||
}
|
||||
)
|
||||
|
||||
self.group_c2 = self.env['res.partner'].create({
|
||||
'name': 'Group Company 2',
|
||||
'is_company': True,
|
||||
'company_id': self.company2.id,
|
||||
})
|
||||
self.group_c2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Group Company 2",
|
||||
"is_company": True,
|
||||
"company_id": self.company2.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_group_order_same_company_constraint(self):
|
||||
"""Test that all groups in an order must be from same company."""
|
||||
start_date = datetime.now().date()
|
||||
|
||||
|
||||
# Creating order with groups from different companies should fail
|
||||
with self.assertRaises(ValidationError):
|
||||
self.env['group.order'].create({
|
||||
'name': 'Multi-Company Order',
|
||||
'group_ids': [(6, 0, [self.group_c1.id, self.group_c2.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.env["group.order"].create(
|
||||
{
|
||||
"name": "Multi-Company Order",
|
||||
"group_ids": [(6, 0, [self.group_c1.id, self.group_c2.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_group_order_same_company_mixed_single(self):
|
||||
"""Test that single company group is valid."""
|
||||
start_date = datetime.now().date()
|
||||
|
||||
|
||||
# Single company should pass
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Single Company Order',
|
||||
'group_ids': [(6, 0, [self.group_c1.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Single Company Order",
|
||||
"group_ids": [(6, 0, [self.group_c1.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.assertTrue(order.exists())
|
||||
|
||||
def test_group_order_date_validation_start_after_end(self):
|
||||
"""Test that start_date must be before end_date."""
|
||||
start_date = datetime.now().date()
|
||||
end_date = start_date - timedelta(days=1) # End before start
|
||||
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
self.env['group.order'].create({
|
||||
'name': 'Bad Dates Order',
|
||||
'group_ids': [(6, 0, [self.group_c1.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.env["group.order"].create(
|
||||
{
|
||||
"name": "Bad Dates Order",
|
||||
"group_ids": [(6, 0, [self.group_c1.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": end_date,
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_group_order_date_validation_same_date(self):
|
||||
"""Test that start_date == end_date is allowed (single-day order)."""
|
||||
same_date = datetime.now().date()
|
||||
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Same Day Order',
|
||||
'group_ids': [(6, 0, [self.group_c1.id])],
|
||||
'type': 'regular',
|
||||
'start_date': same_date,
|
||||
'end_date': same_date,
|
||||
'period': 'once',
|
||||
'pickup_day': '0',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Same Day Order",
|
||||
"group_ids": [(6, 0, [self.group_c1.id])],
|
||||
"type": "regular",
|
||||
"start_date": same_date,
|
||||
"end_date": same_date,
|
||||
"period": "once",
|
||||
"pickup_day": "0",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
self.assertTrue(order.exists())
|
||||
|
||||
|
||||
|
|
@ -114,43 +130,47 @@ class TestGroupOrderImageFallback(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_image_fallback_order_image_first(self):
|
||||
"""Test that order image takes priority over group image."""
|
||||
# Set both order and group image
|
||||
test_image = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='
|
||||
|
||||
test_image = b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
|
||||
|
||||
self.group_order.image_1920 = test_image
|
||||
self.group.image_1920 = test_image
|
||||
|
||||
|
||||
# Order image should be returned
|
||||
computed_image = self.group_order.image_1920
|
||||
self.assertEqual(computed_image, test_image)
|
||||
|
||||
def test_image_fallback_group_image_when_no_order_image(self):
|
||||
"""Test fallback to group image when order has no image."""
|
||||
test_image = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='
|
||||
|
||||
test_image = b"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
|
||||
|
||||
# Only set group image
|
||||
self.group_order.image_1920 = False
|
||||
self.group.image_1920 = test_image
|
||||
|
||||
|
||||
# Group image should be returned as fallback
|
||||
# Note: This requires the computed field logic to be tested
|
||||
# after field recalculation
|
||||
|
|
@ -160,7 +180,7 @@ class TestGroupOrderImageFallback(TransactionCase):
|
|||
# No images set
|
||||
self.group_order.image_1920 = False
|
||||
self.group.image_1920 = False
|
||||
|
||||
|
||||
# Should be empty/False
|
||||
computed_image = self.group_order.image_1920
|
||||
self.assertFalse(computed_image)
|
||||
|
|
@ -171,34 +191,42 @@ class TestGroupOrderProductCount(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.group_order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.group_order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
self.product1 = self.env['product.product'].create({
|
||||
'name': 'Product 1',
|
||||
'type': 'consu',
|
||||
'list_price': 10.0,
|
||||
})
|
||||
self.product1 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product 1",
|
||||
"type": "consu",
|
||||
"list_price": 10.0,
|
||||
}
|
||||
)
|
||||
|
||||
self.product2 = self.env['product.product'].create({
|
||||
'name': 'Product 2',
|
||||
'type': 'consu',
|
||||
'list_price': 20.0,
|
||||
})
|
||||
self.product2 = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product 2",
|
||||
"type": "consu",
|
||||
"list_price": 20.0,
|
||||
}
|
||||
)
|
||||
|
||||
def test_product_count_initial_zero(self):
|
||||
"""Test that new order has zero products."""
|
||||
|
|
@ -232,28 +260,32 @@ class TestStateTransitions(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
start_date = datetime.now().date()
|
||||
self.order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
self.order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
def test_illegal_transition_draft_to_closed(self):
|
||||
"""Test that Draft -> Closed transition is not allowed."""
|
||||
# Should not allow skipping Open state
|
||||
self.assertEqual(self.order.state, 'draft')
|
||||
|
||||
self.assertEqual(self.order.state, "draft")
|
||||
|
||||
# Calling action_close() without action_open() should fail
|
||||
with self.assertRaises((ValidationError, UserError)):
|
||||
self.order.action_close()
|
||||
|
|
@ -261,36 +293,36 @@ class TestStateTransitions(TransactionCase):
|
|||
def test_illegal_transition_cancelled_to_open(self):
|
||||
"""Test that Cancelled -> Open transition is not allowed."""
|
||||
self.order.action_cancel()
|
||||
self.assertEqual(self.order.state, 'cancelled')
|
||||
|
||||
self.assertEqual(self.order.state, "cancelled")
|
||||
|
||||
# Should not allow re-opening cancelled order
|
||||
with self.assertRaises((ValidationError, UserError)):
|
||||
self.order.action_open()
|
||||
|
||||
def test_legal_transition_draft_open_closed(self):
|
||||
"""Test that Draft -> Open -> Closed is allowed."""
|
||||
self.assertEqual(self.order.state, 'draft')
|
||||
|
||||
self.assertEqual(self.order.state, "draft")
|
||||
|
||||
self.order.action_open()
|
||||
self.assertEqual(self.order.state, 'open')
|
||||
|
||||
self.assertEqual(self.order.state, "open")
|
||||
|
||||
self.order.action_close()
|
||||
self.assertEqual(self.order.state, 'closed')
|
||||
self.assertEqual(self.order.state, "closed")
|
||||
|
||||
def test_transition_draft_to_cancelled(self):
|
||||
"""Test that Draft -> Cancelled is allowed."""
|
||||
self.assertEqual(self.order.state, 'draft')
|
||||
|
||||
self.assertEqual(self.order.state, "draft")
|
||||
|
||||
self.order.action_cancel()
|
||||
self.assertEqual(self.order.state, 'cancelled')
|
||||
self.assertEqual(self.order.state, "cancelled")
|
||||
|
||||
def test_transition_open_to_cancelled(self):
|
||||
"""Test that Open -> Cancelled is allowed (emergency stop)."""
|
||||
self.order.action_open()
|
||||
self.assertEqual(self.order.state, 'open')
|
||||
|
||||
self.assertEqual(self.order.state, "open")
|
||||
|
||||
self.order.action_cancel()
|
||||
self.assertEqual(self.order.state, 'cancelled')
|
||||
self.assertEqual(self.order.state, "cancelled")
|
||||
|
||||
|
||||
class TestUserPartnerValidation(TransactionCase):
|
||||
|
|
@ -298,31 +330,37 @@ class TestUserPartnerValidation(TransactionCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group = self.env['res.partner'].create({
|
||||
'name': 'Test Group',
|
||||
'is_company': True,
|
||||
})
|
||||
self.group = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Test Group",
|
||||
"is_company": True,
|
||||
}
|
||||
)
|
||||
|
||||
# Create user without partner (edge case)
|
||||
self.user_no_partner = self.env['res.users'].create({
|
||||
'name': 'User No Partner',
|
||||
'login': 'noparnter@test.com',
|
||||
'partner_id': False, # Explicitly no partner
|
||||
})
|
||||
self.user_no_partner = self.env["res.users"].create(
|
||||
{
|
||||
"name": "User No Partner",
|
||||
"login": "noparnter@test.com",
|
||||
"partner_id": False, # Explicitly no partner
|
||||
}
|
||||
)
|
||||
|
||||
def test_user_without_partner_cannot_access_order(self):
|
||||
"""Test that user without partner_id has no access to orders."""
|
||||
start_date = datetime.now().date()
|
||||
order = self.env['group.order'].create({
|
||||
'name': 'Test Order',
|
||||
'group_ids': [(6, 0, [self.group.id])],
|
||||
'type': 'regular',
|
||||
'start_date': start_date,
|
||||
'end_date': start_date + timedelta(days=7),
|
||||
'period': 'weekly',
|
||||
'pickup_day': '3',
|
||||
'cutoff_day': '0',
|
||||
})
|
||||
order = self.env["group.order"].create(
|
||||
{
|
||||
"name": "Test Order",
|
||||
"group_ids": [(6, 0, [self.group.id])],
|
||||
"type": "regular",
|
||||
"start_date": start_date,
|
||||
"end_date": start_date + timedelta(days=7),
|
||||
"period": "weekly",
|
||||
"pickup_day": "3",
|
||||
"cutoff_day": "0",
|
||||
}
|
||||
)
|
||||
|
||||
# User without partner should not have access
|
||||
# This should be validated in controller
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue