summaryrefslogtreecommitdiff
path: root/addons/event_sale/tests
diff options
context:
space:
mode:
Diffstat (limited to 'addons/event_sale/tests')
-rw-r--r--addons/event_sale/tests/__init__.py6
-rw-r--r--addons/event_sale/tests/common.py21
-rw-r--r--addons/event_sale/tests/test_event_internals.py146
-rw-r--r--addons/event_sale/tests/test_event_sale.py282
-rw-r--r--addons/event_sale/tests/test_event_sale_ui.py29
5 files changed, 484 insertions, 0 deletions
diff --git a/addons/event_sale/tests/__init__.py b/addons/event_sale/tests/__init__.py
new file mode 100644
index 00000000..47f238b9
--- /dev/null
+++ b/addons/event_sale/tests/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import test_event_internals
+from . import test_event_sale
+from . import test_event_sale_ui
diff --git a/addons/event_sale/tests/common.py b/addons/event_sale/tests/common.py
new file mode 100644
index 00000000..bc4be1d8
--- /dev/null
+++ b/addons/event_sale/tests/common.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.event.tests.common import TestEventCommon
+from odoo.addons.sales_team.tests.common import TestSalesCommon
+
+
+class TestEventSaleCommon(TestEventCommon, TestSalesCommon):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestEventSaleCommon, cls).setUpClass()
+
+ cls.event_product = cls.env['product.product'].create({
+ 'name': 'Test Registration Product',
+ 'description_sale': 'Mighty Description',
+ 'list_price': 10,
+ 'event_ok': True,
+ 'standard_price': 30.0,
+ 'type': 'service',
+ })
diff --git a/addons/event_sale/tests/test_event_internals.py b/addons/event_sale/tests/test_event_internals.py
new file mode 100644
index 00000000..b61b5a29
--- /dev/null
+++ b/addons/event_sale/tests/test_event_internals.py
@@ -0,0 +1,146 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from datetime import date, datetime, timedelta
+from unittest.mock import patch
+
+from odoo.addons.event_sale.tests.common import TestEventSaleCommon
+from odoo.fields import Datetime as FieldsDatetime, Date as FieldsDate
+from odoo.tests.common import users
+
+
+class TestEventData(TestEventSaleCommon):
+
+ @users('user_eventmanager')
+ def test_event_configuration_from_type(self):
+ """ In addition to event test, also test tickets configuration coming
+ from event_sale capabilities. """
+ event_type = self.event_type_complex.with_user(self.env.user)
+ event_type.write({
+ 'use_mail_schedule': False,
+ 'use_ticket': False,
+ })
+ self.assertEqual(event_type.event_type_ticket_ids, self.env['event.type.ticket'])
+
+ event = self.env['event.event'].create({
+ 'name': 'Event Update Type',
+ 'event_type_id': event_type.id,
+ 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)),
+ 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)),
+ })
+ self.assertEqual(event.event_ticket_ids, self.env['event.event.ticket'])
+
+ event_type.write({
+ 'use_ticket': True,
+ 'event_type_ticket_ids': [(5, 0), (0, 0, {
+ 'name': 'First Ticket',
+ 'product_id': self.event_product.id,
+ 'seats_max': 5,
+ })]
+ })
+ self.assertEqual(event_type.event_type_ticket_ids.description, self.event_product.description_sale)
+
+ # synchronize event
+ event.write({'event_type_id': event_type.id})
+ self.assertEqual(event.event_ticket_ids.name, event.event_type_id.event_type_ticket_ids.name)
+ self.assertTrue(event.event_ticket_ids.seats_limited)
+ self.assertEqual(event.event_ticket_ids.seats_max, 5)
+ self.assertEqual(event.event_ticket_ids.product_id, self.event_product)
+ self.assertEqual(event.event_ticket_ids.price, self.event_product.list_price)
+ self.assertEqual(event.event_ticket_ids.description, self.event_product.description_sale)
+
+ def test_event_registrable(self):
+ """Test if `_compute_event_registrations_open` works properly with additional
+ product active conditions compared to base tests (see event) """
+ event = self.event_0.with_user(self.env.user)
+ self.assertTrue(event.event_registrations_open)
+
+ # ticket without dates boundaries -> ok
+ ticket = self.env['event.event.ticket'].create({
+ 'name': 'TestTicket',
+ 'event_id': event.id,
+ 'product_id': self.event_product.id,
+ })
+ self.assertTrue(event.event_registrations_open)
+
+ # ticket has inactive product -> ko
+ ticket.product_id.action_archive()
+ self.assertFalse(event.event_registrations_open)
+
+ # at least one valid ticket -> ok is back
+ event_product = self.env['product.product'].create({'name': 'Test Registration Product New',})
+ new_ticket = self.env['event.event.ticket'].create({
+ 'name': 'TestTicket 2',
+ 'event_id': event.id,
+ 'product_id': event_product.id,
+ 'end_sale_date': datetime.now() + timedelta(days=2),
+ })
+ self.assertTrue(new_ticket.sale_available)
+ self.assertTrue(event.event_registrations_open)
+
+
+class TestEventTicketData(TestEventSaleCommon):
+
+ def setUp(self):
+ super(TestEventTicketData, self).setUp()
+ self.ticket_date_patcher = patch('odoo.addons.event.models.event_ticket.fields.Date', wraps=FieldsDate)
+ self.ticket_date_patcher_mock = self.ticket_date_patcher.start()
+ self.ticket_date_patcher_mock.context_today.return_value = date(2020, 1, 31)
+
+ def tearDown(self):
+ super(TestEventTicketData, self).tearDown()
+ self.ticket_date_patcher.stop()
+
+ @users('user_eventmanager')
+ def test_event_ticket_fields(self):
+ """ Test event ticket fields synchronization """
+ event = self.event_0.with_user(self.env.user)
+ event.write({
+ 'event_ticket_ids': [
+ (5, 0),
+ (0, 0, {
+ 'name': 'First Ticket',
+ 'product_id': self.event_product.id,
+ 'seats_max': 30,
+ }), (0, 0, { # limited in time, available (01/10 (start) < 01/31 (today) < 02/10 (end))
+ 'name': 'Second Ticket',
+ 'product_id': self.event_product.id,
+ 'start_sale_date': date(2020, 1, 10),
+ 'end_sale_date': date(2020, 2, 10),
+ })
+ ],
+ })
+ first_ticket = event.event_ticket_ids.filtered(lambda t: t.name == 'First Ticket')
+ second_ticket = event.event_ticket_ids.filtered(lambda t: t.name == 'Second Ticket')
+ # force second ticket price, after calling the onchange
+ second_ticket.write({'price': 8.0})
+
+ # price coming from product
+ self.assertEqual(first_ticket.price, self.event_product.list_price)
+ self.assertEqual(second_ticket.price, 8.0)
+
+ # default availability
+ self.assertTrue(first_ticket.seats_limited)
+ self.assertTrue(first_ticket.sale_available)
+ self.assertFalse(first_ticket.is_expired)
+ self.assertFalse(second_ticket.seats_limited)
+ self.assertTrue(second_ticket.sale_available)
+ self.assertFalse(second_ticket.is_expired)
+
+ # product archived
+ self.event_product.action_archive()
+ self.assertFalse(first_ticket.sale_available)
+ self.assertFalse(second_ticket.sale_available)
+
+ # sale is ended
+ self.event_product.action_unarchive()
+ second_ticket.write({'end_sale_date': date(2020, 1, 20)})
+ self.assertFalse(second_ticket.sale_available)
+ self.assertTrue(second_ticket.is_expired)
+ # sale has not started
+ second_ticket.write({
+ 'start_sale_date': date(2020, 2, 10),
+ 'end_sale_date': date(2020, 2, 20),
+ })
+ self.assertFalse(second_ticket.sale_available)
+ self.assertFalse(second_ticket.is_expired)
diff --git a/addons/event_sale/tests/test_event_sale.py b/addons/event_sale/tests/test_event_sale.py
new file mode 100644
index 00000000..1398b8a5
--- /dev/null
+++ b/addons/event_sale/tests/test_event_sale.py
@@ -0,0 +1,282 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.event_sale.tests.common import TestEventSaleCommon
+from odoo.addons.mail.tests.common import mail_new_test_user
+
+from odoo.tests import tagged
+from odoo.tests.common import users
+
+
+@tagged('event_flow')
+class TestEventSale(TestEventSaleCommon):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestEventSale, cls).setUpClass()
+
+ product = cls.env['product.product'].create({
+ 'name': 'Event',
+ 'type': 'service',
+ 'event_ok': True,
+ })
+
+ cls.user_salesperson = mail_new_test_user(cls.env, login='user_salesman', groups='sales_team.group_sale_salesman')
+
+ cls.ticket = cls.env['event.event.ticket'].create({
+ 'name': 'First Ticket',
+ 'product_id': cls.event_product.id,
+ 'seats_max': 30,
+ 'event_id': cls.event_0.id,
+ })
+
+ cls.event_0.write({
+ 'event_ticket_ids': [
+ (6, 0, cls.ticket.ids),
+ (0, 0, {
+ 'name': 'Second Ticket',
+ 'product_id': cls.event_product.id,
+ })
+ ],
+ })
+
+ cls.sale_order = cls.env['sale.order'].create({
+ 'partner_id': cls.env.ref('base.res_partner_2').id,
+ 'note': 'Invoice after delivery',
+ 'payment_term_id': cls.env.ref('account.account_payment_term_end_following_month').id
+ })
+
+ # In the sales order I add some sales order lines. i choose event product
+ cls.env['sale.order.line'].create({
+ 'product_id': product.id,
+ 'price_unit': 190.50,
+ 'product_uom': cls.env.ref('uom.product_uom_unit').id,
+ 'product_uom_qty': 1.0,
+ 'order_id': cls.sale_order.id,
+ 'name': 'sales order line',
+ 'event_id': cls.event_0.id,
+ 'event_ticket_id': cls.ticket.id,
+ })
+
+ cls.register_person = cls.env['registration.editor'].create({
+ 'sale_order_id': cls.sale_order.id,
+ 'event_registration_ids': [(0, 0, {
+ 'event_id': cls.event_0.id,
+ 'name': 'Administrator',
+ 'email': 'abc@example.com',
+ 'sale_order_line_id': cls.sale_order.order_line.id,
+ })],
+ })
+
+ # make a SO for a customer, selling some tickets
+ cls.customer_so = cls.env['sale.order'].with_user(cls.user_sales_salesman).create({
+ 'partner_id': cls.event_customer.id,
+ })
+
+ @users('user_sales_salesman')
+ def test_event_crm_sale(self):
+ TICKET1_COUNT, TICKET2_COUNT = 3, 1
+ customer_so = self.customer_so.with_user(self.env.user)
+ ticket1 = self.event_0.event_ticket_ids[0]
+ ticket2 = self.event_0.event_ticket_ids[1]
+
+ # PREPARE SO DATA
+ # ------------------------------------------------------------
+
+ # adding some tickets to SO
+ customer_so.write({
+ 'order_line': [
+ (0, 0, {
+ 'event_id': self.event_0.id,
+ 'event_ticket_id': ticket1.id,
+ 'product_id': ticket1.product_id.id,
+ 'product_uom_qty': TICKET1_COUNT,
+ 'price_unit': 10,
+ }), (0, 0, {
+ 'event_id': self.event_0.id,
+ 'event_ticket_id': ticket2.id,
+ 'product_id': ticket2.product_id.id,
+ 'product_uom_qty': TICKET2_COUNT,
+ 'price_unit': 50,
+ })
+ ]
+ })
+ ticket1_line = customer_so.order_line.filtered(lambda line: line.event_ticket_id == ticket1)
+ ticket2_line = customer_so.order_line.filtered(lambda line: line.event_ticket_id == ticket2)
+ self.assertEqual(customer_so.amount_untaxed, TICKET1_COUNT * 10 + TICKET2_COUNT * 50)
+
+ # one existing registration for first ticket
+ ticket1_reg1 = self.env['event.registration'].create({
+ 'event_id': self.event_0.id,
+ 'event_ticket_id': ticket1.id,
+ 'partner_id': self.event_customer2.id,
+ 'sale_order_id': customer_so.id,
+ 'sale_order_line_id': ticket1_line.id,
+ })
+ self.assertEqual(ticket1_reg1.partner_id, self.event_customer)
+ for field in ['name', 'email', 'phone', 'mobile']:
+ self.assertEqual(ticket1_reg1[field], self.event_customer[field])
+
+ # EVENT REGISTRATION EDITOR
+ # ------------------------------------------------------------
+
+ # use event registration editor to create missing lines and update details
+ editor = self.env['registration.editor'].with_context({
+ 'default_sale_order_id': customer_so.id
+ }).create({})
+ self.assertEqual(len(editor.event_registration_ids), TICKET1_COUNT + TICKET2_COUNT)
+ self.assertEqual(editor.sale_order_id, customer_so)
+ self.assertEqual(editor.event_registration_ids.sale_order_line_id, ticket1_line | ticket2_line)
+
+ # check line linked to existing registration (ticket1_reg1)
+ ticket1_editor_reg1 = editor.event_registration_ids.filtered(lambda line: line.registration_id)
+ for field in ['name', 'email', 'phone', 'mobile']:
+ self.assertEqual(ticket1_editor_reg1[field], ticket1_reg1[field])
+
+ # check new lines
+ ticket1_editor_other = editor.event_registration_ids.filtered(lambda line: not line.registration_id and line.event_ticket_id == ticket1)
+ self.assertEqual(len(ticket1_editor_other), 2)
+ ticket2_editor_other = editor.event_registration_ids.filtered(lambda line: not line.registration_id and line.event_ticket_id == ticket2)
+ self.assertEqual(len(ticket2_editor_other), 1)
+
+ # update lines in editor and save them
+ ticket1_editor_other[0].write({
+ 'name': 'ManualEntry1',
+ 'email': 'manual.email.1@test.example.com',
+ 'phone': '+32456111111',
+ })
+ ticket1_editor_other[1].write({
+ 'name': 'ManualEntry2',
+ 'email': 'manual.email.2@test.example.com',
+ 'mobile': '+32456222222',
+ })
+ editor.action_make_registration()
+
+ # check editor correctly created new registrations with information coming from it or SO as fallback
+ self.assertEqual(len(self.event_0.registration_ids), TICKET1_COUNT + TICKET2_COUNT)
+ new_registrations = self.event_0.registration_ids - ticket1_reg1
+ self.assertEqual(new_registrations.sale_order_id, customer_so)
+ ticket1_new_reg = new_registrations.filtered(lambda reg: reg.event_ticket_id == ticket1)
+ ticket2_new_reg = new_registrations.filtered(lambda reg: reg.event_ticket_id == ticket2)
+ self.assertEqual(len(ticket1_new_reg), 2)
+ self.assertEqual(len(ticket2_new_reg), 1)
+ self.assertEqual(
+ set(ticket1_new_reg.mapped('name')),
+ set(['ManualEntry1', 'ManualEntry2'])
+ )
+ self.assertEqual(
+ set(ticket1_new_reg.mapped('email')),
+ set(['manual.email.1@test.example.com', 'manual.email.2@test.example.com'])
+ )
+ self.assertEqual(
+ set(ticket1_new_reg.mapped('phone')),
+ set(['+32456111111', self.event_customer.phone])
+ )
+ self.assertEqual(
+ set(ticket1_new_reg.mapped('mobile')),
+ set(['+32456222222', self.event_customer.mobile])
+ )
+ for field in ['name', 'email', 'phone', 'mobile']:
+ self.assertEqual(ticket2_new_reg[field], self.event_customer[field])
+
+ # ADDING MANUAL LINES ON SO
+ # ------------------------------------------------------------
+
+ ticket2_line.write({'product_uom_qty': 3})
+ editor_action = customer_so.action_confirm()
+ self.assertEqual(customer_so.state, 'sale')
+ self.assertEqual(customer_so.amount_untaxed, TICKET1_COUNT * 10 + (TICKET2_COUNT + 2) * 50)
+
+ # check confirm of SO correctly created new registrations with information coming from SO
+ self.assertEqual(len(self.event_0.registration_ids), 6) # 3 for each ticket now
+ new_registrations = self.event_0.registration_ids - (ticket1_reg1 | ticket1_new_reg | ticket2_new_reg)
+ self.assertEqual(new_registrations.event_ticket_id, ticket2)
+ self.assertEqual(new_registrations.partner_id, self.customer_so.partner_id)
+
+ self.assertEqual(editor_action['type'], 'ir.actions.act_window')
+ self.assertEqual(editor_action['res_model'], 'registration.editor')
+
+ def test_ticket_price_with_pricelist_and_tax(self):
+ self.env.user.partner_id.country_id = False
+ pricelist = self.env['product.pricelist'].search([], limit=1)
+
+ tax = self.env['account.tax'].create({
+ 'name': "Tax 10",
+ 'amount': 10,
+ })
+
+ event_product = self.env['product.template'].create({
+ 'name': 'Event Product',
+ 'list_price': 10.0,
+ })
+
+ event_product.taxes_id = tax
+
+ event = self.env['event.event'].create({
+ 'name': 'New Event',
+ 'date_begin': '2020-02-02',
+ 'date_end': '2020-04-04',
+ })
+ event_ticket = self.env['event.event.ticket'].create({
+ 'name': 'VIP',
+ 'price': 1000.0,
+ 'event_id': event.id,
+ 'product_id': event_product.product_variant_id.id,
+ })
+
+ pricelist.item_ids = self.env['product.pricelist.item'].create({
+ 'applied_on': "1_product",
+ 'base': "list_price",
+ 'compute_price': "fixed",
+ 'fixed_price': 6.0,
+ 'product_tmpl_id': event_product.id,
+ })
+
+ pricelist.discount_policy = 'without_discount'
+
+ so = self.env['sale.order'].create({
+ 'partner_id': self.env.user.partner_id.id,
+ 'pricelist_id': pricelist.id,
+ })
+ sol = self.env['sale.order.line'].create({
+ 'name': event.name,
+ 'product_id': event_product.product_variant_id.id,
+ 'product_uom_qty': 1,
+ 'product_uom': event_product.uom_id.id,
+ 'price_unit': event_product.list_price,
+ 'order_id': so.id,
+ 'event_id': event.id,
+ 'event_ticket_id': event_ticket.id,
+ })
+ sol.product_id_change()
+ self.assertEqual(so.amount_total, 660.0, "Ticket is $1000 but the event product is on a pricelist 10 -> 6. So, $600 + a 10% tax.")
+
+ @users('user_salesman')
+ def test_unlink_so(self):
+ """ This test ensures that when deleting a sale order, if the latter is linked to an event registration,
+ the number of expected seats will be correctly updated """
+ event = self.env['event.event'].browse(self.event_0.ids)
+ self.register_person.action_make_registration()
+ self.assertEqual(event.seats_expected, 1)
+ self.sale_order.unlink()
+ self.assertEqual(event.seats_expected, 0)
+
+ @users('user_salesman')
+ def test_unlink_soline(self):
+ """ This test ensures that when deleting a sale order line, if the latter is linked to an event registration,
+ the number of expected seats will be correctly updated """
+ event = self.env['event.event'].browse(self.event_0.ids)
+ self.register_person.action_make_registration()
+ self.assertEqual(event.seats_expected, 1)
+ self.sale_order.order_line.unlink()
+ self.assertEqual(event.seats_expected, 0)
+
+ @users('user_salesman')
+ def test_cancel_so(self):
+ """ This test ensures that when canceling a sale order, if the latter is linked to an event registration,
+ the number of expected seats will be correctly updated """
+ event = self.env['event.event'].browse(self.event_0.ids)
+ self.register_person.action_make_registration()
+ self.assertEqual(event.seats_expected, 1)
+ self.sale_order.action_cancel()
+ self.assertEqual(event.seats_expected, 0)
diff --git a/addons/event_sale/tests/test_event_sale_ui.py b/addons/event_sale/tests/test_event_sale_ui.py
new file mode 100644
index 00000000..24e68c5d
--- /dev/null
+++ b/addons/event_sale/tests/test_event_sale_ui.py
@@ -0,0 +1,29 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from datetime import timedelta
+
+from odoo.fields import Datetime
+from odoo.tests import HttpCase, tagged
+
+
+@tagged('post_install', '-at_install')
+class TestUi(HttpCase):
+
+ def test_event_configurator(self):
+
+ event = self.env['event.event'].create({
+ 'name': 'Design Fair Los Angeles',
+ 'date_begin': Datetime.now() + timedelta(days=1),
+ 'date_end': Datetime.now() + timedelta(days=5),
+ })
+
+ self.env['event.event.ticket'].create([{
+ 'name': 'Standard',
+ 'event_id': event.id,
+ 'product_id': self.env.ref('event_sale.product_product_event').id,
+ }, {
+ 'name': 'VIP',
+ 'event_id': event.id,
+ 'product_id': self.env.ref('event_sale.product_product_event').id,
+ }])
+ self.start_tour("/web", 'event_configurator_tour', login="admin")