diff --git a/addons/event/__manifest__.py b/addons/event/__manifest__.py
index ecba97514f5..e537a56152c 100644
--- a/addons/event/__manifest__.py
+++ b/addons/event/__manifest__.py
@@ -17,7 +17,7 @@ Key Features
* Manage your Events and Registrations
* Use emails to automatically confirm and send acknowledgments for any event registration
""",
- 'depends': ['base_setup', 'mail', 'phone_validation', 'portal', 'utm'],
+ 'depends': ['barcodes', 'base_setup', 'mail', 'phone_validation', 'portal', 'utm'],
'data': [
'security/event_security.xml',
'security/ir.model.access.csv',
@@ -30,6 +30,7 @@ Key Features
'views/event_stage_views.xml',
'report/event_event_templates.xml',
'report/event_event_reports.xml',
+ 'report/event_registration_report.xml',
'data/ir_cron_data.xml',
'data/mail_template_data.xml',
'data/event_data.xml',
@@ -48,6 +49,7 @@ Key Features
'installable': True,
'assets': {
'web.assets_backend': [
+ 'event/static/src/client_action/**/*',
'event/static/src/scss/event.scss',
'event/static/src/icon_selection_field/icon_selection_field.js',
'event/static/src/icon_selection_field/icon_selection_field.xml',
diff --git a/addons/event/controllers/main.py b/addons/event/controllers/main.py
index 72211d0d191..94d8ac41ce3 100644
--- a/addons/event/controllers/main.py
+++ b/addons/event/controllers/main.py
@@ -4,7 +4,7 @@
import json
from werkzeug.exceptions import NotFound
-from odoo import _
+from odoo import http, _
from odoo.http import Controller, request, route, content_disposition
from odoo.tools import consteq
@@ -75,3 +75,23 @@ class EventController(Controller):
('Content-Disposition', content_disposition(f'{report_name}.pdf')),
]
return request.make_response(pdf, headers=pdfhttpheaders)
+
+ @http.route(['/event/init_barcode_interface'], type='json', auth="user")
+ def init_barcode_interface(self, event_id):
+ event = request.env['event.event'].browse(event_id).exists() if event_id else False
+ if event:
+ return {
+ 'name': event.name,
+ 'country': event.address_id.country_id.name,
+ 'city': event.address_id.city,
+ 'company_name': event.company_id.name,
+ 'company_id': event.company_id.id
+ }
+ else:
+ return {
+ 'name': _('Registration Desk'),
+ 'country': False,
+ 'city': False,
+ 'company_name': request.env.company.name,
+ 'company_id': request.env.company.id
+ }
diff --git a/addons/event/models/event_registration.py b/addons/event/models/event_registration.py
index 4b6799407bf..1e6ce011c69 100644
--- a/addons/event/models/event_registration.py
+++ b/addons/event/models/event_registration.py
@@ -1,11 +1,14 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+import logging
+import os
from dateutil.relativedelta import relativedelta
from odoo import _, api, fields, models, SUPERUSER_ID
from odoo.tools import format_date, email_normalize, email_normalize_all
from odoo.exceptions import AccessError, ValidationError
+_logger = logging.getLogger(__name__)
class EventRegistration(models.Model):
@@ -14,6 +17,20 @@ class EventRegistration(models.Model):
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'id desc'
+ @api.model
+ def _get_random_token(self):
+ """Generate a string representation of a pseudo-random 8-byte number for barcode
+ generation.
+
+ A decimal serialisation is longer than a hexadecimal one *but* it
+ generates a more compact barcode (Code128C rather than Code128A).
+
+ Generate 8 bytes (64 bits) barcodes as 16 bytes barcodes are not
+ compatible with all scanners.
+ """
+ return str(int.from_bytes(os.urandom(8), 'little'))
+ barcode = fields.Char(default=_get_random_token, readonly=True, copy=False, index=True)
+
# event
event_id = fields.Many2one(
'event.event', string='Event', required=True)
@@ -48,7 +65,9 @@ class EventRegistration(models.Model):
('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
('open', 'Confirmed'), ('done', 'Attended')],
string='Status', default='draft', readonly=True, copy=False, tracking=6)
-
+ _sql_constraints = [
+ ('barcode_event_uniq', 'unique(barcode)', "Barcode should be unique")
+ ]
@api.depends('partner_id')
def _compute_name(self):
for registration in self:
@@ -116,6 +135,27 @@ class EventRegistration(models.Model):
country = self.partner_id.country_id or self.event_id.country_id or self.env.company.country_id
self.phone = self._phone_format(fname='phone', country=country) or self.phone
+ @api.model
+ def register_attendee(self, barcode, event_id):
+ attendee = self.search([('barcode', '=', barcode)], limit=1)
+ if not attendee:
+ return {'error': 'invalid_ticket'}
+ res = attendee._get_registration_summary()
+ if attendee.state == 'cancel':
+ status = 'canceled_registration'
+ elif not attendee.event_id.is_ongoing:
+ status = 'not_ongoing_event'
+ elif attendee.state != 'done':
+ if event_id and attendee.event_id.id != event_id:
+ status = 'need_manual_confirmation'
+ else:
+ attendee.action_set_done()
+ status = 'confirmed_registration'
+ else:
+ status = 'already_registered'
+ res.update({'status': status, 'event_id': event_id})
+ return res
+
# ------------------------------------------------------------
# CRUD
# ------------------------------------------------------------
diff --git a/addons/event/models/res_config_settings.py b/addons/event/models/res_config_settings.py
index fdb24bf3bb2..fc045a28e2b 100644
--- a/addons/event/models/res_config_settings.py
+++ b/addons/event/models/res_config_settings.py
@@ -24,10 +24,11 @@ class ResConfigSettings(models.TransientModel):
module_website_event_track_live = fields.Boolean("Live Mode")
module_website_event_track_quiz = fields.Boolean("Quiz on Tracks")
module_website_event_exhibitor = fields.Boolean("Advanced Sponsors")
- module_event_barcode = fields.Boolean("Barcode")
+ use_event_barcode = fields.Boolean(string="Use Event Barcode", help="Enable or Disable Event Barcode functionality.", config_parameter='event.use_event_barcode')
module_website_event_sale = fields.Boolean("Online Ticketing")
module_event_booth = fields.Boolean("Booth Management")
use_google_maps_static_api = fields.Boolean("Google Maps static API", default=_default_use_google_maps_static_api)
+ barcode_nomenclature_id = fields.Many2one('barcode.nomenclature', related='company_id.nomenclature_id', readonly=False)
@api.depends('use_google_maps_static_api')
def _compute_maps_static_api_key(self):
diff --git a/addons/event/report/event_event_reports.xml b/addons/event/report/event_event_reports.xml
index 35a92018485..4925680b0cd 100644
--- a/addons/event/report/event_event_reports.xml
+++ b/addons/event/report/event_event_reports.xml
@@ -92,5 +92,15 @@
| Name | +Company | +Ticket type | +Phone number | ++ |
|---|---|---|---|---|
|
+ |
+