@ -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>`__ |
@ -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 |
@ -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 |
|||
} |
@ -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 |
@ -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, |
|||
}) |
@ -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 |
@ -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 |
@ -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> |
@ -0,0 +1,7 @@ |
|||
## Module <event_seat_booking> |
|||
|
|||
#### 18.06.2024 |
|||
#### Version 16.0.1.0.0 |
|||
#### ADD |
|||
|
|||
- Initial Commit For Event Seat Booking. |
@ -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 |
@ -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.') |
@ -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', |
|||
} |
@ -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 |
@ -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 |
|||
}) |
@ -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() |
@ -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) |
@ -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> |
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 129 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 192 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 185 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 174 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 661 KiB |
After Width: | Height: | Size: 123 KiB |
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 489 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 16 KiB |
@ -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 & |
|||
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 & 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 --> |
@ -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; |
|||
} |
@ -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); |
|||
}); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
|
|||
|
@ -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; |
|||
}); |
@ -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> |
@ -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> |
@ -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> |
@ -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 > 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> |
@ -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> |
@ -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> |
@ -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> |