diff --git a/cab_booking_management/README.rst b/cab_booking_management/README.rst new file mode 100644 index 000000000..126346dc3 --- /dev/null +++ b/cab_booking_management/README.rst @@ -0,0 +1,33 @@ +Cab Booking Management System v11 +================================= + +This module was developed to manage the cab system.It helps booking the cab, maintains logs +and record every activity related to the cab management. + +Installation +============ + +Just select it from available modules to install it, there is no need to extra installations. + +Configuration +============= + +Nothing to configure. + +Usage +===== + +To use this functionality, you need to: +#.First create cabs(Cab Management > Cabs) +#.Then,you need to set timing for each cabs( Cab management > Timing) +#.On clicking Booking menu( Cab management > Booking) ,you have option to select cabs based on your time and location +#. Email is sent,once your booking is confirmed +#.To get total expense,first you need to set maintenance form ( Cab management > Maintenance).In this form ,you can +select cab and date, and all total activity of that cab on that day is fetched here. +#.To get data's on maintenance form ,first you must book one cab + + +Credits +======= +Developer: Saritha @ cybrosys +Developer: Shereef @ cybrosys diff --git a/cab_booking_management/__init__.py b/cab_booking_management/__init__.py new file mode 100644 index 000000000..a779c8578 --- /dev/null +++ b/cab_booking_management/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: Cybrosys Techno Solutions() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import models diff --git a/cab_booking_management/__manifest__.py b/cab_booking_management/__manifest__.py new file mode 100644 index 000000000..c3b5d23c5 --- /dev/null +++ b/cab_booking_management/__manifest__.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: Cybrosys Techno Solutions() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': "Cab Booking Management System", + 'summary': """Complete Cab Booking Management and its Related Records""", + 'author': "Cybrosys Techno Solutions", + 'website': "https://www.cybrosys.com", + 'category': 'Industries', + 'version': '11.0.1.0.0', + 'depends': ['base', 'mail'], + 'data': [ + 'views/templates.xml', + 'views/cab_log_view.xml', + 'views/cab_conf_view.xml', + 'views/cab_location_view.xml', + 'views/cab_timing_view.xml', + 'views/cab_booking_view.xml', + 'views/cab_creation_view.xml', + 'views/cab_maintanence_view.xml', + 'security/ir.model.access.csv' + ], + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': True, +} diff --git a/cab_booking_management/models/__init__.py b/cab_booking_management/models/__init__.py new file mode 100644 index 000000000..9c417f74a --- /dev/null +++ b/cab_booking_management/models/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2018-TODAY Cybrosys Technologies(). +# Author: Cybrosys Techno Solutions() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import cab_creation +from . import cab_log +from . import cab_conf +from . import cab_booking +from . import cab_location +from . import cab_timing +from . import cab_maintanence + + diff --git a/cab_booking_management/models/cab_booking.py b/cab_booking_management/models/cab_booking.py new file mode 100644 index 000000000..c4d75bee1 --- /dev/null +++ b/cab_booking_management/models/cab_booking.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api +from datetime import date + + +class CabBooking(models.Model): + _name = 'cab.booking' + _rec_name = 'booking_date' + + booking_date = fields.Date(string="Booking Date", default=date.today(), required=True) + cab_timing = fields.Many2one('cab.time', string="Timing", required=True) + cab_routes = fields.Many2one('cab.location', string="Route From", required=True) + cab_routes_to = fields.Many2one('cab.location', string="Route To", required=True) + seat_available = fields.One2many('cab.timing', compute="scheduled_details") + + @api.onchange('cab_routes', 'cab_timing', 'cab_routes_to') + def scheduled_details(self): + data = self.env['cab.timing'].search([('cab_route.name', '=', self.cab_routes.name), + ('cab_time.name', '=', self.cab_timing.name), + ('cab_route_to.name', '=', self.cab_routes_to.name)]) + self.seat_available = data + + + + + + + + + + diff --git a/cab_booking_management/models/cab_conf.py b/cab_booking_management/models/cab_conf.py new file mode 100644 index 000000000..a8947b4b9 --- /dev/null +++ b/cab_booking_management/models/cab_conf.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields + + +class CabConfiguration(models.Model): + _name = 'cab.configuration' + _rec_name = 'cab_manager' + + auto_approve = fields.Boolean(string="Auto Approve") + cab_manager = fields.Many2one('res.users', string='Manager', required=True) diff --git a/cab_booking_management/models/cab_creation.py b/cab_booking_management/models/cab_creation.py new file mode 100644 index 000000000..2b0c8f641 --- /dev/null +++ b/cab_booking_management/models/cab_creation.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api +from odoo.exceptions import UserError, ValidationError + + +class CabManagement(models.Model): + _name = 'cab.management' + + name = fields.Char(compute="complete_name_compute", string="Cab Name") + ref_name = fields.Char(string="Cab Name", required=True) + cab_image = fields.Binary(string='Image', store=True, attachment=True) + licence_plate = fields.Char(string="Licence Plate", required=True) + activity_period_from = fields.Date(string="Activity Period") + activity_period_to = fields.Date(string="To") + driver_plot = fields.Char(string="Driver Ploted") + cab_value = fields.Float(string="Cab Value") + cab_model = fields.Char(string="Cab Model") + cab_color = fields.Char(string="Cab Color") + aq_date = fields.Date(string="Aquisition Date") + chas_no = fields.Char(string="Chasis No") + odo_reading = fields.Float(string="Odometre Reading") + seating_capacity = fields.Integer(string="Seating Capacity", required=True) + fuel_type = fields.Char(string="Fuel Type") + related_log_details = fields.One2many('cab.log', string="Log Details", compute="auto_fetch_log_details") + total_log_details = fields.One2many('cab.maintanence', string='Total Expenses', compute="auto_fetch_total_details") + location_log_details = fields.One2many('cab.log', string="Location", compute="auto_fetch_location_details") + + @api.onchange('licence_plate') + def check_unique_constraint(self): + for records in self.env['cab.management'].search([]): + if self.licence_plate == records.licence_plate: + raise ValidationError("Record already exists and violates unique field constraint") + + @api.one + def complete_name_compute(self): + self.name = self.ref_name + if self.licence_plate: + self.name = str(self.licence_plate) + ' / ' + str(self.ref_name) + + @api.onchange('activity_period_from', 'activity_period_to') + def auto_fetch_log_details(self): + if self.activity_period_from and self.activity_period_to: + if self.activity_period_from <= self.activity_period_to: + data = self.env['cab.log'].search([("cab_log_date", ">=", self.activity_period_from), + ("cab_log_date", "<=", self.activity_period_to)]) + self.related_log_details = data + else: + self.activity_period_to = 0 + raise UserError("Enter Valid Dates") + + @api.onchange('activity_period_from', 'activity_period_to') + def auto_fetch_total_details(self): + if self.activity_period_from and self.activity_period_to: + if self.activity_period_from <= self.activity_period_to: + data = self.env['cab.maintanence'].search([("cab_log_date", ">=", self.activity_period_from), + ("cab_log_date", "<=", self.activity_period_to)]) + self.total_log_details = data + else: + raise UserError("Enter Valid Dates") + + @api.onchange('activity_period_from', 'activity_period_to') + def auto_fetch_location_details(self): + if self.activity_period_from and self.activity_period_to: + if self.activity_period_from <= self.activity_period_to: + data = self.env['cab.log'].search([("cab_log_date", ">=", self.activity_period_from), + ("cab_log_date", "<=", self.activity_period_to)]) + self.location_log_details = data + else: + raise UserError("Enter Valid Dates") + diff --git a/cab_booking_management/models/cab_location.py b/cab_booking_management/models/cab_location.py new file mode 100644 index 000000000..f06deb9dd --- /dev/null +++ b/cab_booking_management/models/cab_location.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields + + +class CabLocation(models.Model): + _name = 'cab.location' + + name = fields.Char(string='City', required=True) + cab_zip = fields.Char(string='ZIP') + cab_code = fields.Char(string='City Code', size=64, help="The official code for the city") + state_id = fields.Many2one('res.country.state', string='State', required=True) + country_id = fields.Many2one('res.country', string='Country', required=True) + diff --git a/cab_booking_management/models/cab_log.py b/cab_booking_management/models/cab_log.py new file mode 100644 index 000000000..b0f50771f --- /dev/null +++ b/cab_booking_management/models/cab_log.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError +from datetime import date + + +class CabLog(models.Model): + _name = 'cab.log' + _inherit = 'mail.thread' + _description = 'Cab' + + name = fields.Many2one('cab.management', string="Name", store=True, required=True) + cab_log_date = fields.Date(string="Date", default=date.today(), required=True) + fuel_used = fields.Float(string="Fuel Used", required=True, help="To get total fuel used in Litre") + seat_capacity = fields.Integer(string="Seat Capacity", related="name.seating_capacity") + seat_available = fields.Integer(string="Seat Available") + cab_location = fields.Char(string="Destination Point", required=True) + cab_location_from = fields.Char(string="Starting Point", required=True) + seat_booked = fields.Integer(string="How many seats you need to book?", required=True) + odo_metre = fields.Float(string="OdoMetre Reading", required=True, help="Total distance covered in Km") + cab_expense = fields.Float(string="Expense", required=True) + cab_log_timing = fields.Many2one('cab.time', string="Time", required=True) + total_passenger = fields.Integer(string="Total Passenger", required=True) + partner_id = fields.Many2one('res.users', string="Customer Name", required=True) + cab_image = fields.Binary(string='Image', store=True, attachment=True) + state = fields.Selection([ + ('draft', 'Draft'), + ('approved', 'Approved'), + ('discard', 'Discard'), + ('cancel', 'Cancelled'), + ('done', 'Done') + ], default='draft') + + @api.onchange('name') + def change_location(self): + for records in self.env['cab.timing'].search([('name.name', '=', self.name.name)]): + if self.name.name == records.name.name: + self.cab_location = records.cab_route_to.name + self.cab_location_from = records.cab_route.name + + @api.one + @api.constrains('cab_log_timing') + def change_time(self): + for records in self.env['cab.timing'].search([('name.name', '=', self.name.name)]): + if self.cab_log_timing: + if self.cab_log_timing not in records.cab_time: + raise ValidationError("No cabs available at given time") + + @api.one + @api.constrains('seat_booked') + def error_message(self): + if self.seat_available < self.seat_booked: + raise ValidationError("No Available Seats") + elif self.seat_booked != self.total_passenger: + raise ValidationError("No of seat requested for booking and total passenger must be equal") + + @api.onchange('seat_booked') + def change_total_passenger(self): + self.total_passenger = self.seat_booked + + @api.one + def action_approve(self): + self.state = "approved" + + @api.one + def action_cancel(self): + self.state = "cancel" + + @api.one + def action_discard(self): + self.state = "discard" + + @api.onchange('cab_log_date', 'state') + def auto_cabs_approve(self): + for data in self.env['cab.configuration'].search([]): + if data.auto_approve != False: + user_obj = self.env.user + if user_obj == data.cab_manager: + self.state = 'approved' + + @api.onchange('cab_log_date', 'name', 'cab_log_timing') + def change_available_seat(self): + for data in self.env['cab.management'].search([('name', '=', self.name.name)]): + flag = 0 + total_seat_booked = 0 + for records in self.env['cab.log'].search([('name.name', '=', data.name)]): + if self.cab_log_date == records.cab_log_date and self.cab_log_timing == records.cab_log_timing: + if self.cab_location == records.cab_location and self.cab_location_from == records.cab_location_from: + total_seat_booked = total_seat_booked+records.seat_booked + flag += 1 + if flag > 0: + test_val = self.seat_capacity - total_seat_booked + self.seat_available = test_val + + else: + self.seat_available = self.seat_capacity + + @api.multi + def action_sent(self): + self.ensure_one() + ir_model_data = self.env['ir.model.data'] + try: + template_id = ir_model_data.get_object_reference('cab_booking_management', 'email_template_edi_cab')[1] + except ValueError: + template_id = False + try: + compose_form_id = ir_model_data.get_object_reference('mail', 'email_compose_message_wizard_form')[1] + except ValueError: + compose_form_id = False + ctx = dict() + ctx.update({ + 'default_model': 'cab.log', + 'default_res_id': self.ids[0], + 'default_use_template': bool(template_id), + 'default_template_id': template_id, + 'default_composition_mode': 'comment', + }) + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'mail.compose.message', + 'views': [(compose_form_id, 'form')], + 'view_id': compose_form_id, + 'target': 'new', + 'context': ctx, + } + + +class MailComposeMessage(models.TransientModel): + _inherit = 'mail.compose.message' + + @api.multi + def send_mail(self, auto_commit=False): + if self._context.get('default_model') == 'cab.log' and self._context.get('default_res_id'): + order = self.env['cab.log'].browse([self._context['default_res_id']]) + if order.state == 'approved': + order.state = 'done' + order.sent = True + self = self.with_context(mail_post_autofollow=True) + return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit) diff --git a/cab_booking_management/models/cab_maintanence.py b/cab_booking_management/models/cab_maintanence.py new file mode 100644 index 000000000..cfca775d3 --- /dev/null +++ b/cab_booking_management/models/cab_maintanence.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + + +class CabMaintanence(models.Model): + _name = 'cab.maintanence' + + name = fields.Many2one('cab.management', string="Name", required=True) + cab_log_date = fields.Date(string="Date", required=True) + fuel_used = fields.Float(string="Fuel Used") + odo_metre = fields.Float(string="OdoMetre Reading") + cab_expense = fields.Float(string="Expense") + total_passenger = fields.Integer(string="Total Passenger") + + @api.onchange('cab_log_date') + def total_log_details(self): + total_fuel = 0 + odo_metres = 0 + expense = 0 + passenger = 0 + for data in self.env['cab.log'].search([]): + if data.cab_log_date == self.cab_log_date: + total_fuel += data.fuel_used + odo_metres += data.odo_metre + expense += data.cab_expense + passenger += data.total_passenger + self.write({'fuel_used': total_fuel, + 'odo_metre': odo_metres, + 'cab_expense': expense, + 'total_passenger': passenger}) + + + diff --git a/cab_booking_management/models/cab_timing.py b/cab_booking_management/models/cab_timing.py new file mode 100644 index 000000000..6111c8f60 --- /dev/null +++ b/cab_booking_management/models/cab_timing.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + + +class CabTiming(models.Model): + _name = 'cab.timing' + + name = fields.Many2one('cab.management', string="Cab Name", required=True) + cab_time = fields.Many2many('cab.time', 'cab_name_rel', string="Time", required=True, + help="Use this format 00:00,ex: 01:15") + cab_route = fields.Many2one('cab.location', string='Starting Place', required=True) + cab_route_to = fields.Many2one('cab.location', string='Destination Place', required=True) + seat = fields.Integer(string="Seating Capacity", related='name.seating_capacity', required=True) + + @api.multi + def action_log_form_view(self): + return { + 'name': 'CabLog', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'cab.log', + 'type': 'ir.actions.act_window', + 'target': 'current' + } + + +class Time(models.Model): + _name = 'cab.time' + + name = fields.Char(string="Name", required=True, help="Use this format 00:00,ex: 01:15") + + + + + diff --git a/cab_booking_management/security/ir.model.access.csv b/cab_booking_management/security/ir.model.access.csv new file mode 100644 index 000000000..d23dbeb67 --- /dev/null +++ b/cab_booking_management/security/ir.model.access.csv @@ -0,0 +1,16 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_cab_management,cab.management,model_cab_management,base.group_user,1,1,1,0 +access_cab_maintenanace,cab.maintanence,model_cab_maintanence,base.group_user,1,1,1,0 +access_cab_log,cab.log,model_cab_log,base.group_user,1,1,1,0 +access_cab_timing,cab.timing,model_cab_timing,base.group_user,1,1,1,0 +access_cab_location,cab.location,model_cab_location,base.group_user,1,1,1,0 +access_cab_booking,cab.booking,model_cab_booking,base.group_user,1,1,1,0 +access_cab_conf,cab.configuration,model_cab_configuration,base.group_user,1,1,1,0 +access_cab_time,cab.time,model_cab_time,base.group_user,1,1,1,0 + + + + + + + diff --git a/cab_booking_management/static/description/banner.jpg b/cab_booking_management/static/description/banner.jpg new file mode 100644 index 000000000..8c41b7664 Binary files /dev/null and b/cab_booking_management/static/description/banner.jpg differ diff --git a/cab_booking_management/static/description/booking.png b/cab_booking_management/static/description/booking.png new file mode 100644 index 000000000..da75ae380 Binary files /dev/null and b/cab_booking_management/static/description/booking.png differ diff --git a/cab_booking_management/static/description/cab_activity.png b/cab_booking_management/static/description/cab_activity.png new file mode 100644 index 000000000..f5ab7e04e Binary files /dev/null and b/cab_booking_management/static/description/cab_activity.png differ diff --git a/cab_booking_management/static/description/cab_booking.png b/cab_booking_management/static/description/cab_booking.png new file mode 100644 index 000000000..4d09f542c Binary files /dev/null and b/cab_booking_management/static/description/cab_booking.png differ diff --git a/cab_booking_management/static/description/cab_cancel.png b/cab_booking_management/static/description/cab_cancel.png new file mode 100644 index 000000000..0e97f0816 Binary files /dev/null and b/cab_booking_management/static/description/cab_cancel.png differ diff --git a/cab_booking_management/static/description/cab_conf.png b/cab_booking_management/static/description/cab_conf.png new file mode 100644 index 000000000..a6ff8e21f Binary files /dev/null and b/cab_booking_management/static/description/cab_conf.png differ diff --git a/cab_booking_management/static/description/cab_creation.png b/cab_booking_management/static/description/cab_creation.png new file mode 100644 index 000000000..10f83a8de Binary files /dev/null and b/cab_booking_management/static/description/cab_creation.png differ diff --git a/cab_booking_management/static/description/cab_details.png b/cab_booking_management/static/description/cab_details.png new file mode 100644 index 000000000..4aae5bd6a Binary files /dev/null and b/cab_booking_management/static/description/cab_details.png differ diff --git a/cab_booking_management/static/description/cab_maintain.png b/cab_booking_management/static/description/cab_maintain.png new file mode 100644 index 000000000..aaf675c90 Binary files /dev/null and b/cab_booking_management/static/description/cab_maintain.png differ diff --git a/cab_booking_management/static/description/cybro_logo.png b/cab_booking_management/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/cab_booking_management/static/description/cybro_logo.png differ diff --git a/cab_booking_management/static/description/icon.png b/cab_booking_management/static/description/icon.png new file mode 100644 index 000000000..53f81b27b Binary files /dev/null and b/cab_booking_management/static/description/icon.png differ diff --git a/cab_booking_management/static/description/index.html b/cab_booking_management/static/description/index.html new file mode 100644 index 000000000..086692564 --- /dev/null +++ b/cab_booking_management/static/description/index.html @@ -0,0 +1,177 @@ +
+
+

Cab Booking Management System (CBMS)

+

Manage the cabs with ease

+

Cybrosys Technologies , www.cybrosys.com

+
+

Major Features:

+
    +
  •   Booking the Cab.
  • +
  •   Auto approval Settings in Configuration.
  • +
  •   Cab Logs for Every Trip.
  • +
  •   Record Every Activity Related to CBMS.
  • +
  •   Email Notification for Successful Booking.
  • +
  •   Booking Status.
  • +
  •   View All Cab Activities with Advanced Filttrations.
  • +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+

Cab Booking

+
+

+ We can book cabs from list of cabs based on your time and location. +

+
+
+
+ +
+
+
+
+ +
+
+

Auto approval

+
+
+ +
+
+
+

+ Approve cab booking automatically. +

+
+
+
+ +
+
+

Cab Logs for Every Trip

+
+

+ It keep the record of all expenses of each cab trips. +

+
+
+
+ +
+
+
+
+ +
+
+

Record Every Activity Related to CBMS

+
+
+ +
+
+
+

+ It shows the total expenses for a cab, on daily basis. +

+
+
+
+ +
+
+

Email Notification for Successful Booking.

+
+

+ Email is sent to the user on successful booking of cab. +

+
+
+
+ +
+
+
+
+ +
+
+

Booking Status

+
+
+ +
+
+
+

+ View your status of booking.You can also cancel your booking. +

+
+
+
+ +
+
+

Cab Maintenance

+
+

+ It shows the total expenses for a cab, on daily basis. +

+
+
+
+ +
+
+
+
+ +
+
+

View All Cab Activities with Advanced Filttrations

+
+
+ +
+
+
+
+ +
+

You Looking for a free Documentation of this Application.?

+

Give a Request Mail to:    odoo@cybrosys.com

+
+ +
+

Need Any Help?

+ + +
+ + + + diff --git a/cab_booking_management/static/description/log_details.png b/cab_booking_management/static/description/log_details.png new file mode 100644 index 000000000..992758d39 Binary files /dev/null and b/cab_booking_management/static/description/log_details.png differ diff --git a/cab_booking_management/static/description/mail.png b/cab_booking_management/static/description/mail.png new file mode 100644 index 000000000..07eca6214 Binary files /dev/null and b/cab_booking_management/static/description/mail.png differ diff --git a/cab_booking_management/views/cab_booking_view.xml b/cab_booking_management/views/cab_booking_view.xml new file mode 100644 index 000000000..0bb73c82e --- /dev/null +++ b/cab_booking_management/views/cab_booking_view.xml @@ -0,0 +1,72 @@ + + + + + Cab Booking + cab.booking + +
+
+ +
+

BOOK YOUR CAB

+
+ +
+ + + + + + + + + + + + + + + + +