Browse Source

Oct 16: [ADD] Initial commit 'event_seat_booking'

pull/345/merge
Cybrosys Technologies 6 months ago
parent
commit
f36fc6d2ce
  1. 49
      event_seat_booking/README.rst
  2. 23
      event_seat_booking/__init__.py
  3. 61
      event_seat_booking/__manifest__.py
  4. 24
      event_seat_booking/controllers/__init__.py
  5. 67
      event_seat_booking/controllers/event_seat_booking.py
  6. 89
      event_seat_booking/controllers/website_event.py
  7. 62
      event_seat_booking/controllers/website_sale.py
  8. 13
      event_seat_booking/data/seat_column_sequence.xml
  9. 7
      event_seat_booking/doc/RELEASE_NOTES.md
  10. 27
      event_seat_booking/models/__init__.py
  11. 31
      event_seat_booking/models/event_event.py
  12. 57
      event_seat_booking/models/event_event_ticket.py
  13. 82
      event_seat_booking/models/event_registration.py
  14. 112
      event_seat_booking/models/seat_arrangement.py
  15. 48
      event_seat_booking/models/seat_arrangement_line.py
  16. 47
      event_seat_booking/models/seat_column.py
  17. 31
      event_seat_booking/report/event_report_template_full_page_ticket.xml
  18. 4
      event_seat_booking/security/ir.model.access.csv
  19. BIN
      event_seat_booking/static/description/assets/icons/check.png
  20. BIN
      event_seat_booking/static/description/assets/icons/chevron.png
  21. BIN
      event_seat_booking/static/description/assets/icons/cogs.png
  22. BIN
      event_seat_booking/static/description/assets/icons/consultation.png
  23. BIN
      event_seat_booking/static/description/assets/icons/ecom-black.png
  24. BIN
      event_seat_booking/static/description/assets/icons/education-black.png
  25. BIN
      event_seat_booking/static/description/assets/icons/hotel-black.png
  26. BIN
      event_seat_booking/static/description/assets/icons/license.png
  27. BIN
      event_seat_booking/static/description/assets/icons/lifebuoy.png
  28. BIN
      event_seat_booking/static/description/assets/icons/manufacturing-black.png
  29. BIN
      event_seat_booking/static/description/assets/icons/pos-black.png
  30. BIN
      event_seat_booking/static/description/assets/icons/puzzle.png
  31. BIN
      event_seat_booking/static/description/assets/icons/restaurant-black.png
  32. BIN
      event_seat_booking/static/description/assets/icons/service-black.png
  33. BIN
      event_seat_booking/static/description/assets/icons/trading-black.png
  34. BIN
      event_seat_booking/static/description/assets/icons/training.png
  35. BIN
      event_seat_booking/static/description/assets/icons/update.png
  36. BIN
      event_seat_booking/static/description/assets/icons/user.png
  37. BIN
      event_seat_booking/static/description/assets/icons/wrench.png
  38. BIN
      event_seat_booking/static/description/assets/misc/categories.png
  39. BIN
      event_seat_booking/static/description/assets/misc/check-box.png
  40. BIN
      event_seat_booking/static/description/assets/misc/compass.png
  41. BIN
      event_seat_booking/static/description/assets/misc/corporate.png
  42. BIN
      event_seat_booking/static/description/assets/misc/customer-support.png
  43. BIN
      event_seat_booking/static/description/assets/misc/cybrosys-logo.png
  44. BIN
      event_seat_booking/static/description/assets/misc/features.png
  45. BIN
      event_seat_booking/static/description/assets/misc/logo.png
  46. BIN
      event_seat_booking/static/description/assets/misc/pictures.png
  47. BIN
      event_seat_booking/static/description/assets/misc/pie-chart.png
  48. BIN
      event_seat_booking/static/description/assets/misc/right-arrow.png
  49. BIN
      event_seat_booking/static/description/assets/misc/star.png
  50. BIN
      event_seat_booking/static/description/assets/misc/support.png
  51. BIN
      event_seat_booking/static/description/assets/misc/whatsapp.png
  52. BIN
      event_seat_booking/static/description/assets/modules/1.jpg
  53. BIN
      event_seat_booking/static/description/assets/modules/2.jpg
  54. BIN
      event_seat_booking/static/description/assets/modules/3.png
  55. BIN
      event_seat_booking/static/description/assets/modules/4.png
  56. BIN
      event_seat_booking/static/description/assets/modules/5.jpg
  57. BIN
      event_seat_booking/static/description/assets/modules/7.jpg
  58. BIN
      event_seat_booking/static/description/assets/screenshots.zip
  59. BIN
      event_seat_booking/static/description/assets/screenshots/1.png
  60. BIN
      event_seat_booking/static/description/assets/screenshots/10.png
  61. BIN
      event_seat_booking/static/description/assets/screenshots/11.png
  62. BIN
      event_seat_booking/static/description/assets/screenshots/12.png
  63. BIN
      event_seat_booking/static/description/assets/screenshots/13.png
  64. BIN
      event_seat_booking/static/description/assets/screenshots/14.png
  65. BIN
      event_seat_booking/static/description/assets/screenshots/15.png
  66. BIN
      event_seat_booking/static/description/assets/screenshots/16.png
  67. BIN
      event_seat_booking/static/description/assets/screenshots/17.png
  68. BIN
      event_seat_booking/static/description/assets/screenshots/2.png
  69. BIN
      event_seat_booking/static/description/assets/screenshots/3.png
  70. BIN
      event_seat_booking/static/description/assets/screenshots/4.png
  71. BIN
      event_seat_booking/static/description/assets/screenshots/5.png
  72. BIN
      event_seat_booking/static/description/assets/screenshots/6.png
  73. BIN
      event_seat_booking/static/description/assets/screenshots/7.png
  74. BIN
      event_seat_booking/static/description/assets/screenshots/8.png
  75. BIN
      event_seat_booking/static/description/assets/screenshots/9.png
  76. BIN
      event_seat_booking/static/description/assets/screenshots/v16-hero (1).gif
  77. BIN
      event_seat_booking/static/description/banner.jpg
  78. BIN
      event_seat_booking/static/description/icon.png
  79. 711
      event_seat_booking/static/description/index.html
  80. 73
      event_seat_booking/static/src/css/template.css
  81. 81
      event_seat_booking/static/src/js/register.js
  82. 140
      event_seat_booking/static/src/js/templates.js
  83. 23
      event_seat_booking/views/event_event_ticket_views.xml
  84. 16
      event_seat_booking/views/event_event_views.xml
  85. 35
      event_seat_booking/views/event_registration_views.xml
  86. 190
      event_seat_booking/views/event_seat_booking_board_templates.xml
  87. 204
      event_seat_booking/views/registration_template.xml
  88. 31
      event_seat_booking/views/seat_arrangement_line_views.xml
  89. 52
      event_seat_booking/views/seat_arrangement_views.xml

49
event_seat_booking/README.rst

@ -0,0 +1,49 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Event Seat Booking
==================
This module helps you to book seminars, conferences, appointments and
conventions tickets through website. The event managers can add different types
of tickets and screams in the backend of any event.
Configuration
=============
* No additional configurations needed
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
Affero General Public License v3.0 (AGPL v3)
(https://www.gnu.org/licenses/agpl-3.0-standalone.html)
Credits
-------
* Developer : (V16) Junaidul Ansar M, Contact : odoo@cybrosys.com
* Developer : (V16) Anfas Faisal K, Contact : odoo@cybrosys.com
Contacts
--------
* Mail Contact : odoo@cybrosys.com
* Website : https://cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit `Our Website <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

23
event_seat_booking/__init__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import controllers
from . import models

61
event_seat_booking/__manifest__.py

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
{
'name': 'Event Seat Booking',
'version': '16.0.1.0.0',
'category': 'Website',
'summary': 'The module used to book seats for the event',
'description': "This module helps you to book seminars, conferences, "
"appointments and conventions tickets through website.The "
"event managers can add different types of tickets and "
"screams in the backend of any event",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['base', 'event', 'sale_management', 'website', 'website_event',
'website_sale'],
'data': [
'security/ir.model.access.csv',
'data/seat_column_sequence.xml',
'report/event_report_template_full_page_ticket.xml',
'views/seat_arrangement_views.xml',
'views/event_event_ticket_views.xml',
'views/event_event_views.xml',
'views/event_registration_views.xml',
'views/seat_arrangement_line_views.xml',
'views/registration_template.xml',
'views/event_seat_booking_board_templates.xml',
],
'assets': {
'web.assets_frontend': [
'event_seat_booking/static/src/js/templates.js',
'event_seat_booking/static/src/js/register.js',
'event_seat_booking/static/src/css/template.css',
],
},
'images': ['static/description/banner.jpg'],
'license': 'AGPL-3',
'installable': True,
'application': True,
'auto_install': False
}

24
event_seat_booking/controllers/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from . import event_seat_booking
from . import website_event
from . import website_sale

67
event_seat_booking/controllers/event_seat_booking.py

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import http, _
from odoo.http import request
class SeatBookingController(http.Controller):
"""The controller handle for the event seat booking page"""
@http.route(['''/event/<model("event.event"):event>/SeatsBooking'''],
type='http', auth='public', website=True)
def seat_booking_page(self, event):
"""It displays the seat booking information """
# Fetch the seat arrangement lines related to the event or
# user(based on your requirement)
event_tickets = request.env['event.event.ticket'].search([
('event_id', '=', event.id),
])
event_seat_templates = {}
for ticket in event_tickets:
seat_arrangement_lines = ticket.seat_arrangement_id.prepare_seat_ids
event_seat_template = {}
for line in seat_arrangement_lines:
row_no = line.row_no
if row_no not in event_seat_template:
event_seat_template[row_no] = []
for column in line.column_ids:
seat_data = {
'seat_column_id': column.column_no,
'reservation_status': column.reservation_status,
'row_no': row_no,
'column_no': column.column_no,
'unique_column': column.unique_seat_identifier
}
event_seat_template[row_no].append(seat_data)
event_seat_templates[
ticket.seat_arrangement_id.id] = event_seat_template
return request.render(
'event_seat_booking.event_seat_booking_board_templates',
{
'event_name': event.name,
'event': event.id,
'event_tickets': event_tickets,
'event_seat_templates': event_seat_templates,
})

89
event_seat_booking/controllers/website_event.py

@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import _
from odoo.http import request
from odoo.addons.website_event.controllers.main import WebsiteEventController
class WebsiteEventController(WebsiteEventController):
def _process_tickets_form(self, event, form_details):
""" Process posted data about ticket order. Generic ticket are supported
for event without tickets (generic registration).
:return: list of order per ticket: [{
'id': if of ticket if any (0 if no ticket),
'ticket': browse record of ticket if any (None if no ticket),
'name': ticket name (or generic 'Registration' name if no ticket),
'quantity': number of registrations for that ticket,
}, {...}]
"""
ticket_order = {}
for key, value in form_details.items():
registration_items = key.split('nb_register-')
if len(registration_items) != 2:
continue
ticket_order[int(registration_items[1])] = int(value)
ticket_dict = dict((ticket.id, ticket) for ticket in
request.env['event.event.ticket'].sudo().search([
('id', 'in',
[tid for tid in ticket_order.keys() if tid]),
('event_id', '=', event.id)
]))
# Process seat details
unique_ids = form_details.get('unique_id', '').split(',')
if not unique_ids or unique_ids == ['']:
order = [{
'id': tid if ticket_dict.get(tid) else 0,
'ticket': ticket_dict.get(tid),
'name': ticket_dict[tid]['name'] if ticket_dict.get(
tid) else _('Registration'),
'quantity': count,
} for tid, count in ticket_order.items() if count]
return order
column_numbers = form_details.get('column_no', [])
row_numbers = form_details.get('row_no', [])
order = []
for tid, count in ticket_order.items():
seat_details = []
for i in range(count):
index = sum(ticket_order[key] for key in ticket_order.keys() if
key < tid) + i
if index < len(unique_ids):
seat_details.append({
'unique_id': unique_ids[index],
'row_no': row_numbers[index],
'column_no': column_numbers[index],
})
order.append({
'id': tid if ticket_dict.get(tid) else 0,
'ticket': ticket_dict.get(tid),
'name': ticket_dict[tid]['name'] if ticket_dict.get(
tid) else _('Registration'),
'quantity': count,
'seat_details': seat_details,
})
return order

62
event_seat_booking/controllers/website_sale.py

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale
class PaymentController(WebsiteSale):
@http.route('/shop/payment/validate', type='http', auth="public",
website=True, sitemap=False)
def shop_payment_validate(self, sale_order_id=None, **post):
"""
Validates the payment for the sale order and updates the seat
reservation status for event-related products. Overrides the default
`shop_payment_validate` method from `WebsiteSale` to handle seat
booking reservations.
"""
res = super(
PaymentController, self).shop_payment_validate(
sale_order_id=sale_order_id, **post)
last_order_id = request.session['sale_last_order_id']
order = request.env['sale.order'].sudo().browse(last_order_id).exists()
for line in order.order_line:
if line.product_id.detailed_type == 'event':
if line.event_id.is_seat_booking:
event_id_ticket = line.event_ticket_id.id
registrations = request.env[
'event.registration'].sudo().search(
[('sale_order_line_id', '=', line.id)])
for registration in registrations:
unique_column_id = registration.unique_column_id
seat_record = request.env[
'seat.arrangement.line'].sudo().search([
('seat_manage_id.current_event_id', '=',
event_id_ticket),
])
if seat_record:
column_record = seat_record.column_ids.filtered(
lambda
c: c.unique_seat_identifier == unique_column_id)
column_record.write(
{'reservation_status': 'reserved'})
return res

13
event_seat_booking/data/seat_column_sequence.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Sequence Number for Seat-->
<data noupdate="1">
<record id="seq_seat_column" model="ir.sequence">
<field name="name">Seat Column</field>
<field name="code">seat.column</field>
<field name="prefix">SN</field>
<field name="padding">4</field>
<field name="company_id" eval="False"/>
</record>
</data>
</odoo>

7
event_seat_booking/doc/RELEASE_NOTES.md

@ -0,0 +1,7 @@
## Module <event_seat_booking>
#### 18.06.2024
#### Version 16.0.1.0.0
#### ADD
- Initial Commit For Event Seat Booking.

27
event_seat_booking/models/__init__.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import event_event
from . import event_event_ticket
from . import seat_arrangement
from . import seat_arrangement_line
from . import seat_column
from . import event_registration

31
event_seat_booking/models/event_event.py

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from odoo import fields, models
class EventEvent(models.Model):
"""Inheriting the module and add a field to enabling the event seat booking
register button to the website"""
_inherit = 'event.event'
is_seat_booking = fields.Boolean(string="Is Seat Booking ?",
help='Seat booking enable or not.')

57
event_seat_booking/models/event_event_ticket.py

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class EventEventTicket(models.Model):
"""Inheriting the module to add a field"""
_inherit = 'event.event.ticket'
total_row = fields.Integer(string="Total Row",
help='Total row used in this event.')
sequence = fields.Integer(string='Sequence', help='Drag the records')
seat_arrangement_id = fields.Many2one('seat.arrangement',
string='Seat Arrangement Id',
help='Seat arrangement model '
'reference')
def seat_arrangement_action(self):
"""Opening the seat arrangement model"""
context = self.env.context
default_seat_arrangement_id = context.get(
'default_seat_arrangement_id',
False)
if default_seat_arrangement_id:
return {
'type': 'ir.actions.act_window',
'res_model': 'seat.arrangement',
'view_mode': 'form',
'res_id': default_seat_arrangement_id,
'target': 'new',
}
else:
return {
'type': 'ir.actions.act_window',
'res_model': 'seat.arrangement',
'view_mode': 'form',
'target': 'new',
}

82
event_seat_booking/models/event_registration.py

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class EventRegistration(models.Model):
_inherit = 'event.registration'
row_number = fields.Char(string="Row Number", help="Row Number he booked",
readonly=True)
column_number = fields.Char(string="Column Number",
help="Column Number he booked", readonly=True)
unique_column_id = fields.Char(string="Unique Column Number",
help="Column Number ID he booked",
readonly=True)
complete_name = fields.Char(string="Seat No",
compute='_compute_seat_name', store=True)
@api.depends('row_number', 'column_number')
def _compute_seat_name(self):
"""Compute the complete seat name based on row and column numbers."""
for record in self:
rec_name = f"R{record.row_number or ''} S{record.column_number or ''}"
record.complete_name = rec_name.strip()
def _get_website_registration_allowed_fields(self):
"""Get the fields allowed for website registration."""
return {'name', 'phone', 'email', 'mobile', 'event_id', 'partner_id',
'event_ticket_id', 'row_number', 'column_number',
'unique_column_id'}
def action_cancel(self):
"""Cancel the event registration and update the seat reservation
status to 'available'."""
res = super(EventRegistration,self).action_cancel()
unique_column_id = self.unique_column_id
seat_record = self.env[
'seat.arrangement.line'].sudo().search([
('seat_manage_id.current_event_id', '=', self.event_ticket_id.id),
])
if seat_record:
column_record = seat_record.column_ids.filtered(
lambda c: c.unique_seat_identifier == unique_column_id)
column_record.write({'reservation_status': 'available'})
return res
def action_confirm(self):
"""Confirm the event registration and update the seat
reservation status to 'booked'."""
res = super(EventRegistration,self).action_confirm()
unique_column_id = self.unique_column_id
seat_record = self.env[
'seat.arrangement.line'].sudo().search([
('seat_manage_id.current_event_id', '=', self.event_ticket_id.id),
])
if seat_record:
# for col in seat_record.column_ids:
column_record = seat_record.column_ids.filtered(
lambda c: c.unique_seat_identifier == unique_column_id)
column_record.write({'reservation_status': 'booked'})
return res

112
event_seat_booking/models/seat_arrangement.py

@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class SeatArrangement(models.Model):
"""This class handle to the seat arrangement details."""
_name = 'seat.arrangement'
_description = 'Seat Arrangement'
event = fields.Char(string='Event', help='Current event name.',
readonly=True)
ticket_type = fields.Char(string='Ticket Type',
help='Current event type.', readonly=True)
total_row = fields.Integer(string='Total Row',
help='Enter total row of this ticket type '
'in screen.')
max_seat_single_row = fields.Integer(string='Max Seat Number in Single Row',
help='Enter maximum number of seat in '
'single row of particular this'
' ticket type.')
prepare_seat_ids = fields.One2many('seat.arrangement.line',
'seat_manage_id',
string='Arranged Seat'
)
seats_max = fields.Integer(string="Maximum Attendees",
help='Define number of available tickets.')
current_event_id = fields.Integer(string='Event ID',
help='Get current event id.',
readonly=True)
def action_create_one_two_many_record(self):
"""Create seat records based on total_row and max_seat_single_row."""
# Clear existing seat records before creating new ones
if self.prepare_seat_ids:
self.prepare_seat_ids.unlink()
# Create seat.column records if they don't already exist
if not self.env['seat.column'].search([]):
for column_num in range(1, self.max_seat_single_row + 1):
d = self.env['seat.column'].create({'column_no': column_num})
row = 1
while row <= self.total_row:
seat_line_ids = []
# Case 1: When both blank_row and blank_seat are not enabled
for column_num in range(1, self.max_seat_single_row + 1):
column_record = self.env['seat.column'].create(
{'column_no': column_num})
seat_line_ids.append((4, column_record.id))
# Create the seat arrangement line
self.env['seat.arrangement.line'].create({
'row_no': row,
'column_ids': seat_line_ids if seat_line_ids else None,
'seat_manage_id': self.id
})
row += 1
cr = self.env.cr
# updating the maximum seat
query = f"""select count(seat_column_id) from seat_arrangement_line as a
join seat_arrangement_line_seat_column_rel as b on
a.id=b.seat_arrangement_line_id join seat_arrangement as c on
c.id=a.seat_manage_id where a.seat_manage_id = {self.id}"""
cr.execute(query)
seat_count = cr.fetchone()[0]
self.seats_max = seat_count
return {
'type': 'ir.actions.act_window',
'res_model': 'seat.arrangement',
'view_mode': 'form',
'res_id': self.id,
'target': 'new',
}
def action_clear_seat_arrangement(self):
"""Clear the entire seat arrangement."""
self.prepare_seat_ids.unlink()
return {
'type': 'ir.actions.act_window',
'res_model': 'seat.arrangement',
'view_mode': 'form',
'res_id': self.id,
'target': 'new',
}
def action_save_record(self):
"""Save button to save the seat arrangement details"""
event_ticket = self.env['event.event.ticket'].browse(
self.current_event_id)
if event_ticket:
event_ticket.write({
'total_row': self.total_row,
'seats_max': self.seats_max,
'seat_arrangement_id': self.id
})

48
event_seat_booking/models/seat_arrangement_line.py

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class SeatArrangementLine(models.Model):
"""Prepared seat based on the row and column count"""
_name = 'seat.arrangement.line'
_description = 'Seat Arrangement Line'
row_no = fields.Integer(string='Row No', help='Enter the row Number.')
column_ids = fields.Many2many('seat.column',
string='Column Selection',
help='Selected Columns.')
seat_manage_id = fields.Many2one('seat.arrangement',
string='Arrange seat',
help='Seat arrangement co-model.')
reservation_status = fields.Selection([
('available', 'Available'),
('reserved', 'Reserved'),
('booked', 'Booked'),
], string='Reservation Status', default='available')
def action_delete_row(self):
"""Delete the current seat arrangement line."""
skip_save = self.env.context.get('seat_arrangement_skip_save', False)
self.unlink()
if not skip_save:
self.env.cr.commit()

47
event_seat_booking/models/seat_column.py

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Junaidul Ansar M (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class SeatColumn(models.Model):
"""Column selection creation"""
_name = 'seat.column'
_description = 'Seat Column'
_rec_name = 'column_no'
unique_seat_identifier = fields.Char(string='Unique Seat Identifier',
readonly=True)
column_no = fields.Integer(string='Column Number',
help='Enter column number.')
reservation_status = fields.Selection([
('available', 'Available'),
('reserved', 'Reserved'),
('booked', 'Booked'),
], string='Reservation Status', default='available')
@api.model
def create(self, vals):
vals['unique_seat_identifier'] = self.env['ir.sequence'].next_by_code(
'seat.column')
return super(SeatColumn, self).create(vals)

31
event_seat_booking/report/event_report_template_full_page_ticket.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="event_report_template_full_page_ticket_inherit_seat_no"
inherit_id="event.event_report_template_full_page_ticket">
<xpath expr="//div[hasclass('o_event_full_page_ticket_side_info')]"
position="inside">
<div t-if="attendee and attendee.row_number" class="mb-2">
<div class="o_event_full_page_ticket_font_faded o_event_full_page_ticket_small_caps fw-bold">
Seat Number
</div>
<div class="o_event_full_page_ticket_small"
t-out="attendee.complete_name"/>
</div>
</xpath>
</template>
<template id="event_report_template_foldable_badge_inherit_seat_no"
inherit_id="event.event_report_template_foldable_badge"
priority="1">
<xpath expr="//div[hasclass('o_event_foldable_badge_barcode')]"
position="before">
<div t-if="attendee and attendee.row_number" class="mb-2">
<div class="text-center mt-5 pt-2">
Seat Number
<div class="o_event_foldable_badge_font_faded"
t-out="attendee.complete_name"/>
</div>
</div>
</xpath>
</template>
</odoo>

4
event_seat_booking/security/ir.model.access.csv

@ -0,0 +1,4 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_seat_arrangement_user,access.seat.arrangement.user,model_seat_arrangement,base.group_user,1,1,1,1
access_seat_arrangement_line_user,access.seat.arrangement.line.user,model_seat_arrangement_line,base.group_user,1,1,1,1
access_seat_column_user,access.seat.column.user,model_seat_column,base.group_user,1,1,1,1
1 id name model_id/id group_id/id perm_read perm_write perm_create perm_unlink
2 access_seat_arrangement_user access.seat.arrangement.user model_seat_arrangement base.group_user 1 1 1 1
3 access_seat_arrangement_line_user access.seat.arrangement.line.user model_seat_arrangement_line base.group_user 1 1 1 1
4 access_seat_column_user access.seat.column.user model_seat_column base.group_user 1 1 1 1

BIN
event_seat_booking/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
event_seat_booking/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
event_seat_booking/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
event_seat_booking/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
event_seat_booking/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
event_seat_booking/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
event_seat_booking/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
event_seat_booking/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
event_seat_booking/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
event_seat_booking/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
event_seat_booking/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
event_seat_booking/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
event_seat_booking/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
event_seat_booking/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
event_seat_booking/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
event_seat_booking/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
event_seat_booking/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
event_seat_booking/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
event_seat_booking/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
event_seat_booking/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
event_seat_booking/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
event_seat_booking/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
event_seat_booking/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
event_seat_booking/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
event_seat_booking/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
event_seat_booking/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
event_seat_booking/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
event_seat_booking/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
event_seat_booking/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
event_seat_booking/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
event_seat_booking/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
event_seat_booking/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
event_seat_booking/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
event_seat_booking/static/description/assets/modules/1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
event_seat_booking/static/description/assets/modules/2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
event_seat_booking/static/description/assets/modules/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
event_seat_booking/static/description/assets/modules/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
event_seat_booking/static/description/assets/modules/5.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
event_seat_booking/static/description/assets/modules/7.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
event_seat_booking/static/description/assets/screenshots.zip

Binary file not shown.

BIN
event_seat_booking/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
event_seat_booking/static/description/assets/screenshots/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
event_seat_booking/static/description/assets/screenshots/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
event_seat_booking/static/description/assets/screenshots/12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
event_seat_booking/static/description/assets/screenshots/13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
event_seat_booking/static/description/assets/screenshots/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
event_seat_booking/static/description/assets/screenshots/15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
event_seat_booking/static/description/assets/screenshots/16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
event_seat_booking/static/description/assets/screenshots/17.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
event_seat_booking/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
event_seat_booking/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
event_seat_booking/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 KiB

BIN
event_seat_booking/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
event_seat_booking/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
event_seat_booking/static/description/assets/screenshots/7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
event_seat_booking/static/description/assets/screenshots/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
event_seat_booking/static/description/assets/screenshots/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
event_seat_booking/static/description/assets/screenshots/v16-hero (1).gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

BIN
event_seat_booking/static/description/banner.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
event_seat_booking/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

711
event_seat_booking/static/description/index.html

@ -0,0 +1,711 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between"
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42"
style="width: 42px; height: 42px;"/>
<div>
<div style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Community
</div>
<div style="color: #875A7B; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
<div style="color: #017E84; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Odoo.sh
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<!-- APP HERO -->
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;">
Event Seat Booking
</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">
The Module Used to Book Seats for the Event</p>
<!-- END OF APP HERO -->
<img src="assets/screenshots/v16-hero (1).gif"
class="img-responsive"
style="width: 100%; margin-left: auto; margin-right: auto;"/>
</div>
</div>
</div>
</div>
<!-- NAVIGATION SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn
more about this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
features of this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
screenshots for this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
</div>
<!-- END OF NAVIGATION SECTION -->
<!-- OVERVIEW SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="overview">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Overview
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
This module helps you to book seminars, conferences, appointments and
conventions. The event managers can add different types of tickets and screams
in the backend of any event. The event manager can arrange the seat as per
the needs, and they can know the name of every participant and full details.
You can add the event questionnaire before attending the event and the event
manager can switch the seat before the confirmation.The attached have to
select just the seat with the total price.After that registration and last is
payment.
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="features">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Features
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center"
style="margin-top: 40px; margin-bottom: 40px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Community &amp;
Enterprise Support.</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Easy to manage online event ticket seat booking.
</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> The admin can arrange the seat as per the event. .
</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> You can generate full page ticket report & foldable badge report.
</span>
</div>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pictures.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Event Creation.
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
After Install the Module
Go to Event module -> Select an Event ->
->
Inside that Event we can see the 'Open Seat Arrangement' list view icon to the Ticket page.
Click that button you can arrange the Event Seat.
</p>
<img src="assets/screenshots/1.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Event Seat Arrangement.
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Inside this model, you can arrange the event seats according to your needs.</p>
<img src="assets/screenshots/2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
After Seat Arrangement.
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
After the Seat Arrangement enable the 'Is Seat Booking' Boolean field
to enable the booking through Website.
</p>
<img src="assets/screenshots/3.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Website View.
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Click the "Seat Booking" Option to view the Seat Arrangement
</p>
<img src="assets/screenshots/4.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Event Seat Booking View.
</h3>
<img src="assets/screenshots/5.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Select the seats you want to book and Click on the "Register" Button.
</h3>
<img src="assets/screenshots/6.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
After that, it open a wizard and enter the attendees details and then Click the "Continue" Button.
</h3>
<img src="assets/screenshots/7.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Select the payment method and press the "Pay Now " button.
</h3>
<img src="assets/screenshots/9.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Booked Seats are marked with red color, if payment is not done then the seat will not be marked as booked.
</h3>
<img src="assets/screenshots/10.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Now go to the event Backend and click on the Attendees Button to see the attendee's detail.
</h3>
<img src="assets/screenshots/11.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
The Seat No details will be shown in tree view.
</h3>
<img src="assets/screenshots/12.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
The Seat No details will be shown in form view.
</h3>
<img src="assets/screenshots/17.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
You can print full page ticket from Print.
</h3>
<img src="assets/screenshots/13.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Full page Ticket.
</h3>
<img src="assets/screenshots/14.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
You can print foldable page ticket from Print.
</h3>
<img src="assets/screenshots/15.png"
class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Foldable page Ticket
</h3>
<img src="assets/screenshots/16.png"
class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- RELATED PRODUCTS -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/categories.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Related
Products
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner" style="padding: 30px;">
<div class="carousel-item" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/website_hide_button/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/1.jpg">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/website_portal_events/#" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/2.jpg">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/website_seo_kit/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/3.png">
</div>
</a>
</div>
</div>
<div class="carousel-item active" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/call_for_price_website/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/4.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/special_product_snippet/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/5.jpg">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/website_favourites_grid/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/7.jpg">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev"
style="width:35px; color:#000"> <span
class="carousel-control-prev-icon"><i
class="fa fa-chevron-left"
style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo1"
data-slide="next" style="width:35px; color:#000">
<span class="carousel-control-next-icon"><i
class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF RELATED PRODUCTS -->
<!-- OUR SERVICES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/star.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our Services
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</div>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/corporate.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our
Industries
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/trading-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/pos-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/education-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/manufacturing-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/ecom-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/service-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/restaurant-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/hotel-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</div>
<!-- END OF OUR INDUSTRIES -->
<!-- SUPPORT -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/customer-support.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Support
</h2>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/support.png" height="48" width="48"
style="width: 42px; height: 42px;"/>
</div>
<div>
<h4>Need Help?</h4>
<p style="line-height: 100%;">Got questions or need help?
Get in touch.</p>
<a href="mailto:odoo@cybrosys.com">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
odoo@cybrosys.com</p>
</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/whatsapp.png" height="52" width="52"
style="width: 52px; height: 52px;"/>
</div>
<div>
<h4>WhatsApp</h4>
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p>
<a href="https://api.whatsapp.com/send?phone=918606827707">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
+91 86068
27707</p>
</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center">
<img src="assets/misc/logo.png" width="144" height="31"
style="width:144px; height: 31px; margin-top: 40px;"/>
</div>
</div>
</div>
<!-- END OF SUPPORT -->

73
event_seat_booking/static/src/css/template.css

@ -0,0 +1,73 @@
.event_seat_arrangemet{
display: flex;
flex-direction: column;
justify-content: center;
align-items: normal;
width:100%;
}
.separate-event{
width: 0%;
}
/*.seats-row {
text-align: center;
justify-content: center;
display: flex;
flex-direction: column;
align-items: center;
}*/
.seats-column{
display: flex;
gap: 5px;
}
.seat-button {
width: 30px;
height: 30px;
border: 1px solid #000;
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin: 6px;
}
.row-button {
width: 30px;
height: 30px;
border: 1px solid #000;
background-color: gray;
color: white;
display: flex;
align-items: center;
justify-content: center;
margin: 6px;
}
.seat-button.selected {
background-color: pink;
}
.print-clean {
border: none;
background: transparent;
}
.event-button {
width: 30px;
height: 30px;
border: 1px solid #000;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
.VIP {
background-color: darksalmon;
}
.Standard {
background-color: #b9dea0;
}
.Free {
background-color: #3a78c3;
}
.confirmed-seat {
background-color: brown;
}

81
event_seat_booking/static/src/js/register.js

@ -0,0 +1,81 @@
odoo.define('event_seat_booking.register', function (require) {
'use strict';
var core = require('web.core');
var event = require('website_event.website_event');
var _t = core._t;
var ajax = require('web.ajax');
event.include({
init: function () {
this._super.apply(this, arguments); // Call the parent's init method if needed
},
//Handles the click event on the registration form, processes the form data, and makes an AJAX request
// to submit the form. It also includes additional logic for seat booking.
on_click: function (ev) {
ev.preventDefault();
ev.stopPropagation();
var $form = $(ev.currentTarget).closest('form');
var $target = $(ev.currentTarget);
var $button = $(ev.currentTarget).closest('[type="submit"]');
var post = {};
$('#registration_form table').siblings('.alert').remove();
$('#registration_form select').each(function () {
post[$(this).attr('name')] = $(this).val();
console.log(post,"VALUES")
});
var tickets_ordered = _.some(_.map(post, function (value, key) { return parseInt(value); }));
if (!tickets_ordered) {
$('<div class="alert alert-info"/>')
.text(_t('Please select at least one ticket.'))
.insertAfter('#registration_form table');
return new Promise(function () {});
} else {
var uniqueId = $('#unique_column_id').val();
if (!uniqueId) {
this._super(ev);
return;
}
var columnNumbers = $('#col_number_id').val(); //
var rowNumbers = $('#row_number_id').val();
var colNumbers = columnNumbers.match(/C(\d+)/g).map(e => e.substring(1)); // ['2', '3']
var rowNumbersExtracted = rowNumbers.match(/R(\d+)/g).map(e => e.substring(1)); // ['4', '4']
post['unique_id'] = uniqueId;
post['row_no'] = rowNumbersExtracted;
post['column_no'] = colNumbers;
var colNumbers = columnNumbers.match(/C(\d+)/g).map(e => e.substring(1)); // ['2', '3']
var rowNumbersExtracted = rowNumbers.match(/R(\d+)/g).map(e => e.substring(1)); // ['4', '4']
$button.attr('disabled', true);
var action = $form.data('action') || $form.attr('action');
return ajax.jsonRpc(action, 'call', post).then(function (modal) {
var $modal = $(modal);
$modal.find('.modal-body > div').removeClass('container'); // retrocompatibility - REMOVE ME in master / saas-19
const hidden_div = $modal.find('.ticket_essentials')[0]
const $hiddenDiv = $(hidden_div);
const rowNumberInput = $hiddenDiv.find('input[name="row_number"]')[0];
const columnNumberInput = $hiddenDiv.find('input[name="column_number"]')[0];
const uniqueIdInput = $hiddenDiv.find('input[name="unique_id"]')[0];
$modal.appendTo(document.body);
const modalBS = new Modal($modal[0], {backdrop: 'static', keyboard: false});
modalBS.show();
$modal.appendTo('body').modal('show');
$modal.on('click', '.js_goto_event', function () {
$modal.modal('hide');
$button.prop('disabled', false);
});
$modal.on('click', '.btn-close', function () {
$button.prop('disabled', false);
});
});
}
},
});
});

140
event_seat_booking/static/src/js/templates.js

@ -0,0 +1,140 @@
odoo.define('event_seat_booking.templates', function (require) {
'use strict';
var publicWidget = require('web.public.widget');
var ajax = require('web.ajax');
var core = require('web.core');
var _t = core._t;
publicWidget.registry.SeatBooking = publicWidget.Widget.extend({
selector: '.main',
events: {
'click .seat-button': '_onSeatClick',
},
init: function () {
this._super.apply(this, arguments);
this.selectedSeats = [];
this.seatCount = 0;
this.totalPrice = 0;
this.eventPrices = {}; // Dictionary to store event prices
this.seatInformation = {};
},
//Seat onClick
_onSeatClick: function (ev) {
const seatButton = document.querySelector('.seat-button');
const eventId = seatButton.getAttribute('data-event-id');
var $target = $(ev.currentTarget);
var ticketId = $target.data('event-id');
var uniqueId = $target.data('seat-id');
var seatCount = $target.hasClass('selected') ? 0 : 0;
// Update the seat count for the ticket ID in the object
this.eventPrices[ticketId] = (this.eventPrices[ticketId] || 0) + seatCount;
var seatCount = 0;
var rowNumber = $target.closest('.seats-column').find('.row-button').text().trim();
var seatNumber = $target.text().trim();
var eventName = $target.data('event-name');
var eventPrice = parseFloat($target.data('event-price'));
var selectedSeats = [];
// Check if eventPrice is NaN (zero) and handle accordingly
if (isNaN(eventPrice)) {
eventPrice = 0;
}
//if reserved seat show alert
if ($target.hasClass('reserved-seat')) {
alert('This seat is already booked. Please choose another seat.');
return; // Do nothing if the seat is confirmed
}
// Toggle the "selected" class on the seat-button
$target.toggleClass('selected');
// Show or hide the seat information in the selected-seats div based on the selected state
var seatInfo = eventName + ' Seat' + '#' + 'R' + rowNumber + 'S' + seatNumber + ':' + eventPrice + "<br/>" ;
var SeatID = 'Row' + rowNumber + 'Column' + seatNumber
var uniqueRowKey = uniqueId + 'R' + rowNumber;
var uniqueColumnKey = uniqueId + 'C' + seatNumber
if ($target.hasClass('selected')) {
// Add the uniqueId to the text input field
var currentValue = this.$('#unique_column_id').val();
var newValue = currentValue ? currentValue + ',' + uniqueId : uniqueId;
this.$('#unique_column_id').val(newValue);
// Add the uniqueRowKey to the row_number_id input field
var currentRowNumberValue = this.$('#row_number_id').val();
var newRowNumberValue = currentRowNumberValue ? currentRowNumberValue + ',' + uniqueRowKey : uniqueRowKey;
this.$('#row_number_id').val(newRowNumberValue);
// Add the seatNumber to the col_number_id input field
var currentColNumberValue = this.$('#col_number_id').val();
var newColNumberValue = currentColNumberValue ? currentColNumberValue + ',' + uniqueColumnKey : uniqueColumnKey;
this.$('#col_number_id').val(newColNumberValue);
this.seatCount += $target.hasClass('selected') ? 1 : 0;
this.eventPrices[ticketId] = (this.eventPrices[ticketId] || 0) + 1;
$('.seat-count').html(this.seatCount);
this.totalPrice += $target.hasClass('selected') ? eventPrice : -eventPrice;
$('.total').html(this.totalPrice);
var seatDetail = $('<div>').addClass('seat-detail');
seatDetail.append(seatInfo);
$('.selected-seats').append(seatDetail);
}
else {
// Handle the case where the seat is deselected
var currentValue = $('#unique_column_id').val();
var newValue = currentValue.split(',').filter(function(value) {
return value !== uniqueId;
}).join(',');
$('#unique_column_id').val(newValue)
// Remove the seatNumber from the col_number_id input field
var currentColNumberValue = $('#col_number_id').val();
var newColNumberValue = currentColNumberValue.split(',').filter(function(value) {
return value !== uniqueColumnKey;
}).join(',');
$('#col_number_id').val(newColNumberValue);
// Remove the uniqueRowKey from the row_number_id input field
var currentRowNumberValue = $('#row_number_id').val();
var newRowNumberValue = currentRowNumberValue.split(',').filter(function(value) {
return value !== uniqueRowKey;
}).join(',');
$('#row_number_id').val(newRowNumberValue);
this.seatCount += $target.hasClass('selected') ? 0 : -1;
this.eventPrices[ticketId] = (this.eventPrices[ticketId] || 0) + -1;
$('.seat-count').html(this.seatCount);
this.totalPrice -= eventPrice;
$('.total').html(this.totalPrice);
var seatToRemove = $('.seat-detail').eq(rowNumber - 1);
seatToRemove.remove();
}
if (this.seatCount === 0) {
$('.seat-detail').html('');
}
// Collect selected seat numbers
this.$('.seat-button.selected').each(function () {
var rowNumber = $(this).closest('.seats-column').find('.row-button').text();
var seatNumber = $(this).text();
selectedSeats.push("R" + rowNumber.trim() + "S" + seatNumber.trim() );
});
// Attach selected seat numbers to the register button
$('#all_selected-seats').html(selectedSeats.join(', '));
console.log(this.$('#all_selected-seats'),"the seats")
var $nearestSelect = $target.closest('.separate-event').find('#selected_seats_input'); // Find the parent select tag
console.log($nearestSelect,34432432)
$nearestSelect.empty();
for (var id in this.eventPrices) {
if (this.eventPrices.hasOwnProperty(id)) {
var optionValue = id; // Use the ticket ID as the option value
var optionText = optionValue + ': ' + this.eventPrices[id];
$nearestSelect.append($('<option>', {
value: this.eventPrices[id],
text: optionText,
selected: true
}));
}
}
},
});
return publicWidget.registry.SeatBooking;
});

23
event_seat_booking/views/event_event_ticket_views.xml

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Inheriting the view and add a seat arrangement button to set the seat arrangements-->
<record id="event_event_ticket_view_tree_from_event" model="ir.ui.view">
<field name="name">event.event.ticket.view.form.inherit.event.seat.booking</field>
<field name="model">event.event.ticket</field>
<field name="inherit_id" ref="event.event_event_ticket_view_tree_from_event"/>
<field name="arch" type="xml">
<xpath expr="field[@name='seats_unconfirmed']" position="after">
<field name="seat_arrangement_id" invisible="0"/>
<field name="total_row"/>
<button icon="fa-list"
string="Open Seat Arrangement"
name="seat_arrangement_action"
type="object"
context="{'default_event': parent.name + '(' + parent.date_begin + ')','default_ticket_type': name, 'default_current_event_id': id,'default_seat_arrangement_id':seat_arrangement_id}"/>
</xpath>
<xpath expr="field[@name='name']" position="before">
<field name="sequence" widget="handle"/>
</xpath>
</field>
</record>
</odoo>

16
event_seat_booking/views/event_event_views.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Inheriting and add the field to enable the seat booking option to the
website-->
<record id="view_event_form" model="ir.ui.view">
<field name="name">event.event.view.form.inherit.event.seat.booking</field>
<field name="model">event.event</field>
<field name="inherit_id" ref="event.view_event_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='auto_confirm']"
position="after">
<field name="is_seat_booking"/>
</xpath>
</field>
</record>
</odoo>

35
event_seat_booking/views/event_registration_views.xml

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Inheriting from the form view of the view_event_registration model to add additional fields in to it -->
<record id="view_event_registration_form" model="ir.ui.view">
<field name="name">
event.registration.view.form.inherit.event.seat.booking
</field>
<field name="model">event.registration</field>
<field name="inherit_id" ref="event.view_event_registration_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='date_closed']" position="after">
<field name="row_number" invisible="1"/>
<field name="column_number" invisible="1"/>
<field name="unique_column_id" invisible="1"/>
<field name="complete_name" invisible="1"/>
</xpath>
<xpath expr="//div[@name='button_box']" position="after">
<div class="oe_title" attrs="{'invisible': [('row_number', '=', False)]}">
<h1><field class="text-break" name="complete_name"/></h1>
</div>
</xpath>
</field>
</record>
<!-- Inheriting from the tree view of the view_event_registration_tree model to add additional fields in to it -->
<record id="view_event_registration_tree" model="ir.ui.view">
<field name="name">event.registration.view.form.inherit.event.seat.booking</field>
<field name="model">event.registration</field>
<field name="inherit_id" ref="event.view_event_registration_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='create_date']" position="before">
<field name="complete_name"/>
</xpath>
</field>
</record>
</odoo>

190
event_seat_booking/views/event_seat_booking_board_templates.xml

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="Big5" ?>
<odoo>
<!-- Seat booking website board template to book the event seat through the website-->
<template id="event_seat_booking_board_templates"
name="Event Seat Booking Board">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure">
<div class="row">
<form id="registration_form"
t-attf-action="/event/#{event}/registration/new"
method="post"
itemscope="itemscope"
itemprop="offers"
itemtype="http://schema.org/AggregateOffer">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<div class="container d-flex flex-column flex-grow-1 justify-content-around">
<div class="o_wevent_event_title"
style="text-align: center;">
<h1 class="o_wevent_event_name">
<t t-esc="event_name"/>
</h1>
</div>
</div>
<div id="seat_layout">
<div class="row">
<div class="col-lg-7 col-md-12 col-sm-12 col-12">
<div id="seat_layout_left"
style="overflow:auto; padding-left:25%;border-right: 1px solid #000;">
<div id="seat-map" style="display: ruby-text; width:100%;"
class="sh-10 seatCharts-container">
<div class="front-indicator"
style="text-align: center;
background:#bdbdbd;
width:98%;
float:left;
padding: 5px 0px;">
SCREEN
</div>
<div class="main event_seat_arrangemet">
<t t-set="sl_no"
t-value="0"/>
<t t-foreach="event_tickets"
t-as="ticket">
<div class="separate-event">
<select t-att-name="'nb_register-%s' % (ticket.id if ticket.id else '0')"
id="selected_seats_input"
style="display: none;">
<option>0
</option>
</select>
<input type="hidden"
name="selected_seats_html"
id="selected_seats_html"/>
<br/>
<t t-if="ticket.total_row and ticket.total_row &gt; 0">
<div class="seats-row mt-4"
style="text-align: center;">
<t t-foreach="event_seat_templates[ticket.seat_arrangement_id.id]"
t-as="event">
<div class="seat-colum-main">
<div class="seats-column">
<div class="row-button btn btn-primary">
<t t-esc="sl_no+1"/>
<t t-set="sl_no"
t-value="sl_no + 1"/>
</div>
<t t-foreach="event_value"
t-as="col">
<t t-if="col['reservation_status'] == 'available'">
<div class="seat-button btn btn-primary confirmed-seat "
t-att-data-event-name="ticket.name"
t-att-data-event-id="ticket.id"
t-att-data-event-price="ticket.price"
t-att-data-seat-id="col['unique_column']"
t-att-data-seat-row="col['row_no']"
t-att-data-seat-coloumn="col['column_no']"
t-attf-class="seat-button btn btn-primary #{'VIP' if ticket.name == 'VIP' else ('Standard' if ticket.name == 'Standard' else ('Free' if ticket.name == 'Free' else 'other-event'))}">
<t t-esc="col['seat_column_id']"/>
</div>
</t>
<t t-else="">
<div class="seat-button btn btn-danger reserved-seat">
<t t-esc="col['seat_column_id']"/>
</div>
</t>
</t>
</div>
</div>
</t>
</div>
</t>
</div>
</t>
<input type="hidden"
name="unique_id"
id="unique_column_id"/>
<input type="hidden"
name="row_number"
id="row_number_id"/>
<input type="hidden"
name="column_number"
id="col_number_id"/>
<br/>
<br/>
</div>
</div>
</div>
</div>
<div class="col-lg-5 col-md-12 col-sm-12 col-12">
<div class="front-indicator"
style="text-align: center;
background:#bdbdbd;
width:100%;
float:left;
padding: 5px 0px;margin-bottom:30px;">
Seat Booking Information
</div>
<div class="booking-details">
<input type="hidden"
name="all_selected_seats"
id="all_selected_seats"
value="hii"/>
<h6>Selected Seats
:
<div class="seat-count"
style="display: inline;">
0
</div>
</h6>
<div class="selected-seats"
id="selected_seats_info">
<span id="seat_name"/>
</div>
<h6>Total :
<div class="total"
style="display: inline;"></div>
</h6>
<button type="submit"
class="btn btn-primary o_wait_lazy_js a-submit submit"
disabled=""
t-attf-id="#{event}">
Register
</button>
<br/>
<div class="gene-event" style="line-height: 42px; margin-top:24px;">
<t t-foreach="event_tickets"
t-as="line">
<t t-if="line.name == 'VIP'">
<span class="event-button btn btn-primary"
style="background-color: darksalmon;"/>
<span>
<t t-esc="line.name"/>
</span>
</t>
<t t-elif="line.name == 'Standard'">
<div class="event-button btn btn-primary"
style="background-color: #b9dea0;"/>
<t t-esc="line.name"/>
</t>
<t t-elif="line.name == 'Free'">
<div class="event-button btn btn-primary"
style="background-color: #3a78c3;"/>
<t t-esc="line.name"/>
</t>
<t t-else="line.name == ' '">
<div class="event-button btn btn-primary"
style="background-color: green;"/>
<t t-esc="line.name"/>
</t>
</t>
<span class="event-button btn btn-primary"
style="background-color: brown;"/>
<span>Already
Booked
</span>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</t>
</template>
</odoo>

204
event_seat_booking/views/registration_template.xml

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- New Template - Custom Registration -->
<template id="custom_registration_template"
inherit_id="website_event.registration_template"
name="Custom Registration">
<xpath expr="//form[@id='registration_form']" position="attributes">
<attribute name="t-if">not event.is_seat_booking</attribute>
</xpath>
<xpath expr="//form[@id='registration_form']" position="after">
<div t-if="event.is_seat_booking">
<div t-if="event.event_registrations_open">
<t t-call="event_seat_booking.seat_booking_button_template"/>
</div>
</div>
</xpath>
</template>
<!-- Button Template for Seat Booking-->
<template id="seat_booking_button_template" name="Seat Booking Button">
<form id="seat_booking_form"
class="mb-5 bg-white rounded shadow-sm d-flex align-items-center">
<div class="d-grid col-lg-4 pt-3 pt-lg-0 ps-2 ps-lg-0">
<a t-attf-href="/event/#{event.id}/SeatsBooking"
class="btn btn-primary o_wait_lazy_js">Seat Booking
</a>
</div>
</form>
</template>
<!-- New Registration Attendee Template-->
<template id="registration_attendee_details_booking"
inherit_id="website_event.registration_attendee_details"
name="Attendess Registration">
<xpath expr="//form[@id='attendee_registration']/div[@class='modal-content']"
position="replace">
<t t-if="event.is_seat_booking">
<div class="modal-content">
<div class="modal-header align-items-center">
<h4 class="modal-title">Attendees</h4>
<button type="button" class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<t t-set="counter_type" t-value="1"/>
<t t-set="counter" t-value="0"/>
<t t-foreach="tickets" t-as="ticket"
t-if="availability_check">
<t t-foreach="range(1, ticket['quantity'] + 1)"
t-as="att_counter" name="attendee_loop">
<t t-if="counter is None">
<t t-set="counter" t-value="0"/>
</t>
<t t-set="counter" t-value="counter + 1"/>
<div class="modal-body border-bottom">
<div class="row mb-2">
<div class="col-lg">
<h5 class="mt-1 pb-2 border-bottom">
<t t-if="ticket['seat_details'] and ticket['seat_details'][att_counter-1]">
Seat No #R
<t t-out="ticket['seat_details'][att_counter-1]['row_no']"/>
S
<t t-out="ticket['seat_details'][att_counter-1]['column_no']"/>
</t>
-
<span t-out="ticket['name']"/>
</h5>
</div>
</div>
<div class="row">
<div class="col-lg my-2">
<label>Name *</label>
<input class="form-control" type="text"
t-attf-name="#{counter}-name"
required="This field is required"
t-att-value="default_first_attendee.get('name', '') if counter == 1 else ''"/>
</div>
<div class="col-lg my-2">
<label>Email *</label>
<input class="form-control"
type="email"
t-attf-name="#{counter}-email"
required="This field is required"
t-att-value="default_first_attendee.get('email', '') if counter == 1 else ''"/>
</div>
<div class="col-lg my-2">
<label>Phone
<small>(Optional)</small>
</label>
<input class="form-control" type="tel"
t-attf-name="#{counter}-phone"
t-att-value="default_first_attendee.get('phone', '') if counter == 1 else ''"/>
</div>
<input class="d-none" type="text"
t-attf-name="#{counter}-event_ticket_id"
t-attf-value="#{ticket['id']}"/>
<t t-if="ticket['seat_details'] and ticket['seat_details'][att_counter-1]">
<input type="hidden"
t-attf-name="#{counter}-unique_column_id"
t-attf-value="#{ticket['seat_details'][att_counter-1]['unique_id']}"/>
<input type="hidden"
t-attf-name="#{counter}-row_number"
t-attf-value="#{ticket['seat_details'][att_counter-1]['row_no']}"/>
<input type="hidden"
t-attf-name="#{counter}-column_number"
t-attf-value="#{ticket['seat_details'][att_counter-1]['column_no']}"/>
</t>
</div>
</div>
</t>
<t t-set="counter_type" t-value="counter_type + 1"/>
</t>
<t t-if="not availability_check">
<div class="modal-body border-bottom">
<strong>You ordered more tickets than available
seats
</strong>
</div>
</t>
<div class="modal-footer border-0 justify-content-between">
<button type="button"
class="btn btn-secondary js_goto_event"
data-bs-dismiss="modal">Cancel
</button>
<button type="submit" class="btn btn-primary"
t-if="availability_check">Continue
</button>
</div>
</div>
</t>
<t t-else="">
<div class="modal-content">
<div class="modal-header align-items-center">
<h4 class="modal-title">Attendees</h4>
<button type="button" class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<t t-set="counter_type" t-value="1"/>
<t t-set="counter" t-value="0"/>
<t t-foreach="tickets" t-as="ticket"
t-if="availability_check">
<t t-foreach="range(1, ticket['quantity'] + 1)"
t-as="att_counter" name="attendee_loop">
<t t-set="counter" t-value="counter + 1"/>
<div class="modal-body border-bottom">
<h5 class="mt-1 pb-2 border-bottom">Ticket #
<span t-out="counter"/>
<small class="text-muted">-
<span t-out="ticket['name']"/>
</small>
</h5>
<div class="row">
<div class="col-lg my-2">
<label>Name *</label>
<input class="form-control" type="text"
t-attf-name="#{counter}-name"
required="This field is required"
t-att-value="default_first_attendee.get('name', '') if counter == 1 else ''"/>
</div>
<div class="col-lg my-2">
<label>Email *</label>
<input class="form-control"
type="email"
t-attf-name="#{counter}-email"
required="This field is required"
t-att-value="default_first_attendee.get('email', '') if counter == 1 else ''"/>
</div>
<div class="col-lg my-2">
<label>Phone
<small>(Optional)</small>
</label>
<input class="form-control" type="tel"
t-attf-name="#{counter}-phone"
t-att-value="default_first_attendee.get('phone', '') if counter == 1 else ''"/>
</div>
<input class="d-none" type="text"
t-attf-name="#{counter}-event_ticket_id"
t-attf-value="#{ticket['id']}"/>
</div>
</div>
</t>
<t t-set="counter_type" t-value="counter_type + 1"/>
</t>
<t t-if="not availability_check">
<div class="modal-body border-bottom">
<strong>You ordered more tickets than available
seats
</strong>
</div>
</t>
<div class="modal-footer border-0 justify-content-between">
<button type="button"
class="btn btn-secondary js_goto_event"
data-bs-dismiss="modal">Cancel
</button>
<button type="submit" class="btn btn-primary"
t-if="availability_check">Continue
</button>
</div>
</div>
</t>
</xpath>
</template>
</odoo>

31
event_seat_booking/views/seat_arrangement_line_views.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Seat arrangements view action-->
<record id="seat_arrangement_line_action" model="ir.actions.act_window">
<field name="name">seat.arrangement.line.action</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">seat.arrangement.line</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add the seat.
</p>
</field>
</record>
<!-- Seat arrangements form view-->
<record id="seat_arrangement_line_view_form" model="ir.ui.view">
<field name="name">seat.arrangement.line.view.form</field>
<field name="model">seat.arrangement.line</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="row_no"/>
<field name="column_ids" widget="many2many_tags"/>
<field name="seat_manage_id" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
</odoo>

52
event_seat_booking/views/seat_arrangement_views.xml

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- view action-->
<record id="seat_arrangement_action" model="ir.actions.act_window">
<field name="name">Seat Arrangement</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">seat.arrangement</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<!-- form view -->
<record id="seat_arrangement_view_form" model="ir.ui.view">
<field name="name">seat.arrangement.view.form</field>
<field name="model">seat.arrangement</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="event"/>
<field name="ticket_type"/>
<field name="total_row"/>
<field name="max_seat_single_row"/>
<field name="current_event_id" invisble="1"/>
<button name="action_create_one_two_many_record" type='object' string="Prepare Seat Arrangement" class="btn btn-primary"/>
<button name="action_clear_seat_arrangement" string="Clear Seat Arrangement" type='object' class="btn btn-primary"/>
</group>
<notebook>
<page>
<field name="prepare_seat_ids">
<tree editable="bottom">
<field name="row_no"/>
<field name="column_ids"
widget="many2many_tags"
options="{'no_create': True, 'no_create_edit':True}"/>
</tree>
</field>
</page>
</notebook>
<group>
<field name="seats_max"/>
</group>
<footer>
<button name="action_save_record"
type="object"
class="btn btn-primary o_form_button_save"
>Save</button>
</footer>
</sheet>
</form>
</field>
</record>
</odoo>
Loading…
Cancel
Save