@ -0,0 +1,42 @@ | 
				
			|||
.. image:: https://img.shields.io/badge/license-OPL--1-red.svg | 
				
			|||
    :target: https://www.odoo.com/documentation/17.0/legal/licenses.html#odoo-apps | 
				
			|||
    :alt: License: OPL-1 | 
				
			|||
 | 
				
			|||
Advanced Fleet Rental Management | 
				
			|||
========================== | 
				
			|||
Advanced Fleet Rental Management system is designed to streamline the process of managing a fleet of vehicles for rental businesses | 
				
			|||
 | 
				
			|||
License | 
				
			|||
------- | 
				
			|||
Odoo Proprietary License v1.0. | 
				
			|||
(https://www.odoo.com/documentation/17.0/legal/licenses.html#odoo-apps) | 
				
			|||
 | 
				
			|||
Company | 
				
			|||
------- | 
				
			|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ | 
				
			|||
 | 
				
			|||
Credits | 
				
			|||
------- | 
				
			|||
* Developer: (V17)Anfas Faisal K, Contact: odoo@cybrosys.com | 
				
			|||
 | 
				
			|||
Contacts | 
				
			|||
-------- | 
				
			|||
* Mail Contact : odoo@cybrosys.com | 
				
			|||
* Website : https://cybrosys.com | 
				
			|||
 | 
				
			|||
Bug Tracker | 
				
			|||
----------- | 
				
			|||
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. | 
				
			|||
 | 
				
			|||
Maintainer | 
				
			|||
========== | 
				
			|||
.. image:: https://cybrosys.com/images/logo.png | 
				
			|||
   :target: https://cybrosys.com | 
				
			|||
 | 
				
			|||
This module is maintained by Cybrosys Technologies. | 
				
			|||
 | 
				
			|||
For support and more information, please visit https://www.cybrosys.com | 
				
			|||
 | 
				
			|||
Further information | 
				
			|||
=================== | 
				
			|||
HTML Description: `<static/description/index.html>`__ | 
				
			|||
@ -0,0 +1,23 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from . import models | 
				
			|||
from . import wizard | 
				
			|||
@ -0,0 +1,71 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
{ | 
				
			|||
    'name': 'Advanced Fleet Rental Management', | 
				
			|||
    'version': '17.0.1.0.0', | 
				
			|||
    'category': "Extra Tools", | 
				
			|||
    'summary': """This module will helps you to give the vehicles for Rent.""", | 
				
			|||
    'description': "This module enhances Odoo’s fleet management " | 
				
			|||
                   "functionality for vehicle rentals, including cars, " | 
				
			|||
                   "vans, bikes, and jeeps. Key features include:" | 
				
			|||
                   "Detailed rental contracts and invoicing." | 
				
			|||
                   "Management of daily, hourly, and kilometer-based rental terms." | 
				
			|||
                   "Integration with Odoo’s accounting module for automated invoicing and payments." | 
				
			|||
                   "Tracking of vehicle status, maintenance, and extra service charges." | 
				
			|||
                   "A user-friendly dashboard for monitoring fleet performance and rental contracts.", | 
				
			|||
    'author': 'Cybrosys Techno Solutions', | 
				
			|||
    'company': 'Cybrosys Techno Solutions', | 
				
			|||
    'maintainer': 'Cybrosys Techno Solutions', | 
				
			|||
    'website': "https://www.cybrosys.com", | 
				
			|||
    'depends': ['fleet', 'mail', 'sale_management', 'account', ], | 
				
			|||
    'data': [ | 
				
			|||
        'security/ir.model.access.csv', | 
				
			|||
        'data/ir_cron_data.xml', | 
				
			|||
        'data/product_product_data.xml', | 
				
			|||
        'data/ir_sequence_data.xml', | 
				
			|||
        'views/fleet_vehicle_views.xml', | 
				
			|||
        'views/fleet_dashboard.xml', | 
				
			|||
        'views/multi_image_views.xml', | 
				
			|||
        'views/fleet_rental_contract_views.xml', | 
				
			|||
        'report/fleet_rental_contract_report.xml', | 
				
			|||
        'report/fleet_rental_contract_template.xml', | 
				
			|||
        'views/res_partner_views.xml', | 
				
			|||
        'views/account_move_views.xml', | 
				
			|||
        'views/rental_payment_plan_views.xml', | 
				
			|||
        'views/cancellation_policy_views.xml', | 
				
			|||
        'views/fleet_dashboard.xml', | 
				
			|||
        'wizard/damage_invoice_views.xml', | 
				
			|||
    ], | 
				
			|||
    'assets': { | 
				
			|||
        'web.assets_backend': [ | 
				
			|||
            'advanced_fleet_rental/static/src/js/fleet_dashboard.js', | 
				
			|||
            'advanced_fleet_rental/static/src/xml/fleet_dashboard.xml', | 
				
			|||
            'advanced_fleet_rental/static/src/css/xero_dashboard.css', | 
				
			|||
            'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.umd.min.js', | 
				
			|||
        ] | 
				
			|||
    }, | 
				
			|||
    'images': ['static/description/banner.jpg'], | 
				
			|||
    'license': 'OPL-1', | 
				
			|||
    'installable': True, | 
				
			|||
    'auto_install': False, | 
				
			|||
    'application': False, | 
				
			|||
} | 
				
			|||
@ -0,0 +1,16 @@ | 
				
			|||
<?xml version="1.0" encoding="utf-8" ?> | 
				
			|||
<odoo> | 
				
			|||
    <data noupdate="1"> | 
				
			|||
<!-- Schedule action for generating automatic database backup--> | 
				
			|||
        <record id="ir_cron_auto_invoice_create" model="ir.cron"> | 
				
			|||
            <field name="name">Fleet : Automatic Invoice Creation</field> | 
				
			|||
            <field name="model_id" ref="model_rental_payment_plan"/> | 
				
			|||
            <field name="state">code</field> | 
				
			|||
            <field name="code">model._schedule_auto_invoice_checker()</field> | 
				
			|||
            <field name="interval_number">1</field> | 
				
			|||
            <field name="interval_type">days</field> | 
				
			|||
            <field name="numbercall">-1</field> | 
				
			|||
            <field name="active">False</field> | 
				
			|||
        </record> | 
				
			|||
    </data> | 
				
			|||
</odoo> | 
				
			|||
@ -0,0 +1,11 @@ | 
				
			|||
<?xml version="1.0" encoding="UTF-8" ?> | 
				
			|||
<odoo> | 
				
			|||
<!--    Sequence Number--> | 
				
			|||
    <record id="vehicle_sequence_id" model="ir.sequence"> | 
				
			|||
        <field name="name">Vehicle Rental Code</field> | 
				
			|||
        <field name="code">vehicle.sequence</field> | 
				
			|||
        <field name="prefix">VC/%(year)s/%(month)s/%(day)s/</field> | 
				
			|||
        <field name="padding">5</field> | 
				
			|||
        <field name="number_next">1</field> | 
				
			|||
    </record> | 
				
			|||
</odoo> | 
				
			|||
@ -0,0 +1,49 @@ | 
				
			|||
<?xml version="1.0" encoding="utf-8"?> | 
				
			|||
<odoo> | 
				
			|||
    <data noupdate="1"> | 
				
			|||
        <!--Vehicle Rental Charge--> | 
				
			|||
        <record id="product_product_vehicle_rental_charge" model="product.product"> | 
				
			|||
            <field name="name">Vehicle Rent Charge</field> | 
				
			|||
            <field name="default_code">VRC</field> | 
				
			|||
            <field name="description">Lets you charge a fixed rate for Vehicle Rental.</field> | 
				
			|||
            <field name="type">service</field> | 
				
			|||
            <field name="sale_ok" eval="True"/> | 
				
			|||
            <field name="purchase_ok" eval="False"/> | 
				
			|||
            <field name="list_price">0.0</field> | 
				
			|||
            <field name="invoice_policy">order</field> | 
				
			|||
        </record> | 
				
			|||
        <!--Extra Charge--> | 
				
			|||
        <record id="product_product_vehicle_extra_rental_charge" model="product.product"> | 
				
			|||
            <field name="name">Extra Charges</field> | 
				
			|||
            <field name="default_code">EC</field> | 
				
			|||
            <field name="description">Fixed rate for Extra Charges.</field> | 
				
			|||
            <field name="type">service</field> | 
				
			|||
            <field name="sale_ok" eval="True"/> | 
				
			|||
            <field name="purchase_ok" eval="False"/> | 
				
			|||
            <field name="list_price">0.0</field> | 
				
			|||
            <field name="invoice_policy">order</field> | 
				
			|||
        </record> | 
				
			|||
        <!--Damage Charge--> | 
				
			|||
        <record id="product_product_vehicle_damage_charge" model="product.product"> | 
				
			|||
            <field name="name">Damage Charge</field> | 
				
			|||
            <field name="default_code">DC</field> | 
				
			|||
            <field name="description">Fixed rate for Damage Charges.</field> | 
				
			|||
            <field name="type">service</field> | 
				
			|||
            <field name="sale_ok" eval="True"/> | 
				
			|||
            <field name="purchase_ok" eval="False"/> | 
				
			|||
            <field name="list_price">0.0</field> | 
				
			|||
            <field name="invoice_policy">order</field> | 
				
			|||
        </record> | 
				
			|||
        <!--Cancellation Charge--> | 
				
			|||
        <record id="product_product_vehicle_cancel_charge" model="product.product"> | 
				
			|||
            <field name="name">Cancellation Charge</field> | 
				
			|||
            <field name="default_code">CC</field> | 
				
			|||
            <field name="description">Fixed rate for Cancellation Charges.</field> | 
				
			|||
            <field name="type">service</field> | 
				
			|||
            <field name="sale_ok" eval="True"/> | 
				
			|||
            <field name="purchase_ok" eval="False"/> | 
				
			|||
            <field name="list_price">0.0</field> | 
				
			|||
            <field name="invoice_policy">order</field> | 
				
			|||
        </record> | 
				
			|||
    </data> | 
				
			|||
</odoo> | 
				
			|||
@ -0,0 +1,7 @@ | 
				
			|||
## Module <advanced_fleet_rental> | 
				
			|||
 | 
				
			|||
#### 07.04.2025 | 
				
			|||
#### Version 17.0.1.0.0 | 
				
			|||
#### ADD | 
				
			|||
 | 
				
			|||
- Initial commit for Advanced Fleet Rental Management | 
				
			|||
@ -0,0 +1,31 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from . import account_move | 
				
			|||
from . import cancellation_policy | 
				
			|||
from . import extra_service | 
				
			|||
from . import fleet_dashboard | 
				
			|||
from . import fleet_rental_contract | 
				
			|||
from . import fleet_vehicle | 
				
			|||
from . import insurance_policy | 
				
			|||
from . import multi_image | 
				
			|||
from . import rental_payment_plan | 
				
			|||
 | 
				
			|||
@ -0,0 +1,38 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from odoo import fields, models | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class AccountMove(models.Model): | 
				
			|||
    """ | 
				
			|||
    Inherits the 'account.move' model to add a relationship with the | 
				
			|||
    'fleet.rental.contract' model. This allows linking a vehicle rental | 
				
			|||
    contract to an accounting move. | 
				
			|||
    """ | 
				
			|||
    _inherit = "account.move" | 
				
			|||
 | 
				
			|||
    vehicle_rental_id = fields.Many2one('fleet.rental.contract', | 
				
			|||
                                        string="Vehicle Contract", | 
				
			|||
                                        readonly=True) | 
				
			|||
 | 
				
			|||
 | 
				
			|||
 | 
				
			|||
@ -0,0 +1,37 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from odoo import  fields, models | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class CancellationPolicy(models.Model): | 
				
			|||
    """ | 
				
			|||
    Model for defining a cancellation policy, including the policy name, | 
				
			|||
    creation date, and detailed terms and conditions. | 
				
			|||
    """ | 
				
			|||
    _name = 'cancellation.policy' | 
				
			|||
    _description = 'Cancellation Policy' | 
				
			|||
 | 
				
			|||
    name = fields.Char(string='Policy Name', required=True, | 
				
			|||
                       help='Name of the cancellation policy.') | 
				
			|||
    terms_conditions = fields.Text(string='Terms & Conditions', | 
				
			|||
                                   help='Detailed terms and conditions ' | 
				
			|||
                                        'of the cancellation policy.') | 
				
			|||
@ -0,0 +1,66 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from odoo import api, fields, models | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class ExtraService(models.Model): | 
				
			|||
    """ | 
				
			|||
    Model for defining extra services that can be added to a fleet rental | 
				
			|||
    contract Each service is associated with a product, and the total amount | 
				
			|||
    is computed based on the quantity and unit price of the product. | 
				
			|||
    """ | 
				
			|||
    _name = 'extra.service' | 
				
			|||
    _description = 'Extra Services' | 
				
			|||
 | 
				
			|||
    product_id = fields.Many2one('product.product', | 
				
			|||
                                 string='Product', | 
				
			|||
                                 required=True, | 
				
			|||
                                 help='Description of the extra service.') | 
				
			|||
    quantity = fields.Float(string='Quantity', default=1.0, | 
				
			|||
                            required=True, | 
				
			|||
                            help='Quantity of the extra service.') | 
				
			|||
    unit_price = fields.Float(string='Unit Price', | 
				
			|||
                              related='product_id.lst_price', store=True, | 
				
			|||
                              readonly=False, | 
				
			|||
                              help='Unit price of the extra service.') | 
				
			|||
    amount = fields.Float(string='Amount', compute='_compute_amount', | 
				
			|||
                          store=True, | 
				
			|||
                          help='Total amount for the extra service.') | 
				
			|||
    description = fields.Char(string='Description', | 
				
			|||
                              help='Description of the Product') | 
				
			|||
    contract_id = fields.Many2one('fleet.rental.contract', | 
				
			|||
                                  string='Contract Rent', | 
				
			|||
                                  help='Reference to the vehicle rent.') | 
				
			|||
 | 
				
			|||
    @api.depends('quantity', 'unit_price') | 
				
			|||
    def _compute_amount(self): | 
				
			|||
        """ | 
				
			|||
        Compute the total amount for the extra service based on the | 
				
			|||
        quantity and unit price. The amount is calculated as | 
				
			|||
        quantity * unit_price and stored in the 'amount' field. | 
				
			|||
        """ | 
				
			|||
        for service in self: | 
				
			|||
            service.amount = service.quantity * service.unit_price | 
				
			|||
 | 
				
			|||
 | 
				
			|||
 | 
				
			|||
 | 
				
			|||
@ -0,0 +1,102 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from odoo import api, models | 
				
			|||
from datetime import datetime, timedelta | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class FleetDashboard(models.Model): | 
				
			|||
    """ | 
				
			|||
    Model for the Fleet Dashboard, providing various statistics and data | 
				
			|||
    related to the fleet vehicles, contracts, and invoices. | 
				
			|||
    """ | 
				
			|||
    _name = 'fleet.dashboard' | 
				
			|||
    _description = 'Fleet Dashboard' | 
				
			|||
 | 
				
			|||
    @api.model | 
				
			|||
    def get_datas(self): | 
				
			|||
        """ | 
				
			|||
        Retrieves overall statistics related to fleet vehicles, contracts, | 
				
			|||
        and invoices. | 
				
			|||
        """ | 
				
			|||
        total_vehicles = self.env['fleet.vehicle'].search_count([]) | 
				
			|||
        operational_vehicles = self.env['fleet.vehicle'].search_count( | 
				
			|||
            [('status', '=', 'operational')]) | 
				
			|||
        maintenance_vehicles = self.env['fleet.vehicle'].search_count( | 
				
			|||
            [('status', '=', 'undermaintenance')]) | 
				
			|||
        all_invoices = self.env['account.move'].search_count( | 
				
			|||
            [('vehicle_rental_id', '!=', False)]) | 
				
			|||
        pending_invoices = self.env['account.move'].search_count([ | 
				
			|||
            ('vehicle_rental_id', '!=', False), | 
				
			|||
            ('state', '=', 'posted'), | 
				
			|||
            ('payment_state', '!=', 'paid') | 
				
			|||
        ]) | 
				
			|||
        total_contracts = self.env['fleet.rental.contract'].search_count([]) | 
				
			|||
        total_contract_working = self.env[ | 
				
			|||
            'fleet.rental.contract'].search_count( | 
				
			|||
            [('state', '=', 'in_progress')]) | 
				
			|||
        total_contract_returned = self.env[ | 
				
			|||
            'fleet.rental.contract'].search_count( | 
				
			|||
            [('state', '=', 'return')]) | 
				
			|||
        total_contract_cancel = self.env['fleet.rental.contract'].search_count( | 
				
			|||
            [('state', '=', 'cancel')]) | 
				
			|||
 | 
				
			|||
        return { | 
				
			|||
            'total_vehicles': total_vehicles, | 
				
			|||
            'total_contracts': total_contracts, | 
				
			|||
            'total_contract_working': total_contract_working, | 
				
			|||
            'total_contract_return': total_contract_returned, | 
				
			|||
            'total_contract_cancel': total_contract_cancel, | 
				
			|||
            'operational': operational_vehicles, | 
				
			|||
            'under_maintenance': maintenance_vehicles, | 
				
			|||
            'all_customers': self.env['res.partner'].search_count([]), | 
				
			|||
            'all_invoices': all_invoices, | 
				
			|||
            'pending_invoices': pending_invoices, | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
    @api.model | 
				
			|||
    def get_monthly_contract_invoices(self): | 
				
			|||
        """ | 
				
			|||
        Retrieves the count of posted invoices for each month of the | 
				
			|||
        current year related to vehicle rentals. | 
				
			|||
        """ | 
				
			|||
        current_year = datetime.now().year | 
				
			|||
        data = [] | 
				
			|||
        labels = ['January', 'February', 'March', 'April', 'May', 'June', | 
				
			|||
                  'July', 'August', 'September', 'October', 'November', | 
				
			|||
                  'December'] | 
				
			|||
 | 
				
			|||
        for month in range(1, 13): | 
				
			|||
            start_date = datetime(current_year, month, 1) | 
				
			|||
            end_date = (start_date + timedelta(days=32)).replace( | 
				
			|||
                day=1) - timedelta(days=1) | 
				
			|||
 | 
				
			|||
            invoice_count = self.env['account.move'].search_count([ | 
				
			|||
                ('vehicle_rental_id', '!=', False), | 
				
			|||
                ('invoice_date', '>=', start_date), | 
				
			|||
                ('invoice_date', '<=', end_date), | 
				
			|||
                ('state', '=', 'posted') | 
				
			|||
            ]) | 
				
			|||
            data.append(invoice_count) | 
				
			|||
        return { | 
				
			|||
            'labels': labels, | 
				
			|||
            'data': data | 
				
			|||
        } | 
				
			|||
@ -0,0 +1,677 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from datetime import date | 
				
			|||
from odoo import api, fields, models, _ | 
				
			|||
from dateutil.relativedelta import relativedelta | 
				
			|||
from odoo.exceptions import ValidationError | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class FleetRentalContract(models.Model): | 
				
			|||
    """ | 
				
			|||
    Represents a car rental contract, including details about the customer, | 
				
			|||
    vehicle, rental period, charges, and various related information. | 
				
			|||
    """ | 
				
			|||
    _name = 'fleet.rental.contract' | 
				
			|||
    _description = 'Fleet Rental Contract' | 
				
			|||
    _inherit = ['mail.thread', 'mail.activity.mixin'] | 
				
			|||
 | 
				
			|||
    name = fields.Char(string="Sequence", | 
				
			|||
                       default=lambda self: _('New'), | 
				
			|||
                       copy=False, readonly=True, tracking=True, | 
				
			|||
                       help='Unique contract number for the rental agreement.') | 
				
			|||
 | 
				
			|||
    state = fields.Selection( | 
				
			|||
        [('new', 'New'), | 
				
			|||
         ('in_progress', 'In Progress'), | 
				
			|||
         ('return', 'Return'), ('cancel', 'Cancel')], | 
				
			|||
        string='State', default='new', | 
				
			|||
        help='Contract Progress', | 
				
			|||
        group_expand='_group_expand_states',tracking=True) | 
				
			|||
    customer_id = fields.Many2one( | 
				
			|||
        'res.partner', string='Customer', | 
				
			|||
        help='The customer who is renting the vehicle.', | 
				
			|||
        required=True, tracking=True) | 
				
			|||
    email = fields.Char(string='Email', | 
				
			|||
                        related='customer_id.email', | 
				
			|||
                        help='Email address of the customer.', | 
				
			|||
                        readonly=False) | 
				
			|||
    phone = fields.Char('Phone', related='customer_id.phone', | 
				
			|||
                        help="Phone Number of the customer") | 
				
			|||
    pickup_date = fields.Datetime( | 
				
			|||
        string='Pick-up Date', | 
				
			|||
        help='Date and time when the vehicle will be picked up.', | 
				
			|||
        required=True, tracking=True) | 
				
			|||
    dropoff_date = fields.Datetime( | 
				
			|||
        string='Drop-off Date', | 
				
			|||
        help='Date and time when the vehicle will be returned.', | 
				
			|||
        required=True, tracking=True) | 
				
			|||
    pickup_location = fields.Char( | 
				
			|||
        string='Pick-Up Location', | 
				
			|||
        help='Location where the vehicle will be picked up.', | 
				
			|||
        required=True) | 
				
			|||
    dropoff_location = fields.Char( | 
				
			|||
        string='Drop-Off Location', | 
				
			|||
        help='Location where the vehicle will be dropped off.', | 
				
			|||
        required=True) | 
				
			|||
    pickup_street = fields.Char( | 
				
			|||
        string='Pick-Up Street', | 
				
			|||
        help='Street address for the pick-up location.', | 
				
			|||
        required=True) | 
				
			|||
    dropoff_street = fields.Char( | 
				
			|||
        string='Drop-Off Street', | 
				
			|||
        help='Street address for the drop-off location.', | 
				
			|||
        required=True) | 
				
			|||
    pickup_city = fields.Char( | 
				
			|||
        string='Pick-Up City', | 
				
			|||
        help='City where the vehicle will be picked up.', | 
				
			|||
        required=True) | 
				
			|||
    dropoff_city = fields.Char( | 
				
			|||
        string='Drop-Off City', | 
				
			|||
        help='City where the vehicle will be dropped off.', | 
				
			|||
        required=True) | 
				
			|||
    pickup_state_id = fields.Many2one( | 
				
			|||
        'res.country.state', | 
				
			|||
        string='Pick-Up State', | 
				
			|||
        help='State where the vehicle will be picked up.', | 
				
			|||
        required=True) | 
				
			|||
    dropoff_state_id = fields.Many2one( | 
				
			|||
        'res.country.state', | 
				
			|||
        string='Drop-Off State', | 
				
			|||
        help='State where the vehicle will be dropped off.', | 
				
			|||
        required=True) | 
				
			|||
    pickup_zip = fields.Char( | 
				
			|||
        string='Pick-Up ZIP', | 
				
			|||
        help='ZIP code for the pick-up location.', | 
				
			|||
        required=True) | 
				
			|||
    dropoff_zip = fields.Char(string='Drop-Off ZIP', | 
				
			|||
                              help='ZIP code for the drop-off location.') | 
				
			|||
    pickup_country_id = fields.Many2one( | 
				
			|||
        'res.country', | 
				
			|||
        string='Pick-Up Country', | 
				
			|||
        help='Country where the vehicle will be picked up.', | 
				
			|||
        required=True) | 
				
			|||
    dropoff_country_id = fields.Many2one( | 
				
			|||
        'res.country', | 
				
			|||
        string='Drop-Off Country', | 
				
			|||
        help='Country where the vehicle will be dropped off.', | 
				
			|||
        required=True) | 
				
			|||
    vehicle_id = fields.Many2one( | 
				
			|||
        'fleet.vehicle', string='Vehicle', | 
				
			|||
        help='The vehicle being rented.', | 
				
			|||
        required=True) | 
				
			|||
    model = fields.Char(related='vehicle_id.model_id.name', string='Model', | 
				
			|||
                        help='Model of the rented vehicle.') | 
				
			|||
    transmission = fields.Selection( | 
				
			|||
        [('automatic', 'Automatic'), ('manual', 'Manual')], | 
				
			|||
        string='Transmission', related='vehicle_id.transmission', | 
				
			|||
        help='Transmission type of the rented vehicle.') | 
				
			|||
    fuel_type = fields.Selection( | 
				
			|||
        [ | 
				
			|||
            ('diesel', 'Diesel'), | 
				
			|||
            ('gasoline', 'Gasoline'), | 
				
			|||
            ('full_hybrid', 'Full Hybrid'), | 
				
			|||
            ('plug_in_hybrid_diesel', 'Plug-in Hybrid Diesel'), | 
				
			|||
            ('plug_in_hybrid_gasoline', 'Plug-in Hybrid Gasoline'), | 
				
			|||
            ('cng', 'CNG'), | 
				
			|||
            ('lpg', 'LPG'), | 
				
			|||
            ('hydrogen', 'Hydrogen'), | 
				
			|||
            ('electric', 'Electric'), | 
				
			|||
        ], string='Fuel Type', related='vehicle_id.fuel_type', | 
				
			|||
        help='Fuel type of the rented vehicle.') | 
				
			|||
    last_odometer = fields.Float( | 
				
			|||
        string='Last Odometer', | 
				
			|||
        related='vehicle_id.odometer', | 
				
			|||
        help='Last recorded odometer reading of the vehicle.') | 
				
			|||
    odometer_unit = fields.Selection( | 
				
			|||
        [('kilometers', 'km'), ('miles', 'mi')], | 
				
			|||
        string='Odometer Unit', default='kilometers', | 
				
			|||
        related='vehicle_id.odometer_unit', | 
				
			|||
        help='Unit of measurement for the odometer reading.') | 
				
			|||
 | 
				
			|||
    driver_required = fields.Boolean( | 
				
			|||
        string='Driver Required', | 
				
			|||
        help='Indicates if a driver is required for the rental.') | 
				
			|||
    driver_id = fields.Many2one( | 
				
			|||
        'res.partner', string='Driver', | 
				
			|||
        help='Driver assigned to the rental if required.') | 
				
			|||
    charge_type = fields.Selection( | 
				
			|||
        [('excluding', 'Excluding in rent charge'), | 
				
			|||
         ('including', 'Including in rent charge')], | 
				
			|||
        string='Charge Type', | 
				
			|||
        help='Specifies if the driver charge is included in the rental ' | 
				
			|||
             'charge or not.') | 
				
			|||
    driver_charge = fields.Float( | 
				
			|||
        string='Driver Charge', | 
				
			|||
        help='Charge for the driver if not included ' | 
				
			|||
             'in the rental charge.') | 
				
			|||
 | 
				
			|||
    # Rent Details | 
				
			|||
    rent_type = fields.Selection( | 
				
			|||
        [('hours', 'Hours'), ('days', 'Days'), | 
				
			|||
         ('kilometers', 'Kilometers')], | 
				
			|||
        string='Rent Type', | 
				
			|||
        default='hours', | 
				
			|||
        help='Type of rent calculation (per day, per kilometer, or per mile).') | 
				
			|||
    rent_per_hour = fields.Float(string='Rent / Hour', | 
				
			|||
                                 help='Rental charge per hour.', | 
				
			|||
                                 related='vehicle_id.rent_hour') | 
				
			|||
    total_hours = fields.Float(string='Total Hours ', | 
				
			|||
                               help="Total Hours Taken for Rent", | 
				
			|||
                               compute='_compute_rental_period', store=True, | 
				
			|||
                               readonly=False) | 
				
			|||
    rent_per_day = fields.Float(string='Rent / Day', | 
				
			|||
                                help='Rental charge per day.', | 
				
			|||
                                related='vehicle_id.rent_day') | 
				
			|||
    total_days = fields.Integer(string='Total Days', | 
				
			|||
                                help='Total number of rental days.', | 
				
			|||
                                compute='_compute_rental_period', store=True, | 
				
			|||
                                readonly=False) | 
				
			|||
    rent_per_km = fields.Float(string='Rent / KM', | 
				
			|||
                               help='Rental charge per km.' | 
				
			|||
                               , related='vehicle_id.rent_kilometer') | 
				
			|||
    total_km = fields.Integer(string='Total KM', | 
				
			|||
                              help='Total Kilometers.') | 
				
			|||
    total_rental_charge = fields.Float( | 
				
			|||
        string='Total Rental Charge', | 
				
			|||
        compute='_compute_total_rental_charge', store=True, | 
				
			|||
        help='Total rental charge for the contract.') | 
				
			|||
 | 
				
			|||
    payment_type = fields.Selection( | 
				
			|||
        [('daily', 'Daily'), ('weekly', 'Weekly'), | 
				
			|||
         ('monthly', 'Monthly'), | 
				
			|||
         ('full', 'Fully')], | 
				
			|||
        string='Payment Type', | 
				
			|||
        help='Payment schedule for the rental charge.', | 
				
			|||
        default='full') | 
				
			|||
    invoice_item_id = fields.Many2one( | 
				
			|||
        'product.product', | 
				
			|||
        string='Invoice Item', | 
				
			|||
        help='Description of the item to be invoiced.', | 
				
			|||
        default=lambda self: self.env.ref( | 
				
			|||
            'advanced_fleet_rental.product_product_vehicle_rental_charge')) | 
				
			|||
    is_extra_charge = fields.Boolean(string='Is any extra charge', | 
				
			|||
                                     help='Indicates if there are any extra ' | 
				
			|||
                                          'charges applicable.') | 
				
			|||
    extra_per_hour = fields.Float(string='Extra Charges / Hour', | 
				
			|||
                                  help='Rental charge per hour.', | 
				
			|||
                                  related='vehicle_id.charge_hour') | 
				
			|||
    total_extra_hours = fields.Integer(string='Total Extra Hours', | 
				
			|||
                                       help='Total number of rental hours.') | 
				
			|||
    extra_per_day = fields.Float(string='Extra Charges / Day', | 
				
			|||
                                 help='Rental charge per hour.', | 
				
			|||
                                 related='vehicle_id.charge_day') | 
				
			|||
    total_extra_days = fields.Integer(string='Total Extra Days', | 
				
			|||
                                      help='Total number of rental days.') | 
				
			|||
    extra_per_km = fields.Float(string='Extra Charges / KM', | 
				
			|||
                                help='Rental charge per hour.', | 
				
			|||
                                related='vehicle_id.charge_kilometer') | 
				
			|||
 | 
				
			|||
    total_extra_km = fields.Float(string='Total Extra K/M', | 
				
			|||
                                  help="Total Extra K/M taken") | 
				
			|||
    total_extra_charge = fields.Float(string="Total Extra Charge", | 
				
			|||
                                      help="Extra Charges per K/M", | 
				
			|||
                                      compute='_compute_total_extra_charge' | 
				
			|||
                                      , store=True) | 
				
			|||
 | 
				
			|||
    rental_payment_plan_ids = (fields.One2many | 
				
			|||
                               ('rental.payment.plan', | 
				
			|||
                                'contract_id', | 
				
			|||
                                string="Vehicle Payment Details", | 
				
			|||
                                help="Details of the paymentplans for the" | 
				
			|||
                                     " vehicle rental.")) | 
				
			|||
    extra_service_ids = (fields.One2many | 
				
			|||
                         ('extra.service', | 
				
			|||
                          'contract_id', | 
				
			|||
                          string="Extra Services", | 
				
			|||
                          help="List of extra services associated with this" | 
				
			|||
                               "vehicle rental." | 
				
			|||
                          )) | 
				
			|||
    is_extra_invoice_created = fields.Boolean( | 
				
			|||
        string='Extra Invoice Created', | 
				
			|||
        help="Indicates whether an extra invoice has been created for the" | 
				
			|||
             " extra services.") | 
				
			|||
    image_ids = fields.One2many( | 
				
			|||
        'multi.image', | 
				
			|||
        'contract_id', | 
				
			|||
        string="Images of the Vehicle", | 
				
			|||
        help="Images related to the Vehicles of vehicle rental." | 
				
			|||
    ) | 
				
			|||
    insurance_ids = fields.One2many( | 
				
			|||
        'insurance.policy', | 
				
			|||
        'contract_id', | 
				
			|||
        string="Insurance Policy", | 
				
			|||
        help="Insurance policies associated with the vehicle rental.") | 
				
			|||
 | 
				
			|||
    vehicle_to_invoice_count = fields.Integer( | 
				
			|||
        string='Number of vehicle rent to invoice', | 
				
			|||
        compute='_compute_vehicle_to_invoice', | 
				
			|||
        readonly=True, | 
				
			|||
        help="Number of vehicle rental invoices that is created." | 
				
			|||
    ) | 
				
			|||
    is_damaged_invoiced = fields.Boolean( | 
				
			|||
        string='Damage Invoice Created', | 
				
			|||
        help="Indicates whether an extra invoice has been created for the" | 
				
			|||
             " extra services.") | 
				
			|||
    cancellation_policy_id = fields.Many2one( | 
				
			|||
        'cancellation.policy', string='Cancellation Policy', | 
				
			|||
        help='Select the cancellation policy applicable for this record. ' | 
				
			|||
             'The cancellation charges will be calculated based on the ' | 
				
			|||
             'selected policy.') | 
				
			|||
    cancellation_charge = fields.Float(string='Cancellation Charge') | 
				
			|||
 | 
				
			|||
    cancellation_terms = fields.Text( | 
				
			|||
        string='Cancellation Terms and Conditions', | 
				
			|||
        related="cancellation_policy_id.terms_conditions", | 
				
			|||
        readonly=False) | 
				
			|||
    is_cancelled_invoiced = fields.Boolean( | 
				
			|||
        string='Cancelled Invoice Created', | 
				
			|||
        help="Indicates whether an cancelled invoice has been created for the" | 
				
			|||
             "Cancellation Policy.") | 
				
			|||
    digital_sign = fields.Binary(string='Signature', help="Binary field to " | 
				
			|||
                                                          "store digital " | 
				
			|||
                                                          "signatures.") | 
				
			|||
    sign_date = fields.Datetime( | 
				
			|||
        string='Sign Date', | 
				
			|||
        help='Date and time of the signature signed.') | 
				
			|||
    currency_id = fields.Many2one( | 
				
			|||
        'res.currency', 'Currency', | 
				
			|||
        default=lambda self: self.env.user.company_id.currency_id.id, | 
				
			|||
        help="if you select this currency bidding will be on that currency " | 
				
			|||
             "itself") | 
				
			|||
    damage_description = fields.Text(string="Damage Description") | 
				
			|||
    damage_amount = fields.Float(string="Damage Amount", | 
				
			|||
                                 help="Total Amount for the damages") | 
				
			|||
    # Responsible | 
				
			|||
    responsible_id = fields.Many2one( | 
				
			|||
        'res.users', string='Responsible', | 
				
			|||
        help='User responsible for managing the rental contract.', | 
				
			|||
        required=True, tracking=True) | 
				
			|||
 | 
				
			|||
    @api.onchange('pickup_state_id') | 
				
			|||
    def _onchange_pickup_state(self): | 
				
			|||
        """ | 
				
			|||
        Automatically updates the 'Pick-Up Country' field based on the selected 'Pick-Up State'. | 
				
			|||
 | 
				
			|||
        When a user selects a state for vehicle pick-up, this method fetches the corresponding | 
				
			|||
        country from the selected state and sets it in the 'Pick-Up Country' field. | 
				
			|||
        """ | 
				
			|||
        if self.pickup_state_id: | 
				
			|||
            self.pickup_country_id = self.pickup_state_id.country_id | 
				
			|||
 | 
				
			|||
    @api.onchange('dropoff_state_id') | 
				
			|||
    def _onchange_dropoff_state(self): | 
				
			|||
        """ | 
				
			|||
        Automatically updates the 'Drop-Off Country' field based on the selected 'Drop-Off State'. | 
				
			|||
 | 
				
			|||
        When a user selects a state for vehicle drop-off, this method fetches the corresponding | 
				
			|||
        country from the selected state and sets it in the 'Drop-Off Country' field. | 
				
			|||
        """ | 
				
			|||
        if self.dropoff_state_id: | 
				
			|||
            self.dropoff_country_id = self.dropoff_state_id.country_id | 
				
			|||
 | 
				
			|||
    def _group_expand_states(self, states, domain, order): | 
				
			|||
        """ | 
				
			|||
        Expands the available group states for selection. | 
				
			|||
        """ | 
				
			|||
        return ['new', 'in_progress', 'return', 'cancel'] | 
				
			|||
 | 
				
			|||
    @api.model | 
				
			|||
    def create(self, vals_list): | 
				
			|||
        """ | 
				
			|||
        Override the create method to set a default sequence number if not | 
				
			|||
        provided. | 
				
			|||
        """ | 
				
			|||
        if vals_list.get('name', 'New') == 'New': | 
				
			|||
            vals_list['name'] = self.env['ir.sequence'].next_by_code( | 
				
			|||
                'vehicle.sequence') or 'New' | 
				
			|||
        return super().create(vals_list) | 
				
			|||
 | 
				
			|||
    @api.depends('extra_per_hour', 'total_extra_hours', 'extra_per_day', | 
				
			|||
                 'total_extra_days', 'extra_per_km', 'total_extra_km') | 
				
			|||
    def _compute_total_extra_charge(self): | 
				
			|||
        """ | 
				
			|||
        Compute the total extra charge based on the rent type and extra usage | 
				
			|||
        (hours, days, kilometers). | 
				
			|||
        """ | 
				
			|||
        for record in self: | 
				
			|||
            if record.rent_type == 'hours': | 
				
			|||
                record.total_extra_charge = (record.extra_per_hour * | 
				
			|||
                                             record.total_extra_hours) | 
				
			|||
            elif record.rent_type == 'days': | 
				
			|||
                record.total_extra_charge = (record.extra_per_day * | 
				
			|||
                                             record.total_extra_days) | 
				
			|||
            elif record.rent_type == 'kilometers': | 
				
			|||
                record.total_extra_charge = ( | 
				
			|||
                        record.extra_per_km * record.total_extra_km) | 
				
			|||
            else: | 
				
			|||
                record.total_extra_charge = 0 | 
				
			|||
 | 
				
			|||
    @api.depends( | 
				
			|||
        'rent_type', | 
				
			|||
        'rent_per_hour', 'total_hours', | 
				
			|||
        'rent_per_day', 'total_days', | 
				
			|||
        'rent_per_km', 'total_km', | 
				
			|||
        'driver_charge', 'charge_type', | 
				
			|||
        'driver_required' | 
				
			|||
    ) | 
				
			|||
    def _compute_total_rental_charge(self): | 
				
			|||
        """ | 
				
			|||
        Compute the total rental charge based on the rent type and usage | 
				
			|||
        (hours, days, kilometers). Include driver charge if applicable. | 
				
			|||
        """ | 
				
			|||
        for record in self: | 
				
			|||
            if record.rent_type == 'hours': | 
				
			|||
                record.total_rental_charge = ( | 
				
			|||
                        record.rent_per_hour * record.total_hours) | 
				
			|||
            elif record.rent_type == 'days': | 
				
			|||
                record.total_rental_charge = ( | 
				
			|||
                        record.rent_per_day * record.total_days) | 
				
			|||
            elif record.rent_type == 'kilometers': | 
				
			|||
                record.total_rental_charge = ( | 
				
			|||
                        record.rent_per_km * record.total_km) | 
				
			|||
            else: | 
				
			|||
                record.total_rental_charge = 0 | 
				
			|||
            if record.charge_type == 'including' and record.driver_required: | 
				
			|||
                record.total_rental_charge += record.driver_charge | 
				
			|||
 | 
				
			|||
    def action_create_extra_invoice(self): | 
				
			|||
        """ | 
				
			|||
        Create an invoice for extra charges incurred during the rental period. | 
				
			|||
        """ | 
				
			|||
        product_id = self.env.ref( | 
				
			|||
            'advanced_fleet_rental.product_product_vehicle_extra_rental_charge') | 
				
			|||
        invoice_vals = { | 
				
			|||
            'partner_id': self.customer_id.id, | 
				
			|||
            'move_type': 'out_invoice', | 
				
			|||
            'vehicle_rental_id': self.id, | 
				
			|||
            'invoice_date': date.today(), | 
				
			|||
            'invoice_line_ids': [(0, 0, { | 
				
			|||
                'product_id': product_id.id, | 
				
			|||
                'name': product_id.name, | 
				
			|||
                'quantity': 1, | 
				
			|||
                'price_unit': self.total_extra_charge, | 
				
			|||
            })], | 
				
			|||
        } | 
				
			|||
        invoice = self.env['account.move'].create(invoice_vals) | 
				
			|||
        invoice.action_post() | 
				
			|||
 | 
				
			|||
    def action_installment(self): | 
				
			|||
        """ | 
				
			|||
        Generate the rental payment plan based on the selected payment type. | 
				
			|||
        """ | 
				
			|||
        self.ensure_one() | 
				
			|||
        self.rental_payment_plan_ids.unlink() | 
				
			|||
        if self.rent_type == 'kilometers' and self.total_km == 0: | 
				
			|||
            raise ValidationError( | 
				
			|||
                _('If the rent type is "kilometers", the total ' | 
				
			|||
                  'kilometers cannot be 0.')) | 
				
			|||
        if self.rent_type == 'hours' and self.payment_type != 'full': | 
				
			|||
            raise ValidationError( | 
				
			|||
                _('If the rent type is "hours", the payment type must be ' | 
				
			|||
                  '"full".')) | 
				
			|||
        if self.rent_type == 'kilometers' and self.payment_type != 'full': | 
				
			|||
            raise ValidationError( | 
				
			|||
                _('If the rent type is "kilometers", the payment type must be ' | 
				
			|||
                  '"full".')) | 
				
			|||
        if (self.rent_type == 'days' and self.payment_type == 'weekly' | 
				
			|||
                and self.total_days < 7): | 
				
			|||
            raise ValidationError(_( | 
				
			|||
                'The total days are less than a week. ' | 
				
			|||
                'Please select a valid payment type.')) | 
				
			|||
        if (self.rent_type == 'days' and self.payment_type == 'monthly' | 
				
			|||
                and self.total_days < 30): | 
				
			|||
            raise ValidationError(_( | 
				
			|||
                'The total days are less than a month. ' | 
				
			|||
                'Please select a valid payment type.')) | 
				
			|||
        pick_up = self.pickup_date | 
				
			|||
        drop_date = self.dropoff_date | 
				
			|||
        total_amount = self.total_rental_charge | 
				
			|||
 | 
				
			|||
        if self.payment_type == 'full': | 
				
			|||
            self.env['rental.payment.plan'].create({ | 
				
			|||
                'contract_id': self.id, | 
				
			|||
                'invoice_item_id': self.invoice_item_id.id, | 
				
			|||
                'payment_date': pick_up, | 
				
			|||
                'payment_amount': total_amount, | 
				
			|||
                'payment_state': 'not_paid', | 
				
			|||
            }) | 
				
			|||
            return | 
				
			|||
 | 
				
			|||
        # Calculate interval and number of installments based on rent_type | 
				
			|||
        if self.rent_type == 'hours': | 
				
			|||
            amount_per_unit = self.rent_per_hour | 
				
			|||
            base_interval = relativedelta(hours=1) | 
				
			|||
        elif self.rent_type == 'days': | 
				
			|||
            amount_per_unit = self.rent_per_day | 
				
			|||
            base_interval = relativedelta(days=1) | 
				
			|||
 | 
				
			|||
        if self.payment_type == 'daily': | 
				
			|||
            payment_interval = relativedelta(days=1) | 
				
			|||
            current_date = pick_up | 
				
			|||
        elif self.payment_type == 'weekly': | 
				
			|||
            payment_interval = relativedelta(weeks=1) | 
				
			|||
            current_date = pick_up | 
				
			|||
        elif self.payment_type == 'monthly': | 
				
			|||
            payment_interval = relativedelta(months=1) | 
				
			|||
            current_date = pick_up + payment_interval | 
				
			|||
        else: | 
				
			|||
            payment_interval = base_interval | 
				
			|||
        while current_date < drop_date: | 
				
			|||
            next_date = min(current_date + payment_interval, drop_date) | 
				
			|||
 | 
				
			|||
            # Calculate units in this payment period | 
				
			|||
            if self.rent_type == 'hours': | 
				
			|||
                units_in_period = ( | 
				
			|||
                                          next_date - current_date).total_seconds() / 3600 | 
				
			|||
            elif self.rent_type == 'days': | 
				
			|||
                units_in_period = (next_date - current_date).days | 
				
			|||
 | 
				
			|||
            installment_amount = units_in_period * amount_per_unit | 
				
			|||
 | 
				
			|||
            if installment_amount > 0: | 
				
			|||
                self.env['rental.payment.plan'].create({ | 
				
			|||
                    'contract_id': self.id, | 
				
			|||
                    'invoice_item_id': self.invoice_item_id.id, | 
				
			|||
                    'payment_date': current_date, | 
				
			|||
                    'payment_amount': installment_amount, | 
				
			|||
                    'payment_state': 'not_paid', | 
				
			|||
                }) | 
				
			|||
 | 
				
			|||
            current_date = next_date | 
				
			|||
        # Handle any remaining amount due to rounding | 
				
			|||
        remaining_amount = total_amount - sum( | 
				
			|||
            self.rental_payment_plan_ids.mapped('payment_amount')) | 
				
			|||
        if remaining_amount > 0: | 
				
			|||
            self.env['rental.payment.plan'].create({ | 
				
			|||
                'contract_id': self.id, | 
				
			|||
                'invoice_item_id': self.invoice_item_id.id, | 
				
			|||
                'payment_date': drop_date, | 
				
			|||
                'payment_amount': remaining_amount, | 
				
			|||
                'payment_state': 'not_paid', | 
				
			|||
            }) | 
				
			|||
 | 
				
			|||
    @api.depends('pickup_date', 'dropoff_date') | 
				
			|||
    def _compute_rental_period(self): | 
				
			|||
        """ | 
				
			|||
        Compute the total rental period in hours and days based on pickup | 
				
			|||
         and drop-off dates. | 
				
			|||
        """ | 
				
			|||
        for record in self: | 
				
			|||
            if record.pickup_date and record.dropoff_date: | 
				
			|||
                pickup = fields.Datetime.from_string(record.pickup_date) | 
				
			|||
                dropoff = fields.Datetime.from_string(record.dropoff_date) | 
				
			|||
                delta = dropoff - pickup | 
				
			|||
 | 
				
			|||
                # Calculate total days | 
				
			|||
                total_days = delta.days + 1 | 
				
			|||
                record.total_days = total_days | 
				
			|||
 | 
				
			|||
                # Calculate total hours | 
				
			|||
                total_hours = delta.total_seconds() / 3600 | 
				
			|||
                record.total_hours = total_hours | 
				
			|||
 | 
				
			|||
            else: | 
				
			|||
                record.total_days = 0 | 
				
			|||
                record.total_hours = 0 | 
				
			|||
 | 
				
			|||
    @api.constrains('rent_type', 'pickup_date', 'dropoff_date', 'total_hours', | 
				
			|||
                    'total_days', ) | 
				
			|||
    def _check_rental_period(self): | 
				
			|||
        """ | 
				
			|||
        Ensure the drop-off date is not before the pick-up date. | 
				
			|||
        """ | 
				
			|||
        for record in self: | 
				
			|||
            if record.pickup_date and record.dropoff_date: | 
				
			|||
                pickup = fields.Datetime.from_string(record.pickup_date) | 
				
			|||
                dropoff = fields.Datetime.from_string(record.dropoff_date) | 
				
			|||
                delta = dropoff - pickup | 
				
			|||
 | 
				
			|||
                if record.rent_type == 'hours': | 
				
			|||
                    total_hours_computed = delta.total_seconds() / 3600 | 
				
			|||
                    if record.total_hours > total_hours_computed: | 
				
			|||
                        raise ValidationError( | 
				
			|||
                            f'The total hours ({record.total_hours})' | 
				
			|||
                            f' exceed the period between the pickup ' | 
				
			|||
                            f'and dropoff dates.') | 
				
			|||
                    if record.total_hours == 0: | 
				
			|||
                        raise ValidationError( | 
				
			|||
                            f'The total hours cannot be zero.') | 
				
			|||
                if record.rent_type == 'days': | 
				
			|||
                    total_days_computed = delta.days + 1 | 
				
			|||
                    if record.total_days > total_days_computed: | 
				
			|||
                        raise ValidationError( | 
				
			|||
                            f'The total days ({record.total_days})' | 
				
			|||
                            f' exceed the period between the pickup ' | 
				
			|||
                            f'and dropoff dates.') | 
				
			|||
                    if record.total_days == 0: | 
				
			|||
                        raise ValidationError( | 
				
			|||
                            f'The total days cannot be zero.') | 
				
			|||
 | 
				
			|||
    def action_account_tab(self): | 
				
			|||
        """View the Invoices in the Smart Tab.""" | 
				
			|||
        return { | 
				
			|||
            'type': 'ir.actions.act_window', | 
				
			|||
            'name': 'Invoices', | 
				
			|||
            'res_model': 'account.move', | 
				
			|||
            'target': 'current', | 
				
			|||
            'domain': [('partner_id', '=', self.customer_id.id), | 
				
			|||
                       ('vehicle_rental_id', '=', self.id)], | 
				
			|||
            'view_mode': 'tree,form', | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
    def _compute_vehicle_to_invoice(self): | 
				
			|||
        """ | 
				
			|||
        Computes the number of invoices related to the vehicle rental | 
				
			|||
        contract and updates the 'vehicle_to_invoice_count' field for each record. | 
				
			|||
        """ | 
				
			|||
        for record in self: | 
				
			|||
            record.vehicle_to_invoice_count = self.env[ | 
				
			|||
                'account.move'].search_count([ | 
				
			|||
                ('vehicle_rental_id', '=', record.id) | 
				
			|||
            ]) | 
				
			|||
 | 
				
			|||
    def action_extra_invoice_charge(self): | 
				
			|||
        """ | 
				
			|||
        Creates an invoice for extra services added to the vehicle | 
				
			|||
        rental contract. If there are no extra services, raises a | 
				
			|||
        ValidationError. | 
				
			|||
        """ | 
				
			|||
        if self.extra_service_ids: | 
				
			|||
            invoice_line_vals = [ | 
				
			|||
                { | 
				
			|||
                    'product_id': line.product_id.id, | 
				
			|||
                    'name': line.description or line.product_id.name, | 
				
			|||
                    'quantity': line.quantity, | 
				
			|||
                    'price_unit': line.amount, | 
				
			|||
                } | 
				
			|||
                for line in self.extra_service_ids | 
				
			|||
            ] | 
				
			|||
            invoice_vals = { | 
				
			|||
                'move_type': 'out_invoice', | 
				
			|||
                'partner_id': self.customer_id.id, | 
				
			|||
                'invoice_line_ids': [(0, 0, line) for line in | 
				
			|||
                                     invoice_line_vals], | 
				
			|||
                'vehicle_rental_id': self.id, | 
				
			|||
            } | 
				
			|||
            invoice = self.env['account.move'].create(invoice_vals) | 
				
			|||
            invoice.action_post() | 
				
			|||
            self.is_extra_invoice_created = True | 
				
			|||
        else: | 
				
			|||
            raise ValidationError( | 
				
			|||
                _('Add Extra Services Products.')) | 
				
			|||
 | 
				
			|||
    def action_damage_invoice(self): | 
				
			|||
        """ | 
				
			|||
        This method opens a new window to link invoices and remove invoices | 
				
			|||
        for the current sale order. | 
				
			|||
        """ | 
				
			|||
        return { | 
				
			|||
            "type": "ir.actions.act_window", | 
				
			|||
            "name": "Damage Invoices", | 
				
			|||
            "view_mode": "form", | 
				
			|||
            "res_model": "damage.invoice", | 
				
			|||
            "target": "new", | 
				
			|||
            "context": { | 
				
			|||
                "default_contract_id": self.id, | 
				
			|||
            }, | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
    def action_cancel(self): | 
				
			|||
        """ | 
				
			|||
        Cancels the rental contract by setting its state to 'cancel'. | 
				
			|||
        """ | 
				
			|||
        self.write({'state': 'cancel'}) | 
				
			|||
 | 
				
			|||
    def action_cancel_charges(self): | 
				
			|||
        """ | 
				
			|||
        Creates an invoice for the cancellation charges based on the contract's | 
				
			|||
        cancellation policy. The invoice is created using a predefined product | 
				
			|||
        for cancellation charges. If the cancellation policy is not set, | 
				
			|||
        it raises a ValidationError. | 
				
			|||
        """ | 
				
			|||
        if self.cancellation_policy_id: | 
				
			|||
            product_id = self.env.ref( | 
				
			|||
                'advanced_fleet_rental.product_product_vehicle_cancel_charge') | 
				
			|||
            invoice_vals = { | 
				
			|||
                'partner_id': self.customer_id.id, | 
				
			|||
                'move_type': 'out_invoice', | 
				
			|||
                'vehicle_rental_id': self.id, | 
				
			|||
                'invoice_date': date.today(), | 
				
			|||
                'invoice_line_ids': [(0, 0, { | 
				
			|||
                    'product_id': product_id.id, | 
				
			|||
                    'name': self.cancellation_terms, | 
				
			|||
                    'quantity': 1, | 
				
			|||
                    'price_unit': self.cancellation_charge, | 
				
			|||
                })], | 
				
			|||
            } | 
				
			|||
            invoice = self.env['account.move'].create(invoice_vals) | 
				
			|||
            self.is_cancelled_invoiced = True | 
				
			|||
            return { | 
				
			|||
                'type': 'ir.actions.act_window', | 
				
			|||
                'res_model': 'account.move', | 
				
			|||
                'view_mode': 'form', | 
				
			|||
                'res_id': invoice.id, | 
				
			|||
                'target': 'current', | 
				
			|||
            } | 
				
			|||
        else: | 
				
			|||
            raise ValidationError( | 
				
			|||
                _("No cancellation policy set on the contract.")) | 
				
			|||
@ -0,0 +1,45 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from odoo import fields, models | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class FleetVehicle(models.Model): | 
				
			|||
    """ | 
				
			|||
    Inherits from 'fleet.vehicle' to add additional fields and functionality. | 
				
			|||
    """ | 
				
			|||
    _inherit = 'fleet.vehicle' | 
				
			|||
 | 
				
			|||
    status = fields.Selection([ | 
				
			|||
        ('operational', 'Operational'), | 
				
			|||
        ('undermaintenance', 'Under Maintenance'), | 
				
			|||
    ], default='operational') | 
				
			|||
    rent_hour = fields.Float(string='Rent / Hour', help="Rent per hour") | 
				
			|||
    rent_day = fields.Float(string='Rent / Day', help="Rent per day") | 
				
			|||
    rent_kilometer = fields.Float(string='Rent / Kilometer', | 
				
			|||
                                  help="Rent per kilometer") | 
				
			|||
    charge_hour = fields.Float(string='Extra Charge / Hour', | 
				
			|||
                               help="Extra charge per hour") | 
				
			|||
    charge_day = fields.Float(string='Extra Charge / Day', | 
				
			|||
                              help="Extra charge per day") | 
				
			|||
 | 
				
			|||
    charge_kilometer = fields.Float(string='Extra Charge / Kilometer', | 
				
			|||
                                    help="Extra charge per kilometer") | 
				
			|||
@ -0,0 +1,55 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from odoo import fields, models | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class InsurancePolicy(models.Model): | 
				
			|||
    """ | 
				
			|||
    Model for managing insurance policies related to fleet rental contracts. | 
				
			|||
    """ | 
				
			|||
    _name = 'insurance.policy' | 
				
			|||
    _description = 'Insurance Policy' | 
				
			|||
 | 
				
			|||
    policy_number = fields.Char( | 
				
			|||
        string='Policy Number', | 
				
			|||
        required=True, | 
				
			|||
        help='Unique identifier for the insurance policy.') | 
				
			|||
    name = fields.Char( | 
				
			|||
        string='Name', | 
				
			|||
        required=True, | 
				
			|||
        help='Name of the insurance policy.') | 
				
			|||
    description = fields.Char( | 
				
			|||
        string='Description', | 
				
			|||
        help='Brief description of the insurance policy.') | 
				
			|||
    document = fields.Binary( | 
				
			|||
        string='Document', | 
				
			|||
        help='Upload the document related to the insurance policy.') | 
				
			|||
    file_name = fields.Char( | 
				
			|||
        string="File Name", | 
				
			|||
        help='File Name of the Document') | 
				
			|||
 | 
				
			|||
    policy_amount = fields.Float( | 
				
			|||
        string='Policy Amount', | 
				
			|||
        help='Total amount covered by the insurance policy.') | 
				
			|||
    contract_id = fields.Many2one('fleet.rental.contract', | 
				
			|||
                                  string='Contract Rent', | 
				
			|||
                                  help='Reference to the vehicle rent.') | 
				
			|||
@ -0,0 +1,35 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from odoo import fields, models | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class MultiImage(models.Model): | 
				
			|||
    """ | 
				
			|||
    Model for storing multiple images related to a fleet rental contract. | 
				
			|||
    """ | 
				
			|||
    _name = 'multi.image' | 
				
			|||
    _description = 'Multi Image' | 
				
			|||
 | 
				
			|||
    image = fields.Binary(string="Image", help="Upload the Images") | 
				
			|||
    contract_id = fields.Many2one( | 
				
			|||
        'fleet.rental.contract', string='Rental Contract', | 
				
			|||
        ondelete='cascade', readonly=True) | 
				
			|||
@ -0,0 +1,105 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################### | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    Author: Anfas Faisal K (odoo@cybrosys.com) | 
				
			|||
# | 
				
			|||
#    This program is under the terms of the Odoo Proprietary License v1.0(OPL-1) | 
				
			|||
#    It is forbidden to publish, distribute, sublicense, or sell copies of the | 
				
			|||
#    Software or modified copies of the Software. | 
				
			|||
# | 
				
			|||
#    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
				
			|||
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
				
			|||
#    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | 
				
			|||
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | 
				
			|||
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | 
				
			|||
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
				
			|||
#    DEALINGS IN THE SOFTWARE. | 
				
			|||
# | 
				
			|||
############################################################################### | 
				
			|||
from datetime import date | 
				
			|||
from odoo import api, fields, models | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class RentalPaymentPlan(models.Model): | 
				
			|||
    """ | 
				
			|||
    Model for managing rental payment plans associated with fleet rental | 
				
			|||
    contracts. | 
				
			|||
    """ | 
				
			|||
    _name = 'rental.payment.plan' | 
				
			|||
    _description = 'Rental Payment Plan' | 
				
			|||
 | 
				
			|||
    contract_id = fields.Many2one( | 
				
			|||
        'fleet.rental.contract', string='Rental Contract', | 
				
			|||
        ondelete='cascade') | 
				
			|||
    invoice_item_id = fields.Many2one('product.product', | 
				
			|||
                                   string='Invoice Item', ) | 
				
			|||
    payment_date = fields.Date(string='Payment Date' ) | 
				
			|||
    payment_amount = fields.Float( | 
				
			|||
        string='Payment Amount', | 
				
			|||
        help='Amount to be paid based on the invoice item.') | 
				
			|||
    invoice_id = fields.Many2one('account.move', string='Invoice', | 
				
			|||
                                 readonly=True) | 
				
			|||
    payment_state = fields.Selection( | 
				
			|||
        [ | 
				
			|||
            ('not_paid', 'Not Paid'), | 
				
			|||
            ('in_payment', 'In Payment'), | 
				
			|||
            ('paid', 'Paid'), | 
				
			|||
            ('partial', 'Partially Paid'), | 
				
			|||
            ('reversed', 'Reversed'), | 
				
			|||
            ('invoicing_legacy', 'Invoicing App Legacy'), | 
				
			|||
        ], compute='_compute_payment_state', | 
				
			|||
        string='Payment State') | 
				
			|||
    is_invoiced = fields.Boolean(string="Invoice Button", help="Invoiced") | 
				
			|||
 | 
				
			|||
    @api.depends('invoice_id.payment_state') | 
				
			|||
    def _compute_payment_state(self): | 
				
			|||
        """ | 
				
			|||
        Computes the payment state based on the associated invoice's | 
				
			|||
        payment state. | 
				
			|||
        """ | 
				
			|||
        for record in self: | 
				
			|||
            if record.invoice_id: | 
				
			|||
                record.payment_state = record.invoice_id.payment_state | 
				
			|||
            else: | 
				
			|||
                record.payment_state = 'not_paid' | 
				
			|||
 | 
				
			|||
    def action_create_invoice(self): | 
				
			|||
        """ | 
				
			|||
        Creates an invoice for the payment plan. | 
				
			|||
        """ | 
				
			|||
        self.ensure_one() | 
				
			|||
        invoice_vals = { | 
				
			|||
            'partner_id': self.contract_id.customer_id.id, | 
				
			|||
            'move_type': 'out_invoice', | 
				
			|||
            'invoice_date': self.payment_date, | 
				
			|||
            'vehicle_rental_id': self.contract_id.id, | 
				
			|||
            'invoice_line_ids': [(0, 0, { | 
				
			|||
                'product_id': self.invoice_item_id.id, | 
				
			|||
                'name': self.invoice_item_id.name, | 
				
			|||
                'quantity': 1, | 
				
			|||
                'price_unit': self.payment_amount, | 
				
			|||
            })], | 
				
			|||
        } | 
				
			|||
        invoice = self.env['account.move'].create(invoice_vals) | 
				
			|||
        invoice.action_post() | 
				
			|||
        self.invoice_id = invoice.id | 
				
			|||
        self.is_invoiced = True | 
				
			|||
        return invoice | 
				
			|||
 | 
				
			|||
    @api.model | 
				
			|||
    def _schedule_auto_invoice_checker(self): | 
				
			|||
        """ | 
				
			|||
        Scheduled action to automatically generate invoices for rental payment | 
				
			|||
        plans where the payment date is today. Searches for payment plans with | 
				
			|||
        today's date and no associated invoice, and generates invoices for them. | 
				
			|||
        """ | 
				
			|||
        today = date.today() | 
				
			|||
        payment_plans = self.search([ | 
				
			|||
            ('payment_date', '=', today), | 
				
			|||
            ('invoice_id', '=', False) | 
				
			|||
        ]) | 
				
			|||
        for plan in payment_plans: | 
				
			|||
            plan.action_create_invoice() | 
				
			|||
@ -0,0 +1,13 @@ | 
				
			|||
<?xml version="1.0" encoding="UTF-8"?> | 
				
			|||
<odoo> | 
				
			|||
<!--    Report Function inside Contract Form--> | 
				
			|||
    <record id="vehicle_contract_report" model="ir.actions.report"> | 
				
			|||
        <field name="name">Vehicle Rental Report</field> | 
				
			|||
        <field name="model">fleet.rental.contract</field> | 
				
			|||
        <field name="report_type">qweb-pdf</field> | 
				
			|||
        <field name="report_name">advanced_fleet_rental.report_fleet_rental_contract</field> | 
				
			|||
        <field name="report_file">advanced_fleet_rental.report_fleet_rental_contract</field> | 
				
			|||
        <field name="binding_model_id" ref="model_fleet_rental_contract"/> | 
				
			|||
        <field name="binding_type">report</field> | 
				
			|||
    </record> | 
				
			|||
</odoo> | 
				
			|||
@ -0,0 +1,393 @@ | 
				
			|||
<?xml version="1.0" encoding="UTF-8" ?> | 
				
			|||
<odoo> | 
				
			|||
    <!-- Report Template--> | 
				
			|||
    <template id="report_fleet_rental_contract"> | 
				
			|||
        <t t-call="web.html_container"> | 
				
			|||
            <t t-foreach="docs" t-as="data"> | 
				
			|||
                <t t-call="web.external_layout"> | 
				
			|||
                    <div class="page" style="font-size: 12pt;"> | 
				
			|||
                        <h2 style="text-align: center;">Vehicle Contract | 
				
			|||
                            Details | 
				
			|||
                        </h2> | 
				
			|||
                        <p>Reference Number: | 
				
			|||
                            <span t-field="data.name"/> | 
				
			|||
                        </p> | 
				
			|||
 | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid transparent; border-collapse: collapse; width: 100%;"> | 
				
			|||
                            <tr> | 
				
			|||
                                <td colspan="2"> | 
				
			|||
                                    <strong>Customer Details</strong> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                            <tr> | 
				
			|||
                                <td style="width: 50%;"> | 
				
			|||
                                    <span>Customer:</span> | 
				
			|||
                                    <span t-field="data.customer_id.name"/> | 
				
			|||
                                </td> | 
				
			|||
                                <td style="width: 50%; text-align: right;"> | 
				
			|||
                                    <span>Phone:</span> | 
				
			|||
                                    <span t-field="data.customer_id.phone"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Email:</span> | 
				
			|||
                                    <span t-field="data.email"/> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                        </table> | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid transparent; width: 100%; margin-top: 10px;"> | 
				
			|||
 | 
				
			|||
                            <tr> | 
				
			|||
                                <td colspan="2"> | 
				
			|||
                                    <strong>Pick-Up & Drop-Off Details | 
				
			|||
                                    </strong> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                            <tr> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <span>Pick-up Date:</span> | 
				
			|||
                                    <span t-field="data.pickup_date"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Pick-Up Location:</span> | 
				
			|||
                                    <span t-field="data.pickup_location"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span t-field="data.pickup_street"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span t-field="data.pickup_city"/>, | 
				
			|||
                                    <span t-field="data.pickup_state_id.name"/> | 
				
			|||
                                    <span t-field="data.pickup_zip"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span t-field="data.pickup_country_id.name"/> | 
				
			|||
                                </td> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <span>Drop-off Date:</span> | 
				
			|||
                                    <span t-field="data.dropoff_date"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Drop-Off Location:</span> | 
				
			|||
                                    <span t-field="data.dropoff_location"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span t-field="data.dropoff_street"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span t-field="data.dropoff_city"/>, | 
				
			|||
                                    <span t-field="data.dropoff_state_id.name"/> | 
				
			|||
                                    <span t-field="data.dropoff_zip"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span t-field="data.dropoff_country_id.name"/> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                        </table> | 
				
			|||
 | 
				
			|||
                        <!--Vehicle Deatils--> | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid transparent; width: 100%; margin-top: 10px;"> | 
				
			|||
                            <tr> | 
				
			|||
                                <td colspan="2"> | 
				
			|||
                                    <strong>Vehicle Details</strong> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                            <tr> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <span>Vehicle:</span> | 
				
			|||
                                    <span t-field="data.vehicle_id.name"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Model:</span> | 
				
			|||
                                    <span t-field="data.model"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Transmission:</span> | 
				
			|||
                                    <span t-field="data.transmission"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Fuel Type:</span> | 
				
			|||
                                    <span t-field="data.fuel_type"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Last Odometer:</span> | 
				
			|||
                                    <span t-field="data.last_odometer"/> | 
				
			|||
                                    <span t-field="data.odometer_unit"/> | 
				
			|||
                                </td> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <t t-if="data.driver_required"> | 
				
			|||
                                        <span>Driver:</span> | 
				
			|||
                                        <span t-field="data.driver_id.name"/> | 
				
			|||
                                        <br/> | 
				
			|||
                                        <span>Driver Charge Type:</span> | 
				
			|||
                                        <span t-field="data.charge_type"/> | 
				
			|||
                                        <br/> | 
				
			|||
 | 
				
			|||
                                        <span>Driver Charge:</span> | 
				
			|||
                                        <span t-field="data.driver_charge" | 
				
			|||
                                              t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                    </t> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                        </table> | 
				
			|||
 | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid transparent; width: 100%; margin-top: 10px;"> | 
				
			|||
                            <tr> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <strong>Rent Details</strong> | 
				
			|||
                                    <br/> | 
				
			|||
 | 
				
			|||
                                    <span>Rent Type:</span> | 
				
			|||
                                    <span t-field="data.rent_type"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Rent /</span> | 
				
			|||
                                    <span t-field="data.rent_type"/> | 
				
			|||
                                    <span>:</span> | 
				
			|||
                                    <span t-field="data.rent_per_hour" | 
				
			|||
                                          t-if="data.rent_type == 'hours'" | 
				
			|||
                                          t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                    <span t-field="data.rent_per_day" | 
				
			|||
                                          t-if="data.rent_type == 'days'" | 
				
			|||
                                          t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                    <span t-field="data.rent_per_km" | 
				
			|||
                                          t-if="data.rent_type == 'kilometers'" | 
				
			|||
                                          t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Total</span> | 
				
			|||
                                    <span t-field="data.rent_type"/> | 
				
			|||
                                    <span>:</span> | 
				
			|||
                                    <span t-field="data.total_hours" | 
				
			|||
                                          t-if="data.rent_type == 'hours'"/> | 
				
			|||
                                    <span t-field="data.total_days" | 
				
			|||
                                          t-if="data.rent_type == 'days'"/> | 
				
			|||
                                    <span t-field="data.total_km" | 
				
			|||
                                          t-if="data.rent_type == 'kilometers'"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Total:</span> | 
				
			|||
                                    <span t-field="data.total_rental_charge" | 
				
			|||
                                          t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                </td> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <strong>Payment Details</strong> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Payment Type:</span> | 
				
			|||
                                    <span t-field="data.payment_type"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Invoice Item:</span> | 
				
			|||
                                    <span t-field="data.invoice_item_id"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                        </table> | 
				
			|||
                        <!--              Extra Charges Details--> | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid transparent; width: 100%; margin-top: 10px;"> | 
				
			|||
                            <tr> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <strong>Extra Charges Details</strong> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Is any extra charges:</span> | 
				
			|||
 | 
				
			|||
 | 
				
			|||
                                    <span t-field="data.is_extra_charge"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Total Extra:</span> | 
				
			|||
                                    <span t-field="data.rent_type"/> | 
				
			|||
                                    : | 
				
			|||
                                    <span t-field="data.total_extra_hours" | 
				
			|||
                                          t-if="data.rent_type == 'hours'"/> | 
				
			|||
                                    <span t-field="data.total_extra_days" | 
				
			|||
                                          t-if="data.rent_type == 'days'"/> | 
				
			|||
                                    <span t-field="data.total_extra_km" | 
				
			|||
                                          t-if="data.rent_type == 'kilometers'"/> | 
				
			|||
                                    <br/> | 
				
			|||
 | 
				
			|||
                                    <span>Extra Charge /</span> | 
				
			|||
                                    <span t-field="data.rent_type"/> | 
				
			|||
                                    <span t-field="data.extra_per_hour" | 
				
			|||
                                          t-if="data.rent_type == 'hours'"/> | 
				
			|||
                                    <span t-field="data.extra_per_day" | 
				
			|||
                                          t-if="data.rent_type == 'days'"/> | 
				
			|||
                                    <span t-field="data.extra_per_km" | 
				
			|||
                                          t-if="data.rent_type == 'kilometers'"/> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Total Extra Charges:</span> | 
				
			|||
                                    <span t-field="data.total_extra_charge" | 
				
			|||
                                          t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
 | 
				
			|||
                                </td> | 
				
			|||
                                <td style="width: 50%; vertical-align: top;"> | 
				
			|||
                                    <strong>Responsible Details</strong> | 
				
			|||
                                    <br/> | 
				
			|||
                                    <span>Responsible:</span> | 
				
			|||
                                    <span t-field="data.responsible_id.name"/> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                        </table> | 
				
			|||
                        <!--Vehicle Payment Option--> | 
				
			|||
                        <h4 style="margin-top: 20px;">Vehicle Payment Option | 
				
			|||
                        </h4> | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid black; border-collapse: collapse; width: 100%;"> | 
				
			|||
                            <thead> | 
				
			|||
                                <tr style="background-color: #f2f2f2;"> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Invoice Item | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Payment Date | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Payment Amount Invoice | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Payment State | 
				
			|||
                                    </th> | 
				
			|||
                                </tr> | 
				
			|||
                            </thead> | 
				
			|||
                            <tbody> | 
				
			|||
                                <tr t-foreach="data.rental_payment_plan_ids" | 
				
			|||
                                    t-as="payment"> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="payment.invoice_item_id"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="payment.payment_date"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="payment.payment_amount" | 
				
			|||
                                              t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                        <t t-if="payment.invoice_id"> | 
				
			|||
                                            <span t-field="payment.invoice_id.name"/> | 
				
			|||
                                        </t> | 
				
			|||
                                        <t t-else=""> | 
				
			|||
                                            Draft Invoice | 
				
			|||
                                        </t> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="payment.payment_state"/> | 
				
			|||
                                    </td> | 
				
			|||
                                </tr> | 
				
			|||
                            </tbody> | 
				
			|||
                        </table> | 
				
			|||
                        <!-- Insurance Policy--> | 
				
			|||
                        <h4 style="margin-top: 20px;">Insurance Policy</h4> | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid black; border-collapse: collapse; width: 100%;"> | 
				
			|||
                            <thead> | 
				
			|||
                                <tr style="background-color: #f2f2f2;"> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Policy Number | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Name | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Description | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Policy Amount | 
				
			|||
                                    </th> | 
				
			|||
                                </tr> | 
				
			|||
                            </thead> | 
				
			|||
                            <tbody> | 
				
			|||
                                <tr t-foreach="data.insurance_ids" | 
				
			|||
                                    t-as="insurance"> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="insurance.policy_number"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="insurance.name"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="insurance.description"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="insurance.policy_amount" | 
				
			|||
                                              t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                    </td> | 
				
			|||
                                </tr> | 
				
			|||
                            </tbody> | 
				
			|||
                        </table> | 
				
			|||
                        <!--Extra Services--> | 
				
			|||
                        <h4 style="margin-top: 20px;">Extra Services</h4> | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid black; border-collapse: collapse; width: 100%;"> | 
				
			|||
                            <thead> | 
				
			|||
                                <tr style="background-color: #f2f2f2;"> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Product | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Qty | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Description | 
				
			|||
                                    </th> | 
				
			|||
                                    <th style="border: 1px solid black; padding: 5px; text-align: left;"> | 
				
			|||
                                        Amount | 
				
			|||
                                    </th> | 
				
			|||
                                </tr> | 
				
			|||
                            </thead> | 
				
			|||
                            <tbody> | 
				
			|||
                                <tr t-foreach="data.extra_service_ids" | 
				
			|||
                                    t-as="service"> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="service.product_id"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="service.quantity"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="service.description"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                        <span t-field="service.amount" | 
				
			|||
                                              t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                    </td> | 
				
			|||
                                </tr> | 
				
			|||
                            </tbody> | 
				
			|||
                        </table> | 
				
			|||
                        <!-- Damage Details Tab --> | 
				
			|||
                        <h4 style="margin-top: 20px;">Vehicle Damages</h4> | 
				
			|||
                        <table class="table table-sm" | 
				
			|||
                               style="border: 1px solid black; border-collapse: collapse; width: 100%;"> | 
				
			|||
                            <tr> | 
				
			|||
                                <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                    <strong>Total Damage Amount:</strong> | 
				
			|||
                                </td> | 
				
			|||
                                <td style="border: 1px solid black; padding: 5px;"> | 
				
			|||
                                    <span t-field="data.damage_amount" | 
				
			|||
                                          t-options="{'widget': 'monetary', 'display_currency': data.currency_id}"/> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                        </table> | 
				
			|||
 | 
				
			|||
                        <p style="margin-top: 10px;"> | 
				
			|||
                            <strong>Descriptions</strong> | 
				
			|||
                        </p> | 
				
			|||
                        <p t-field="data.damage_description"/> | 
				
			|||
                        <!-- Vehicle Images --> | 
				
			|||
                        <h4 style="margin-top: 20px;">Vehicle Images</h4> | 
				
			|||
                        <div class="vehicle-images" | 
				
			|||
                             style="text-align: center;"> | 
				
			|||
                            <t t-foreach="data.image_ids" t-as="image_record"> | 
				
			|||
                                <img t-if="image_record.image" | 
				
			|||
                                     t-att-src="image_record.image and ('data:image/png;base64,%s' % image_record.image.decode('utf-8'))" | 
				
			|||
                                     alt="Vehicle Image" | 
				
			|||
                                     style="max-width: 200px; margin: 10px;"/> | 
				
			|||
                            </t> | 
				
			|||
                        </div> | 
				
			|||
 | 
				
			|||
                        <!-- Signature Section --> | 
				
			|||
                        <div class="signature-section" | 
				
			|||
                             style="margin-top: 30px; text-align: right;"> | 
				
			|||
 | 
				
			|||
                            <p>Signature Date: | 
				
			|||
                                <span t-field="data.sign_date"/> | 
				
			|||
                            </p> | 
				
			|||
                            <p> | 
				
			|||
                                <strong>Signature</strong> | 
				
			|||
                                <img t-if="data.digital_sign" | 
				
			|||
                                     class="mobile-hide" | 
				
			|||
                                     t-attf-src="data:image/png;base64,{{data.digital_sign}}" | 
				
			|||
                                     style="width:125px; margin-top:8px;margin-bottom:-25px;" | 
				
			|||
                                     alt="Signature"/> | 
				
			|||
                            </p> | 
				
			|||
                        </div> | 
				
			|||
                    </div> | 
				
			|||
                </t> | 
				
			|||
            </t> | 
				
			|||
        </t> | 
				
			|||
    </template> | 
				
			|||
</odoo> | 
				
			|||
		
		
			
  | 
| 
		 After Width: | Height: | Size: 2.2 KiB  | 
| 
		 After Width: | Height: | Size: 28 KiB  | 
| 
		 After Width: | Height: | Size: 628 KiB  | 
| 
		 After Width: | Height: | Size: 19 KiB  | 
| 
		 After Width: | Height: | Size: 16 KiB  | 
| 
		 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: 16 KiB  | 
| 
		 After Width: | Height: | Size: 542 B  | 
| 
		 After Width: | Height: | Size: 576 B  | 
| 
		 After Width: | Height: | Size: 733 B  | 
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
		 After Width: | Height: | Size: 4.0 KiB  | 
| 
		 After Width: | Height: | Size: 911 B  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 673 B  | 
| 
		 After Width: | Height: | Size: 2.0 KiB  | 
| 
		 After Width: | Height: | Size: 878 B  | 
| 
		 After Width: | Height: | Size: 18 KiB  | 
| 
		 After Width: | Height: | Size: 653 B  | 
| 
		 After Width: | Height: | Size: 905 B  | 
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
		 After Width: | Height: | Size: 839 B  | 
| 
		 After Width: | Height: | Size: 5.9 KiB  | 
| 
		 After Width: | Height: | Size: 34 KiB  | 
| 
		 After Width: | Height: | Size: 26 KiB  | 
| 
		 After Width: | Height: | Size: 3.8 KiB  | 
| 
		 After Width: | Height: | Size: 23 KiB  | 
| 
		 After Width: | Height: | Size: 1.9 KiB  | 
| 
		 After Width: | Height: | Size: 2.3 KiB  | 
| 
		 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: 3.7 KiB  | 
| 
		 After Width: | Height: | Size: 5.0 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 912 KiB  | 
| 
		 After Width: | Height: | Size: 81 KiB  | 
| 
		 After Width: | Height: | Size: 46 KiB  | 
| 
		 After Width: | Height: | Size: 44 KiB  | 
| 
		 After Width: | Height: | Size: 46 KiB  | 
| 
		 After Width: | Height: | Size: 85 KiB  | 
| 
		 After Width: | Height: | Size: 97 KiB  | 
| 
		 After Width: | Height: | Size: 162 KiB  | 
| 
		 After Width: | Height: | Size: 407 KiB  | 
| 
		 After Width: | Height: | Size: 87 KiB  | 
| 
		 After Width: | Height: | Size: 134 KiB  | 
| 
		 After Width: | Height: | Size: 96 KiB  | 
| 
		 After Width: | Height: | Size: 107 KiB  | 
| 
		 After Width: | Height: | Size: 102 KiB  | 
| 
		 After Width: | Height: | Size: 74 KiB  | 
| 
		 After Width: | Height: | Size: 120 KiB  | 
| 
		 After Width: | Height: | Size: 353 KiB  | 
| 
		 After Width: | Height: | Size: 118 KiB  | 
| 
		 After Width: | Height: | Size: 15 KiB  | 
| 
		 After Width: | Height: | Size: 19 KiB  | 
| 
		 After Width: | Height: | Size: 184 KiB  | 
| 
		 After Width: | Height: | Size: 231 KiB  | 
| 
		 After Width: | Height: | Size: 71 KiB  | 
| 
		 After Width: | Height: | Size: 96 KiB  | 
| 
		 After Width: | Height: | Size: 265 KiB  | 
| 
		 After Width: | Height: | Size: 85 KiB  | 
| 
		 After Width: | Height: | Size: 114 KiB  | 
| 
		 After Width: | Height: | Size: 87 KiB  | 
| 
		 After Width: | Height: | Size: 103 KiB  | 
| 
		 After Width: | Height: | Size: 103 KiB  | 
| 
		 After Width: | Height: | Size: 410 KiB  | 
| 
		 After Width: | Height: | Size: 880 KiB  | 
| 
		 After Width: | Height: | Size: 95 KiB  | 
| 
		 After Width: | Height: | Size: 20 KiB  | 
@ -0,0 +1,78 @@ | 
				
			|||
.components{ | 
				
			|||
    margin: 40px !important; | 
				
			|||
    border-radius: 17px; | 
				
			|||
    padding-bottom: 25px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.heading{ | 
				
			|||
    margin-top:15px; | 
				
			|||
    margin-bottom:8px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.tile{ | 
				
			|||
    height: 125px; | 
				
			|||
    border-radius: 30px; | 
				
			|||
    display: flex; | 
				
			|||
    justify-content: center; | 
				
			|||
    flex-direction: column; | 
				
			|||
} | 
				
			|||
.tile:hover{ | 
				
			|||
  box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19); | 
				
			|||
} | 
				
			|||
.card:hover{ | 
				
			|||
  box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.chart{ | 
				
			|||
    margin: 40px !important; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.row_table{ | 
				
			|||
    margin: 40px !important; | 
				
			|||
    padding-bottom: 40px; | 
				
			|||
} | 
				
			|||
/* Basic styling for the header */ | 
				
			|||
.contracts-header { | 
				
			|||
  font-family: 'Poppins', 'Open Sans', sans-serif; | 
				
			|||
  font-size: 1.5rem; | 
				
			|||
  font-weight: 600; | 
				
			|||
  color: #333; | 
				
			|||
  margin-bottom: 1.5rem; | 
				
			|||
  padding-bottom: 0.5rem; | 
				
			|||
  position: relative; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/* Option 1: With subtle text shadow */ | 
				
			|||
.contracts-header-shadow { | 
				
			|||
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/* Option 2: With gradient text color */ | 
				
			|||
.contracts-header-gradient { | 
				
			|||
  background: linear-gradient(90deg, #3498db, #2980b9); | 
				
			|||
  -webkit-background-clip: text; | 
				
			|||
  background-clip: text; | 
				
			|||
  color: transparent; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/* Option 3: With icon prefix */ | 
				
			|||
.contracts-header-icon::before { | 
				
			|||
  content: "📄 "; | 
				
			|||
  margin-right: 8px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/* Option 4: With subtle background */ | 
				
			|||
.contracts-header-background { | 
				
			|||
  background-color: #f5f9ff; | 
				
			|||
  padding: 10px 15px; | 
				
			|||
  border-radius: 6px; | 
				
			|||
  border-bottom: none; | 
				
			|||
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/* Option 5: Uppercase with letter spacing */ | 
				
			|||
.contracts-header-uppercase { | 
				
			|||
  text-transform: uppercase; | 
				
			|||
  letter-spacing: 1.5px; | 
				
			|||
  font-size: 1.2rem; | 
				
			|||
} | 
				
			|||
| 
		 After Width: | Height: | Size: 8.0 KiB  | 
| 
		 After Width: | Height: | Size: 5.9 KiB  |