# Copyright 2025 Criptomart # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) """ Test suite for cart/draft persistence in website_sale_aplicoop. Coverage: - Save draft order (empty, with items) - Load draft order - Draft consistency (prices don't change unexpectedly) - Product archived in draft (handling) - Merge inconsistent drafts - Draft timeline (very old draft, recent draft) """ from datetime import datetime from datetime import timedelta from odoo.tests.common import TransactionCase class TestSaveDraftOrder(TransactionCase): """Test saving draft orders.""" def setUp(self): super().setUp() 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.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.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.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.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, }, ), ], } ) self.assertTrue(draft_order.exists()) 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": [], } ) # Should be valid (user hasn't added products yet) self.assertTrue(empty_draft.exists()) self.assertEqual(len(empty_draft.order_line), 0) 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_id = draft.id # Simulate "save" with different quantity draft.order_line[0].product_qty = 5 # Should be same draft, not new one 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", } ) # 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", } ) self.assertEqual(draft.pickup_date, self.group_order.pickup_date) class TestLoadDraftOrder(TransactionCase): """Test loading (retrieving) draft orders.""" def setUp(self): super().setUp() 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.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.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.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, }, ) ], } ) # Load it 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) 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", } ) # Create another user/partner other_partner = self.env["res.partner"].create( { "name": "Other Member", "email": "other@test.com", } ) 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), ] ) self.assertEqual(len(other_drafts), 0) def test_load_draft_from_expired_order(self): """Test loading draft from closed/expired group order.""" # Close the group order 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 should still be loadable (but should warn) loaded = self.env["sale.order"].browse(draft.id) self.assertTrue(loaded.exists()) # Controller should check: group_order.state and warn if closed class TestDraftConsistency(TransactionCase): """Test that draft prices remain consistent across saves.""" def setUp(self): super().setUp() 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.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.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.action_open() def test_draft_price_snapshot(self): """Test that draft captures price at time of save.""" 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, }, ) ], } ) saved_price = draft.order_line[0].price_unit # Change product price self.product.list_price = 150.0 # Draft should still have original price self.assertEqual(draft.order_line[0].price_unit, saved_price) self.assertNotEqual(draft.order_line[0].price_unit, self.product.list_price) 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, }, ) ], } ) # Re-load draft reloaded = self.env["sale.order"].browse(draft.id) self.assertEqual(reloaded.order_line[0].product_qty, 5) class TestProductArchivedInDraft(TransactionCase): """Test handling when product in draft gets archived.""" def setUp(self): super().setUp() 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.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.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.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, }, ) ], } ) # Archive the product self.product.active = False # Load draft - should still work (historical data) loaded = self.env["sale.order"].browse(draft.id) self.assertTrue(loaded.exists()) # But product may not be editable/accessible class TestDraftTimeline(TransactionCase): """Test very old vs recent drafts.""" def setUp(self): super().setUp() 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.group.member_ids = [(4, self.member_partner.id)] 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.action_open() 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") 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.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", } ) # Should still exist but be inaccessible (order closed) self.assertTrue(old_draft.exists()) 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", } ) 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", } ) # Count drafts for user user_drafts = self.env["sale.order"].search( [ ("partner_id", "=", self.member_partner.id), ("state", "=", "draft"), ] ) self.assertEqual(len(user_drafts), 3)