From 83a7fb5f9215c5cebcca547e62bb06fde716b05f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 15 May 2020 12:10:17 +0000 Subject: [PATCH 1/3] [IMP] event_sale: add some tests for registration update In this commit we add some tests related to sale order / event registrations synchronization, notably * registrations automatically created when _update_registrations of an SO line is called, for example at SO confirmation; * using the registration editor; LINKS Task ID 2258685 Prepare Task ID 2166679 (create leads from registrations) PR odoo/odoo#51341 --- addons/event/tests/common.py | 11 +- addons/event/tests/test_event_flow.py | 43 ++-- addons/event/tests/test_event_internals.py | 2 +- addons/event_sale/tests/common.py | 3 +- addons/event_sale/tests/test_event_sale.py | 190 +++++++++++++----- .../wizard/event_edit_registration.py | 1 + 6 files changed, 170 insertions(+), 80 deletions(-) diff --git a/addons/event/tests/common.py b/addons/event/tests/common.py index dab3e3339a1..126a839805f 100644 --- a/addons/event/tests/common.py +++ b/addons/event/tests/common.py @@ -42,12 +42,21 @@ class TestEventCommon(common.SavepointCase): groups='base.group_user,event.group_event_manager', ) - cls.customer = cls.env['res.partner'].create({ + cls.event_customer = cls.env['res.partner'].create({ 'name': 'Constantin Customer', 'email': 'constantin@test.example.com', 'country_id': cls.env.ref('base.be').id, 'phone': '0485112233', + 'mobile': False, }) + cls.event_customer2 = cls.env['res.partner'].create({ + 'name': 'Constantin Customer 2', + 'email': 'constantin2@test.example.com', + 'country_id': cls.env.ref('base.be').id, + 'phone': '0456987654', + 'mobile': '0456654321', + }) + cls.event_type_complex = cls.env['event.type'].create({ 'name': 'Update Type', 'auto_confirm': True, diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py index a1bd3ffcd35..e1602efe73e 100644 --- a/addons/event/tests/test_event_flow.py +++ b/addons/event/tests/test_event_flow.py @@ -27,19 +27,19 @@ class TestEventUI(TestEventCommon): self.assertFalse(registration_form.mobile) # trigger onchange - registration_form.partner_id = self.customer - self.assertEqual(registration_form.name, self.customer.name) - self.assertEqual(registration_form.email, self.customer.email) - self.assertEqual(registration_form.phone, self.customer.phone) - self.assertEqual(registration_form.mobile, self.customer.mobile) + registration_form.partner_id = self.event_customer + self.assertEqual(registration_form.name, self.event_customer.name) + self.assertEqual(registration_form.email, self.event_customer.email) + self.assertEqual(registration_form.phone, self.event_customer.phone) + self.assertEqual(registration_form.mobile, self.event_customer.mobile) # save, check record matches Form values registration = registration_form.save() - self.assertEqual(registration.partner_id, self.customer) - self.assertEqual(registration.name, self.customer.name) - self.assertEqual(registration.email, self.customer.email) - self.assertEqual(registration.phone, self.customer.phone) - self.assertEqual(registration.mobile, self.customer.mobile) + self.assertEqual(registration.partner_id, self.event_customer) + self.assertEqual(registration.name, self.event_customer.name) + self.assertEqual(registration.email, self.event_customer.email) + self.assertEqual(registration.phone, self.event_customer.phone) + self.assertEqual(registration.mobile, self.event_customer.mobile) # allow writing on some fields independently from customer config registration.write({'phone': False, 'mobile': False}) @@ -49,25 +49,18 @@ class TestEventUI(TestEventCommon): # reset partner should not reset other fields registration.write({'partner_id': False}) self.assertEqual(registration.partner_id, self.env['res.partner']) - self.assertEqual(registration.name, self.customer.name) - self.assertEqual(registration.email, self.customer.email) + self.assertEqual(registration.name, self.event_customer.name) + self.assertEqual(registration.email, self.event_customer.email) self.assertFalse(registration.phone) self.assertFalse(registration.mobile) # update to a new partner not through UI -> update only void feilds - customer2 = self.env['res.partner'].create({ - 'name': 'Constantin Customer 2', - 'email': 'constantin2@test.example.com', - 'country_id': self.env.ref('base.be').id, - 'phone': '0456987654', - 'mobile': '0456654321', - }) - registration.write({'partner_id': customer2.id}) - self.assertEqual(registration.partner_id, customer2) - self.assertEqual(registration.name, self.customer.name) - self.assertEqual(registration.email, self.customer.email) - self.assertEqual(registration.phone, customer2.phone) - self.assertEqual(registration.mobile, customer2.mobile) + registration.write({'partner_id': self.event_customer2.id}) + self.assertEqual(registration.partner_id, self.event_customer2) + self.assertEqual(registration.name, self.event_customer.name) + self.assertEqual(registration.email, self.event_customer.email) + self.assertEqual(registration.phone, self.event_customer2.phone) + self.assertEqual(registration.mobile, self.event_customer2.mobile) class TestEventFlow(TestEventCommon): diff --git a/addons/event/tests/test_event_internals.py b/addons/event/tests/test_event_internals.py index 51dd7c33258..9a8d4147d81 100644 --- a/addons/event/tests/test_event_internals.py +++ b/addons/event/tests/test_event_internals.py @@ -30,7 +30,7 @@ class TestEventData(TestEventCommon): def test_event_date_computation(self): event = self.event_0.with_user(self.env.user) event.write({ - 'registration_ids': [(0, 0, {'partner_id': self.customer.id, 'name': 'test_reg'})], + 'registration_ids': [(0, 0, {'partner_id': self.event_customer.id, 'name': 'test_reg'})], 'date_begin': datetime(2020, 1, 31, 15, 0, 0), 'date_end': datetime(2020, 4, 5, 18, 0, 0), }) diff --git a/addons/event_sale/tests/common.py b/addons/event_sale/tests/common.py index 698a52c9805..bc4be1d8f20 100644 --- a/addons/event_sale/tests/common.py +++ b/addons/event_sale/tests/common.py @@ -2,9 +2,10 @@ # 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): +class TestEventSaleCommon(TestEventCommon, TestSalesCommon): @classmethod def setUpClass(cls): diff --git a/addons/event_sale/tests/test_event_sale.py b/addons/event_sale/tests/test_event_sale.py index 70a38f88395..f41949a5fb5 100644 --- a/addons/event_sale/tests/test_event_sale.py +++ b/addons/event_sale/tests/test_event_sale.py @@ -1,69 +1,155 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.tests import common +from odoo.addons.event_sale.tests.common import TestEventSaleCommon +from odoo.tests import tagged +from odoo.tests.common import users -class EventSaleTest(common.TransactionCase): +@tagged('event_flow') +class TestEventSale(TestEventSaleCommon): - def setUp(self): - super(EventSaleTest, self).setUp() + @classmethod + def setUpClass(cls): + super(TestEventSale, cls).setUpClass() - self.EventRegistration = self.env['event.registration'] - - # First I create an event product - product = self.env['product.product'].create({ - 'name': 'test_formation', - 'type': 'service', - 'event_ok': True, + cls.event_0.write({ + 'event_ticket_ids': [ + (5, 0), + (0, 0, { + 'name': 'First Ticket', + 'product_id': cls.event_product.id, + 'seats_max': 30, + }), (0, 0, { + 'name': 'Second Ticket', + 'product_id': cls.event_product.id, + }) + ], }) - # I create an event from the same type than my product - event = self.env['event.event'].create({ - 'name': 'test_event', - 'event_type_id': 1, - 'date_end': '2012-01-01 19:05:15', - 'date_begin': '2012-01-01 18:05:15' + # 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, }) - ticket = self.env['event.event.ticket'].create({ - 'name': 'test_ticket', - 'product_id': product.id, - 'event_id': event.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] - # I create a sales order - self.sale_order = self.env['sale.order'].create({ - 'partner_id': self.env['res.partner'].create({'name': 'My Attendee'}).id, - 'note': 'Invoice after delivery', - 'payment_term_id': self.env.ref('account.account_payment_term_end_following_month').id - }) + # PREPARE SO DATA + # ------------------------------------------------------------ - # In the sales order I add some sales order lines. i choose event product - self.env['sale.order.line'].create({ - 'product_id': product.id, - 'price_unit': 190.50, - 'product_uom': self.env.ref('uom.product_uom_unit').id, - 'product_uom_qty': 8.0, - 'order_id': self.sale_order.id, - 'name': 'sales order line', - 'event_id': event.id, - 'event_ticket_id': ticket.id, + # 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, + }), (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) - # In the event registration I add some attendee detail lines. i choose event product - self.register_person = self.env['registration.editor'].create({ - 'sale_order_id': self.sale_order.id, - 'event_registration_ids': [(0, 0, { - 'event_id': event.id, - 'name': 'Administrator', - 'email': 'abc@example.com' - })], + # 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]) - def test_00_create_event_product(self): - # I click apply to create attendees - self.register_person.action_make_registration() - # I check if a registration is created - registrations = self.EventRegistration.search([('sale_order_id', '=', self.sale_order.id)]) - self.assertTrue(registrations, "The registration is not created.") + # 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') diff --git a/addons/event_sale/wizard/event_edit_registration.py b/addons/event_sale/wizard/event_edit_registration.py index 29c00065856..0cc1ab9c4ca 100644 --- a/addons/event_sale/wizard/event_edit_registration.py +++ b/addons/event_sale/wizard/event_edit_registration.py @@ -64,6 +64,7 @@ class RegistrationEditorLine(models.TransientModel): """Event Registration""" _name = "registration.editor.line" _description = 'Edit Attendee Line on Sales Confirmation' + _order = "id desc" editor_id = fields.Many2one('registration.editor') sale_order_line_id = fields.Many2one('sale.order.line', string='Sales Order Line') From d01144e17d8cf0d8fdf106e307f36d871d0d8737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hennecart?= Date: Fri, 15 May 2020 12:52:25 +0000 Subject: [PATCH 2/3] [REF] website_event(_sale): create registrations in batch when buying tickets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PURPOSE Create event registrations in batch. It will allow to customize group-creation of registrations, notably with automated rules for crm / event synchronization. SPECIFICATIONS Instead of creating registrations one by one when processing registration form details, simply batch-ize their creation. Instead of creating registrations one by one when adding a new line in cart simply let website_event handle its job, or the confirmation action of a sale order that already populates registrations. Creating registrations when adding a cart line has no real use as we have no specific information to create that registration. It is better to let the flow finish and create additional registrations in batch once SO is confirmed. LINKS Task ID 2258685 Prepare Task ID 2166679 (create leads from registrations) PR odoo/odoo#51341 Co-Authored-By: Jeremy Hennecart Co-Authored-By: Thibault Delavallée --- addons/website_event/controllers/main.py | 7 +++---- addons/website_event_sale/controllers/main.py | 12 ++++-------- addons/website_event_sale/models/sale_order.py | 6 ++---- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index 48b6b19936c..f0c5351801f 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -332,15 +332,14 @@ class WebsiteEventController(http.Controller): return list(registrations.values()) def _create_attendees_from_registration_post(self, event, registration_data): - attendees_sudo = request.env['event.registration'].sudo() - + registrations_to_create = [] for registration_values in registration_data: registration_values['event_id'] = event.id if not registration_values.get('partner_id'): registration_values['partner_id'] = request.env.user.partner_id.id - attendees_sudo += request.env['event.registration'].sudo().create(registration_values) + registrations_to_create.append(registration_values) - return attendees_sudo + return request.env['event.registration'].sudo().create(registrations_to_create) @http.route(['''/event//registration/confirm'''], type='http', auth="public", methods=['POST'], website=True) def registration_confirm(self, event, **post): diff --git a/addons/website_event_sale/controllers/main.py b/addons/website_event_sale/controllers/main.py index d9a84510319..00ca7cfd51c 100644 --- a/addons/website_event_sale/controllers/main.py +++ b/addons/website_event_sale/controllers/main.py @@ -29,17 +29,13 @@ class WebsiteEventSaleController(WebsiteEventController): if any(info.get('event_ticket_id') for info in registration_data): order = request.website.sale_get_order(force_create=1) - order_attendee_ids = set() for info in [r for r in registration_data if r.get('event_ticket_id')]: ticket = request.env['event.event.ticket'].sudo().browse(info['event_ticket_id']) - cart_values = order.with_context(event_ticket_id=ticket.id, fixed_price=True)._cart_update(product_id=ticket.product_id.id, add_qty=1, registration_data=[info]) - order_attendee_ids |= set(cart_values.get('attendee_ids', [])) + cart_values = order.with_context(event_ticket_id=ticket.id, fixed_price=True)._cart_update(product_id=ticket.product_id.id, add_qty=1) + info['sale_order_id'] = order.id + info['sale_order_line_id'] = cart_values.get('line_id') - attendees_sudo = super(WebsiteEventSaleController, self)._create_attendees_from_registration_post(event, [r for r in registration_data if not r['event_ticket_id']]) - if order_attendee_ids: - attendees_sudo |= request.env['event.registration'].sudo().browse(order_attendee_ids) - - return attendees_sudo + return super(WebsiteEventSaleController, self)._create_attendees_from_registration_post(event, registration_data) @http.route() def registration_confirm(self, event, **post): diff --git a/addons/website_event_sale/models/sale_order.py b/addons/website_event_sale/models/sale_order.py index 3a7c1c9f307..d092b751366 100644 --- a/addons/website_event_sale/models/sale_order.py +++ b/addons/website_event_sale/models/sale_order.py @@ -91,10 +91,8 @@ class SaleOrder(models.Model): attendees.action_cancel() # adding attendees elif ticket and new_qty > old_qty: - line = OrderLine.browse(values['line_id']) - line._update_registrations(confirm=False, cancel_to_draft=True, registration_data=kwargs.get('registration_data', [])) - # add in return values the registrations, to display them on website (or not) - values['attendee_ids'] = self.env['event.registration'].search([('sale_order_line_id', '=', line.id), ('state', '!=', 'cancel')]).ids + # do not do anything, attendees will be created at SO confirmation if not given previously + pass return values From 5ccfdfd96d4ff1e43f1cb8bf90273cb96d425265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hennecart?= Date: Fri, 15 May 2020 13:35:54 +0000 Subject: [PATCH 3/3] [REF] event_sale: create registrations in batch in SO confirm or registration editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PURPOSE Create event registrations in batch. It will allow to customize group-creation of registrations, notably with automated rules for crm / event synchronization. SPECIFICATIONS Improve registration editor to create registrations in batch. Also be less dependent from context in its code, currently a bit weird. Move creation of registrations based on line from _action_confirm to action_confirm. Indeed it adds complexity and we are unsure it really helps having two methods. Update based on lines now create registrations in batch instead of one by one. LINKS Task ID 2258685 Prepare Task ID 2166679 (create leads from registrations) PR odoo/odoo#51341 Co-Authored-By: Jeremy Hennecart Co-Authored-By: Thibault Delavallée --- addons/event_sale/models/sale_order.py | 23 +++++++++---------- .../wizard/event_edit_registration.py | 14 +++++++---- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/addons/event_sale/models/sale_order.py b/addons/event_sale/models/sale_order.py index b3b79a3899c..28426520a18 100644 --- a/addons/event_sale/models/sale_order.py +++ b/addons/event_sale/models/sale_order.py @@ -18,16 +18,11 @@ class SaleOrder(models.Model): registrations_toupdate.write({'partner_id': vals['partner_id']}) return result - def _action_confirm(self): - res = super(SaleOrder, self)._action_confirm() - for so in self: - # confirm registration if it was free (otherwise it will be confirmed once invoice fully paid) - so.order_line._update_registrations(confirm=so.amount_total == 0, cancel_to_draft=False) - return res - def action_confirm(self): res = super(SaleOrder, self).action_confirm() for so in self: + # confirm registration if it was free (otherwise it will be confirmed once invoice fully paid) + so.order_line._update_registrations(confirm=so.amount_total == 0, cancel_to_draft=False) if any(so.order_line.filtered(lambda line: line.event_id)): return self.env['ir.actions.act_window'] \ .with_context(default_sale_order_id=so.id) \ @@ -87,13 +82,17 @@ class SaleOrderLine(models.Model): if cancel_to_draft: existing_registrations.filtered(lambda self: self.state == 'cancel').action_set_draft() + registrations_vals = [] for count in range(int(so_line.product_uom_qty) - len(existing_registrations)): - registration_vals = {} - if registration_data: - registration_vals = registration_data.pop() + values = { + 'sale_order_line_id': so_line.id, + 'sale_order_id': so_line.order_id.id + } # TDE CHECK: auto confirmation - registration_vals['sale_order_line_id'] = so_line.id - Registration.create(registration_vals) + if registration_data: + values.update(registration_data.pop()) + registrations_vals.append(values) + Registration.create(registrations_vals) return True @api.onchange('product_id') diff --git a/addons/event_sale/wizard/event_edit_registration.py b/addons/event_sale/wizard/event_edit_registration.py index 0cc1ab9c4ca..9db556ba804 100644 --- a/addons/event_sale/wizard/event_edit_registration.py +++ b/addons/event_sale/wizard/event_edit_registration.py @@ -41,6 +41,10 @@ class RegistrationEditor(models.TransientModel): 'event_id': so_line.event_id.id, 'event_ticket_id': so_line.event_ticket_id.id, 'sale_order_line_id': so_line.id, + 'name': so_line.order_partner_id.name, + 'email': so_line.order_partner_id.email, + 'phone': so_line.order_partner_id.phone, + 'mobile': so_line.order_partner_id.mobile, }]) res['event_registration_ids'] = attendee_list res = self._convert_to_write(res) @@ -48,15 +52,17 @@ class RegistrationEditor(models.TransientModel): def action_make_registration(self): self.ensure_one() + registrations_to_create = [] for registration_line in self.event_registration_ids: values = registration_line.get_registration_data() if registration_line.registration_id: registration_line.registration_id.write(values) else: - self.env['event.registration'].create(values) - if self.env.context.get('active_model') == 'sale.order': - for order in self.env['sale.order'].browse(self.env.context.get('active_ids', [])): - order.order_line._update_registrations(confirm=False) + registrations_to_create.append(values) + + self.env['event.registration'].create(registrations_to_create) + self.sale_order_id.order_line._update_registrations(confirm=self.sale_order_id.amount_total == 0) + return {'type': 'ir.actions.act_window_close'}