| @ -0,0 +1,46 @@ | |||||
|  | .. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg | ||||
|  |     :target: http://www.gnu.org/licenses/AGPL-3.0-standalone.html | ||||
|  |     :alt: License: AGPL-3 | ||||
|  | 
 | ||||
|  | Vehicle Subscription Management | ||||
|  | =============================== | ||||
|  | This module helps you to Subscribe,Cancel and Change subscription through website as well as backend. | ||||
|  | 
 | ||||
|  | Configuration | ||||
|  | ============= | ||||
|  | * No additional configurations needed | ||||
|  | 
 | ||||
|  | Company | ||||
|  | ------- | ||||
|  | * `Cybrosys Techno Solutions <https://cybrosys.com/>`__ | ||||
|  | 
 | ||||
|  | Credits | ||||
|  | ------- | ||||
|  | * Developers: (v16) Rahna Rasheed, Contact: odoo@cybrosys.com | ||||
|  | 
 | ||||
|  | License | ||||
|  | ------- | ||||
|  | GNU AFFERO GENERAL PUBLIC LICENSE v3.0 (AGPL-3) | ||||
|  | (https://www.gnu.org/licenses/agpl-3.0-standalone.html) | ||||
|  | 
 | ||||
|  | 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,24 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 controllers | ||||
|  | from . import models | ||||
|  | from . import wizard | ||||
| @ -0,0 +1,71 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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': 'Vehicle Subscription Management', | ||||
|  |     'version': "16.0.1.0.0", | ||||
|  |     'category': 'Fleet', | ||||
|  |     'summary': """Vehicle Subscription Management From Website""", | ||||
|  |     'description': """Vehicle Subscription Management From Website""", | ||||
|  |     'author': 'Cybrosys Techno Solutions', | ||||
|  |     'company': 'Cybrosys Techno Solutions', | ||||
|  |     'maintainer': 'Cybrosys Techno Solutions', | ||||
|  |     'website': 'https://www.cybrosys.com', | ||||
|  |     'depends': ['mail', 'contacts', 'fleet', 'account', 'sale', 'website', | ||||
|  |                 'portal', ], | ||||
|  |     'data': [ | ||||
|  |         'security/vehicle_subscription_groups.xml', | ||||
|  |         'security/ir.model.access.csv', | ||||
|  |         'data/ir_cron_data.xml', | ||||
|  |         'data/product_template_data.xml', | ||||
|  |         'data/website_menu_data.xml', | ||||
|  |         'data/mail_data.xml', | ||||
|  |         'views/website_portal_subscription_template.xml', | ||||
|  |         'views/fleet_vehicle_model_views.xml', | ||||
|  |         'views/fleet_subscription_views.xml', | ||||
|  |         'views/vehicle_insurance_views.xml', | ||||
|  |         'views/subscription_request_views.xml', | ||||
|  |         'views/insurance_type_views.xml', | ||||
|  |         'views/online_subscription_template.xml', | ||||
|  |         'views/online_vehicle_template.xml', | ||||
|  |         'views/account_move_views.xml', | ||||
|  |         'views/subscription_form_success_template.xml', | ||||
|  |         'views/online_vehicle_cancellation_template.xml', | ||||
|  |         'views/cancellation_request_views.xml', | ||||
|  |         'views/change_vehicle_subscription_template.xml', | ||||
|  |         'wizard/change_subscription_views.xml', | ||||
|  |     ], | ||||
|  |     'assets': { | ||||
|  |         'web.assets_frontend': [ | ||||
|  |             'vehicle_subscription/static/src/js/website_subscription.js', | ||||
|  |             'vehicle_subscription/static/src/js/vehicle_booking.js', | ||||
|  |             'vehicle_subscription/static/src/js/subscription_cancellation.js', | ||||
|  |             'vehicle_subscription/static/src/js/change_subscription_form.js', | ||||
|  |             'vehicle_subscription/static/src/js/vehicle_subscription_success.js', | ||||
|  |             'vehicle_subscription/static/src/js/change_subscription_request.js', | ||||
|  |         ], | ||||
|  |     }, | ||||
|  |     'images': ['static/description/banner.png'], | ||||
|  |     'license': 'AGPL-3', | ||||
|  |     'installable': True, | ||||
|  |     'auto_install': False, | ||||
|  |     'application': False, | ||||
|  | } | ||||
| @ -0,0 +1,23 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 vehicle_subscription | ||||
|  | from . import website_portal | ||||
| @ -0,0 +1,392 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 datetime import datetime, timedelta | ||||
|  | from odoo import http | ||||
|  | from odoo.http import request | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class OnlineSubscription(http.Controller): | ||||
|  |     """Online Vehicle subscription through website""" | ||||
|  | 
 | ||||
|  |     @http.route(['/online/subscription/city'], type='json', auth="public", | ||||
|  |                 website=True) | ||||
|  |     def get_city(self, **kwargs): | ||||
|  |         """Calling this function using ajax rpc in order to get city | ||||
|  |         based on state """ | ||||
|  |         state = int(kwargs.get('state')) | ||||
|  |         vehicle = request.env['fleet.vehicle'].sudo().search( | ||||
|  |             [('states_id', '=', state)]) | ||||
|  |         states = [city.location for city in vehicle] | ||||
|  |         return [*set(states)] | ||||
|  | 
 | ||||
|  |     @http.route('/online/subscription', auth='public', website=True) | ||||
|  |     def subscription_form(self): | ||||
|  |         """This function will return vehicle  with which state is not null""" | ||||
|  |         vehicle_id = request.env['fleet.vehicle'].sudo().search( | ||||
|  |             [('states_id', '!=', False)]) | ||||
|  |         insurance_type = request.env['insurance.type'].sudo().search([]) | ||||
|  |         vals = { | ||||
|  |             'states': vehicle_id.states_id, | ||||
|  |             'cities': [rec.location for rec in vehicle_id], | ||||
|  |             'insurance_type': insurance_type, | ||||
|  |         } | ||||
|  |         return http.request.render('vehicle_subscription.subscription_form', | ||||
|  |                                    vals) | ||||
|  | 
 | ||||
|  |     @http.route('/online/subscription/next', auth='public', website=True) | ||||
|  |     def vehicle_form(self, **kw): | ||||
|  |         """Redirect to corresponding templates according to the | ||||
|  |         data provided by user in form page """ | ||||
|  |         if kw.get('start_date'): | ||||
|  |             states = kw.get('state') | ||||
|  |             city = kw.get('city') | ||||
|  |             start_date = kw.get('start_date') | ||||
|  |             end_date = kw.get('end_date') | ||||
|  |             insurance = kw.get('insurance_type') | ||||
|  |             start = datetime.strptime(start_date, '%Y-%m-%d').date() | ||||
|  |             end = datetime.strptime(end_date, '%Y-%m-%d').date() | ||||
|  |             seats = kw.get('seating_capacity') | ||||
|  |             insurance_amount = request.env['vehicle.insurance'].sudo().browse( | ||||
|  |                 int(insurance)).insurance_amount | ||||
|  |             insurance_type = request.env['vehicle.insurance'].sudo().search( | ||||
|  |                 [('insurance_type_id.id', '=', insurance), | ||||
|  |                  ('start_date', '<=', start), ('end_date', '>=', end)]) | ||||
|  |             vehicle_ids = insurance_type.vehicle_id | ||||
|  |             subscribed_vehicle_id = (request.env['fleet.subscription'].sudo(). | ||||
|  |                                      search( | ||||
|  |                 [('state', '=', 'subscribed')]).vehicle_id) | ||||
|  |             vehicle = request.env['fleet.vehicle'].sudo().search( | ||||
|  |                 [('id', 'in', vehicle_ids.ids), ('states_id', '=', int(states)), | ||||
|  |                  ('location', '=', city), | ||||
|  |                  ('seats', '=', int(seats))]) | ||||
|  |             vehicle_id = vehicle.filtered( | ||||
|  |                 lambda v: v.id not in subscribed_vehicle_id.ids) | ||||
|  |             if vehicle_id: | ||||
|  |                 for rec in vehicle_id: | ||||
|  |                     rec.write({ | ||||
|  |                         'insurance': insurance, | ||||
|  |                         'start': start, | ||||
|  |                         'end': end, | ||||
|  |                     }) | ||||
|  |                 data = { | ||||
|  |                     'vehicles': vehicle_id, | ||||
|  |                     'amount': insurance_amount, | ||||
|  |                     'customers': request.env.user.partner_id.name, | ||||
|  |                 } | ||||
|  |                 return http.request.render('vehicle_subscription.vehicle_form', | ||||
|  |                                            data) | ||||
|  |             else: | ||||
|  |                 return http.request.render( | ||||
|  |                     'vehicle_subscription.subscription_vehicle_missing') | ||||
|  |         else: | ||||
|  |             return http.request.render('vehicle_subscription.vehicle_form') | ||||
|  | 
 | ||||
|  |     @http.route(['/online/subscription/book'], type='json', auth="public", | ||||
|  |                 website=True) | ||||
|  |     def get_vehicle(self, **kwargs): | ||||
|  |         """Ajax RPC handler for booking vehicle subscription and | ||||
|  |          creating corresponding invoices in the backend.""" | ||||
|  |         extra_km = kwargs.get('extra_km') | ||||
|  |         product_template_id = (request.env.ref( | ||||
|  |             'vehicle_subscription.product_template_vehicle_subscription_form'). | ||||
|  |                                id) | ||||
|  |         product_id = request.env['product.product'].sudo().search( | ||||
|  |             [('product_tmpl_id', '=', product_template_id)]) | ||||
|  |         vehicle = int(kwargs.get('vehicle')) | ||||
|  |         customer = kwargs.get('customer') | ||||
|  |         checked = int(kwargs.get('checked')) | ||||
|  |         invoice_type = int(kwargs.get('invoice')) | ||||
|  |         vehicle_id = request.env['fleet.vehicle'].sudo().browse(int(vehicle)) | ||||
|  |         customer_id = request.env['res.partner'].sudo().search( | ||||
|  |             [('name', '=', customer)]) | ||||
|  |         if extra_km == '': | ||||
|  |             km = 0 | ||||
|  |         else: | ||||
|  |             km = extra_km | ||||
|  |         subscribe = request.env['fleet.subscription'].sudo().create({ | ||||
|  |             'vehicle_id': vehicle_id.id, | ||||
|  |             'customer_id': customer_id.id, | ||||
|  |             'insurance_type_id': vehicle_id.insurance, | ||||
|  |             'start_date': vehicle_id.start, | ||||
|  |             'end_date': vehicle_id.end, | ||||
|  |             'extra_km': km, | ||||
|  |             'fuel': 'without_fuel' if checked == False else 'with_fuel' | ||||
|  |         }) | ||||
|  |         subscribe.action_invoice() | ||||
|  |         subscribe.sale_id.action_confirm() | ||||
|  |         if invoice_type: | ||||
|  |             subscribe.sale_id._create_invoices().action_post() | ||||
|  |             subscribe.invoice_ids.is_subscription = True | ||||
|  |             subscribe.sale_id.invoice_ids.is_subscription = True | ||||
|  |         else: | ||||
|  |             subscribe.sale_id.invoice_status = 'invoiced' | ||||
|  |             total_price = subscribe.sale_id.order_line.price_unit | ||||
|  |             duration = vehicle_id.duration | ||||
|  |             per_day = total_price / duration | ||||
|  |             start_date = vehicle_id.start | ||||
|  |             end_date = vehicle_id.end | ||||
|  |             next_invoice_day = start_date | ||||
|  |             while next_invoice_day <= end_date: | ||||
|  |                 next_invoice_day = next_invoice_day + timedelta(days=30) | ||||
|  |                 if next_invoice_day <= end_date: | ||||
|  |                     durations = (next_invoice_day - start_date).days | ||||
|  |                     generate_invoice = request.env[ | ||||
|  |                         'account.move'].sudo().create({ | ||||
|  |                             'move_type': 'out_invoice', | ||||
|  |                             'partner_id': customer_id.id, | ||||
|  |                             'invoice_date': next_invoice_day, | ||||
|  |                             'invoice_origin': subscribe.sale_id.name, | ||||
|  |                             'invoice_line_ids': [(0, 0, { | ||||
|  |                                 'product_id': product_id.id, | ||||
|  |                                 'name': vehicle_id.name, | ||||
|  |                                 'price_unit': per_day * durations, | ||||
|  |                             })] | ||||
|  |                         }) | ||||
|  |                     generate_invoice.is_subscription = True | ||||
|  |                     generate_invoice.action_post() | ||||
|  |                     subscribe.sale_id.invoice_ids = [(4, generate_invoice.id)] | ||||
|  |                     subscribe.invoice_ids = [(4, generate_invoice.id)] | ||||
|  |                 else: | ||||
|  |                     next_invoice_day = end_date | ||||
|  |                     durations = (next_invoice_day - start_date).days | ||||
|  |                     generate_invoice = request.env[ | ||||
|  |                         'account.move'].sudo().create({ | ||||
|  |                             'move_type': 'out_invoice', | ||||
|  |                             'partner_id': customer_id.id, | ||||
|  |                             'invoice_date': next_invoice_day, | ||||
|  |                             'invoice_line_ids': [(0, 0, { | ||||
|  |                                 'product_id': product_id.id, | ||||
|  |                                 'name': vehicle_id.name, | ||||
|  |                                 'price_unit': per_day * durations, | ||||
|  |                             })] | ||||
|  |                         }) | ||||
|  |                     generate_invoice.is_subscription = True | ||||
|  |                     generate_invoice.action_post() | ||||
|  |                     subscribe.sale_id.invoice_ids = [(4, generate_invoice.id)] | ||||
|  |                     subscribe.invoice_ids = [(4, generate_invoice.id)] | ||||
|  |                     break | ||||
|  |                 start_date = start_date + timedelta(days=30) | ||||
|  |         values = { | ||||
|  |             'subscription_id': subscribe.id | ||||
|  |         } | ||||
|  |         return values | ||||
|  | 
 | ||||
|  |     @http.route(['/next/vehicle', '/next/vehicle/<int:subscription_id>'], | ||||
|  |                 auth='public', website=True, type='http') | ||||
|  |     def subscription_create(self): | ||||
|  |         """Return template for successful subscription""" | ||||
|  |         current_vehicle = request.env['fleet.subscription'].sudo().search([ | ||||
|  |             ('customer_id', '=', request.env.user.partner_id.id), | ||||
|  |             ('state', '=', 'subscribed'), | ||||
|  |         ], order='write_date desc', limit=1) | ||||
|  |         context = { | ||||
|  |             'vehicle_name': current_vehicle.vehicle_id.name, | ||||
|  |             'customer_name': request.env.user.partner_id.name, | ||||
|  |         } | ||||
|  |         return request.render('vehicle_subscription.subscription_form_success', | ||||
|  |                               context) | ||||
|  | 
 | ||||
|  |     @http.route(['/online/subscription/with/fuel'], type='json', auth="public", | ||||
|  |                 website=True) | ||||
|  |     def get_with_fuel(self, **kwargs): | ||||
|  |         """Calculate price for vehicle according to fuel type """ | ||||
|  |         vehicle = int(kwargs.get('vehicle')) | ||||
|  |         km = kwargs.get('extra_km') | ||||
|  |         vehicle = request.env['fleet.vehicle'].sudo().browse(vehicle) | ||||
|  |         vehicle.write({ | ||||
|  |             'extra_km': km, | ||||
|  |         }) | ||||
|  |         insurance_amount = vehicle.insurance | ||||
|  |         amount = request.env['vehicle.insurance'].sudo() \ | ||||
|  |             .browse(int(insurance_amount)).insurance_amount | ||||
|  |         if float(km) > vehicle.free_km: | ||||
|  |             new_price = (((vehicle.extra_km / vehicle.mileage) * | ||||
|  |                           vehicle.fuel_rate) + | ||||
|  |                          (vehicle.duration * vehicle.subscription_price) + | ||||
|  |                          amount) | ||||
|  |         else: | ||||
|  |             if float(km) <= vehicle.free_km: | ||||
|  |                 new_price = ((vehicle.duration * vehicle.subscription_price) + | ||||
|  |                              amount) | ||||
|  |         return str(new_price) | ||||
|  | 
 | ||||
|  |     @http.route(['/online/subscription/without/fuel'], type='json', | ||||
|  |                 auth="public", | ||||
|  |                 website=True) | ||||
|  |     def get_without_fuel(self, **kwargs): | ||||
|  |         """Calculate price for vehicle according to fuel type """ | ||||
|  |         vehicle = int(kwargs.get('vehicle')) | ||||
|  |         km = kwargs.get('extra_km') | ||||
|  |         vehicle = request.env['fleet.vehicle'].sudo().browse(vehicle) | ||||
|  |         insurance_amount = vehicle.insurance | ||||
|  |         amount = request.env['vehicle.insurance'].sudo() \ | ||||
|  |             .browse(int(insurance_amount)).insurance_amount | ||||
|  |         vehicle.write({ | ||||
|  |             'extra_km': km, | ||||
|  |         }) | ||||
|  |         if float(km) > vehicle.free_km: | ||||
|  |             new_price = (((vehicle.duration * vehicle.subscription_price) + | ||||
|  |                           amount) + (vehicle.charge_km * vehicle.extra_km)) | ||||
|  |         else: | ||||
|  |             new_price = (vehicle.duration * vehicle.subscription_price) + amount | ||||
|  |         return str(new_price) | ||||
|  | 
 | ||||
|  |     @http.route('/online/subscription/cancel', auth='public', website=True) | ||||
|  |     def cancellation_form(self): | ||||
|  |         """Cancel subscription form through website""" | ||||
|  |         customer_id = request.env['res.partner'].sudo().search( | ||||
|  |             [('name', '=', request.env.user.partner_id.name)]) | ||||
|  |         vehicle_id = request.env['fleet.subscription'].sudo().search( | ||||
|  |             [('customer_id', '=', customer_id.id), | ||||
|  |              ('state', '=', 'subscribed')]) | ||||
|  |         vals = { | ||||
|  |             'customers': customer_id.name, | ||||
|  |             'vehicles': vehicle_id, | ||||
|  |         } | ||||
|  |         return http.request.render( | ||||
|  |             'vehicle_subscription.subscription_cancellation_form', vals) | ||||
|  | 
 | ||||
|  |     @http.route('/online/choose/vehicle', type='json', auth="public", | ||||
|  |                 website=True) | ||||
|  |     def choose_vehicle(self, **kwargs): | ||||
|  |         """Only display vehicle of  selected customer in website""" | ||||
|  |         customer = kwargs.get('customer_id') | ||||
|  |         customer_id = request.env['res.partner'].sudo().search( | ||||
|  |             [('name', '=', customer)]) | ||||
|  |         vehicle_id = request.env['fleet.subscription'].sudo().search( | ||||
|  |             [('state', '=', 'subscribed'), | ||||
|  |              ('customer_id', '=', customer_id.id)]).mapped('vehicle_id') | ||||
|  |         if vehicle_id: | ||||
|  |             vehicle = [(rec.id, rec.name) for rec in vehicle_id] | ||||
|  |         return [*set(vehicle)] | ||||
|  | 
 | ||||
|  |     @http.route('/online/cancellation/click', auth='public', type='http', | ||||
|  |                 website=True) | ||||
|  |     def cancellation_click_form(self, **kwargs): | ||||
|  |         """Proceed with cancellation button click""" | ||||
|  |         customer = kwargs.get('customer') | ||||
|  |         vehicle = int(kwargs.get('vehicle')) | ||||
|  |         reason = kwargs.get('reason') | ||||
|  |         customer_id = request.env['res.partner'].sudo().search( | ||||
|  |             [('name', '=', customer)]) | ||||
|  |         vehicle_id = request.env['fleet.vehicle'].sudo().browse(vehicle) | ||||
|  |         cancel_request = request.env['cancellation.request'].sudo().create({ | ||||
|  |             'customer_id': customer_id.id, | ||||
|  |             'vehicle_id': vehicle_id.id, | ||||
|  |             'reason': reason, | ||||
|  |         }) | ||||
|  |         values = { | ||||
|  |             'customer': customer, | ||||
|  |             'vehicle': vehicle_id.name, | ||||
|  |         } | ||||
|  |         cancel_request.state = 'to_approve' | ||||
|  |         return request.render('vehicle_subscription.booking_cancellation', | ||||
|  |                               values) | ||||
|  | 
 | ||||
|  |     @http.route('/online/subscription/change', auth='public', website=True) | ||||
|  |     def subscription_change_form(self): | ||||
|  |         """Rendered response for the 'vehicle_subscription. | ||||
|  |         subscription_change_form' template, | ||||
|  |          containing the available vehicles and the current customer's name.""" | ||||
|  |         vehicle = request.env['fleet.vehicle'].sudo().search( | ||||
|  |             [('states_id', '!=', False)]) | ||||
|  |         customer = request.env.user.partner_id.name | ||||
|  |         customer_id = request.env['res.partner'].sudo().search( | ||||
|  |             [('name', '=', customer)]) | ||||
|  |         vals = { | ||||
|  |             'vehicles': vehicle, | ||||
|  |             'customers': customer_id.name, | ||||
|  |         } | ||||
|  |         return http.request.render( | ||||
|  |             'vehicle_subscription.subscription_change_form', vals) | ||||
|  | 
 | ||||
|  |     @http.route('/online/subscription/change/vehicle', auth='public', | ||||
|  |                 type='http', website=True) | ||||
|  |     def change_click_form(self, **kwargs): | ||||
|  |         """ Rendered response based on the conditions: | ||||
|  |          - If the 'customer' parameter exists, render the | ||||
|  |          'vehicle_subscription.subscription_change_button' template | ||||
|  |            with the provided data. | ||||
|  |          - If the 'customer' parameter does not exist, render the | ||||
|  |          'vehicle_subscription.subscription_change_boolean_false' | ||||
|  |            template.""" | ||||
|  |         if kwargs.get('customer'): | ||||
|  |             customer = kwargs.get('customer') | ||||
|  |             vehicle = int(kwargs.get('vehicle')) | ||||
|  |             reason = kwargs.get('reason') | ||||
|  |             checkbox = kwargs.get('checkbox_model') | ||||
|  |             customer_id = request.env['res.partner'].sudo(). \ | ||||
|  |                 search([('name', '=', customer)]) | ||||
|  |             vehicle_id = request.env['fleet.vehicle'].sudo().browse(vehicle) | ||||
|  |             new_vehicle_id = request.env['fleet.vehicle'].sudo() \ | ||||
|  |                 .search([('model_id', '=', vehicle_id.model_id.id)]) | ||||
|  |             if checkbox == 'on': | ||||
|  |                 values = { | ||||
|  |                     'customer_name': customer_id.name, | ||||
|  |                     'vehicle_name': vehicle_id.name, | ||||
|  |                     'vehicles': [rec for rec in new_vehicle_id], | ||||
|  |                     'reason': reason, | ||||
|  |                 } | ||||
|  |                 return request.render( | ||||
|  |                     'vehicle_subscription.subscription_change_button', values) | ||||
|  |             else: | ||||
|  |                 return request.render( | ||||
|  |                     'vehicle_subscription.subscription_change_boolean_false') | ||||
|  |         else: | ||||
|  |             return request.render( | ||||
|  |                 'vehicle_subscription.subscription_change_button') | ||||
|  | 
 | ||||
|  |     @http.route('/online/subscription/change/button', auth='public', | ||||
|  |                 type='http', website=True) | ||||
|  |     def click_form(self, **kwargs): | ||||
|  |         """Rendered response for the | ||||
|  |             'vehicle_subscription.change_subscription' template. """ | ||||
|  |         customer = kwargs.get('customer') | ||||
|  |         reason = kwargs.get('reason') | ||||
|  |         current_vehicle = kwargs.get('vehicle') | ||||
|  |         vehicle_id = int(kwargs.get('new_vehicle')) | ||||
|  |         current_vehicle_id = request.env['fleet.vehicle'].sudo() \ | ||||
|  |             .search([('name', '=', current_vehicle)]) | ||||
|  |         customer_id = request.env['res.partner'].sudo() \ | ||||
|  |             .search([('name', '=', customer)]) | ||||
|  |         vehicle = request.env['fleet.vehicle'].sudo().browse(vehicle_id) | ||||
|  |         change_subscription = request.env['subscription.request'] \ | ||||
|  |             .sudo().create({ | ||||
|  |                 'current_vehicle': current_vehicle_id.id, | ||||
|  |                 'new_vehicle_id': vehicle.id, | ||||
|  |                 'reason_to_change': reason, | ||||
|  |                 'customer_id': customer_id.id, | ||||
|  |             }) | ||||
|  |         change_subscription.state = 'to_approve' | ||||
|  |         return request.render('vehicle_subscription.change_subscription') | ||||
|  | 
 | ||||
|  |     @http.route('/online/proceed/cancellation', auth='public', type='http', | ||||
|  |                 website=True) | ||||
|  |     def proceed_cancellation(self): | ||||
|  |         """Proceed with cancellation in change subscription """ | ||||
|  |         return request.redirect('/online/subscription/cancel') | ||||
|  | 
 | ||||
|  |     @http.route(['/web/signup/user'], type='http', auth="user", | ||||
|  |                 website=True) | ||||
|  |     def redirect_login(self): | ||||
|  |         """Used to redirect on clicking signup page""" | ||||
|  |         return request.redirect('/online/subscription') | ||||
| @ -0,0 +1,63 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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.portal.controllers.portal import CustomerPortal, \ | ||||
|  |     pager as portal_pager | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class PortalAccount(CustomerPortal): | ||||
|  |     """PortalAccount for subscription""" | ||||
|  | 
 | ||||
|  |     @http.route(['/my/subscription/invoice'], type='http', auth="user", | ||||
|  |                 website=True) | ||||
|  |     def portal_my_subscription_order(self, page=1, date_begin=None, | ||||
|  |                                      date_end=None, sortby=None, filterby=None): | ||||
|  |         """Rendered response for the ' | ||||
|  |         vehicle_subscription.portal_my_invoices_subscription' template, | ||||
|  |          containing the subscription invoices.""" | ||||
|  |         partner = request.env.user.partner_id | ||||
|  |         values = self._prepare_my_invoices_values(page, date_begin, date_end, | ||||
|  |                                                   sortby, filterby) | ||||
|  |         pager = portal_pager(**values['pager']) | ||||
|  |         domain = [ | ||||
|  |             ('invoice_line_ids.product_id', 'like', 'Vehicle Subscription'), | ||||
|  |             ('partner_id', '=', partner.id) | ||||
|  |         ] | ||||
|  |         values.update({ | ||||
|  |             'invoices': request.env['account.move'].sudo().search(domain), | ||||
|  |             'pager': pager, | ||||
|  |         }) | ||||
|  |         return request.render( | ||||
|  |             "vehicle_subscription.portal_my_invoices_subscription", values) | ||||
|  | 
 | ||||
|  |     def _prepare_home_portal_values(self, counters): | ||||
|  |         """Prepare the values for the home portal page.""" | ||||
|  |         values = super()._prepare_home_portal_values(counters) | ||||
|  |         partner = request.env.user.partner_id | ||||
|  |         if 'subscription_count' in counters: | ||||
|  |             values['subscription_count'] = request.env['account.move'].sudo() \ | ||||
|  |                 .search_count( | ||||
|  |                 [( | ||||
|  |                  'invoice_line_ids.product_id', 'like', 'Vehicle Subscription'), | ||||
|  |                  ('partner_id', '=', partner.id)]) | ||||
|  |         return values | ||||
| @ -0,0 +1,14 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Cron action for checking expiration--> | ||||
|  |     <record id="ir_cron_expiry_date_action" model="ir.cron"> | ||||
|  |         <field name="name">Subscription Expired</field> | ||||
|  |         <field name="model_id" ref="model_fleet_subscription"/> | ||||
|  |         <field name="state">code</field> | ||||
|  |         <field name="code">model._onchange_end_date()</field> | ||||
|  |         <field name="interval_number">1</field> | ||||
|  |         <field name="interval_type">days</field> | ||||
|  |         <field name="numbercall">-1</field> | ||||
|  |         <field name="active" eval="True"/> | ||||
|  |     </record> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,76 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Cron action for checking expiration--> | ||||
|  |     <record id="ir_cron_expiry_date_action" model="ir.cron"> | ||||
|  |         <field name="name">Subscription Expired</field> | ||||
|  |         <field name="model_id" ref="model_fleet_subscription"/> | ||||
|  |         <field name="state">code</field> | ||||
|  |         <field name="code">model._onchange_end_date()</field> | ||||
|  |         <field name="interval_number">1</field> | ||||
|  |         <field name="interval_type">days</field> | ||||
|  |         <field name="numbercall">-1</field> | ||||
|  |         <field name="active" eval="True"/> | ||||
|  |     </record> | ||||
|  |     <!--Subscription cancellation mail template--> | ||||
|  |     <record id="cancellation_request_mail" model="mail.template"> | ||||
|  |         <field name="name">Vehicle Cancellation</field> | ||||
|  |         <field name="model_id" | ||||
|  |                ref="vehicle_subscription.model_cancellation_request"/> | ||||
|  |         <field name="subject">Subscription Cancellation</field> | ||||
|  |         <field name="body_html" type="html"> | ||||
|  |             <div style="margin: 0px; padding: 0px;"> | ||||
|  |                 <p> | ||||
|  |                     Dear | ||||
|  |                     <br/> | ||||
|  |                     Sorry....you need to pay amount till date inorder to cancel | ||||
|  |                     subscription.Your invoice is attached | ||||
|  |                     below | ||||
|  |                     <br/> | ||||
|  |                 </p> | ||||
|  |                 Regards, | ||||
|  |                 <br/> | ||||
|  |                 <t t-out="user.name"/> | ||||
|  |             </div> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!-- Mail template for refund in subscription cancellation --> | ||||
|  |     <record id="cancellation_request_refund_mail" model="mail.template"> | ||||
|  |         <field name="name">Vehicle Cancellation</field> | ||||
|  |         <field name="model_id" | ||||
|  |                ref="vehicle_subscription.model_cancellation_request"/> | ||||
|  |         <field name="subject">Subscription Cancellation</field> | ||||
|  |         <field name="body_html" type="html"> | ||||
|  |             <div style="margin: 0px; padding: 0px;"> | ||||
|  |                 <p> | ||||
|  |                     Dear | ||||
|  |                     <br/> | ||||
|  |                     The amount should be refunded immediately. | ||||
|  |                     <br/> | ||||
|  |                 </p> | ||||
|  |                 Regards, | ||||
|  |                 <br/> | ||||
|  |                 <t t-out="user.name"/> | ||||
|  |             </div> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!-- Mail template for approval of subscription cancellation --> | ||||
|  |     <record id="cancellation_approved" model="mail.template"> | ||||
|  |         <field name="name">Vehicle Cancellation</field> | ||||
|  |         <field name="model_id" | ||||
|  |                ref="vehicle_subscription.model_cancellation_request"/> | ||||
|  |         <field name="subject">Subscription Cancellation</field> | ||||
|  |         <field name="body_html" type="html"> | ||||
|  |             <div style="margin: 0px; padding: 0px;"> | ||||
|  |                 <p> | ||||
|  |                     Dear | ||||
|  |                     <br/> | ||||
|  |                     Your request for subscription cancellation is approved | ||||
|  |                     <br/> | ||||
|  |                 </p> | ||||
|  |                 Regards, | ||||
|  |                 <br/> | ||||
|  |                 <t t-out="user.name"/> | ||||
|  |             </div> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,13 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||
|  | <odoo> | ||||
|  |     <data noupdate="1"> | ||||
|  |         <!--Created vehicle subscription as a service product--> | ||||
|  |         <record id="product_template_vehicle_subscription_form" | ||||
|  |                 model="product.template"> | ||||
|  |             <field name="name">Vehicle Subscription</field> | ||||
|  |             <field name="detailed_type">service</field> | ||||
|  |             <field name="invoice_policy">order</field> | ||||
|  |             <field name="sequence" type="int">55</field> | ||||
|  |         </record> | ||||
|  |     </data> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,12 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||
|  | <odoo> | ||||
|  |     <!--Subscription form in website --> | ||||
|  |     <data noupdate="1"> | ||||
|  |         <record id="menu_subscription_form" model="website.menu"> | ||||
|  |             <field name="name">Subscription Form</field> | ||||
|  |             <field name="url">/online/subscription</field> | ||||
|  |             <field name="parent_id" ref="website.main_menu"/> | ||||
|  |             <field name="sequence" type="int">55</field> | ||||
|  |         </record> | ||||
|  |     </data> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,6 @@ | |||||
|  | ## Module <vehicle_subscription> | ||||
|  | 
 | ||||
|  | #### 15.02.2024 | ||||
|  | #### Version 16.0.1.0.0 | ||||
|  | #### ADD | ||||
|  | Initial Commit Vehicle Subscription Management | ||||
| @ -0,0 +1,29 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 account_move | ||||
|  | from . import cancellation_request | ||||
|  | from . import fleet_subscription | ||||
|  | from . import fleet_vehicle | ||||
|  | from . import fleet_vehicle_model | ||||
|  | from . import insurance_type | ||||
|  | from . import subscription_request | ||||
|  | from . import vehicle_insurance | ||||
| @ -0,0 +1,32 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 AccountMove(models.Model): | ||||
|  |     """Inherited  account.move to add a field """ | ||||
|  |     _inherit = 'account.move' | ||||
|  | 
 | ||||
|  |     is_subscription = fields.Boolean(string="Subscribe", | ||||
|  |                                      help="This field will be set  true for " | ||||
|  |                                           "invoice corresponding to vehicle " | ||||
|  |                                           "subscription") | ||||
| @ -0,0 +1,262 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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/>. | ||||
|  | # | ||||
|  | ############################################################################# | ||||
|  | import base64 | ||||
|  | from odoo import fields, models | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class CancellationRequest(models.Model): | ||||
|  |     """Created new model to add new fields and function""" | ||||
|  |     _name = "cancellation.request" | ||||
|  |     _description = "Cancellation Request" | ||||
|  |     _inherit = "mail.thread" | ||||
|  |     _rec_name = 'vehicle_id' | ||||
|  | 
 | ||||
|  |     vehicle_id = fields.Many2one('fleet.vehicle', | ||||
|  |                                  string="Vehicle", help="Choose vehicle " | ||||
|  |                                                         "inorder to cancel " | ||||
|  |                                                         "subscription") | ||||
|  |     date = fields.Date(string="Cancellation Date", default=fields.Date.today(), | ||||
|  |                        help="Date for cancellation of vehicle") | ||||
|  |     customer_id = fields.Many2one('res.partner', string="Customer", | ||||
|  |                                   help="Choose Customer for the cancellation " | ||||
|  |                                        "of vehicle") | ||||
|  |     reason = fields.Char(string="Cancellation Reason", help="Describe the " | ||||
|  |                                                             "reason for " | ||||
|  |                                                             "cancellation") | ||||
|  |     state = fields.Selection(selection=[('draft', 'Draft'), | ||||
|  |                                         ('to_approve', 'To Approve'), | ||||
|  |                                         ('approved', 'Approved')], | ||||
|  |                              string='State', default='draft', | ||||
|  |                              help="States of cancellation subscription") | ||||
|  | 
 | ||||
|  |     def action_request(self): | ||||
|  |         """Change state to to_approve""" | ||||
|  |         self.write({'state': 'to_approve'}) | ||||
|  | 
 | ||||
|  |     def action_approve(self): | ||||
|  |         """Handle cancellation approval by manager. | ||||
|  |         This method handles the approval process for a cancellation | ||||
|  |         request in a vehicle subscription system. | ||||
|  |         It updates the cancellation state, generates invoices or refunds | ||||
|  |         based on the payment status, and sends notifications to the customer.""" | ||||
|  |         self.write({'state': 'approved'}) | ||||
|  |         subscription = self.env['fleet.subscription'].search( | ||||
|  |             [('vehicle_id', '=', self.vehicle_id.id), | ||||
|  |              ('customer_id', '=', self.customer_id.id)]) | ||||
|  |         invoice = subscription.sale_id.invoice_ids | ||||
|  |         multy_invoice = subscription.invoice_ids.ids | ||||
|  |         product_template_id = self.env.ref( | ||||
|  |             'vehicle_subscription.product_template_vehicle_subscription_form').id | ||||
|  |         product_id = self.env['product.product'].search( | ||||
|  |             [('product_tmpl_id', '=', product_template_id)]) | ||||
|  |         per_day_price = subscription.sale_id.amount_untaxed / subscription.duration | ||||
|  |         invoice_duration = (self.date - subscription.start_date).days | ||||
|  |         email_template = self.env.ref( | ||||
|  |             'vehicle_subscription.cancellation_request_mail') | ||||
|  |         template_approved = self.env.ref( | ||||
|  |             'vehicle_subscription.cancellation_approved') | ||||
|  |         refund_approved = self.env.ref( | ||||
|  |             'vehicle_subscription.cancellation_request_refund_mail') | ||||
|  |         uptodate_price = round(per_day_price * invoice_duration, 2) | ||||
|  |         paid_amount = self.env['account.move'].search( | ||||
|  |             [('id', 'in', subscription.invoice_ids.ids), | ||||
|  |              ('payment_state', 'in', ['paid', 'partial'])]) \ | ||||
|  |             .mapped('amount_untaxed_signed') | ||||
|  |         if paid_amount: | ||||
|  |             if sum(paid_amount) == uptodate_price: | ||||
|  |                 subscription.state = 'cancel' | ||||
|  |                 email_values = { | ||||
|  |                     'email_to': self.customer_id.email, | ||||
|  |                     'email_from': self.env.user.email, | ||||
|  |                 } | ||||
|  |                 template_approved.send_mail(self.id, email_values=email_values, | ||||
|  |                                             force_send=True) | ||||
|  |             elif sum(paid_amount) < uptodate_price: | ||||
|  |                 if len(invoice) == 1 or len(multy_invoice) == 1: | ||||
|  |                     invoice.button_cancel() | ||||
|  |                     generate_invoice = self.env['account.move'].sudo().create({ | ||||
|  |                         'move_type': 'out_invoice', | ||||
|  |                         'partner_id': self.customer_id.id, | ||||
|  |                         'invoice_date': self.date, | ||||
|  |                         'invoice_line_ids': [(0, 0, { | ||||
|  |                             'product_id': product_id.id, | ||||
|  |                             'name': self.vehicle_id.name, | ||||
|  |                             'price_unit': | ||||
|  |                                 (per_day_price * invoice_duration) - sum( | ||||
|  |                                     paid_amount), | ||||
|  |                         })] | ||||
|  |                     }) | ||||
|  |                     generate_invoice.action_post() | ||||
|  |                     data_record = base64.b64encode( | ||||
|  |                         self.env['ir.actions.report'].sudo()._render_qweb_pdf( | ||||
|  |                             "account.account_invoices", | ||||
|  |                             generate_invoice.ids)[0]) | ||||
|  |                     ir_values = { | ||||
|  |                         'name': 'Invoice', | ||||
|  |                         'type': 'binary', | ||||
|  |                         'datas': data_record, | ||||
|  |                         'store_fname': 'invoice.pdf', | ||||
|  |                         'mimetype': 'application/pdf', | ||||
|  |                         'res_model': 'account.move', | ||||
|  |                         'res_id': generate_invoice.id, | ||||
|  |                     } | ||||
|  |                     invoice_report_attachment_id = self.env[ | ||||
|  |                         'ir.attachment'].sudo().create( | ||||
|  |                         ir_values) | ||||
|  |                     email_values = { | ||||
|  |                         'email_to': self.customer_id.email, | ||||
|  |                         'email_from': self.env.user.email, | ||||
|  |                         'attachment_ids': [ | ||||
|  |                             (4, invoice_report_attachment_id.id, None)] | ||||
|  |                     } | ||||
|  |                     email_template.send_mail(self.id, email_values=email_values, | ||||
|  |                                              force_send=True) | ||||
|  |                     email_template.attachment_ids = [(5, 0, 0)] | ||||
|  |                     subscription.invoice_ids = [(4, generate_invoice.id)] | ||||
|  |                     subscription.sale_id.write({ | ||||
|  |                         'invoice_ids': [(4, generate_invoice.id)] | ||||
|  |                     }) | ||||
|  |                 else: | ||||
|  |                     for invoice_id in multy_invoice: | ||||
|  |                         invoice = self.env['account.move'].browse(invoice_id) | ||||
|  |                         invoice.button_cancel() | ||||
|  |                     generate_invoice = self.env['account.move'].sudo().create({ | ||||
|  |                         'move_type': 'out_invoice', | ||||
|  |                         'partner_id': self.customer_id.id, | ||||
|  |                         'invoice_date': self.date, | ||||
|  |                         'invoice_line_ids': [(0, 0, { | ||||
|  |                             'product_id': product_id.id, | ||||
|  |                             'name': self.vehicle_id.name, | ||||
|  |                             'price_unit': | ||||
|  |                                 (per_day_price * invoice_duration) - sum( | ||||
|  |                                     paid_amount), | ||||
|  |                         })] | ||||
|  |                     }) | ||||
|  |                     generate_invoice.action_post() | ||||
|  |                     data_record = base64.b64encode( | ||||
|  |                         self.env['ir.actions.report'].sudo()._render_qweb_pdf( | ||||
|  |                             "account.account_invoices", | ||||
|  |                             generate_invoice.ids)[0]) | ||||
|  |                     ir_values = { | ||||
|  |                         'name': 'Invoice', | ||||
|  |                         'type': 'binary', | ||||
|  |                         'datas': data_record, | ||||
|  |                         'store_fname': 'invoice.pdf', | ||||
|  |                         'mimetype': 'application/pdf', | ||||
|  |                         'res_model': 'account.move', | ||||
|  |                         'res_id': generate_invoice.id, | ||||
|  |                     } | ||||
|  |                     invoice_report_attachment_id = self.env[ | ||||
|  |                         'ir.attachment'].sudo().create( | ||||
|  |                         ir_values) | ||||
|  |                     email_values = { | ||||
|  |                         'email_to': self.customer_id.email, | ||||
|  |                         'email_from': self.env.user.email, | ||||
|  |                         'attachment_ids': [ | ||||
|  |                             (4, invoice_report_attachment_id.id, None)] | ||||
|  |                     } | ||||
|  |                     email_template.send_mail(self.id, email_values=email_values, | ||||
|  |                                              force_send=True) | ||||
|  |                     email_template.attachment_ids = [(5, 0, 0)] | ||||
|  |                     subscription.invoice_ids = [(4, generate_invoice.id)] | ||||
|  |                     subscription.sale_id.write({ | ||||
|  |                         'invoice_ids': [(4, generate_invoice.id)] | ||||
|  |                     }) | ||||
|  |             else: | ||||
|  |                 generate_refund = self.env['account.move'].sudo().create({ | ||||
|  |                     'move_type': 'out_refund', | ||||
|  |                     'invoice_date': fields.Date.today(), | ||||
|  |                     'partner_id': self.customer_id.id, | ||||
|  |                     'invoice_line_ids': [(0, 0, { | ||||
|  |                         'product_id': product_id.id, | ||||
|  |                         'name': self.vehicle_id.name, | ||||
|  |                         'price_unit': (sum(paid_amount) - uptodate_price) | ||||
|  |                     })] | ||||
|  |                 }) | ||||
|  |                 generate_refund.action_post() | ||||
|  |                 subscription.refund_id = generate_refund | ||||
|  |                 data_record = base64.b64encode( | ||||
|  |                     self.env['ir.actions.report'].sudo()._render_qweb_pdf( | ||||
|  |                         "account.account_invoices", | ||||
|  |                         generate_refund.ids)[0]) | ||||
|  |                 ir_values = { | ||||
|  |                     'name': 'Invoice', | ||||
|  |                     'type': 'binary', | ||||
|  |                     'datas': data_record, | ||||
|  |                     'store_fname': 'invoice.pdf', | ||||
|  |                     'mimetype': 'application/pdf', | ||||
|  |                     'res_model': 'account.move', | ||||
|  |                     'res_id': generate_refund.id, | ||||
|  |                 } | ||||
|  |                 invoice_report_attachment_id = self.env[ | ||||
|  |                     'ir.attachment'].sudo().create( | ||||
|  |                     ir_values) | ||||
|  |                 email_values = { | ||||
|  |                     'email_to': self.customer_id.email, | ||||
|  |                     'email_from': self.env.user.email, | ||||
|  |                     'attachment_ids': [ | ||||
|  |                         (4, invoice_report_attachment_id.id, None)] | ||||
|  |                 } | ||||
|  |                 refund_approved.send_mail(self.id, email_values=email_values, | ||||
|  |                                           force_send=True) | ||||
|  |                 refund_approved.attachment_ids = [(5, 0, 0)] | ||||
|  |         else: | ||||
|  |             invoice.button_cancel() | ||||
|  |             generate_invoice = self.env['account.move'].sudo().create({ | ||||
|  |                 'move_type': 'out_invoice', | ||||
|  |                 'partner_id': self.customer_id.id, | ||||
|  |                 'invoice_date': self.date, | ||||
|  |                 'invoice_line_ids': [(0, 0, { | ||||
|  |                     'product_id': product_id.id, | ||||
|  |                     'name': self.vehicle_id.name, | ||||
|  |                     'price_unit': per_day_price * invoice_duration, | ||||
|  |                 })] | ||||
|  |             }) | ||||
|  |             generate_invoice.action_post() | ||||
|  |             data_record = base64.b64encode( | ||||
|  |                 self.env['ir.actions.report'].sudo()._render_qweb_pdf( | ||||
|  |                     "account.account_invoices", | ||||
|  |                     generate_invoice.ids)[0]) | ||||
|  |             ir_values = { | ||||
|  |                 'name': 'Invoice', | ||||
|  |                 'type': 'binary', | ||||
|  |                 'datas': data_record, | ||||
|  |                 'store_fname': 'invoice.pdf', | ||||
|  |                 'mimetype': 'application/pdf', | ||||
|  |                 'res_model': 'account.move', | ||||
|  |                 'res_id': generate_invoice.id, | ||||
|  |             } | ||||
|  |             invoice_report_attachment_id = self.env[ | ||||
|  |                 'ir.attachment'].sudo().create( | ||||
|  |                 ir_values) | ||||
|  |             email_values = { | ||||
|  |                 'email_to': self.customer_id.email, | ||||
|  |                 'email_from': self.env.user.email, | ||||
|  |                 'attachment_ids': [(4, invoice_report_attachment_id.id, None)] | ||||
|  |             } | ||||
|  |             email_template.send_mail(self.id, email_values=email_values, | ||||
|  |                                      force_send=True) | ||||
|  |             email_template.attachment_ids = [(5, 0, 0)] | ||||
|  |             subscription.invoice_ids = [(4, generate_invoice.id)] | ||||
|  |             subscription.sale_id.write({ | ||||
|  |                 'invoice_ids': [(4, generate_invoice.id)] | ||||
|  |             }) | ||||
| @ -0,0 +1,377 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 datetime import datetime | ||||
|  | from odoo import api, fields, models, _ | ||||
|  | from odoo.exceptions import ValidationError | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class VehicleSubscription(models.Model): | ||||
|  |     """Created new model to add new fields and function""" | ||||
|  |     _name = "fleet.subscription" | ||||
|  |     _description = "Fleet Subscription" | ||||
|  |     _inherit = "mail.thread" | ||||
|  |     _rec_name = 'vehicle_id' | ||||
|  | 
 | ||||
|  |     vehicle_id = fields.Many2one('fleet.vehicle', string="Vehicle", | ||||
|  |                                  domain="[('id', 'in',vehicle_ids)]", | ||||
|  |                                  help="This field help you to choose vehicle") | ||||
|  |     vehicle_ids = fields.Many2many('fleet.vehicle', string="Vehicle", | ||||
|  |                                    compute='_compute_vehicle_ids', | ||||
|  |                                    help="Returns vehicle by satisfying " | ||||
|  |                                         "the domain") | ||||
|  |     model_id = fields.Many2one(related="vehicle_id.model_id", string='Model', | ||||
|  |                                help="This field help you to choose model " | ||||
|  |                                     "of vehicle") | ||||
|  |     price = fields.Float(compute="_compute_price", string='Price', | ||||
|  |                          help="Compute field which results the price of vehicle") | ||||
|  |     uptodate_price = fields.Float(compute="_compute_uptodate_price", | ||||
|  |                                   string='Price', | ||||
|  |                                   help="Compute field which results the price " | ||||
|  |                                        "of vehicle until the date ") | ||||
|  |     extra_price = fields.Float(string="Extra Price", | ||||
|  |                                compute="_compute_extra_price", | ||||
|  |                                help="Compute field which results the extra " | ||||
|  |                                     "price of vehicle") | ||||
|  |     start_date = fields.Date(string="Start Date", required=True, | ||||
|  |                              help="Start date of subscription") | ||||
|  |     end_date = fields.Date(string="End Date", required=True, | ||||
|  |                            help="End date of subscription") | ||||
|  |     cancellation_date = fields.Date(string="Cancellation Date", | ||||
|  |                                     default=fields.Date.today(), | ||||
|  |                                     help="Subscription cancellation date") | ||||
|  |     duration = fields.Integer(string="Duration", compute='_compute_duration', | ||||
|  |                               help="Compute subscription duration") | ||||
|  |     cancel_duration = fields.Integer(string="Duration", | ||||
|  |                                      compute='_compute_cancel_duration', | ||||
|  |                                      help="compute cancel duration") | ||||
|  |     state = fields.Selection( | ||||
|  |         selection=[('draft', 'Draft'), ('subscribed', 'Subscribed'), | ||||
|  |                    ('cancel', 'Cancelled'), ('expired', 'Expired') | ||||
|  |                    ], string='State', default='draft', | ||||
|  |         help="States of subscription") | ||||
|  |     street = fields.Char(string="Street", help="Choose the street") | ||||
|  |     state_id = fields.Many2one("res.country.state", string='State', | ||||
|  |                                ondelete='restrict', | ||||
|  |                                domain="[('country_id', '=?', country_id)]", | ||||
|  |                                help="Choose the state") | ||||
|  |     city = fields.Char(string="City", help="Choose the city") | ||||
|  |     country_id = fields.Many2one('res.country', string='Country', | ||||
|  |                                  ondelete='restrict', help="Choose the country") | ||||
|  |     fuel = fields.Selection(selection=[('with_fuel', 'With Fuel'), | ||||
|  |                                        ('without_fuel', 'Without Fuel')], | ||||
|  |                             string="Fuel Choice", default='without_fuel', | ||||
|  |                             help="Help you to choose the type of fuel") | ||||
|  |     fuel_type = fields.Selection(string="Fuel Type", | ||||
|  |                                  related= | ||||
|  |                                  "vehicle_id.model_id.default_fuel_type", | ||||
|  |                                  help="Fuel type will be given which is related" | ||||
|  |                                       " to the model") | ||||
|  |     fuel_rate = fields.Integer(String="Rate", default=300, help="Rate of fuel") | ||||
|  |     charge_km = fields.Integer(string="Charge in km", default=12, | ||||
|  |                                help="Rate per kilometer") | ||||
|  |     default_km = fields.Float(string="Default KMS", | ||||
|  |                               related='vehicle_id.free_km', | ||||
|  |                               help="Default km is set based on free km of " | ||||
|  |                                    "vehicle which is given by authorised " | ||||
|  |                                    "person") | ||||
|  |     extra_km = fields.Float(string="Extra KMS", default_km=1, | ||||
|  |                             help="As per customer he/she can choose extra km") | ||||
|  |     mileage = fields.Float(string='Mileage', | ||||
|  |                            related='vehicle_id.model_id.mileage', | ||||
|  |                            help="Helps to set mileage of vehicle") | ||||
|  |     sale = fields.Integer(string="sale", compute='_compute_sale', | ||||
|  |                           help="Helps you to store count of sale") | ||||
|  |     invoice = fields.Integer(string="Invoice", compute='_compute_invoice', | ||||
|  |                              help="Helps you to store count of invoice") | ||||
|  |     invoice_ids = fields.Many2many('account.move', string='Invoices', | ||||
|  |                                    help="Used to store ids of invoices") | ||||
|  |     customer_id = fields.Many2one('res.partner', string="Customer", | ||||
|  |                                   help="Helps you to choose customer") | ||||
|  |     sale_id = fields.Many2one('sale.order', string='sale', readonly=True, | ||||
|  |                               help="Stores id of sale order") | ||||
|  |     refund_id = fields.Many2one('account.move', string='Refund', readonly=True, | ||||
|  |                                 help="Stores id of invoice which belongs " | ||||
|  |                                      "to refund") | ||||
|  |     insurance_type_id = fields.Many2one('vehicle.insurance', | ||||
|  |                                         domain= | ||||
|  |                                         "[('vehicle_id', '=',vehicle_id)]") | ||||
|  |     refund = fields.Integer(compute='_compute_refund', | ||||
|  |                             help="Helps you to store count of refund") | ||||
|  |     seating_capacity = fields.Integer(string='Seating Capacity', | ||||
|  |                                       help="Seating capacity of vehicle can " | ||||
|  |                                            "be set") | ||||
|  |     invisible_sub = fields.Boolean(string="Approve Subscription", | ||||
|  |                                    help="As subscription request get approved " | ||||
|  |                                         "this field will be enabled") | ||||
|  | 
 | ||||
|  |     def _get_vehicle_domain(self): | ||||
|  |         """This method retrieves the vehicles that meet the following | ||||
|  |         criteria""" | ||||
|  |         insurance_ids = self.env['vehicle.insurance'].search([]).mapped( | ||||
|  |             'vehicle_id') | ||||
|  |         domain = [] | ||||
|  |         for record in insurance_ids: | ||||
|  |             state = record.log_services.mapped('state') | ||||
|  |             if 'done' in state and 'running' not in state and 'new' \ | ||||
|  |                     not in state and 'cancelled' not in state: | ||||
|  |                 if not self.search( | ||||
|  |                         [('vehicle_id', '=', record.id), | ||||
|  |                          ('state', '!=', 'subscribe')]): | ||||
|  |                     domain.append(record.id) | ||||
|  |         return domain | ||||
|  | 
 | ||||
|  |     @api.onchange('vehicle_id') | ||||
|  |     def _onchange_vehicle_id(self): | ||||
|  |         """Function used to fill the seating capacity""" | ||||
|  |         if self.vehicle_id: | ||||
|  |             self.seating_capacity = self.vehicle_id.model_id.seats | ||||
|  | 
 | ||||
|  |     @api.onchange('seating_capacity') | ||||
|  |     def _onchange_seating_capacity(self): | ||||
|  |         """As the seating capacity changes vehicles are shown """ | ||||
|  |         if self.seating_capacity != self.vehicle_id.model_id.seats: | ||||
|  |             self.vehicle_id = False | ||||
|  | 
 | ||||
|  |     @api.onchange('default_km') | ||||
|  |     def _onchange_default_km(self): | ||||
|  |         """Charge per km is set as onchange of default_km""" | ||||
|  |         if self.default_km <= self.vehicle_id.free_km: | ||||
|  |             self.charge_km = 0 | ||||
|  | 
 | ||||
|  |     @api.depends('vehicle_id', 'seating_capacity') | ||||
|  |     def _compute_vehicle_ids(self): | ||||
|  |         """Compute the vehicle_IDS based on the vehicle and seating capacity.""" | ||||
|  |         for rec in self: | ||||
|  |             if not rec.vehicle_ids: | ||||
|  |                 domain = rec._get_vehicle_domain() | ||||
|  |                 if rec.seating_capacity: | ||||
|  |                     model_id = self.env['fleet.vehicle'].search( | ||||
|  |                         [('state_id', '=', 'registered'), | ||||
|  |                          ('model_id.seats', '=', rec.seating_capacity), | ||||
|  |                          ('id', 'in', domain)]) | ||||
|  |                     for record in model_id: | ||||
|  |                         self.vehicle_ids = [(4, record.id)] | ||||
|  |                 else: | ||||
|  |                     model_id = self.env['fleet.vehicle'].search( | ||||
|  |                         [('id', 'in', domain)]) | ||||
|  |                     for record in model_id: | ||||
|  |                         self.vehicle_ids = [(4, record.id)] | ||||
|  | 
 | ||||
|  |     @api.depends('start_date', 'end_date') | ||||
|  |     def _compute_duration(self): | ||||
|  |         """Compute duration based on start and end date""" | ||||
|  |         for record in self: | ||||
|  |             if record.end_date: | ||||
|  |                 if record.end_date < record.start_date: | ||||
|  |                     raise ValidationError(_( | ||||
|  |                         "End date should be greater than start date.")) | ||||
|  |             if record.start_date and record.end_date: | ||||
|  |                 start = record.start_date.strftime("%Y-%m-%d") | ||||
|  |                 end = record.end_date.strftime("%Y-%m-%d") | ||||
|  |                 start_datetime = datetime.strptime(start, "%Y-%m-%d") | ||||
|  |                 end_datetime = datetime.strptime(end, "%Y-%m-%d") | ||||
|  |                 delta = end_datetime - start_datetime | ||||
|  |                 record.duration = delta.days | ||||
|  |             else: | ||||
|  |                 record.duration = 0 | ||||
|  | 
 | ||||
|  |     @api.depends('start_date', 'cancellation_date') | ||||
|  |     def _compute_cancel_duration(self): | ||||
|  |         """Compute duration based on cancellation date""" | ||||
|  |         for record in self: | ||||
|  |             if record.start_date and record.cancellation_date: | ||||
|  |                 start = record.start_date.strftime("%Y-%m-%d") | ||||
|  |                 end = record.cancellation_date.strftime("%Y-%m-%d") | ||||
|  |                 start_datetime = datetime.strptime(start, "%Y-%m-%d") | ||||
|  |                 end_datetime = datetime.strptime(end, "%Y-%m-%d") | ||||
|  |                 delta = end_datetime - start_datetime | ||||
|  |                 record.cancel_duration = delta.days | ||||
|  |             else: | ||||
|  |                 record.cancel_duration = 0 | ||||
|  | 
 | ||||
|  |     @api.depends('extra_km', 'charge_km', 'fuel_rate', 'fuel') | ||||
|  |     def _compute_extra_price(self): | ||||
|  |         """Compute extra charges based on criteria""" | ||||
|  |         for rec in self: | ||||
|  |             if rec.fuel == 'without_fuel': | ||||
|  |                 rec.extra_price = (rec.extra_km * rec.charge_km) | ||||
|  |             elif rec.mileage == 0: | ||||
|  |                 raise ValidationError(_("Mileage cannot be zero.")) | ||||
|  |             else: | ||||
|  |                 rec.extra_price = ((rec.extra_km / rec.mileage) * rec.fuel_rate) | ||||
|  | 
 | ||||
|  |     @api.depends('duration') | ||||
|  |     def _compute_price(self): | ||||
|  |         """Function used to compute price of vehicle""" | ||||
|  |         for rec in self: | ||||
|  |             rec.price = (rec.duration * rec.vehicle_id.subscription_price) \ | ||||
|  |                         + rec.insurance_type_id.insurance_amount | ||||
|  | 
 | ||||
|  |     @api.depends('cancel_duration') | ||||
|  |     def _compute_uptodate_price(self): | ||||
|  |         """Compute price as per the cancellation date""" | ||||
|  |         for rec in self: | ||||
|  |             rec.uptodate_price = ( | ||||
|  |                     (rec.sale_id.order_line.price_unit / rec.duration) * ( | ||||
|  |                         (rec.cancellation_date - rec.start_date).days)) | ||||
|  | 
 | ||||
|  |     def action_get_car_insurance(self): | ||||
|  |         """Get the action to view the car | ||||
|  |         insurance associated with the subscription.""" | ||||
|  |         self.ensure_one() | ||||
|  |         return { | ||||
|  |             'type': 'ir.actions.act_window', | ||||
|  |             'name': 'Insurance', | ||||
|  |             'view_mode': 'form', | ||||
|  |             'res_model': 'vehicle.insurance', | ||||
|  |             'res_id': self.insurance_type_id.id, | ||||
|  |             'context': [('create', '=', False)] | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     def action_get_sale(self): | ||||
|  |         """Get the action to view the sale | ||||
|  |         associated with the subscription.""" | ||||
|  |         return { | ||||
|  |             'type': 'ir.actions.act_window', | ||||
|  |             'name': 'Sale Order', | ||||
|  |             'view_mode': 'form', | ||||
|  |             'res_model': 'sale.order', | ||||
|  |             'res_id': self.sale_id.id, | ||||
|  |             'context': [('create', '=', False)] | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     def _compute_sale(self): | ||||
|  |         """Used to calculate the sale count""" | ||||
|  |         for record in self: | ||||
|  |             record.sale = self.env['sale.order'].search_count( | ||||
|  |                 [('id', '=', self.sale_id.id)]) | ||||
|  | 
 | ||||
|  |     def action_get_refund(self): | ||||
|  |         """Get the action to view the refund | ||||
|  |         associated with the subscription.""" | ||||
|  |         return { | ||||
|  |             'type': 'ir.actions.act_window', | ||||
|  |             'name': 'Refund', | ||||
|  |             'view_mode': 'form', | ||||
|  |             'res_id': self.refund_id.id, | ||||
|  |             'res_model': 'account.move', | ||||
|  |             'context': [('create', '=', False)] | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     def _compute_refund(self): | ||||
|  |         """Used to calculate count of refund""" | ||||
|  |         for record in self: | ||||
|  |             record.refund = self.env['account.move'].search_count( | ||||
|  |                 [('id', '=', self.refund_id.id)]) | ||||
|  | 
 | ||||
|  |     def action_get_invoice(self): | ||||
|  |         """Get the action to view the invoice | ||||
|  |         associated with the subscription.""" | ||||
|  |         invoice_ids = self.invoice_ids + self.sale_id.invoice_ids | ||||
|  |         return { | ||||
|  |             'type': 'ir.actions.act_window', | ||||
|  |             'name': 'Sale Order', | ||||
|  |             'view_mode': 'tree,form', | ||||
|  |             'res_model': 'account.move', | ||||
|  |             'domain': [('id', 'in', invoice_ids.ids)], | ||||
|  |             'context': [('create', '=', False)] | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     def _compute_invoice(self): | ||||
|  |         """Used to calculate invoice count""" | ||||
|  |         for record in self: | ||||
|  |             invoice_ids = record.invoice_ids + record.sale_id.invoice_ids | ||||
|  |             record.invoice = self.env['account.move'].search_count( | ||||
|  |                 [('id', 'in', invoice_ids.ids)]) | ||||
|  | 
 | ||||
|  |     def action_invoice(self): | ||||
|  |         """Used to generate invoice on clicking the button""" | ||||
|  |         self.write({'state': 'subscribed'}) | ||||
|  |         product_template_id = self.env.ref( | ||||
|  |             'vehicle_subscription.product_template_vehicle_subscription_form').id | ||||
|  |         product_id = self.env['product.product'].search( | ||||
|  |             [('product_tmpl_id', '=', product_template_id)]) | ||||
|  |         sale_order_id = self.env['sale.order'].create({ | ||||
|  |             'partner_id': self.customer_id.id, | ||||
|  |             'order_line': [(0, 0, { | ||||
|  |                 'product_id': product_id.id, | ||||
|  |                 'name': self.vehicle_id.name, | ||||
|  |                 'price_unit': self.price + self.extra_price, | ||||
|  |             })] | ||||
|  |         }) | ||||
|  |         self.sale_id = sale_order_id | ||||
|  | 
 | ||||
|  |     def action_request(self): | ||||
|  |         """Request for change subscription is generated """ | ||||
|  |         return { | ||||
|  |             'type': 'ir.actions.act_window', | ||||
|  |             'view_mode': 'form', | ||||
|  |             'res_model': 'change.subscription', | ||||
|  |             'target': 'new', | ||||
|  |         } | ||||
|  | 
 | ||||
|  |     def action_cancel(self): | ||||
|  |         """Proceed with cancellation of subscription""" | ||||
|  |         product_template_id = self.env.ref( | ||||
|  |             'vehicle_subscription.product_template_vehicle_subscription_form').id | ||||
|  |         product_id = self.env['product.product'].search( | ||||
|  |             [('product_tmpl_id', '=', product_template_id)]) | ||||
|  |         invoice = self.env['account.move'].search( | ||||
|  |             [('id', 'in', self.invoice_ids.ids), | ||||
|  |              ('payment_state', 'in', ['paid', 'partial'])]).mapped( | ||||
|  |             'amount_untaxed_signed') | ||||
|  |         invoiced_amount = sum(invoice) | ||||
|  |         total_price = self.uptodate_price | ||||
|  |         if invoiced_amount == total_price: | ||||
|  |             self.write({'state': 'cancel'}) | ||||
|  |             self.sale_id.action_done() | ||||
|  |         elif invoiced_amount > total_price: | ||||
|  |             self.write({'state': 'cancel'}) | ||||
|  |             self.refund_id = self.env['account.move'].create({ | ||||
|  |                 'move_type': 'out_refund', | ||||
|  |                 'invoice_date': fields.Date.today(), | ||||
|  |                 'partner_id': self.customer_id.id, | ||||
|  |                 'invoice_line_ids': [(0, 0, { | ||||
|  |                     'product_id': product_id.id, | ||||
|  |                     'name': self.vehicle_id.name, | ||||
|  |                     'price_unit': self.uptodate_price + self.extra_price, | ||||
|  |                 })] | ||||
|  |             }) | ||||
|  |         else: | ||||
|  |             return { | ||||
|  |                 'type': 'ir.actions.client', | ||||
|  |                 'tag': 'display_notification', | ||||
|  |                 'params': { | ||||
|  |                     'title': _('Warning'), | ||||
|  |                     'message': 'you need to pay amount till date inorder to ' | ||||
|  |                                'cancel subscription', | ||||
|  |                     'sticky': True, | ||||
|  |                 } | ||||
|  |             } | ||||
|  | 
 | ||||
|  |     @api.onchange('end_date') | ||||
|  |     def _onchange_end_date(self): | ||||
|  |         """Check expiry for subscription""" | ||||
|  |         if self.end_date: | ||||
|  |             if self.end_date < fields.Date.today(): | ||||
|  |                 self.write({'state': 'expired'}) | ||||
|  |                 self.sale_id.action_done() | ||||
| @ -0,0 +1,69 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 datetime import datetime | ||||
|  | from odoo import api, fields, models | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class FleetVehicle(models.Model): | ||||
|  |     """Inherited model to add fields and functions""" | ||||
|  |     _inherit = 'fleet.vehicle' | ||||
|  | 
 | ||||
|  |     free_km = fields.Float(string="Free KM", required=True, default=1500, | ||||
|  |                            help="Set free km for each vehicle") | ||||
|  |     subscription_price = fields.Float(string="Subscription price per day", | ||||
|  |                                       help='Price of vehicle per day', | ||||
|  |                                       required=True, default=12) | ||||
|  |     states_id = fields.Many2one("res.country.state", string='State', | ||||
|  |                                 help="Help you choose the state") | ||||
|  |     countries_id = fields.Many2one('res.country', string='Country', | ||||
|  |                                    help="help you to choose country") | ||||
|  |     insurance = fields.Char(string="Insurance", | ||||
|  |                             help="Helps you to set Insurance") | ||||
|  |     start = fields.Date(string="Start Date", | ||||
|  |                         help="Helps you to choose start date") | ||||
|  |     end = fields.Date(string="End Date", help="Helps you to choose end date") | ||||
|  |     duration = fields.Integer(string="Duration", compute='_compute_duration') | ||||
|  |     fuel = fields.Selection(selection=[('with_fuel', 'With Fuel'), | ||||
|  |                                        ('without_fuel', 'Without Fuel')], | ||||
|  |                             string="Fuel Choice", default='without_fuel', | ||||
|  |                             help="Help you to choose the type of fuel") | ||||
|  |     fuel_rate = fields.Integer(String="Rate", default=300, help="Rate of fuel") | ||||
|  |     charge_km = fields.Integer(string="Charge in km", default=12, | ||||
|  |                                help="Rate per kilometer") | ||||
|  |     extra_km = fields.Float(string="Extra KMS", default=1500, | ||||
|  |                             help="As per customer he/she can choose extra km") | ||||
|  |     mileage = fields.Float(related='model_id.mileage', string='Mileage', | ||||
|  |                            help="Helps to set mileage of vehicle") | ||||
|  | 
 | ||||
|  |     @api.depends('start', 'end') | ||||
|  |     def _compute_duration(self): | ||||
|  |         """Compute duration of days based on start and end date""" | ||||
|  |         for record in self: | ||||
|  |             if record.start and record.end: | ||||
|  |                 start = record.start.strftime("%Y-%m-%d") | ||||
|  |                 end = record.end.strftime("%Y-%m-%d") | ||||
|  |                 start_datetime = datetime.strptime(start, "%Y-%m-%d") | ||||
|  |                 end_datetime = datetime.strptime(end, "%Y-%m-%d") | ||||
|  |                 delta = end_datetime - start_datetime | ||||
|  |                 record.duration = delta.days | ||||
|  |             else: | ||||
|  |                 record.duration = 0 | ||||
| @ -0,0 +1,34 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 FleetVehicleModel(models.Model): | ||||
|  |     """Inherited fleet.vehicle.model to add fields""" | ||||
|  |     _inherit = 'fleet.vehicle.model' | ||||
|  | 
 | ||||
|  |     mileage = fields.Float(string="Mileage", required=True, | ||||
|  |                            default=12, help="Helps you to set mileage for " | ||||
|  |                                             "vehicle") | ||||
|  |     seats = fields.Integer(string='Seats Number', required=True, | ||||
|  |                            default=4, helps="Helps you to choose seating " | ||||
|  |                                             "capacity") | ||||
| @ -0,0 +1,46 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 InsuranceType(models.Model): | ||||
|  |     """New model insurance type to add fields""" | ||||
|  |     _name = "insurance.type" | ||||
|  |     _description = "Insurance type" | ||||
|  |     _inherit = "mail.thread" | ||||
|  | 
 | ||||
|  |     name = fields.Char(string="Insurance Name", | ||||
|  |                        help="This field is used to set name for insurance") | ||||
|  |     coverage_ids = fields.One2many('insurance.coverage', 'coverage_id', | ||||
|  |                                    string="Coverage", | ||||
|  |                                    help="Helps you to give details of coverage") | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class InsuranceCoverageType(models.Model): | ||||
|  |     """One2many field for insurance type""" | ||||
|  |     _name = 'insurance.coverage' | ||||
|  |     _description = "Insurance Coverage" | ||||
|  | 
 | ||||
|  |     description = fields.Char(string="Description", help="Detail of coverage") | ||||
|  |     coverage_price = fields.Float(string="Price", help="Rate of insurance") | ||||
|  |     coverage_id = fields.Many2one('insurance.type', | ||||
|  |                                   help="Can choose insurance type") | ||||
| @ -0,0 +1,92 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 api, fields, models | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class SubscriptionRequest(models.Model): | ||||
|  |     """New model subscription.request""" | ||||
|  |     _name = "subscription.request" | ||||
|  |     _description = "Subscription Request" | ||||
|  |     _inherit = "mail.thread" | ||||
|  |     _rec_name = "new_vehicle_id" | ||||
|  | 
 | ||||
|  |     customer_id = fields.Many2one('res.partner', string="Customer", | ||||
|  |                                   help="Choose the customer for subscription " | ||||
|  |                                        "request") | ||||
|  |     sale_id = fields.Many2one('sale.order', string='sale', readonly=True, | ||||
|  |                               help="Helps you to store sale order") | ||||
|  |     refund_id = fields.Many2one('account.move', string='Refund', readonly=True) | ||||
|  |     current_vehicle_id = fields.Many2one('fleet.vehicle', | ||||
|  |                                          string="Current Vehicle", | ||||
|  |                                          help="Currently using vehicle of " | ||||
|  |                                               "customer will be set") | ||||
|  |     new_vehicle_id = fields.Many2one('fleet.vehicle', string="New Vehicle" | ||||
|  |                                      , domain="[('id', 'in', vehicle_ids)]", | ||||
|  |                                      help="Can choose different vehicle " | ||||
|  |                                           "with same model") | ||||
|  |     vehicle_ids = fields.Many2many('fleet.vehicle', | ||||
|  |                                    compute='_compute_vehicle_ids', | ||||
|  |                                    help="Compute and can choose vehicle with " | ||||
|  |                                         "satisfying domain ") | ||||
|  |     reason_to_change = fields.Char(string="Reason", | ||||
|  |                                    help="Reason for changing vehicle") | ||||
|  |     state = fields.Selection( | ||||
|  |         selection=[('to_approve', 'To Approve'), | ||||
|  |                    ('approved', 'Approved'), | ||||
|  |                    ], string='State', default='to_approve', | ||||
|  |         help="States of subscription") | ||||
|  | 
 | ||||
|  |     @api.depends('current_vehicle_id') | ||||
|  |     def _compute_vehicle_ids(self): | ||||
|  |         """This method searches for vehicles with the same model and brand | ||||
|  |         as the current vehicle, excluding the current vehicle itself. | ||||
|  |         The vehicle IDs are updated accordingly, and the state | ||||
|  |         is set to 'to_approve'.""" | ||||
|  |         self.vehicle_ids = False | ||||
|  |         model_id = self.env['fleet.vehicle'].search( | ||||
|  |             [('model_id', '=', self.current_vehicle_id.model_id.id), | ||||
|  |              ('model_id.brand_id', '=', | ||||
|  |               self.current_vehicle_id.model_id.brand_id.id), | ||||
|  |              ('id', '!=', self.current_vehicle_id.id)]) | ||||
|  |         for record in model_id: | ||||
|  |             self.vehicle_ids = [(4, record.id)] | ||||
|  |         self.write({'state': 'to_approve'}) | ||||
|  | 
 | ||||
|  |     def action_approve(self): | ||||
|  |         """ Process the approval of the subscription request.""" | ||||
|  |         subscription = self.env['fleet.subscription'].search( | ||||
|  |             [('vehicle_id', '=', self.current_vehicle_id.id), | ||||
|  |              ('state', '=', 'subscribed')]) | ||||
|  |         subscription.update({ | ||||
|  |             'vehicle_id': self.new_vehicle_id, | ||||
|  |             'invisible_sub': True, | ||||
|  |         }) | ||||
|  |         self.write({'state': 'approved'}) | ||||
|  |         sale_order = subscription.sale_id | ||||
|  |         if sale_order.order_line: | ||||
|  |             sale_order.order_line[0].name = self.new_vehicle_id.name | ||||
|  |         invoice_ids = subscription.invoice_ids | ||||
|  |         for rec in invoice_ids: | ||||
|  |             if rec.invoice_line_ids: | ||||
|  |                 rec.invoice_line_ids[0].name = self.new_vehicle_id.name | ||||
|  |         subscription.write({'sale_id': sale_order.id}) | ||||
|  |         subscription.write({'invoice_ids': invoice_ids.ids}) | ||||
| @ -0,0 +1,47 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 VehicleInsurance(models.Model): | ||||
|  |     """New model vehicle .insurance""" | ||||
|  |     _name = "vehicle.insurance" | ||||
|  |     _description = "Vehicle Insurance" | ||||
|  |     _inherit = "mail.thread" | ||||
|  |     _rec_name = "insurance_type_id" | ||||
|  | 
 | ||||
|  |     vehicle_id = fields.Many2one('fleet.vehicle', string="Vehicle", | ||||
|  |                                  help="Help you to choose vehicle") | ||||
|  |     start_date = fields.Date(string="Start Date", help="Insurance start date") | ||||
|  |     end_date = fields.Date(string="End Date", help="Insurance end date") | ||||
|  |     insurance_type_id = fields.Many2one('insurance.type', | ||||
|  |                                         string='Insurance Type', | ||||
|  |                                         help="Choose insurance type") | ||||
|  |     insurance_amount = fields.Float(string="Amount", | ||||
|  |                                     compute="_compute_insurance_amount", | ||||
|  |                                     help="Calculate insurance amount") | ||||
|  | 
 | ||||
|  |     def _compute_insurance_amount(self): | ||||
|  |         """Function used to compute insurance amount""" | ||||
|  |         for rec in self: | ||||
|  |             rec.insurance_amount = sum(rec.insurance_type_id.coverage_ids. | ||||
|  |                                        mapped('coverage_price')) | ||||
| 
 | 
| @ -0,0 +1,17 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |        <!--User access levels for Fleet module--> | ||||
|  |         <record  id="module_vehicle_subscription" model="ir.module.category"> | ||||
|  |             <field name="name">Vehicle Subscription</field> | ||||
|  |             <field name="description">User access levels for Fleet module</field> | ||||
|  |             <field name="sequence">10</field> | ||||
|  |         </record> | ||||
|  |         <record id="vehicle_subscription_group_user" model="res.groups"> | ||||
|  |             <field name="name">User</field> | ||||
|  |             <field name="category_id" ref="module_vehicle_subscription"/> | ||||
|  |         </record> | ||||
|  |         <record id="vehicle_subscription_group_manager" model="res.groups"> | ||||
|  |             <field name="name">Manager</field> | ||||
|  |             <field name="category_id" ref="module_vehicle_subscription"/> | ||||
|  |         </record> | ||||
|  | </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: 322 B | 
| After Width: | Height: | Size: 84 KiB | 
| After Width: | Height: | Size: 81 KiB | 
| After Width: | Height: | Size: 85 KiB | 
| After Width: | Height: | Size: 85 KiB | 
| After Width: | Height: | Size: 95 KiB | 
| After Width: | Height: | Size: 80 KiB | 
| After Width: | Height: | Size: 354 KiB | 
| After Width: | Height: | Size: 1.2 MiB | 
| After Width: | Height: | Size: 98 KiB | 
| After Width: | Height: | Size: 51 KiB | 
| After Width: | Height: | Size: 158 KiB | 
| After Width: | Height: | Size: 203 KiB | 
| After Width: | Height: | Size: 201 KiB | 
| After Width: | Height: | Size: 163 KiB | 
| After Width: | Height: | Size: 116 KiB | 
| After Width: | Height: | Size: 210 KiB | 
| After Width: | Height: | Size: 101 KiB | 
| After Width: | Height: | Size: 175 KiB | 
| After Width: | Height: | Size: 90 KiB | 
| After Width: | Height: | Size: 73 KiB | 
| After Width: | Height: | Size: 16 KiB | 
| @ -0,0 +1,631 @@ | |||||
|  | <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;"> | ||||
|  |                     Vehicle Subscription Management</h1> | ||||
|  |                 <p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">Vehicle Subscription Management From Website</p> | ||||
|  |                 <!-- END OF APP HERO --> | ||||
|  |                 <img src="assets/screenshots/hero.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 Subscribe,Cancel and Change subscription through website as well as backend. | ||||
|  |     </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;">Subscription of vehicle</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;">Cancellation of subscription</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;">Option to switch subscription</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;">Payment option Monthly and Full Payment from website</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;">Down Payment </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;">Option to choose vehicle based on Location</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;">Can decide Insurance type</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;">Vehicle Subscription | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Go to Website -> | ||||
|  |                 Subscription Form -> | ||||
|  |                 Choose Location , Insurance and duration of subscription.</p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_01.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;">Choose Vehicle | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Book vehicle from | ||||
|  |                 listed vehicle user can change default km choose fuel type ,choose payment type. </p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_02.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;">Subscription Order | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Go to Fleet | ||||
|  |                 -> Under Fleet Menu ->In Subscription submenu -> Subscription Order get created </p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_04.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;">Subscription order in | ||||
|  |                 Portal view. | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Go to My Account -> | ||||
|  |                 Subscription Order -> User can see their invoices so that they can pay change and cancel subscription | ||||
|  |                 from invoice</p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_05.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;">Cancel subscription | ||||
|  |             </h3> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_06.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;">Cancellation form | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Specify the Reason </p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_07.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;">Cancel Request | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">By submitting the | ||||
|  |                 cancellation form cancel request will be generated in backend.</p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_08.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;">Switch Subscription | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">From portal , user have | ||||
|  |                 option to Change Subscription.</p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_09.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;">Change Subscription | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">User need to choose | ||||
|  |                 whether he or she needs to change for same model vehicle or different model and need to specify the | ||||
|  |                 reason.</p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_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;">Switch Subscription | ||||
|  |                 to new vehicle | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">If user chosen same | ||||
|  |                 model, then user will redirect to the different form where user can choose vehicle of same model .</p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_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;">Switch Request | ||||
|  |             </h3> | ||||
|  |             <p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Go to Fleet -> | ||||
|  |                 Configuration -> Change Subscription -> Request for switching subscription will be generated</p> | ||||
|  |             <img src="assets/screenshots/vehicle_subscription_12.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/dynamic_accounts_report/" target="_blank"> | ||||
|  |                             <div style="border-radius:10px"> | ||||
|  |                                 <img class="img img-responsive center-block" style="border-radius: 0px;" | ||||
|  |                                      src="assets/modules/1.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/pos_product_creation//" target="_blank"> | ||||
|  |                             <div style="border-radius:10px"> | ||||
|  |                                 <img class="img img-responsive center-block" style="border-radius: 0px;" | ||||
|  |                                      src="assets/modules/2.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/pos_mrp_order/#" 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 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/product_barcode/#overview" 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/hr_organizational_chart/" target="_blank"> | ||||
|  |                             <div style="border-radius:10px"> | ||||
|  |                                 <img class="img img-responsive center-block" style="border-radius: 0px;" | ||||
|  |                                      src="assets/modules/5.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/timesheets_by_employee/" target="_blank"> | ||||
|  |                             <div style="border-radius:10px"> | ||||
|  |                                 <img class="img img-responsive center-block" style="border-radius: 0px;" | ||||
|  |                                      src="assets/modules/6.png"> | ||||
|  |                             </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,31 @@ | |||||
|  | odoo.define('vehicle_subscription.subscription_change', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | const ajax = require('web.ajax'); | ||||
|  | publicWidget.registry.Change = publicWidget.Widget.extend({ | ||||
|  |     selector: '.change_sub_vehicle', | ||||
|  |     start: function() { | ||||
|  |             this._super.apply(this, arguments); | ||||
|  |             this._onChangeCustomer(); // Call the function initially
 | ||||
|  |         }, | ||||
|  |            //On the onchange function customer is passed to controller
 | ||||
|  |     _onChangeCustomer: async  function(ev){ | ||||
|  |            var self=this; | ||||
|  |            var customer_id = this.$('input[name="customer"]')[0].value | ||||
|  |            await ajax.jsonRpc('/online/choose/vehicle', "call", { | ||||
|  |                     'customer_id': customer_id, | ||||
|  |            }) | ||||
|  |            .then(function(result) { | ||||
|  |                 const select = self.$el.find('#vehicle_change')[0]; | ||||
|  |                 const options = Array.from(select.options); | ||||
|  |                     options.forEach((option) => { | ||||
|  |                         option.remove(); | ||||
|  |                     }); | ||||
|  |                     result.forEach((item) => { | ||||
|  |                         let newOption = new Option(item[1], item[0]); | ||||
|  |                         select.add(newOption, undefined); | ||||
|  |                     }); | ||||
|  |            }); | ||||
|  |    }, | ||||
|  | }) | ||||
|  | }) | ||||
| @ -0,0 +1,19 @@ | |||||
|  | odoo.define('vehicle_subscription.subscription_submit_request', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | const ajax = require('web.ajax'); | ||||
|  | //To getitem  to get vehicle.
 | ||||
|  | $(function() { | ||||
|  |                if (localStorage.getItem('current_vehicle')) { | ||||
|  |                   $('#current_vehicle').val(localStorage.getItem('current_vehicle')); | ||||
|  |               } | ||||
|  | }); | ||||
|  | publicWidget.registry.Request = publicWidget.Widget.extend({ | ||||
|  |     selector: '.submit_boolean_on', | ||||
|  |     start: function() { | ||||
|  |     var self = this;//setitem  to store the element.
 | ||||
|  |     var current_vehicle = self.$('#current_vehicle').val(); | ||||
|  |     localStorage.setItem('current_vehicle', current_vehicle); | ||||
|  |        } | ||||
|  | }) | ||||
|  | }) | ||||
| @ -0,0 +1,31 @@ | |||||
|  | odoo.define('vehicle_subscription.subscription_cancellation', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | const ajax = require('web.ajax'); | ||||
|  | publicWidget.registry.Cancellation = publicWidget.Widget.extend({ | ||||
|  |     selector: '.cancel_sub', | ||||
|  |       start: function() { | ||||
|  |             this._super.apply(this, arguments); | ||||
|  |             this._onChangeCustomer(); // Call the function initially
 | ||||
|  |         }, | ||||
|  |     //On the onchange function customer is passed to controller
 | ||||
|  |     _onChangeCustomer: async  function(ev){ | ||||
|  |            var self=this; | ||||
|  |            var customer_id = this.$('input[name="customer"]')[0].value | ||||
|  |            await ajax.jsonRpc('/online/choose/vehicle', "call", { | ||||
|  |                     'customer_id': customer_id, | ||||
|  |            }) | ||||
|  |             .then(function(result) { | ||||
|  |                 const select = self.$el.find('#vehicle_cancellation')[0]; | ||||
|  |                 const options = Array.from(select.options); | ||||
|  |                     options.forEach((option) => { | ||||
|  |                         option.remove(); | ||||
|  |                     }); | ||||
|  |                     result.forEach((item) => { | ||||
|  |                         let newOption = new Option(item[1], item[0]); | ||||
|  |                         select.add(newOption, undefined); | ||||
|  |                     }); | ||||
|  |             }); | ||||
|  |          } | ||||
|  | }) | ||||
|  | }) | ||||
| @ -0,0 +1,94 @@ | |||||
|  | odoo.define('vehicle_subscription.book', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | const ajax = require('web.ajax'); | ||||
|  | publicWidget.registry.book = publicWidget.Widget.extend({ | ||||
|  |     selector: '#book_my_vehicle', | ||||
|  |     events: { | ||||
|  |         'click .redirect_back_with_data':'_onClickBack', | ||||
|  |         'click .book_now':'_onClickBook', | ||||
|  |         'click #with_fuel':'_onClickWithFuel', | ||||
|  |         'click #without_fuel':'_onClickWithoutFuel', | ||||
|  |         'change #extra_km':'_onChangeExtraKm', | ||||
|  |         'click #full_subscription':'_onClickFullPayment', | ||||
|  |         'click #monthly_subscription':'_onClickMonthlyPayment', | ||||
|  |     }, | ||||
|  |    _onClickBook: async function(ev){ //Click function to book subscription
 | ||||
|  |         var checked=this.$('#checkbox_for_fuel')[0].checked | ||||
|  |         var invoice_checked=this.$('#checkbox_for_invoice_type')[0].checked | ||||
|  |         var customer_id = this.$('input[name="customer"]')[0].value | ||||
|  |         var km = this.$('#extra_km')[0].value | ||||
|  |         var vehicle_id = ev.currentTarget.firstChild.nextSibling.defaultValue | ||||
|  |         await ajax.jsonRpc('/online/subscription/book', "call", { | ||||
|  |                     'vehicle': vehicle_id, | ||||
|  |                     'customer':customer_id, | ||||
|  |                     'checked':checked, | ||||
|  |                     'invoice':invoice_checked, | ||||
|  |                     'extra_km':km, | ||||
|  |         }).then(function(result) { | ||||
|  |         window.location.href="/next/vehicle/" +result.subscription_id; | ||||
|  |     }); | ||||
|  |   }, | ||||
|  |           _onClickWithFuel: async  function(ev){ //Click function to set  price
 | ||||
|  |                 this.$('#checkbox_for_fuel')[0].checked = true | ||||
|  |                 var km = this.$('#extra_km')[0].value | ||||
|  |                 var table = this.$('#vehicle_booking_table')[0]; | ||||
|  |                 for (var i = 1, row; row = table.rows[i]; i++) { | ||||
|  |                      for (var j = 1, col; col = row.cells[j]; j++) { | ||||
|  |                          var current_price = row.cells[2].innerText | ||||
|  |                          var vehicle_id = row.cells[1].getAttribute('value') | ||||
|  |                         await  ajax.jsonRpc('/online/subscription/with/fuel', "call", { | ||||
|  |                                     'vehicle': vehicle_id, | ||||
|  |                                     'price':current_price, | ||||
|  |                                     'extra_km': km, | ||||
|  |                          }) | ||||
|  |                          .then(function(result) { | ||||
|  |                               row.cells[2].innerText = result | ||||
|  |                           }) | ||||
|  |                     } | ||||
|  |                     } | ||||
|  |           }, | ||||
|  |           _onClickWithoutFuel: async  function(ev){//Click function to set  price without fuel
 | ||||
|  |                 this.$('#checkbox_for_fuel')[0].checked = true | ||||
|  |                 var km = this.$('#extra_km')[0].value | ||||
|  |                 var table = this.$('#vehicle_booking_table')[0]; | ||||
|  |                 for (var i = 1, row; row = table.rows[i]; i++) { | ||||
|  |                      for (var j = 1, col; col = row.cells[j]; j++) { | ||||
|  |                          var current_price = row.cells[2].innerText | ||||
|  |                          var vehicle_id = row.cells[1].getAttribute('value') | ||||
|  |                         await  ajax.jsonRpc('/online/subscription/without/fuel', "call", { | ||||
|  |                                     'vehicle': vehicle_id, | ||||
|  |                                     'price':current_price, | ||||
|  |                                     'extra_km':km, | ||||
|  |                          }) | ||||
|  |                          .then(function(result) { | ||||
|  |                               row.cells[2].innerText = result | ||||
|  |                           }) | ||||
|  |                     } | ||||
|  |                 } | ||||
|  |          }, | ||||
|  |          _onChangeExtraKm: async function(ev){ //Change function to set price  using extra km
 | ||||
|  |                 var km = ev.currentTarget.value | ||||
|  |                 var table = this.$('#vehicle_booking_table')[0]; | ||||
|  |                  for (var i = 1, row; row = table.rows[i]; i++) { | ||||
|  |                      for (var j = 1, col; col = row.cells[j]; j++) { | ||||
|  |                          await  ajax.jsonRpc('/online/subscription/with/fuel', "call", { | ||||
|  |                                 'extra_km': km, | ||||
|  |                             }) | ||||
|  |                             .then(function(result){ | ||||
|  |                                 row.cells[1].innerText = result | ||||
|  |                             }) | ||||
|  |                      } | ||||
|  |                 } | ||||
|  |         }, | ||||
|  |         _onClickFullPayment:function(ev){//Click function
 | ||||
|  |             this.$('#checkbox_for_invoice_type')[0].checked = true | ||||
|  |         }, | ||||
|  |         _onClickMonthlyPayment:function(ev){//Click function
 | ||||
|  |            this.$('#checkbox_for_invoice_type')[0].checked = true | ||||
|  |         }, | ||||
|  |         _onClickBack:function(ev){//Click function for previous page
 | ||||
|  |             window.history.back(); | ||||
|  |         } | ||||
|  | }) | ||||
|  | }) | ||||
| @ -0,0 +1,78 @@ | |||||
|  | odoo.define('vehicle_subscription.form_page', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | publicWidget.registry.form_page = publicWidget.Widget.extend({ | ||||
|  |     selector: '#subscription_form_page', | ||||
|  |     events: { | ||||
|  |         'click .redirect_back_with_data':'_onClickBack', | ||||
|  |     }, | ||||
|  |         _onClickBack:function(ev){ //Previous page
 | ||||
|  |             window.history.back(); | ||||
|  |         } | ||||
|  | }) | ||||
|  | }) | ||||
|  | odoo.define('vehicle_subscription.missing_page', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | publicWidget.registry.missing_page = publicWidget.Widget.extend({ | ||||
|  |     selector: '#subscription_missing_page', | ||||
|  |     events: { | ||||
|  |         'click .redirect_back_with_data':'_onClickBack', | ||||
|  |     }, | ||||
|  |         _onClickBack:function(ev){ //Previous page
 | ||||
|  |             window.history.back(); | ||||
|  |         } | ||||
|  | }) | ||||
|  | }) | ||||
|  | odoo.define('vehicle_subscription.cancellation_page', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | publicWidget.registry.cancellation_page = publicWidget.Widget.extend({ | ||||
|  |     selector: '#subscription_cancellation_page', | ||||
|  |     events: { | ||||
|  |         'click .redirect_back_with_data':'_onClickBack', | ||||
|  |     }, | ||||
|  |         _onClickBack:function(ev){ //Previous page
 | ||||
|  |             window.history.back(); | ||||
|  |         } | ||||
|  | }) | ||||
|  | }) | ||||
|  | odoo.define('vehicle_subscription.boolean_false', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | publicWidget.registry.boolean_false = publicWidget.Widget.extend({ | ||||
|  |     selector: '#boolean_false', | ||||
|  |     events: { | ||||
|  |         'click .redirect_back_with_data':'_onClickBack', | ||||
|  |     }, | ||||
|  |         _onClickBack:function(ev){ //Previous page
 | ||||
|  |             window.history.back(); | ||||
|  |         } | ||||
|  | }) | ||||
|  | }) | ||||
|  | odoo.define('vehicle_subscription.boolean_true', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | publicWidget.registry.boolean_true = publicWidget.Widget.extend({ | ||||
|  |     selector: '#boolean_true', | ||||
|  |     events: { | ||||
|  |         'click .redirect_back_with_data':'_onClickBack', | ||||
|  |     }, | ||||
|  |         _onClickBack:function(ev){ //Previous page
 | ||||
|  |             window.history.back(); | ||||
|  |         } | ||||
|  | }) | ||||
|  | }) | ||||
|  | odoo.define('vehicle_subscription.change_subscription_on', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | publicWidget.registry.change_subscription_on = publicWidget.Widget.extend({ | ||||
|  |     selector: '#change_subscription_on', | ||||
|  |     events: { | ||||
|  |         'click .redirect_back_with_data':'_onClickBack', | ||||
|  |     }, | ||||
|  |         _onClickBack:function(ev){ //Previous page
 | ||||
|  |             window.history.back(); | ||||
|  |         } | ||||
|  | }) | ||||
|  | }) | ||||
| @ -0,0 +1,44 @@ | |||||
|  | odoo.define('vehicle_subscription.subscription', function (require) { | ||||
|  |     "use strict"; | ||||
|  | var publicWidget = require('web.public.widget'); | ||||
|  | const Dialog = require('web.Dialog'); | ||||
|  | const ajax = require('web.ajax'); | ||||
|  | publicWidget.registry.Location = publicWidget.Widget.extend({ | ||||
|  |     selector: '#whole_sub', | ||||
|  |     events: { | ||||
|  |         'click #location_id': '_onLocationClick', | ||||
|  |         'change #state_id':'_onStateChange', | ||||
|  |         'click #dismiss':'_onCloseClick', | ||||
|  |     }, | ||||
|  |      _onLocationClick: function (ev) { //function that opens modal
 | ||||
|  |             var location = this.$('#location_temp')[0]; | ||||
|  |             location.style.display='block'; | ||||
|  |      }, | ||||
|  |     _onStateChange:function(ev){ // On the change of state ,city gets changed
 | ||||
|  |            var self=this; | ||||
|  |            var state_id = ev.currentTarget.value | ||||
|  |            ajax.jsonRpc('/online/subscription/city', "call", { | ||||
|  |                     'state': state_id, | ||||
|  |            }) | ||||
|  |             .then(function(result) { | ||||
|  |                 const select = self.$el.find('#city_id')[0]; | ||||
|  |                 const options = Array.from(select.options); | ||||
|  |                     options.forEach((option) => { | ||||
|  |                         option.remove(); | ||||
|  |                     }); | ||||
|  |                     result.forEach((item) => { | ||||
|  |                      let newOption = new Option(item, item); | ||||
|  |                         select.add(newOption, undefined); | ||||
|  |                     }); | ||||
|  |             }); | ||||
|  |          }, | ||||
|  |       // Click function of close button state and city is appended in location field.
 | ||||
|  |       _onCloseClick: function(ev){ | ||||
|  |            var location = this.$('#location_temp')[0]; | ||||
|  |            var city=this.$('#city_id')[0].value | ||||
|  |            var state=this.$("#state_id option:selected").data('state-name'); | ||||
|  |            this.$('#location_id')[0].value = state +','+ city | ||||
|  |            location.style.display='none'; | ||||
|  |       }, | ||||
|  |     }) | ||||
|  | }) | ||||
| @ -0,0 +1,14 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Used to add field in account.move--> | ||||
|  |     <record id="view_move_form" model="ir.ui.view"> | ||||
|  |         <field name="name">account.move.view.form.inherited.vehicle.subscription</field> | ||||
|  |         <field name="model">account.move</field> | ||||
|  |         <field name="inherit_id" ref="account.view_move_form"/> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <xpath expr="//field[@name='company_id']" position="before"> | ||||
|  |                 <field name="is_subscription" invisible="1"/> | ||||
|  |             </xpath> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,46 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Action of cancellation request--> | ||||
|  |     <record id="cancellation_request_action" model="ir.actions.act_window"> | ||||
|  |         <field name="name">Cancellation Request</field> | ||||
|  |         <field name="res_model">cancellation.request</field> | ||||
|  |         <field name="view_mode">tree,form</field> | ||||
|  |     </record> | ||||
|  | <!--    Form view of the cancellation request--> | ||||
|  |     <record id="cancellation_request_view_form" model="ir.ui.view"> | ||||
|  |         <field name="name">cancellation.request.view.form</field> | ||||
|  |         <field name="model">cancellation.request</field> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <form string="Channel"> | ||||
|  |                 <header> | ||||
|  |                     <field name="state" widget="statusbar"/> | ||||
|  |                     <button name="action_request" class="oe_highlight" | ||||
|  |                             states="draft" string="Request" | ||||
|  |                             type="object"/> | ||||
|  |                     <button name="action_approve" class="oe_highlight" | ||||
|  |                             states="to_approve" string="Approve" | ||||
|  |                             type="object" | ||||
|  |                             groups="vehicle_subscription.vehicle_subscription_group_manager"/> | ||||
|  |                 </header> | ||||
|  |                 <sheet> | ||||
|  |                     <group> | ||||
|  |                         <field name="customer_id"/> | ||||
|  |                         <field name="vehicle_id"/> | ||||
|  |                         <field name="date"/> | ||||
|  |                         <field name="reason"/> | ||||
|  |                     </group> | ||||
|  |                 </sheet> | ||||
|  |                 <div class="oe_chatter"> | ||||
|  |                     <field name="message_follower_ids"/> | ||||
|  |                     <field name="message_ids"/> | ||||
|  |                 </div> | ||||
|  |             </form> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!--Menu item of cancellation--> | ||||
|  |     <menuitem id="cancellation_request_menu_action" | ||||
|  |               name="Cancellation Request" | ||||
|  |               parent="fleet.fleet_configuration" | ||||
|  |               action="cancellation_request_action" | ||||
|  |               sequence="7"/> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,309 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Template for change subscription--> | ||||
|  |     <template id="subscription_change_form" name="Vehicle Form"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <div id="wrap" class="oe_structure oe_empty change_sub_vehicle"> | ||||
|  |                 <section class="s_website_form" id="change_my_vehicle" | ||||
|  |                          data-vcss="001" data-snippet="s_website_form"> | ||||
|  |                     <div class="container"> | ||||
|  |                         <br/> | ||||
|  |                         <h1 style="text-align: center;">Change Subscription | ||||
|  |                         </h1> | ||||
|  |                         <br/> | ||||
|  |                         <form action="/online/subscription/change/vehicle" | ||||
|  |                               method="post" enctype="multipart/form-data" | ||||
|  |                               class="o_mark_required" data-mark="*" | ||||
|  |                               data-model_name="" data-success-page="" | ||||
|  |                               style="width: 50%;margin: 0 auto;padding: 40px;background: white;border-radius: 6px;box-shadow: 0 3px 10px rgb(0 0 0 /0.2);margin-bottom:60px"> | ||||
|  |                             <input type="hidden" name="csrf_token" | ||||
|  |                                    t-att-value="request.csrf_token()"/> | ||||
|  |                             <div class="s_website_form_rows row s_col_no_bgcolor"> | ||||
|  |                                 <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                      data-type="char" data-name="Field"> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor" | ||||
|  |                                          style="display:none"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 200px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 Name | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <div class="col-sm"> | ||||
|  |                                                 <input class="form-control s_website_form_input" | ||||
|  |                                                        name='customer' | ||||
|  |                                                        type="text" | ||||
|  |                                                        t-att-value="customers"/> | ||||
|  |                                             </div> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                     <br/> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 200px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 Vehicle | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <select id="vehicle_change" | ||||
|  |                                                     type="text" | ||||
|  |                                                     class="form-control s_website_form_input" | ||||
|  |                                                     name="vehicle" | ||||
|  |                                                     required="1"> | ||||
|  |                                                 <option t-att-value=""/> | ||||
|  |                                                 <t t-foreach="vehicles or []" | ||||
|  |                                                    t-as="vehicle"> | ||||
|  |                                                     <option t-att-value="vehicle.id" | ||||
|  |                                                             required="1"> | ||||
|  |                                                         <t t-esc="vehicle.name"/> | ||||
|  |                                                     </option> | ||||
|  |                                                 </t> | ||||
|  |                                             </select> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                 <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                        style="width: 200px" for="studio1"> | ||||
|  |                                     <span class="s_website_form_label_content"> | ||||
|  |                                         Change vehicle to same model | ||||
|  |                                     </span> | ||||
|  |                                     <span class="s_website_form_mark">*</span> | ||||
|  |                                 </label> | ||||
|  |                                 <div class="col-sm"> | ||||
|  |                                     <input type="checkbox" | ||||
|  |                                            name="checkbox_model" | ||||
|  |                                            class="form-check-input" | ||||
|  |                                            id="checkbox_vehicle_change"/> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                 <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                        style="width: 200px" for="studio1"> | ||||
|  |                                     <span class="s_website_form_label_content"> | ||||
|  |                                         Reason for changing vehicle | ||||
|  |                                     </span> | ||||
|  |                                     <span class="s_website_form_mark">*</span> | ||||
|  |                                 </label> | ||||
|  |                                 <div class="col-sm"> | ||||
|  |                                     <input id="reason" type="text" | ||||
|  |                                            class="form-control s_website_form_input" | ||||
|  |                                            name="reason" required="1" | ||||
|  |                                            placeholder="Reason for change subscription"/> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <br/> | ||||
|  |                             <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                  data-name="change Button" | ||||
|  |                                  style="margin-bottom: 40px;"> | ||||
|  |                                 <div style="width: 200px;" | ||||
|  |                                      class="s_website_form_label"/> | ||||
|  |                                 <button type="submit" id="cancel" | ||||
|  |                                         class="btn btn-primary" | ||||
|  |                                         style="float: right;">Change | ||||
|  |                                 </button> | ||||
|  |                             </div> | ||||
|  |                         </form> | ||||
|  |                     </div> | ||||
|  |                 </section> | ||||
|  |             </div> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  |     <!--    < On clicking change button if boolean is  enabled >--> | ||||
|  |     <template id="subscription_change_button" name="Vehicle Form"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <div id="wrap" class="oe_structure oe_empty submit_boolean_on "> | ||||
|  |                 <section class="s_website_form" id="boolean_true" | ||||
|  |                          data-vcss="001" data-snippet="s_website_form"> | ||||
|  |                     <div class="btn btn-primary redirect_back_with_data" | ||||
|  |                          style="background:none; border:none;"> | ||||
|  |                         <span style="font-size:18px; color:#000; background-image:url('https://cdn-icons-png.flaticon.com/512/2985/2985162.png');width: 63px; | ||||
|  |                               height: 63px;display: block;background-size: 60%;margin-top: 23px;background-position: center;background-repeat: no-repeat;"/> | ||||
|  |                     </div> | ||||
|  |                     <div class="container"> | ||||
|  |                         <br/> | ||||
|  |                         <h1 style="text-align: center;">Choose New vehicle</h1> | ||||
|  |                         <br/> | ||||
|  |                         <form action="/online/subscription/change/button" | ||||
|  |                               method="post" enctype="multipart/form-data" | ||||
|  |                               class="o_mark_required" data-mark="*" | ||||
|  |                               data-model_name="" data-success-page="" | ||||
|  |                               style="width: 50%;margin: 0 auto;padding: 30px;background: white;box-shadow: 0 3px 10px rgb(0 0 0 /0.2);margin-bottom: 40px;"> | ||||
|  |                             <input type="hidden" name="csrf_token" | ||||
|  |                                    t-att-value="request.csrf_token()"/> | ||||
|  |                             <div class="s_website_form_rows row s_col_no_bgcolor" | ||||
|  |                                  style="display:none"> | ||||
|  |                                 <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                      data-type="char" data-name="Field"> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 200px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 Customer | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <input class="form-control s_website_form_input" | ||||
|  |                                                    name='customer' type="text" | ||||
|  |                                                    t-att-value="customer_name"/> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <div class="s_website_form_rows row s_col_no_bgcolor"> | ||||
|  |                                 <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                      data-type="char" data-name="Field"> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 200px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 Reason | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <input class="form-control s_website_form_input" | ||||
|  |                                                    name='reason' type="text" | ||||
|  |                                                    t-att-value="reason"/> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <div class="s_website_form_rows row s_col_no_bgcolor"> | ||||
|  |                                 <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                      data-type="char" data-name="Field"> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 200px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 Current Vehicle | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <input class="form-control s_website_form_input" | ||||
|  |                                                    name='vehicle' | ||||
|  |                                                    id="current_vehicle" | ||||
|  |                                                    type="text" | ||||
|  |                                                    t-att-value="vehicle_name"/> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <div class="s_website_form_rows row s_col_no_bgcolor"> | ||||
|  |                                 <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                      data-type="char" data-name="Field"> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 200px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 New Vehicle | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <select id="choose_vehicle" | ||||
|  |                                                     type="text" | ||||
|  |                                                     class="form-control s_website_form_input" | ||||
|  |                                                     name="new_vehicle" | ||||
|  |                                                     required="1"> | ||||
|  |                                                 <option t-att-value=""/> | ||||
|  |                                                 <t t-foreach="vehicles or []" | ||||
|  |                                                    t-as="vehicle"> | ||||
|  |                                                     <option t-att-value="vehicle.id" | ||||
|  |                                                             required="1"> | ||||
|  |                                                         <t t-esc="vehicle.name"/> | ||||
|  |                                                     </option> | ||||
|  |                                                 </t> | ||||
|  |                                             </select> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <br/> | ||||
|  |                             <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                  data-name="change Button" | ||||
|  |                                  style="margin-bottom: 40px;"> | ||||
|  |                                 <div style="width: 200px;" | ||||
|  |                                      class="s_website_form_label"/> | ||||
|  |                                 <button type="submit" id="submit_request" | ||||
|  |                                         class="btn btn-primary" | ||||
|  |                                         style="float: right;">Submit | ||||
|  |                                 </button> | ||||
|  |                             </div> | ||||
|  |                         </form> | ||||
|  |                     </div> | ||||
|  |                 </section> | ||||
|  |             </div> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  |     <!--< on clicking change button if boolean is not enabled >--> | ||||
|  |     <template id="subscription_change_boolean_false" name="Vehicle Form"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <div id="wrap" class="oe_structure oe_empty "> | ||||
|  |                 <section class="s_website_form" id="boolean_false" | ||||
|  |                          data-vcss="001" data-snippet="s_website_form" | ||||
|  |                          style="width: 80%;margin: 0 auto;"> | ||||
|  |                     <div class="btn btn-primary redirect_back_with_data" | ||||
|  |                          style="background:none; border:none;"> | ||||
|  |                         <span style="font-size:18px; color:#000; background-image:url('https://cdn-icons-png.flaticon.com/512/2985/2985162.png');width: 63px; | ||||
|  |                                     height: 63px;display: block;background-size: 60%;margin-top: 23px;background-position: center;background-repeat: no-repeat;"/> | ||||
|  |                     </div> | ||||
|  |                     <div class="container" | ||||
|  |                          style="align-items: center; display: flex;flex-direction: column;}"> | ||||
|  |                         <br/> | ||||
|  |                         <h5>You need to cancel subscription inorder to change | ||||
|  |                             to different model | ||||
|  |                         </h5> | ||||
|  |                         <br/> | ||||
|  |                         <form action="/online/proceed/cancellation" | ||||
|  |                               method="post" enctype="multipart/form-data" | ||||
|  |                               class="o_mark_required" data-mark="*" | ||||
|  |                               data-model_name="" data-success-page=""> | ||||
|  |                             <input type="hidden" name="csrf_token" | ||||
|  |                                    t-att-value="request.csrf_token()"/> | ||||
|  |                             <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                  data-name="change Button"> | ||||
|  |                                 <div class="s_website_form_label"/> | ||||
|  |                                 <button type="submit" id="proceed_cancel" | ||||
|  |                                         class="btn btn-primary">Proceed with | ||||
|  |                                     Cancellation | ||||
|  |                                 </button> | ||||
|  |                             </div> | ||||
|  |                         </form> | ||||
|  |                     </div> | ||||
|  |                 </section> | ||||
|  |             </div> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,114 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Action of fleet.subscription--> | ||||
|  |     <record id="fleet_subscription_action" model="ir.actions.act_window"> | ||||
|  |         <field name="name">Subscription</field> | ||||
|  |         <field name="res_model">fleet.subscription</field> | ||||
|  |         <field name="view_mode">tree,form</field> | ||||
|  |     </record> | ||||
|  | <!--    Form view of the fleet subscription--> | ||||
|  |     <record id="fleet_subscription_view_form" model="ir.ui.view"> | ||||
|  |         <field name="name">fleet.subscription.view.form</field> | ||||
|  |         <field name="model">fleet.subscription</field> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <form string="Channel"> | ||||
|  |                 <header> | ||||
|  |                     <button name="action_invoice" class="oe_highlight" | ||||
|  |                             state="draft" string="Create Order" | ||||
|  |                             type="object" | ||||
|  |                             attrs="{'invisible': [('state', '!=', 'draft')]}"/> | ||||
|  |                     <button name="action_request" class="oe_highlight" | ||||
|  |                             string="Change subscription" | ||||
|  |                             type="object" | ||||
|  |                             attrs="{'invisible': ['|',('state', '!=', 'subscribed'),'&',('invisible_sub','=',True),('state','=','subscribed')]}"/> | ||||
|  |                     <button name="action_cancel" class="oe_highlight" | ||||
|  |                             state="draft" string="Cancel subscription" | ||||
|  |                             type="object" | ||||
|  |                             attrs="{'invisible': [('state', '!=', 'subscribed')]}"/> | ||||
|  |                     <field name="state" widget="statusbar" | ||||
|  |                            options="{'clickable': '1'}"/> | ||||
|  |                 </header> | ||||
|  |                 <sheet> | ||||
|  |                     <div> | ||||
|  |                         <div name="button_box" position="inside"> | ||||
|  |                             <button class="oe_stat_button" type="object" | ||||
|  |                                     name="action_get_car_insurance" icon="fa-car" | ||||
|  |                                     attrs="{'invisible': [('insurance_type_id', '=', False)]}" | ||||
|  |                                     string="Insurance"> | ||||
|  |                             </button> | ||||
|  |                             <button class="oe_stat_button" type="object" | ||||
|  |                                     name="action_get_sale" | ||||
|  |                                     attrs="{ 'invisible': [('state', '=', 'draft')] }"> | ||||
|  |                                 <field string="Sale Order" name="sale" | ||||
|  |                                        widget="statinfo"/> | ||||
|  |                             </button> | ||||
|  |                             <button class="oe_stat_button" type="object" | ||||
|  |                                     name="action_get_invoice" | ||||
|  |                                     attrs="{ 'invisible': [('state', '=', 'draft')]}"> | ||||
|  |                                 <field string="Invoice" name="invoice" | ||||
|  |                                        widget="statinfo"/> | ||||
|  |                             </button> | ||||
|  |                             <button class="oe_stat_button" type="object" | ||||
|  |                                     name="action_get_refund" | ||||
|  |                                     attrs="{ 'invisible': [('refund', '=', 0), ('state', '!=', 'cancel')]}"> | ||||
|  |                                 <field string="Refund" name="refund" | ||||
|  |                                        widget="statinfo"/> | ||||
|  |                             </button> | ||||
|  |                         </div> | ||||
|  |                     </div> | ||||
|  |                     <group col="2"> | ||||
|  |                         <group> | ||||
|  |                             <field name="vehicle_id"/> | ||||
|  |                             <field name="vehicle_ids" widget="many2many_tags" | ||||
|  |                                    invisible="True"/> | ||||
|  |                             <field name="customer_id"/> | ||||
|  |                             <field name="insurance_type_id"/> | ||||
|  |                             <field name="seating_capacity"/> | ||||
|  |                             <field name="price"/> | ||||
|  |                             <field name="sale_id" invisible="True"/> | ||||
|  |                             <field name="extra_price"/> | ||||
|  |                             <field name="invoice_ids" widget="many2many_tags" | ||||
|  |                                    invisible="True"/> | ||||
|  |                             <field name="invisible_sub" invisible="True"/> | ||||
|  |                         </group> | ||||
|  |                         <group> | ||||
|  |                             <field name="start_date"/> | ||||
|  |                             <field name="end_date"/> | ||||
|  |                             <field name="cancellation_date" | ||||
|  |                                    attrs="{ 'invisible': [('state', '!=', 'cancel')] }"/> | ||||
|  |                             <field name="city"/> | ||||
|  |                             <field name="state_id"/> | ||||
|  |                             <field name="country_id"/> | ||||
|  |                         </group> | ||||
|  |                     </group> | ||||
|  |                     <notebook> | ||||
|  |                         <page string="Features"> | ||||
|  |                             <group string="Add Extra Features"> | ||||
|  |                                 <field name="fuel"/> | ||||
|  |                                 <field name="fuel_type" | ||||
|  |                                        attrs="{ 'invisible': [('fuel', '!=', 'with_fuel')] }"/> | ||||
|  |                                 <field name="mileage" | ||||
|  |                                        attrs="{ 'invisible': [('fuel', '!=', 'with_fuel')] }"/> | ||||
|  |                                 <field name="fuel_rate" | ||||
|  |                                        attrs="{ 'invisible': [('fuel', '!=', 'with_fuel')] }"/> | ||||
|  |                                 <field name="charge_km"/> | ||||
|  |                                 <field name="default_km"/> | ||||
|  |                                 <field name="extra_km"/> | ||||
|  |                             </group> | ||||
|  |                         </page> | ||||
|  |                     </notebook> | ||||
|  |                 </sheet> | ||||
|  |                 <div class="oe_chatter"> | ||||
|  |                     <field name="message_follower_ids"/> | ||||
|  |                     <field name="message_ids"/> | ||||
|  |                 </div> | ||||
|  |             </form> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!--Menu item of vehicle subscription--> | ||||
|  |     <menuitem id="vehicle_subscription_menu_action" | ||||
|  |               name="Subscription" | ||||
|  |               action="fleet_subscription_action" | ||||
|  |               parent="fleet.fleet_vehicles" | ||||
|  |     /> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,42 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Used to add field in fleet.vehicle.model--> | ||||
|  |     <record id="fleet_vehicle_model_view_form" model="ir.ui.view"> | ||||
|  |         <field name="name"> | ||||
|  |             fleet.vehicle.model.view.form.inherited.vehicle.subscription | ||||
|  |         </field> | ||||
|  |         <field name="model">fleet.vehicle.model</field> | ||||
|  |         <field name="inherit_id" ref="fleet.fleet_vehicle_model_view_form"/> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <xpath expr="//group/field[@name='default_fuel_type']" | ||||
|  |                    position="after"> | ||||
|  |                 <field name="mileage"/> | ||||
|  |             </xpath> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!--Add fields in fleet.vehicle--> | ||||
|  |     <record id="fleet_vehicle_view_form" model="ir.ui.view"> | ||||
|  |         <field name="name"> | ||||
|  |             fleet.vehicle.view.form.inherited.vehicle.subscription | ||||
|  |         </field> | ||||
|  |         <field name="model">fleet.vehicle</field> | ||||
|  |         <field name="inherit_id" ref="fleet.fleet_vehicle_view_form"/> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <xpath expr="//field[@name='horsepower_tax']" position='after'> | ||||
|  |                 <field name="free_km" invisible="1"/> | ||||
|  |                 <field name="subscription_price" invisible="1"/> | ||||
|  |                 <field name="states_id"/> | ||||
|  |                 <field name="countries_id"/> | ||||
|  |                 <field name="insurance" invisible="1"/> | ||||
|  |                 <field name="end" invisible="1"/> | ||||
|  |                 <field name="start" invisible="1"/> | ||||
|  |                 <field name="duration" invisible="1"/> | ||||
|  |                 <field name="fuel" invisible="1"/> | ||||
|  |                 <field name="fuel_rate" invisible="1"/> | ||||
|  |                 <field name="charge_km" invisible="1"/> | ||||
|  |                 <field name="extra_km" invisible="1"/> | ||||
|  |                 <field name="mileage" invisible="1"/> | ||||
|  |             </xpath> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,44 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Action of insurance.type--> | ||||
|  |     <record id="insurance_type_action" model="ir.actions.act_window"> | ||||
|  |         <field name="name">Insurance Type</field> | ||||
|  |         <field name="res_model">insurance.type</field> | ||||
|  |         <field name="view_mode">tree,form</field> | ||||
|  |     </record> | ||||
|  | <!--    Form view of the insurance type--> | ||||
|  |     <record id="insurance_type_view_form" model="ir.ui.view"> | ||||
|  |         <field name="name">insurance.type.view.form</field> | ||||
|  |         <field name="model">insurance.type</field> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <form string="Channel"> | ||||
|  |                 <sheet> | ||||
|  |                     <group> | ||||
|  |                         <field name="name"/> | ||||
|  |                     </group> | ||||
|  |                     <notebook> | ||||
|  |                         <page string="Coverages"> | ||||
|  |                             <field name="coverage_ids"> | ||||
|  |                                 <tree editable="bottom"> | ||||
|  |                                     <field name="description"/> | ||||
|  |                                     <field name="coverage_price"/> | ||||
|  |                                 </tree> | ||||
|  |                             </field> | ||||
|  |                         </page> | ||||
|  |                     </notebook> | ||||
|  |                 </sheet> | ||||
|  |                 <div class="oe_chatter"> | ||||
|  |                     <field name="message_follower_ids"/> | ||||
|  |                     <field name="message_ids"/> | ||||
|  |                 </div> | ||||
|  |             </form> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!--Menu item of insurance type--> | ||||
|  |     <menuitem id="insurance_type_menu_action" | ||||
|  |               name="Insurance Type" | ||||
|  |               parent="fleet.fleet_configuration" | ||||
|  |               action="insurance_type_action" | ||||
|  |               groups="vehicle_subscription.vehicle_subscription_group_manager" | ||||
|  |               sequence="8"/> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,254 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Template for Subscription--> | ||||
|  |     <template id="subscription_form" name="Subscription Form"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <div class="image_website_form" style="background-image: linear-gradient(to bottom, rgb(255 255 255 / 43%), rgb(0 0 0 / 50%)), url('https://cdn.pixabay.com/photo/2017/01/31/17/44/highway-2025863_960_720.jpg'); | ||||
|  |     background-size: cover;background-position: center;"> | ||||
|  |                 <div class="online_vehicle_main_form" | ||||
|  |                      style="max-width: 1320px; margin: 0px auto;width: 100%;"> | ||||
|  |                     <div id="wrap" class="oe_structure oe_empty" | ||||
|  |                          style="display: flex; justify-content: flex-end;align-items: center;"> | ||||
|  |                         <section class="s_website_form" data-vcss="001" | ||||
|  |                                  data-snippet="s_website_form" | ||||
|  |                                  style="padding: 50px 0px;"> | ||||
|  |                             <div class="container" | ||||
|  |                                  style="padding: 30px 50px;border-radius: 6px;background-color: #fffafa75;box-shadow: 0 3px 10px rgb(255 255 255 / 17%);"> | ||||
|  |                                 <br/> | ||||
|  |                                 <h1 style="text-align: center;">Subscription | ||||
|  |                                 </h1> | ||||
|  |                                 <br/> | ||||
|  |                                 <form action="/online/subscription/next" | ||||
|  |                                       method="post" | ||||
|  |                                       enctype="multipart/form-data" | ||||
|  |                                       class="o_mark_required" data-mark="*" | ||||
|  |                                       data-model_name="" data-success-page=""> | ||||
|  |                                     <input type="hidden" name="csrf_token" | ||||
|  |                                            t-att-value="request.csrf_token()"/> | ||||
|  |                                     <div class="s_website_form_rows row s_col_no_bgcolor" | ||||
|  |                                          id="whole_sub"> | ||||
|  |                                         <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                              data-type="char" | ||||
|  |                                              data-name="Field"> | ||||
|  |                                             <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                                  data-type="char" | ||||
|  |                                                  data-name="Field"> | ||||
|  |                                                 <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                                     <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                            style="width: 200px" | ||||
|  |                                                            for="studio1"> | ||||
|  |                                                         <span class="s_website_form_label_content"> | ||||
|  |                                                             Location | ||||
|  |                                                         </span> | ||||
|  |                                                         <span class="s_website_form_mark"> | ||||
|  |                                                             * | ||||
|  |                                                         </span> | ||||
|  |                                                     </label> | ||||
|  |                                                     <div id="location_temp" | ||||
|  |                                                          style="display:none"> | ||||
|  |                                                         <div class="location_modal_container" | ||||
|  |                                                              style="position: fixed;left: 0;height: 100%;width: 100%;background: rgba(0,0,0,0.2);top: 0;display: flex;align-items: center;justify-content: center;"> | ||||
|  |                                                             <div class="modal-dialog"> | ||||
|  |                                                                 <div class="modal-content" | ||||
|  |                                                                      style="width: 400px;"> | ||||
|  |                                                                     <div class="modal-header" | ||||
|  |                                                                          style="justify-content: center;"> | ||||
|  |                                                                         <h4 class="modal-title"> | ||||
|  |                                                                             Choose | ||||
|  |                                                                             Location | ||||
|  |                                                                         </h4> | ||||
|  |                                                                     </div> | ||||
|  |                                                                     <div class="modal-body"> | ||||
|  |                                                                         <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                                                             <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                                                    for="studio1"> | ||||
|  |                                                                                 <span class="s_website_form_label_content"> | ||||
|  |                                                                                     State | ||||
|  |                                                                                 </span> | ||||
|  |                                                                                 <span class="s_website_form_mark"> | ||||
|  |                                                                                     * | ||||
|  |                                                                                 </span> | ||||
|  |                                                                             </label> | ||||
|  |                                                                             <div class="col-sm"> | ||||
|  |                                                                                 <select id="state_id" | ||||
|  |                                                                                         type="text" | ||||
|  |                                                                                         class="form-control s_website_form_input" | ||||
|  |                                                                                         name="state" | ||||
|  |                                                                                         required="1"> | ||||
|  |                                                                                     <option t-att-value=""/> | ||||
|  |                                                                                     <t t-foreach="states or []" | ||||
|  |                                                                                        t-as="state"> | ||||
|  |                                                                                         <option t-att-value="state.id" | ||||
|  |                                                                                                 t-att-data-state-name="state.name"> | ||||
|  |                                                                                             <t t-esc="state.name"/> | ||||
|  |                                                                                         </option> | ||||
|  |                                                                                     </t> | ||||
|  |                                                                                 </select> | ||||
|  |                                                                             </div> | ||||
|  |                                                                         </div> | ||||
|  |                                                                         <br/> | ||||
|  |                                                                         <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                                                             <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                                                    for="studio1"> | ||||
|  |                                                                                 <span class="s_website_form_label_content"> | ||||
|  |                                                                                     City | ||||
|  |                                                                                 </span> | ||||
|  |                                                                                 <span class="s_website_form_mark"> | ||||
|  |                                                                                     * | ||||
|  |                                                                                 </span> | ||||
|  |                                                                             </label> | ||||
|  |                                                                             <div class="col-sm"> | ||||
|  |                                                                                 <select id="city_id" | ||||
|  |                                                                                         type="text" | ||||
|  |                                                                                         class="form-control s_website_form_input" | ||||
|  |                                                                                         name="city" | ||||
|  |                                                                                         required="1"> | ||||
|  |                                                                                     <option t-att-value=""/> | ||||
|  |                                                                                     <t t-foreach="cities or []" | ||||
|  |                                                                                        t-as="city"> | ||||
|  |                                                                                         <option t-att-value=""> | ||||
|  |                                                                                             <t t-esc="city"/> | ||||
|  |                                                                                         </option> | ||||
|  |                                                                                     </t> | ||||
|  |                                                                                 </select> | ||||
|  |                                                                             </div> | ||||
|  |                                                                         </div> | ||||
|  |                                                                         <br/> | ||||
|  |                                                                     </div> | ||||
|  |                                                                     <div class="modal-footer"> | ||||
|  |                                                                         <button type="button" | ||||
|  |                                                                                 style="background: black;color: white;" | ||||
|  |                                                                                 class="btn btn-default" | ||||
|  |                                                                                 id="dismiss" | ||||
|  |                                                                                 data-dismiss="modal"> | ||||
|  |                                                                             Close | ||||
|  |                                                                         </button> | ||||
|  |                                                                     </div> | ||||
|  |                                                                 </div> | ||||
|  |                                                             </div> | ||||
|  |                                                         </div> | ||||
|  |                                                     </div> | ||||
|  |                                                     <div class="col-sm" | ||||
|  |                                                          id="col-sm-location"> | ||||
|  |                                                         <input id="location_id" | ||||
|  |                                                                type="text" | ||||
|  |                                                                class="form-control s_website_form_input" | ||||
|  |                                                                data-toggle="modal" | ||||
|  |                                                                data-target="#location_temp"> | ||||
|  |                                                         </input> | ||||
|  |                                                     </div> | ||||
|  |                                                 </div> | ||||
|  |                                             </div> | ||||
|  |                                             <br/> | ||||
|  |                                             <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                                 <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                        style="width: 200px" | ||||
|  |                                                        for="studio1"> | ||||
|  |                                                     <span class="s_website_form_label_content"> | ||||
|  |                                                         Start Date | ||||
|  |                                                     </span> | ||||
|  |                                                     <span class="s_website_form_mark"> | ||||
|  |                                                         * | ||||
|  |                                                     </span> | ||||
|  |                                                 </label> | ||||
|  |                                                 <div class="col-sm"> | ||||
|  |                                                     <input id="start_date" | ||||
|  |                                                            type="Date" | ||||
|  |                                                            class="form-control s_website_form_input" | ||||
|  |                                                            name="start_date" | ||||
|  |                                                            required="1"/> | ||||
|  |                                                 </div> | ||||
|  |                                             </div> | ||||
|  |                                             <br/> | ||||
|  |                                             <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                                 <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                        style="width: 200px" | ||||
|  |                                                        for="studio1"> | ||||
|  |                                                     <span class="s_website_form_label_content"> | ||||
|  |                                                         End Date | ||||
|  |                                                     </span> | ||||
|  |                                                     <span class="s_website_form_mark"> | ||||
|  |                                                         * | ||||
|  |                                                     </span> | ||||
|  |                                                 </label> | ||||
|  |                                                 <div class="col-sm"> | ||||
|  |                                                     <input id="end_date" | ||||
|  |                                                            type="Date" | ||||
|  |                                                            class="form-control s_website_form_input" | ||||
|  |                                                            name="end_date" | ||||
|  |                                                            required="1"/> | ||||
|  |                                                 </div> | ||||
|  |                                             </div> | ||||
|  |                                             <br/> | ||||
|  |                                             <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                                 <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                        style="width: 200px" | ||||
|  |                                                        for="studio1"> | ||||
|  |                                                     <span class="s_website_form_label_content"> | ||||
|  |                                                         Insurance Type | ||||
|  |                                                     </span> | ||||
|  |                                                     <span class="s_website_form_mark"> | ||||
|  |                                                         * | ||||
|  |                                                     </span> | ||||
|  |                                                 </label> | ||||
|  |                                                 <div class="col-sm"> | ||||
|  |                                                     <select id="insurance_type" | ||||
|  |                                                             type="text" | ||||
|  |                                                             class="form-control s_website_form_input" | ||||
|  |                                                             name="insurance_type" | ||||
|  |                                                             required="1"> | ||||
|  |                                                         <option t-att-value=""/> | ||||
|  |                                                         <t t-foreach="insurance_type or []" | ||||
|  |                                                            t-as="type"> | ||||
|  |                                                             <option t-att-value="type.id"> | ||||
|  |                                                                 <t t-esc="type.name"/> | ||||
|  |                                                             </option> | ||||
|  |                                                         </t> | ||||
|  |                                                     </select> | ||||
|  |                                                 </div> | ||||
|  |                                             </div> | ||||
|  |                                             <br/> | ||||
|  |                                             <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                                 <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                        style="width: 200px" | ||||
|  |                                                        for="studio1"> | ||||
|  |                                                     <span class="s_website_form_label_content"> | ||||
|  |                                                         Seating Capacity | ||||
|  |                                                     </span> | ||||
|  |                                                     <span class="s_website_form_mark"> | ||||
|  |                                                         * | ||||
|  |                                                     </span> | ||||
|  |                                                 </label> | ||||
|  |                                                 <div class="col-sm"> | ||||
|  |                                                     <input id="seating_capacity" | ||||
|  |                                                            type="text" | ||||
|  |                                                            class="form-control s_website_form_input" | ||||
|  |                                                            name="seating_capacity" | ||||
|  |                                                            required="1"/> | ||||
|  |                                                 </div> | ||||
|  |                                             </div> | ||||
|  |                                             <br/> | ||||
|  |                                             <br/> | ||||
|  |                                             <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                                  data-name="Next Button"> | ||||
|  |                                                 <div style="width: 200px;" | ||||
|  |                                                      class="s_website_form_label"/> | ||||
|  |                                                 <button type="submit" id="next" | ||||
|  |                                                         class="btn btn-primary" | ||||
|  |                                                         style="width: 100%;"> | ||||
|  |                                                     Next | ||||
|  |                                                 </button> | ||||
|  |                                             </div> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                     <br/> | ||||
|  |                                     <br/> | ||||
|  |                                 </form> | ||||
|  |                             </div> | ||||
|  |                         </section> | ||||
|  |                     </div> | ||||
|  |                 </div> | ||||
|  |             </div> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,110 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Template for subscription cancellation--> | ||||
|  |     <template id="subscription_cancellation_form" name="Vehicle Form"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <div id="wrap" class="oe_structure oe_empty cancel_sub"> | ||||
|  |                 <section class="s_website_form" id="book_my_vehicle" | ||||
|  |                          data-vcss="001" data-snippet="s_website_form"> | ||||
|  |                     <div class="container"> | ||||
|  |                         <br/> | ||||
|  |                         <h1 style="text-align: center;">Choose Vehicle</h1> | ||||
|  |                         <br/> | ||||
|  |                         <form action="/online/cancellation/click" method="post" | ||||
|  |                               enctype="multipart/form-data" | ||||
|  |                               class="o_mark_required" data-mark="*" | ||||
|  |                               data-model_name="" data-success-page="" | ||||
|  |                               style="width: 50%;margin: 0 auto;padding: 30px 58px;border-radius: 6px;padding: 40px 60px;background: white;box-shadow: 0 3px 10px rgb(0 0 0 /0.2);"> | ||||
|  |                             <input type="hidden" name="csrf_token" | ||||
|  |                                    t-att-value="request.csrf_token()"/> | ||||
|  |                             <div class="s_website_form_rows row s_col_no_bgcolor"> | ||||
|  |                                 <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                      data-type="char" data-name="Field"> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 125px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 Name | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <div class="col-sm"> | ||||
|  |                                                 <input class="form-control s_website_form_input" | ||||
|  |                                                        id="customer_name" | ||||
|  |                                                        name='customer' | ||||
|  |                                                        type="text" | ||||
|  |                                                        t-att-value="customers"/> | ||||
|  |                                             </div> | ||||
|  |                                             <br/> | ||||
|  |                                             <br/> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                     <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                         <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                                style="width: 125px" | ||||
|  |                                                for="studio1"> | ||||
|  |                                             <span class="s_website_form_label_content"> | ||||
|  |                                                 Vehicle | ||||
|  |                                             </span> | ||||
|  |                                             <span class="s_website_form_mark"> | ||||
|  |                                                 * | ||||
|  |                                             </span> | ||||
|  |                                         </label> | ||||
|  |                                         <div class="col-sm"> | ||||
|  |                                             <select id="vehicle_cancellation" | ||||
|  |                                                     type="text" | ||||
|  |                                                     class="form-control s_website_form_input" | ||||
|  |                                                     name="vehicle" | ||||
|  |                                                     required="1"> | ||||
|  |                                                 <option t-att-value=""/> | ||||
|  |                                                 <t t-foreach="vehicles or []" | ||||
|  |                                                    t-as="vehicle"> | ||||
|  |                                                     <option t-att-value="vehicle.id" | ||||
|  |                                                             required="1"> | ||||
|  |                                                         <t t-esc="vehicle.vehicle_id.name"/> | ||||
|  |                                                     </option> | ||||
|  |                                                 </t> | ||||
|  |                                             </select> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <br/> | ||||
|  |                             <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                 <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                        style="width: 125px" for="studio1"> | ||||
|  |                                     <span class="s_website_form_label_content"> | ||||
|  |                                         Reason | ||||
|  |                                     </span> | ||||
|  |                                     <span class="s_website_form_mark">*</span> | ||||
|  |                                 </label> | ||||
|  |                                 <div class="col-sm"> | ||||
|  |                                     <input id="reason" type="text" | ||||
|  |                                            class="form-control s_website_form_input" | ||||
|  |                                            name="reason" required="1" | ||||
|  |                                            placeholder="Reason for cancellation"/> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                             <br/> | ||||
|  |                             <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                  data-name="cancel Button" | ||||
|  |                                  style="margin-bottom: 30px"> | ||||
|  |                                 <div style="width: 200px;" | ||||
|  |                                      class="s_website_form_label"/> | ||||
|  |                                 <button type="submit" id="cancel" | ||||
|  |                                         class="btn btn-primary" | ||||
|  |                                         style="float: right;">Cancel | ||||
|  |                                 </button> | ||||
|  |                             </div> | ||||
|  |                         </form> | ||||
|  |                     </div> | ||||
|  |                 </section> | ||||
|  |             </div> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,197 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Booking page of subscription--> | ||||
|  |     <template id="vehicle_form" name="Vehicle Form"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <div id="wrap" class="oe_structure oe_empty"> | ||||
|  |                 <section class="s_website_form" id="book_my_vehicle" | ||||
|  |                          data-vcss="001" data-snippet="s_website_form"> | ||||
|  |                     <div class="container"> | ||||
|  |                         <div class="btn btn-primary redirect_back_with_data" | ||||
|  |                              style="background:none; border:none;"> | ||||
|  |                             <span style="font-size:18px; color:#000; background-image:url('https://cdn-icons-png.flaticon.com/512/2985/2985162.png');width: 63px; | ||||
|  |                                         height: 63px;display: block;background-size: 60%;margin-top: 23px;background-position: center;background-repeat: no-repeat;"/> | ||||
|  |                         </div> | ||||
|  |                         <br/> | ||||
|  |                         <h1 style="text-align: center;">Choose Vehicle</h1> | ||||
|  |                         <br/> | ||||
|  |                         <input type="hidden" name="csrf_token" | ||||
|  |                                t-att-value="request.csrf_token()"/> | ||||
|  |                         <div class="s_website_form_rows row s_col_no_bgcolor"> | ||||
|  |                             <div class="form-group col-12 s_website_form_field s_website_form_required" | ||||
|  |                                  data-type="char" data-name="Field"> | ||||
|  |                                 <div class="row s_col_no_resize s_col_no_bgcolor" | ||||
|  |                                      style="display:none"> | ||||
|  |                                     <label class="col-form-label col-sm-auto s_website_form_label" | ||||
|  |                                            style="width: 200px" for="studio1"> | ||||
|  |                                         <span class="s_website_form_label_content"> | ||||
|  |                                             Name | ||||
|  |                                         </span> | ||||
|  |                                         <span class="s_website_form_mark">* | ||||
|  |                                         </span> | ||||
|  |                                     </label> | ||||
|  |                                     <div class="col-sm"> | ||||
|  |                                         <input class="form-control s_website_form_input" | ||||
|  |                                                name='customer' type="text" | ||||
|  |                                                t-att-value="customers"/> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                                 <div class="row s_col_no_resize s_col_no_bgcolor"> | ||||
|  |                                     <div class="vehicle_table_scroll" style= | ||||
|  |                                             "overflow-y: scroll;"> | ||||
|  |                                         <div class="col-sm" | ||||
|  |                                              style="display: flex;justify-content: center;"> | ||||
|  |                                             <div class="col-lg-8 col-md-6 subscription_book" | ||||
|  |                                                  style="height: 40vh;over-flow-y: scroll;"> | ||||
|  |                                                 <table style="width:100%;border-collapse: separate;border-spacing: 0 20px;" | ||||
|  |                                                        id="vehicle_booking_table"> | ||||
|  |                                                     <thead> <!-- Add the table header section --> | ||||
|  |                                                         <tr style="background-color: #ececec45;-webkit-box-shadow: 0px 0px 6px #0000001f;"> | ||||
|  |                                                             <th style="padding: 10px 0px 10px 50px;"> | ||||
|  |                                                                 Image | ||||
|  |                                                             </th> | ||||
|  |                                                             <th>Name</th> | ||||
|  |                                                             <th>Price</th> | ||||
|  |                                                             <th>Free km</th> | ||||
|  |                                                             <th/> | ||||
|  |                                                         </tr> | ||||
|  |                                                     </thead> | ||||
|  |                                                     <t t-foreach="vehicles or []" | ||||
|  |                                                        t-as="vehicle"> | ||||
|  |                                                         <div class="veh_table_row"> | ||||
|  |                                                             <tr style="background-color: #ececec45;-webkit-box-shadow: 0px 0px 6px #0000001f;"> | ||||
|  |                                                                 <td id="vehicle_img" | ||||
|  |                                                                     style="padding: 0px 20px;"> | ||||
|  |                                                                     <img t-attf-src="/web/image/fleet.vehicle/{{ vehicle.id }}/image_128" | ||||
|  |                                                                          style="width: 100px; height: 100px; object-fit: contain;" | ||||
|  |                                                                          alt="Vehicle image"/> | ||||
|  |                                                                 </td> | ||||
|  |                                                                 <td id="vehicle_fuel" | ||||
|  |                                                                     t-att-data-vehicleid="vehicle.id" | ||||
|  |                                                                     t-att-value="vehicle.id"> | ||||
|  |                                                                     <t t-esc="vehicle.name"/> | ||||
|  |                                                                 </td> | ||||
|  |                                                                 <td> | ||||
|  |                                                                     <span id="vehicle_price"> | ||||
|  |                                                                         <t t-esc="(vehicle.duration * vehicle.subscription_price)+amount"/> | ||||
|  |                                                                     </span> | ||||
|  |                                                                 </td> | ||||
|  |                                                                 <td> | ||||
|  |                                                                     <span id="vehicle_free_km"> | ||||
|  |                                                                         <t t-esc="vehicle.free_km"/> | ||||
|  |                                                                     </span> | ||||
|  |                                                                 </td> | ||||
|  |                                                                 <td> | ||||
|  |                                                                     <div class="form-group col-12 s_website_form_submit " | ||||
|  |                                                                          data-name="submit Button" | ||||
|  |                                                                          t-attf-id="'%s'% vehicle.id"> | ||||
|  |                                                                         <button id="book_now_button" | ||||
|  |                                                                                 t-if="not request.env.user.sudo().has_group('base.group_public')" | ||||
|  |                                                                                 class="btn btn-primary book_now"> | ||||
|  |                                                                             Book | ||||
|  |                                                                             Now | ||||
|  |                                                                             <input type="hidden" | ||||
|  |                                                                                    t-att-value="vehicle.id"/>  <!-- getting vehicle id in js . --> | ||||
|  |                                                                         </button> | ||||
|  |                                                                         <a href="/web/signup/user" | ||||
|  |                                                                            t-if="request.env.user.sudo().has_group('base.group_public')" | ||||
|  |                                                                            class="btn btn-primary book_now"> | ||||
|  |                                                                             Book | ||||
|  |                                                                             Now | ||||
|  |                                                                             <input type="hidden" | ||||
|  |                                                                                    t-att-value="vehicle.id"/>  <!-- getting vehicle id in js . --> | ||||
|  |                                                                         </a> | ||||
|  |                                                                     </div> | ||||
|  |                                                                 </td> | ||||
|  |                                                             </tr> | ||||
|  |                                                         </div> | ||||
|  |                                                     </t> | ||||
|  |                                                 </table> | ||||
|  |                                             </div> | ||||
|  |                                         </div> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                                 <br/> | ||||
|  |                                 <br/> | ||||
|  |                                 <div class="extra_charge_info" | ||||
|  |                                      style="width: 60%;margin: 0 auto;"> | ||||
|  |                                     <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                          style="margin-bottom: 30px;"> | ||||
|  |                                         <tr style="height:10%"> | ||||
|  |                                             <div class="col-sm" | ||||
|  |                                                  style="display: flex;justify-content: center;align-items: center;"> | ||||
|  |                                                 <span style="font-weight: 650;margin-right: 20px;"> | ||||
|  |                                                     Extra KMs | ||||
|  |                                                 </span> | ||||
|  |                                                 <input id="extra_km" | ||||
|  |                                                        type="text" | ||||
|  |                                                        class="form-control s_website_form_input" | ||||
|  |                                                        name="extra_kms" | ||||
|  |                                                        style="width: 30%;"/> | ||||
|  |                                             </div> | ||||
|  |                                         </tr> | ||||
|  |                                     </div> | ||||
|  |                                     <div class="fuel_choice_and_invoice_type" | ||||
|  |                                          style="display: flex;align-items: center;justify-content: space-around;"> | ||||
|  |                                         <table> | ||||
|  |                                             <input type="checkbox" | ||||
|  |                                                    class="form-check-input" | ||||
|  |                                                    id="checkbox_for_fuel" | ||||
|  |                                                    style="display:none;"/> | ||||
|  |                                             <span style="font-weight: 700;"> | ||||
|  |                                                 Fuel choice | ||||
|  |                                                 <td> | ||||
|  |                                                     <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                                          id="with_fuel"> | ||||
|  |                                                         <div class="btn btn-primary"> | ||||
|  |                                                             With Fuel | ||||
|  |                                                         </div> | ||||
|  |                                                     </div> | ||||
|  |                                                 </td> | ||||
|  |                                                 <td> | ||||
|  |                                                     <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                                          id="without_fuel"> | ||||
|  |                                                         <div class="btn btn-primary"> | ||||
|  |                                                             Without Fuel | ||||
|  |                                                         </div> | ||||
|  |                                                     </div> | ||||
|  |                                                 </td> | ||||
|  |                                             </span> | ||||
|  |                                         </table> | ||||
|  |                                         <table> | ||||
|  |                                             <input type="checkbox" | ||||
|  |                                                    class="form-check-input" | ||||
|  |                                                    id="checkbox_for_invoice_type" | ||||
|  |                                                    style="display:none;"/> | ||||
|  |                                             <span style="font-weight: 700;"> | ||||
|  |                                                 Invoice Type | ||||
|  |                                                 <td> | ||||
|  |                                                     <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                                          id="full_subscription"> | ||||
|  |                                                         <div class="btn btn-primary"> | ||||
|  |                                                             Full Payment | ||||
|  |                                                         </div> | ||||
|  |                                                     </div> | ||||
|  |                                                 </td> | ||||
|  |                                                 <td> | ||||
|  |                                                     <div class="form-group col-12 s_website_form_submit" | ||||
|  |                                                          id="monthly_subscription"> | ||||
|  |                                                         <div class="btn btn-primary"> | ||||
|  |                                                             Monthly Payment | ||||
|  |                                                         </div> | ||||
|  |                                                     </div> | ||||
|  |                                                 </td> | ||||
|  |                                             </span> | ||||
|  |                                         </table> | ||||
|  |                                     </div> | ||||
|  |                                 </div> | ||||
|  |                             </div> | ||||
|  |                         </div> | ||||
|  |                         <br/> | ||||
|  |                         <br/> | ||||
|  |                     </div> | ||||
|  |                 </section> | ||||
|  |             </div> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,103 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Template for confirmation of subscription--> | ||||
|  |     <template id="subscription_form_success"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <section id="subscription_form_page"> | ||||
|  |                 <div class="btn btn-primary redirect_back_with_data" | ||||
|  |                      style="background:none; border:none;"> | ||||
|  |                     <span style="font-size:18px; color:#000; background-image:url('https://cdn-icons-png.flaticon.com/512/2985/2985162.png');width: 63px; | ||||
|  |                          height: 63px;display: block;background-size: 60%;margin-top: 23px;background-position: center;background-repeat: no-repeat;"/> | ||||
|  |                 </div> | ||||
|  |                 <div id="wrap"> | ||||
|  |                     <div class="container" | ||||
|  |                          style="height: 50vh;display: flex;align-items: center;"> | ||||
|  |                         <div class="col-md-12"> | ||||
|  |                             <div class="alert alert-success" | ||||
|  |                                  style="text-align: center;width: 50%;margin: 0 auto;"> | ||||
|  |                                 Dear<t t-esc="customer_name"/>, Your | ||||
|  |                                 Subscription for | ||||
|  |                                 <t t-esc="vehicle_name"/> | ||||
|  |                                 vehicle has confirmed. | ||||
|  |                             </div> | ||||
|  |                         </div> | ||||
|  |                     </div> | ||||
|  |                 </div> | ||||
|  |             </section> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  |     <!-- This template get loaded when vehicle is not found. --> | ||||
|  |     <template id="subscription_vehicle_missing"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <section id="subscription_missing_page"> | ||||
|  |                 <div class="btn btn-primary redirect_back_with_data" | ||||
|  |                      style="background:none; border:none;"> | ||||
|  |                     <span style="font-size:18px; color:#000; background-image:url('https://cdn-icons-png.flaticon.com/512/2985/2985162.png');width: 63px; | ||||
|  |  height: 63px;display: block;background-size: 60%;margin-top: 23px;background-position: center;background-repeat: no-repeat;"/> | ||||
|  |                 </div> | ||||
|  |                 <div id="wrap"> | ||||
|  |                     <div class="container" | ||||
|  |                          style="height: 50vh;display: flex;align-items: center;"> | ||||
|  |                         <div class="col-md-12"> | ||||
|  |                             <div class="alert alert-success" | ||||
|  |                                  style="text-align: center;width: 50%;margin: 0 auto;"> | ||||
|  |                                 Sorry Vehicles not found | ||||
|  |                             </div> | ||||
|  |                         </div> | ||||
|  |                     </div> | ||||
|  |                 </div> | ||||
|  |             </section> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  |     <!--Template for cancellation of vehicle--> | ||||
|  |     <template id="booking_cancellation"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <section id="subscription_cancellation_page"> | ||||
|  |                 <div class="btn btn-primary redirect_back_with_data" | ||||
|  |                      style="background:none; border:none;"> | ||||
|  |                     <span style="font-size:18px; color:#000; background-image:url('https://cdn-icons-png.flaticon.com/512/2985/2985162.png');width: 63px; | ||||
|  |  height: 63px;display: block;background-size: 60%;margin-top: 23px;background-position: center;background-repeat: no-repeat;"/> | ||||
|  |                 </div> | ||||
|  |                 <div id="wrap"> | ||||
|  |                     <div class="container" | ||||
|  |                          style="height: 50vh;display: flex;align-items: center;"> | ||||
|  |                         <div class="col-md-12"> | ||||
|  |                             <div class="alert alert-success" | ||||
|  |                                  style="text-align: center;width: 50%;margin: 0 auto;"> | ||||
|  |                                 Dear | ||||
|  |                                 <t t-esc="customer"/> | ||||
|  |                                 Cancellation for the | ||||
|  |                                 <t t-esc="vehicle"/> | ||||
|  |                                 has been Processing.Will get back soon. | ||||
|  |                             </div> | ||||
|  |                         </div> | ||||
|  |                     </div> | ||||
|  |                 </div> | ||||
|  |             </section> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  |     <!--Template for request in vehicle change--> | ||||
|  |     <template id="change_subscription"> | ||||
|  |         <t t-call="website.layout"> | ||||
|  |             <div id="wrap"> | ||||
|  |                 <section id="change_subscription_on"> | ||||
|  |                     <div class="btn btn-primary redirect_back_with_data" | ||||
|  |                          style="background:none; border:none;"> | ||||
|  |                         <span style="font-size:18px; color:#000; background-image:url('https://cdn-icons-png.flaticon.com/512/2985/2985162.png');width: 63px; | ||||
|  |                         height: 63px;display: block;background-size: 60%;margin-top: 23px;background-position: center;background-repeat: no-repeat;"/> | ||||
|  |                     </div> | ||||
|  |                     <div class="container" | ||||
|  |                          style="height: 50vh;display: flex;align-items: center;"> | ||||
|  |                         <div class="col-md-12"> | ||||
|  |                             <div class="alert alert-success" | ||||
|  |                                  style="text-align: center;width: 50%;margin: 0 auto;"> | ||||
|  |                                 Request for changing vehicle has been | ||||
|  |                                 Processing.Will get back soon. | ||||
|  |                             </div> | ||||
|  |                         </div> | ||||
|  |                     </div> | ||||
|  |                 </section> | ||||
|  |             </div> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,45 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Action of subscription.request--> | ||||
|  |     <record id="subscription_request_action" model="ir.actions.act_window"> | ||||
|  |         <field name="name">Subscription Request</field> | ||||
|  |         <field name="res_model">subscription.request</field> | ||||
|  |         <field name="view_mode">tree,form</field> | ||||
|  |     </record> | ||||
|  | <!--    Form view of the model subscription request--> | ||||
|  |     <record id="subscription_request_view_form" model="ir.ui.view"> | ||||
|  |         <field name="name">subscription.request.view.form</field> | ||||
|  |         <field name="model">subscription.request</field> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <form string="Channel"> | ||||
|  |                 <header> | ||||
|  |                     <field name="state" widget="statusbar" | ||||
|  |                            options="{'clickable': '1'}"/> | ||||
|  |                     <button name="action_approve" class="oe_highlight" | ||||
|  |                             states="to_approve" string="Approve" | ||||
|  |                             type="object" | ||||
|  |                             groups="vehicle_subscription.vehicle_subscription_group_manager"/> | ||||
|  |                 </header> | ||||
|  |                 <sheet> | ||||
|  |                     <group> | ||||
|  |                         <field name="current_vehicle_id"/> | ||||
|  |                         <field name="vehicle_ids" widget="many2many_tags" | ||||
|  |                                invisible="True"/> | ||||
|  |                         <field name="new_vehicle_id"/> | ||||
|  |                         <field name="reason_to_change"/> | ||||
|  |                     </group> | ||||
|  |                 </sheet> | ||||
|  |                 <div class="oe_chatter"> | ||||
|  |                     <field name="message_follower_ids"/> | ||||
|  |                     <field name="message_ids"/> | ||||
|  |                 </div> | ||||
|  |             </form> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!--Menu item of change subscription--> | ||||
|  |     <menuitem id="subscription_request_menu_action" | ||||
|  |               name="Change Subscription" | ||||
|  |               parent="fleet.fleet_configuration" | ||||
|  |               action="subscription_request_action" | ||||
|  |               sequence="7"/> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,37 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--Action of vehicle insurance--> | ||||
|  |     <record id="vehicle_insurance_action" model="ir.actions.act_window"> | ||||
|  |         <field name="name">Insurance</field> | ||||
|  |         <field name="res_model">vehicle.insurance</field> | ||||
|  |         <field name="view_mode">tree,form</field> | ||||
|  |     </record> | ||||
|  | <!--    Form view of the vehicle insurance--> | ||||
|  |     <record id="vehicle_insurance_view_form" model="ir.ui.view"> | ||||
|  |         <field name="name">vehicle.insurance.view.form</field> | ||||
|  |         <field name="model">vehicle.insurance</field> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <form string="Channel"> | ||||
|  |                 <sheet> | ||||
|  |                     <group> | ||||
|  |                         <field name="vehicle_id"/> | ||||
|  |                         <field name="start_date"/> | ||||
|  |                         <field name="end_date"/> | ||||
|  |                         <field name="insurance_type_id"/> | ||||
|  |                         <field name="insurance_amount"/> | ||||
|  |                     </group> | ||||
|  |                 </sheet> | ||||
|  |                 <div class="oe_chatter"> | ||||
|  |                     <field name="message_follower_ids"/> | ||||
|  |                     <field name="message_ids"/> | ||||
|  |                 </div> | ||||
|  |             </form> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  |     <!--Menu item of insurance--> | ||||
|  |     <menuitem id="vehicle_insurance_menu_action" | ||||
|  |               name="Insurance" | ||||
|  |               action="vehicle_insurance_action" | ||||
|  |               parent="fleet.fleet_vehicles" | ||||
|  |               sequence="7"/> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,122 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||
|  | <odoo> | ||||
|  |     <!--Website view for invoice in subscription--> | ||||
|  |     <template id="portal_my_home_subscribe" name="Subscription Order" | ||||
|  |               customize_show="True" | ||||
|  |               inherit_id="portal.portal_my_home" priority="1"> | ||||
|  |         <xpath expr="//div[hasclass('o_portal_docs')]" position="inside"> | ||||
|  |             <t t-call="portal.portal_docs_entry"> | ||||
|  |                 <t t-set="title">Subscription Order</t> | ||||
|  |                 <t t-set="url" t-value="'/my/subscription/invoice'"/> | ||||
|  |                 <t t-set="placeholder_count" t-value="'subscription_count'"/> | ||||
|  |             </t> | ||||
|  |         </xpath> | ||||
|  |     </template> | ||||
|  | <!--    Portal view of the invoice--> | ||||
|  |     <template id="portal_my_invoices_subscription" | ||||
|  |               name="My Invoices and Payments"> | ||||
|  |         <t t-call="portal.portal_layout"> | ||||
|  |             <t t-set="breadcrumbs_searchbar" t-value="True"/> | ||||
|  |             <t t-if="not invoices"> | ||||
|  |                 <p>There are currently no invoices and payments for your | ||||
|  |                     account. | ||||
|  |                 </p> | ||||
|  |             </t> | ||||
|  |             <t t-if="invoices" t-call="portal.portal_table"> | ||||
|  |                 <thead> | ||||
|  |                     <tr class="active"> | ||||
|  |                         <th>Invoice #</th> | ||||
|  |                         <th>Invoice Date</th> | ||||
|  |                         <th class='d-none d-md-table-cell'>Due Date</th> | ||||
|  |                         <th class="text-center">Status</th> | ||||
|  |                         <th class="text-end">Amount Due</th> | ||||
|  |                     </tr> | ||||
|  |                 </thead> | ||||
|  |                 <tbody> | ||||
|  |                     <t t-foreach="invoices" t-as="invoice"> | ||||
|  |                         <tr> | ||||
|  |                             <td> | ||||
|  |                                 <a t-att-href="invoice.get_portal_url()" | ||||
|  |                                    t-att-title="invoice.name"> | ||||
|  |                                     <t t-esc="invoice.name" | ||||
|  |                                        t-if="invoice.name != '/'"/> | ||||
|  |                                     <em t-else="">Draft Invoice</em> | ||||
|  |                                 </a> | ||||
|  |                             </td> | ||||
|  |                             <td> | ||||
|  |                                 <span t-field="invoice.invoice_date"/> | ||||
|  |                             </td> | ||||
|  |                             <td class='d-none d-md-table-cell'> | ||||
|  |                                 <span t-field="invoice.invoice_date_due"/> | ||||
|  |                             </td> | ||||
|  |                             <td class="tx_status text-center"> | ||||
|  |                                 <t t-if="invoice.state == 'posted' and invoice.payment_state not in ('in_payment', 'paid', 'reversed')"> | ||||
|  |                                     <span class="badge rounded-pill text-bg-info"> | ||||
|  |                                         <i class="fa fa-fw fa-clock-o" | ||||
|  |                                            aria-label="Opened" title="Opened" | ||||
|  |                                            role="img"/> | ||||
|  |                                         <span class="d-none d-md-inline"> | ||||
|  |                                             Waiting for Payment | ||||
|  |                                         </span> | ||||
|  |                                     </span> | ||||
|  |                                 </t> | ||||
|  |                                 <t t-if="invoice.state == 'posted' and invoice.payment_state in ('paid', 'in_payment')"> | ||||
|  |                                     <span class="badge rounded-pill text-bg-success"> | ||||
|  |                                         <i class="fa fa-fw fa-check" | ||||
|  |                                            aria-label="Paid" title="Paid" | ||||
|  |                                            role="img"/> | ||||
|  |                                         <span class="d-none d-md-inline">Paid | ||||
|  |                                         </span> | ||||
|  |                                     </span> | ||||
|  |                                 </t> | ||||
|  |                                 <t t-if="invoice.state == 'posted' and invoice.payment_state == 'reversed'"> | ||||
|  |                                     <span class="badge rounded-pill text-bg-success"> | ||||
|  |                                         <i class="fa fa-fw fa-check" | ||||
|  |                                            aria-label="Reversed" | ||||
|  |                                            title="Reversed" | ||||
|  |                                            role="img"/> | ||||
|  |                                         <span class="d-none d-md-inline"> | ||||
|  |                                             Reversed | ||||
|  |                                         </span> | ||||
|  |                                     </span> | ||||
|  |                                 </t> | ||||
|  |                                 <t t-if="invoice.state == 'cancel'"> | ||||
|  |                                     <span class="badge rounded-pill text-bg-warning"> | ||||
|  |                                         <i class="fa fa-fw fa-remove" | ||||
|  |                                            aria-label="Cancelled" | ||||
|  |                                            title="Cancelled" | ||||
|  |                                            role="img"/> | ||||
|  |                                         <span class="d-none d-md-inline"> | ||||
|  |                                             Cancelled | ||||
|  |                                         </span> | ||||
|  |                                     </span> | ||||
|  |                                 </t> | ||||
|  |                             </td> | ||||
|  |                             <td class="text-end"> | ||||
|  |                                 <span t-esc="-invoice.amount_residual if invoice.move_type == 'out_refund' else invoice.amount_residual" | ||||
|  |                                       t-options='{"widget": "monetary", "display_currency": invoice.currency_id}'/> | ||||
|  |                             </td> | ||||
|  |                         </tr> | ||||
|  |                     </t> | ||||
|  |                 </tbody> | ||||
|  |             </t> | ||||
|  |         </t> | ||||
|  |     </template> | ||||
|  |     <!--Template for subscription cancel and change--> | ||||
|  |     <template id="subscription_order_portal_id" | ||||
|  |               name="subscription_order_portal" | ||||
|  |               inherit_id="account.portal_invoice_page"> | ||||
|  |         <xpath expr="//div[hasclass('o_download_pdf')]" position="after"> | ||||
|  |             <t t-if="invoice.is_subscription"> | ||||
|  |                 <a href="/online/subscription/cancel" id="my_link" | ||||
|  |                    class="btn btn-secondary btn-block o_download_btn"> | ||||
|  |                     Subscription Cancel | ||||
|  |                 </a> | ||||
|  |                 <a href="/online/subscription/change" id="my_link_data" | ||||
|  |                    class="btn btn-secondary btn-block o_download_btn"> | ||||
|  |                     Subscription Change | ||||
|  |                 </a> | ||||
|  |             </t> | ||||
|  |         </xpath> | ||||
|  |     </template> | ||||
|  | </odoo> | ||||
| @ -0,0 +1,22 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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 change_subscription | ||||
| @ -0,0 +1,54 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | ############################################################################# | ||||
|  | # | ||||
|  | #    Cybrosys Technologies Pvt. Ltd. | ||||
|  | # | ||||
|  | #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | ||||
|  | #    Author: Rahna Rasheed (<https://www.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, _ | ||||
|  | from odoo.exceptions import ValidationError | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class VehicleChange(models.TransientModel): | ||||
|  |     """Transient Model for switching subscription""" | ||||
|  |     _name = "change.subscription" | ||||
|  |     _description = "Change Subscription" | ||||
|  |     _rec_name = "vehicle" | ||||
|  | 
 | ||||
|  |     vehicle = fields.Selection( | ||||
|  |         [('same', 'Same Vehicle'), ('different', 'Different Vehicle')], | ||||
|  |         default='same', string='Vehicle', | ||||
|  |         help="Helps you to choose type of vehicle") | ||||
|  | 
 | ||||
|  |     def action_change_subscription(self): | ||||
|  |         """Proceed with changing subscription""" | ||||
|  |         if self.vehicle == 'different': | ||||
|  |             raise ValidationError(_( | ||||
|  |                 "Inorder to change subscription" | ||||
|  |                 " to different vehicle you need to" | ||||
|  |                 " cancel the current subscription plan")) | ||||
|  |         else: | ||||
|  |             active_id = self._context.get('active_id') | ||||
|  |             subscription = self.env['fleet.subscription'].browse(active_id) | ||||
|  |             return { | ||||
|  |                 'type': 'ir.actions.act_window', | ||||
|  |                 'view_mode': 'form', | ||||
|  |                 'res_model': 'subscription.request', | ||||
|  |                 'target': 'new', | ||||
|  |                 'context': { | ||||
|  |                     'default_current_vehicle_id': subscription.vehicle_id.id} | ||||
|  |             } | ||||
| @ -0,0 +1,29 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||
|  | <odoo> | ||||
|  |     <!--View of change subscription--> | ||||
|  |     <record id="change_subscription_view" model="ir.ui.view"> | ||||
|  |         <field name="name">change.subscription.view</field> | ||||
|  |         <field name="model">change.subscription</field> | ||||
|  |         <field name="arch" type="xml"> | ||||
|  |             <form string="Channel"> | ||||
|  |                 <group class="oe_title"> | ||||
|  |                     <field name="vehicle" widget="radio"/> | ||||
|  |                 </group> | ||||
|  |                 <footer> | ||||
|  |                     <button name="action_change_subscription" string="Ok" | ||||
|  |                             type="object" class="oe_highlight"/> | ||||
|  |                     <button string="Cancel" class="btn-secondary" | ||||
|  |                             special="cancel"/> | ||||
|  |                 </footer> | ||||
|  |             </form> | ||||
|  |         </field> | ||||
|  |     </record> | ||||
|  | <!--    Action for the model change.subscription--> | ||||
|  |     <record id="change_subscription_action" model="ir.actions.act_window"> | ||||
|  |         <field name="type">ir.actions.act_window</field> | ||||
|  |         <field name="res_model">change.subscription</field> | ||||
|  |         <field name="view_mode">form</field> | ||||
|  |         <field name="view_id" ref="change_subscription_view_form"/> | ||||
|  |         <field name="target">new</field> | ||||
|  |     </record> | ||||
|  | </odoo> | ||||