@ -0,0 +1,50 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
Fleet Rental Management |
||||
|
======================= |
||||
|
* This module will helps you to give the vehicles for Rent. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
* No additional configuration required |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
General Public License, Version 3 (AGPL-3). |
||||
|
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developer: (V17) Ashwin A, |
||||
|
(V16) Akhil Ashok, |
||||
|
(V15) Akshay ck, |
||||
|
(V14) Minhaj T |
||||
|
* Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import models |
||||
|
from . import reports |
||||
|
from . import wizard |
@ -0,0 +1,60 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
{ |
||||
|
'name': '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 is an application for Vehicle Rental System which helps in managing the rental of vehicles like car,van,bike, jeep etc. |
||||
|
It manages fleet/vehicle property by extending the basic fleet module of Odoo. |
||||
|
Currently fleet module does not have any connection with accounting module. |
||||
|
But in this module, we integrate the module with accounting also.""", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': "https://www.cybrosys.com", |
||||
|
'depends': ['account', 'fleet', 'mail'], |
||||
|
'data': [ |
||||
|
'security/fleet_rental_groups.xml', |
||||
|
'security/fleet_rental_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'data/fleet_rental_data.xml', |
||||
|
'data/ir_cron_data.xml', |
||||
|
'views/car_rental_contract_views.xml', |
||||
|
'views/car_rental_contract_checklist_views.xml', |
||||
|
'views/car_tools_views.xml', |
||||
|
'views/res_config_settings_views.xml', |
||||
|
'reports/report_fleet_rental.xml', |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_backend': [ |
||||
|
'fleet_rental/static/src/xml/timepicker.xml', |
||||
|
'fleet_rental/static/src/js/time_widget.js', |
||||
|
'fleet_rental/static/src/scss/timepicker.scss', |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': False, |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<data noupdate="1"> |
||||
|
<record id="sequence_car_rental" model="ir.sequence"> |
||||
|
<field name="name">Car Rental Sequence</field> |
||||
|
<field name="code">car.rental.sequence</field> |
||||
|
<field name="prefix">RENT/%(range_year)s/</field> |
||||
|
<field eval="1" name="number_next"/> |
||||
|
<field eval="1" name="number_increment"/> |
||||
|
<field eval="True" name="use_date_range"/> |
||||
|
<field name="padding">4</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
<!-- Creating fleet rental service product--> |
||||
|
<record model="product.product" id="fleet_service_product"> |
||||
|
<field name="name">Fleet Rental Service</field> |
||||
|
<field name="type">service</field> |
||||
|
</record> |
||||
|
<!-- Creating new state named In shop for model fleet.vehicle--> |
||||
|
<record id="vehicle_state_inshop" model="fleet.vehicle.state"> |
||||
|
<field name="name">In shop</field> |
||||
|
<field name="sequence">1</field> |
||||
|
</record> |
||||
|
<!-- Creating new state named Active for model fleet.vehicle--> |
||||
|
<record id="vehicle_state_active" model="fleet.vehicle.state"> |
||||
|
<field name="name">Active</field> |
||||
|
<field name="sequence">2</field> |
||||
|
</record> |
||||
|
<!-- Creating new state named Inactive for model fleet.vehicle--> |
||||
|
<record id="vehicle_state_inactive" model="fleet.vehicle.state"> |
||||
|
<field name="name">Inactive</field> |
||||
|
<field name="sequence">3</field> |
||||
|
</record> |
||||
|
<!-- Creating new state named Sold for model fleet.vehicle--> |
||||
|
<record id="vehicle_state_sold" model="fleet.vehicle.state"> |
||||
|
<field name="name">Sold</field> |
||||
|
<field name="sequence">4</field> |
||||
|
</record> |
||||
|
<!-- Creating new state named Rent for model fleet.vehicle--> |
||||
|
<record id="vehicle_state_rent" model="fleet.vehicle.state"> |
||||
|
<field name="name">Rent</field> |
||||
|
<field name="sequence">3</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,15 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<record id="cron_scheduler_for_fleet" model="ir.cron"> |
||||
|
<field name="name">Fleet scheduler</field> |
||||
|
<field name="model_id" ref="fleet_rental.model_car_rental_contract"/> |
||||
|
<field name="state">code</field> |
||||
|
<field name="code">model.fleet_scheduler()</field> |
||||
|
<field name="active" eval="True"/> |
||||
|
<field name="user_id" ref="base.user_root"/> |
||||
|
<field name="interval_number">1</field> |
||||
|
<field name="interval_type">days</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
<field name="doall" eval="False"/> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,6 @@ |
|||||
|
## Module <fleet_rental> |
||||
|
|
||||
|
#### 06.03.2024 |
||||
|
#### Version 17.0.1.0.0 |
||||
|
#### ADD |
||||
|
- Initial Commit for Fleet Rental Management |
@ -0,0 +1,30 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import account_move |
||||
|
from . import account_move_line |
||||
|
from . import car_rental_checklist |
||||
|
from . import car_rental_contract |
||||
|
from . import car_tools |
||||
|
from . import fleet_rental_line |
||||
|
from . import fleet_vehicle |
||||
|
from . import rental_fleet_reserved |
||||
|
from . import res_config_settings |
@ -0,0 +1,51 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AccountMove(models.Model): |
||||
|
"""Inherit account.move to add extra field """ |
||||
|
_inherit = 'account.move' |
||||
|
|
||||
|
fleet_rent_id = fields.Many2one('car.rental.contract', |
||||
|
string='Rental', |
||||
|
help='Invoice related to which ' |
||||
|
'rental record') |
||||
|
|
||||
|
is_first_invoice = fields.Boolean(string='Is First Rental Invoice', default=False, |
||||
|
help='Is First Rental Invoice') |
||||
|
|
||||
|
def button_cancel(self): |
||||
|
""" |
||||
|
Override the base method button_cancel to handle additional logic |
||||
|
for 'car.rental.contract' model based on 'fleet_rent_id'. |
||||
|
""" |
||||
|
res = super().button_cancel() |
||||
|
fleet_model = self.env['car.rental.contract'].search( |
||||
|
[('id', '=', self.fleet_rent_id.id)]) |
||||
|
if fleet_model.state == 'running': |
||||
|
fleet_model.state = 'running' |
||||
|
fleet_model.first_invoice_created = False |
||||
|
else: |
||||
|
fleet_model.state = 'checking' |
||||
|
return res |
||||
|
|
@ -0,0 +1,37 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import api, models |
||||
|
|
||||
|
|
||||
|
class AccountMoveLine(models.Model): |
||||
|
"""Inherit account.move.line""" |
||||
|
_inherit = 'account.move.line' |
||||
|
|
||||
|
@api.onchange('price_unit') |
||||
|
def _onchange_price_unit(self): |
||||
|
""" |
||||
|
Update the 'first_payment' field of the associated |
||||
|
'car.rental.contract' model when the 'price_unit' field changes. |
||||
|
""" |
||||
|
fleet_model = self.move_id.fleet_rent_id |
||||
|
if fleet_model: |
||||
|
fleet_model.first_payment = self.price_unit |
@ -0,0 +1,48 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class CarRentalChecklist(models.Model): |
||||
|
"""Model to add the checklist of rental""" |
||||
|
_name = 'car.rental.checklist' |
||||
|
|
||||
|
name = fields.Many2one('car.tools', string="Name", |
||||
|
help='Select car tools') |
||||
|
checklist_active = fields.Boolean(string="Available", |
||||
|
default=True, |
||||
|
help='Enable when the tool is available while checking') |
||||
|
checklist_number = fields.Many2one('car.rental.contract', |
||||
|
string="Checklist Number", |
||||
|
help='Number of checklist') |
||||
|
price = fields.Float(string="Price", |
||||
|
help='Price of the car tool') |
||||
|
company_id = fields.Many2one('res.company', string='Company', |
||||
|
default=lambda self: self.env.company, |
||||
|
help="Company this record owns") |
||||
|
|
||||
|
@api.onchange('name') |
||||
|
def onchange_name(self): |
||||
|
""" |
||||
|
Update the price based on the selected name. |
||||
|
""" |
||||
|
self.price = self.name.price |
@ -0,0 +1,744 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from datetime import datetime, date, timedelta |
||||
|
from odoo import api, fields, models, _ |
||||
|
from odoo.exceptions import UserError, ValidationError |
||||
|
|
||||
|
|
||||
|
class CarRentalContract(models.Model): |
||||
|
_name = 'car.rental.contract' |
||||
|
_inherit = 'mail.thread' |
||||
|
_description = 'Fleet Rental Management' |
||||
|
|
||||
|
image = fields.Binary(related='vehicle_id.image_128', |
||||
|
string="Image of Vehicle") |
||||
|
reserved_fleet_id = fields.Many2one('rental.fleet.reserved', |
||||
|
invisible=True, |
||||
|
copy=False) |
||||
|
name = fields.Char(string="Name", |
||||
|
default="Draft Contract", |
||||
|
readonly=True, |
||||
|
copy=False) |
||||
|
customer_id = fields.Many2one('res.partner', |
||||
|
required=True, |
||||
|
string='Customer', |
||||
|
help="Customer") |
||||
|
vehicle_id = fields.Many2one('fleet.vehicle', |
||||
|
string="Vehicle", |
||||
|
required=True, |
||||
|
help="Vehicle") |
||||
|
car_brand = fields.Many2one('fleet.vehicle.model.brand', |
||||
|
string="Fleet Brand", |
||||
|
size=50, |
||||
|
related='vehicle_id.model_id.brand_id', |
||||
|
store=True, |
||||
|
readonly=True) |
||||
|
car_color = fields.Char(string="Fleet Color", |
||||
|
size=50, |
||||
|
related='vehicle_id.color', |
||||
|
store=True, |
||||
|
copy=False, |
||||
|
default='#FFFFFF', |
||||
|
readonly=True) |
||||
|
cost = fields.Float(string="Rent Cost", |
||||
|
help="This fields is to determine the cost of rent", |
||||
|
required=True) |
||||
|
rent_start_date = fields.Date(string="Rent Start Date", |
||||
|
required=True, |
||||
|
default=str(date.today()), |
||||
|
help="Start date of contract", |
||||
|
track_visibility='onchange') |
||||
|
start_time = fields.Char(string="Start By", |
||||
|
help="Enter the contract starting hour") |
||||
|
end_time = fields.Char(string="End By", |
||||
|
help="Enter the contract Ending hour") |
||||
|
rent_by_hour = fields.Boolean(string="Rent By Hour", |
||||
|
help="Enable to start contract on " |
||||
|
"hour basis") |
||||
|
rent_end_date = fields.Date(string="Rent End Date", |
||||
|
required=True, |
||||
|
help="End date of contract", |
||||
|
track_visibility='onchange') |
||||
|
state = fields.Selection( |
||||
|
[('draft', 'Draft'), ('reserved', 'Reserved'), ('running', 'Running'), |
||||
|
('cancel', 'Cancel'), |
||||
|
('checking', 'Checking'), ('invoice', 'Invoice'), ('done', 'Done')], |
||||
|
string="State", default="draft", |
||||
|
copy=False, track_visibility='onchange') |
||||
|
notes = fields.Text(string="Details & Notes") |
||||
|
cost_generated = fields.Float(string='Recurring Cost', |
||||
|
help="Costs paid at regular intervals, depending on the cost frequency") |
||||
|
cost_frequency = fields.Selection( |
||||
|
[('no', 'No'), ('daily', 'Daily'), ('weekly', 'Weekly'), |
||||
|
('monthly', 'Monthly'), |
||||
|
('yearly', 'Yearly')], string="Recurring Cost Frequency", |
||||
|
help='Frequency of the recurring cost', required=True) |
||||
|
journal_type = fields.Many2one('account.journal', 'Journal', |
||||
|
default=lambda self: self.env[ |
||||
|
'account.journal'].search( |
||||
|
[('id', '=', 1)])) |
||||
|
account_type = fields.Many2one('account.account', 'Account', |
||||
|
default=lambda self: self.env[ |
||||
|
'account.account'].search( |
||||
|
[('id', '=', 17)])) |
||||
|
recurring_line = fields.One2many('fleet.rental.line', 'rental_number', |
||||
|
readonly=True, help="Recurring Invoices", |
||||
|
copy=False) |
||||
|
first_payment = fields.Float(string='First Payment', |
||||
|
help="Transaction/Office/Contract charge " |
||||
|
"amount, must paid by customer side " |
||||
|
"other " |
||||
|
"than recurrent payments", |
||||
|
track_visibility='onchange', |
||||
|
required=True) |
||||
|
first_payment_inv = fields.Many2one('account.move', copy=False) |
||||
|
first_invoice_created = fields.Boolean(string="First Invoice Created", |
||||
|
invisible=True, copy=False) |
||||
|
attachment_ids = fields.Many2many('ir.attachment', |
||||
|
'car_rent_checklist_ir_attachments_rel', |
||||
|
'rental_id', 'attachment_id', |
||||
|
string="Attachments", |
||||
|
help="Images of the vehicle before " |
||||
|
"contract/any attachments") |
||||
|
checklist_line = fields.One2many('car.rental.checklist', |
||||
|
'checklist_number', string="Checklist", |
||||
|
help="Facilities/Accessories, That should" |
||||
|
" verify when closing the contract.") |
||||
|
total = fields.Float(string="Total (Accessories/Tools)", readonly=True, |
||||
|
copy=False) |
||||
|
tools_missing_cost = fields.Float(string="Missing Cost", readonly=True, |
||||
|
copy=False, |
||||
|
help='This is the total amount of ' |
||||
|
'missing tools/accessories') |
||||
|
damage_cost = fields.Float(string="Damage Cost / Balance Amount", |
||||
|
copy=False) |
||||
|
damage_cost_sub = fields.Float(string="Damage Cost / Balance Amount", |
||||
|
readonly=True, |
||||
|
copy=False) |
||||
|
total_cost = fields.Float(string="Total", readonly=True, copy=False) |
||||
|
invoice_count = fields.Integer(compute='_invoice_count', |
||||
|
string='# Invoice', copy=False) |
||||
|
check_verify = fields.Boolean(compute='check_action_verify', copy=False) |
||||
|
sales_person = fields.Many2one('res.users', string='Sales Person', |
||||
|
default=lambda self: self.env.uid, |
||||
|
track_visibility='always') |
||||
|
read_only = fields.Boolean(string="Read Only", help="To make field read " |
||||
|
"only") |
||||
|
company_id = fields.Many2one('res.company', string='Company', |
||||
|
default=lambda self: self.env.company, |
||||
|
help="Company this record owns") |
||||
|
|
||||
|
def action_run(self): |
||||
|
""" |
||||
|
Set the state of the object to 'running'. |
||||
|
""" |
||||
|
self.state = 'running' |
||||
|
|
||||
|
@api.depends('checklist_line.checklist_active') |
||||
|
def check_action_verify(self): |
||||
|
""" |
||||
|
Update the 'check_verify' field based on the value of |
||||
|
'checklist_active' in 'checklist_line'. |
||||
|
""" |
||||
|
flag = 0 |
||||
|
for each in self: |
||||
|
for i in each.checklist_line: |
||||
|
if i.checklist_active: |
||||
|
continue |
||||
|
else: |
||||
|
flag = 1 |
||||
|
if flag == 1: |
||||
|
each.check_verify = False |
||||
|
else: |
||||
|
each.check_verify = True |
||||
|
|
||||
|
@api.constrains('rent_start_date', 'rent_end_date') |
||||
|
def validate_dates(self): |
||||
|
""" |
||||
|
Check the validity of the 'rent_start_date' and 'rent_end_date' |
||||
|
fields. |
||||
|
Raise a warning if 'rent_end_date' is earlier than |
||||
|
'rent_start_date'. |
||||
|
""" |
||||
|
if self.rent_end_date < self.rent_start_date: |
||||
|
raise UserError("Please select the valid end date.") |
||||
|
|
||||
|
def set_to_done(self): |
||||
|
""" |
||||
|
Set the state of the object to 'done' based on certain conditions related to invoices. |
||||
|
Raise a UserError if certain invoices are pending or the total cost is zero. |
||||
|
""" |
||||
|
invoice_ids = self.env['account.move'].search( |
||||
|
[('fleet_rent_id', '=', self.id)]) |
||||
|
if any(each.payment_state != 'paid' for each in |
||||
|
invoice_ids): |
||||
|
raise UserError("Some Invoices are pending") |
||||
|
else: |
||||
|
self.state = 'done' |
||||
|
|
||||
|
def _invoice_count(self): |
||||
|
""" |
||||
|
Calculate the count of invoices related to the current object. |
||||
|
Update the 'invoice_count' field accordingly. |
||||
|
""" |
||||
|
self.invoice_count = self.env['account.move'].search_count( |
||||
|
[('fleet_rent_id', '=', self.id)]) |
||||
|
|
||||
|
@api.constrains('state') |
||||
|
def state_changer(self): |
||||
|
""" |
||||
|
Handle state transitions and update the 'state_id' of the |
||||
|
associated vehicle based on the value of the 'state' field. |
||||
|
""" |
||||
|
if self.state == "running": |
||||
|
state_id = self.env.ref('fleet_rental.vehicle_state_rent').id |
||||
|
self.vehicle_id.write({'state_id': state_id}) |
||||
|
elif self.state == "cancel": |
||||
|
state_id = self.env.ref('fleet_rental.vehicle_state_active').id |
||||
|
self.vehicle_id.write({'state_id': state_id}) |
||||
|
elif self.state == "invoice": |
||||
|
self.rent_end_date = fields.Date.today() |
||||
|
state_id = self.env.ref('fleet_rental.vehicle_state_active').id |
||||
|
self.vehicle_id.write({'state_id': state_id}) |
||||
|
|
||||
|
@api.constrains('checklist_line', 'damage_cost') |
||||
|
def total_updater(self): |
||||
|
""" |
||||
|
Update various fields related to totals based on the values in |
||||
|
'checklist_line', 'damage_cost', and other relevant fields. |
||||
|
""" |
||||
|
total = 0.0 |
||||
|
tools_missing_cost = 0.0 |
||||
|
for records in self.checklist_line: |
||||
|
total += records.price |
||||
|
if not records.checklist_active: |
||||
|
tools_missing_cost += records.price |
||||
|
self.total = total |
||||
|
self.tools_missing_cost = tools_missing_cost |
||||
|
self.damage_cost_sub = self.damage_cost |
||||
|
self.total_cost = tools_missing_cost + self.damage_cost |
||||
|
|
||||
|
def fleet_scheduler1(self, rent_date): |
||||
|
""" |
||||
|
Perform actions related to fleet scheduling, including creating |
||||
|
invoices, managing recurring data, and sending email notifications. |
||||
|
""" |
||||
|
inv_obj = self.env['account.move'] |
||||
|
recurring_obj = self.env['fleet.rental.line'] |
||||
|
supplier = self.customer_id |
||||
|
product_id = self.env['product.product'].browse( |
||||
|
self.env.ref('fleet_rental.fleet_service_product').id) |
||||
|
if product_id.property_account_income_id.id: |
||||
|
income_account = product_id.property_account_income_id |
||||
|
elif product_id.categ_id.property_account_income_categ_id.id: |
||||
|
income_account = product_id.categ_id.property_account_income_categ_id |
||||
|
else: |
||||
|
raise UserError( |
||||
|
_('Please define income account for this product: "%s" (id:%d).') % ( |
||||
|
product_id.name, |
||||
|
product_id.id)) |
||||
|
inv_data = { |
||||
|
'ref': supplier.name, |
||||
|
'partner_id': supplier.id, |
||||
|
'journal_id': self.journal_type.id, |
||||
|
'invoice_origin': self.name, |
||||
|
'fleet_rent_id': self.id, |
||||
|
'invoice_payment_term_id': None, |
||||
|
'invoice_date_due': self.rent_end_date, |
||||
|
'move_type': 'out_invoice', |
||||
|
'invoice_line_ids': [(0, 0, { |
||||
|
'account_id': income_account.id, |
||||
|
'price_unit': self.cost_generated, |
||||
|
'quantity': 1, |
||||
|
'product_id': product_id.id, |
||||
|
})] |
||||
|
} |
||||
|
inv_id = inv_obj.create(inv_data) |
||||
|
|
||||
|
recurring_data = { |
||||
|
'name': self.vehicle_id.name, |
||||
|
'date_today': rent_date, |
||||
|
'account_info': income_account.name, |
||||
|
'rental_number': self.id, |
||||
|
'recurring_amount': self.cost_generated, |
||||
|
'invoice_number': inv_id.id, |
||||
|
'invoice_ref': inv_id.id, |
||||
|
} |
||||
|
recurring_obj.create(recurring_data) |
||||
|
mail_content = _( |
||||
|
'<h3>Reminder Recurrent Payment!</h3><br/>Hi %s, <br/> This is to remind you that the ' |
||||
|
'recurrent payment for the ' |
||||
|
'rental contract has to be done.' |
||||
|
'Please make the payment at the earliest.' |
||||
|
'<br/><br/>' |
||||
|
'Please find the details below:<br/><br/>' |
||||
|
'<table><tr><td>Contract Ref<td/><td> %s<td/><tr/>' |
||||
|
'<tr/><tr><td>Amount <td/><td> %s<td/><tr/>' |
||||
|
'<tr/><tr><td>Due Date <td/><td> %s<td/><tr/>' |
||||
|
'<tr/><tr><td>Responsible Person <td/><td> %s, %s<td/><tr/><table/>') % \ |
||||
|
(self.customer_id.name, self.name, inv_id.amount_total, |
||||
|
inv_id.invoice_date_due, |
||||
|
inv_id.user_id.name, |
||||
|
inv_id.user_id.phone) |
||||
|
main_content = { |
||||
|
'subject': "Reminder Recurrent Payment!", |
||||
|
'author_id': self.env.user.partner_id.id, |
||||
|
'body_html': mail_content, |
||||
|
'email_to': self.customer_id.email, |
||||
|
} |
||||
|
self.env['mail.mail'].create(main_content).send() |
||||
|
|
||||
|
@api.model |
||||
|
def fleet_scheduler(self): |
||||
|
""" |
||||
|
Perform fleet scheduling operations, including creating invoices, |
||||
|
managing recurring data, and sending email notifications. |
||||
|
""" |
||||
|
inv_obj = self.env['account.move'] |
||||
|
recurring_obj = self.env['fleet.rental.line'] |
||||
|
today = date.today() |
||||
|
for records in self.search([]): |
||||
|
start_date = datetime.strptime(str(records.rent_start_date), |
||||
|
'%Y-%m-%d').date() |
||||
|
end_date = datetime.strptime(str(records.rent_end_date), |
||||
|
'%Y-%m-%d').date() |
||||
|
if end_date >= date.today(): |
||||
|
temp = 0 |
||||
|
if records.cost_frequency == 'daily': |
||||
|
temp = 1 |
||||
|
elif records.cost_frequency == 'weekly': |
||||
|
week_days = (date.today() - start_date).days |
||||
|
if week_days % 7 == 0 and week_days != 0: |
||||
|
temp = 1 |
||||
|
elif records.cost_frequency == 'monthly': |
||||
|
if start_date.day == date.today().day and start_date != date.today(): |
||||
|
temp = 1 |
||||
|
elif records.cost_frequency == 'yearly': |
||||
|
if start_date.day == date.today().day and start_date.month == date.today().month and \ |
||||
|
start_date != date.today(): |
||||
|
temp = 1 |
||||
|
if temp == 1 and records.cost_frequency != "no" and records.state == "running": |
||||
|
supplier = records.customer_id |
||||
|
product_id = self.env['product.product'].browse( |
||||
|
self.env.ref('fleet_rental.fleet_service_product').id) |
||||
|
if product_id.property_account_income_id.id: |
||||
|
income_account = product_id.property_account_income_id |
||||
|
elif product_id.categ_id.property_account_income_categ_id.id: |
||||
|
income_account = product_id.categ_id.property_account_income_categ_id |
||||
|
else: |
||||
|
raise UserError( |
||||
|
_('Please define income account for this product: "%s" (id:%d).') % ( |
||||
|
product_id.name, |
||||
|
product_id.id)) |
||||
|
inv_data = { |
||||
|
'ref': supplier.name, |
||||
|
'partner_id': supplier.id, |
||||
|
'currency_id': records.account_type.company_id.currency_id.id, |
||||
|
'journal_id': records.journal_type.id, |
||||
|
'invoice_origin': records.name, |
||||
|
'fleet_rent_id': records.id, |
||||
|
'invoice_date': today, |
||||
|
'company_id': records.account_type.company_id.id, |
||||
|
'invoice_payment_term_id': None, |
||||
|
'invoice_date_due': records.rent_end_date, |
||||
|
'move_type': 'out_invoice', |
||||
|
'invoice_line_ids': [(0, 0, { |
||||
|
'account_id': income_account.id, |
||||
|
'price_unit': records.cost_generated, |
||||
|
'quantity': 1, |
||||
|
'product_id': product_id.id, |
||||
|
})] |
||||
|
} |
||||
|
inv_id = inv_obj.create(inv_data) |
||||
|
recurring_data = { |
||||
|
'name': records.vehicle_id.name, |
||||
|
'date_today': today, |
||||
|
'account_info': income_account.name, |
||||
|
'rental_number': records.id, |
||||
|
'recurring_amount': records.cost_generated, |
||||
|
'invoice_number': inv_id.id, |
||||
|
'invoice_ref': inv_id.id, |
||||
|
} |
||||
|
recurring_obj.create(recurring_data) |
||||
|
|
||||
|
mail_content = _( |
||||
|
'<h3>Reminder Recurrent Payment!</h3><br/>Hi %s, <br/> This is to remind you that the ' |
||||
|
'recurrent payment for the ' |
||||
|
'rental contract has to be done.' |
||||
|
'Please make the payment at the earliest.' |
||||
|
'<br/><br/>' |
||||
|
'Please find the details below:<br/><br/>' |
||||
|
'<table><tr><td>Contract Ref<td/><td> %s<td/><tr/>' |
||||
|
'<tr/><tr><td>Amount <td/><td> %s<td/><tr/>' |
||||
|
'<tr/><tr><td>Due Date <td/><td> %s<td/><tr/>' |
||||
|
'<tr/><tr><td>Responsible Person <td/><td> %s, %s<td/><tr/><table/>') % \ |
||||
|
(self.customer_id.name, self.name, |
||||
|
inv_id.amount_total, |
||||
|
inv_id.invoice_date_due, |
||||
|
inv_id.user_id.name, |
||||
|
inv_id.user_id.mobile) |
||||
|
main_content = { |
||||
|
'subject': "Reminder Recurrent Payment!", |
||||
|
'author_id': self.env.user.partner_id.id, |
||||
|
'body_html': mail_content, |
||||
|
'email_to': self.customer_id.email, |
||||
|
} |
||||
|
self.env['mail.mail'].create(main_content).send() |
||||
|
else: |
||||
|
if self.state == 'running': |
||||
|
records.state = "checking" |
||||
|
|
||||
|
def action_verify(self): |
||||
|
""" |
||||
|
Verifies the damage cost or missing cost |
||||
|
""" |
||||
|
self.state = "invoice" |
||||
|
self.reserved_fleet_id.unlink() |
||||
|
self.rent_end_date = fields.Date.today() |
||||
|
self.vehicle_id.rental_check_availability = True |
||||
|
product_id = self.env['product.product'].browse( |
||||
|
self.env.ref('fleet_rental.fleet_service_product').id) |
||||
|
if product_id.property_account_income_id.id: |
||||
|
income_account = product_id.property_account_income_id |
||||
|
elif product_id.categ_id.property_account_income_categ_id.id: |
||||
|
income_account = product_id.categ_id.property_account_income_categ_id |
||||
|
else: |
||||
|
raise UserError( |
||||
|
_('Please define income account for this product: "%s" (id:%d).') % ( |
||||
|
product_id.name, |
||||
|
product_id.id)) |
||||
|
if self.total_cost != 0: |
||||
|
supplier = self.customer_id |
||||
|
inv_data = { |
||||
|
'ref': supplier.name, |
||||
|
'move_type': 'out_invoice', |
||||
|
'partner_id': supplier.id, |
||||
|
'currency_id': self.account_type.company_id.currency_id.id, |
||||
|
'journal_id': self.journal_type.id, |
||||
|
'invoice_origin': self.name, |
||||
|
'fleet_rent_id': self.id, |
||||
|
'company_id': self.account_type.company_id.id, |
||||
|
'invoice_date_due': self.rent_end_date, |
||||
|
'invoice_line_ids': [(0, 0, { |
||||
|
'name': "Damage/Tools missing cost", |
||||
|
'account_id': income_account.id, |
||||
|
'price_unit': self.total_cost, |
||||
|
'quantity': 1, |
||||
|
'product_id': product_id.id, |
||||
|
})] |
||||
|
} |
||||
|
inv_id = self.env['account.move'].create(inv_data) |
||||
|
list_view_id = self.env.ref('account.view_move_form', False) |
||||
|
form_view_id = self.env.ref('account.view_move_tree', False) |
||||
|
result = { |
||||
|
'name': 'Fleet Rental Invoices', |
||||
|
'view_mode': 'form', |
||||
|
'res_model': 'account.move', |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'views': [(list_view_id.id, 'tree'), |
||||
|
(form_view_id.id, 'form')], |
||||
|
} |
||||
|
if len(inv_id) > 1: |
||||
|
result['domain'] = "[('id','in',%s)]" % inv_id.ids |
||||
|
else: |
||||
|
result = {'type': 'ir.actions.act_window_close'} |
||||
|
return result |
||||
|
|
||||
|
def action_confirm(self): |
||||
|
""" |
||||
|
Confirm the rental contract, check vehicle availability, update |
||||
|
state to "reserved," generate a sequence code, and send a |
||||
|
confirmation email. |
||||
|
""" |
||||
|
self.vehicle_id.rental_check_availability = False |
||||
|
check_availability = 0 |
||||
|
for each in self.vehicle_id.rental_reserved_time: |
||||
|
if each.date_from <= self.rent_start_date <= each.date_to: |
||||
|
check_availability = 1 |
||||
|
elif self.rent_start_date < each.date_from: |
||||
|
if each.date_from <= self.rent_end_date <= each.date_to: |
||||
|
check_availability = 1 |
||||
|
elif self.rent_end_date > each.date_to: |
||||
|
check_availability = 1 |
||||
|
else: |
||||
|
check_availability = 0 |
||||
|
else: |
||||
|
check_availability = 0 |
||||
|
if check_availability == 0: |
||||
|
reserved_id = self.vehicle_id.rental_reserved_time.create( |
||||
|
{'customer_id': self.customer_id.id, |
||||
|
'date_from': self.rent_start_date, |
||||
|
'date_to': self.rent_end_date, |
||||
|
'reserved_obj_id': self.vehicle_id.id |
||||
|
}) |
||||
|
self.write({'reserved_fleet_id': reserved_id.id}) |
||||
|
else: |
||||
|
raise UserError( |
||||
|
'Sorry This vehicle is already booked by another customer') |
||||
|
self.state = "reserved" |
||||
|
sequence_code = 'car.rental.sequence' |
||||
|
order_date = self.create_date |
||||
|
order_date = str(order_date)[0:10] |
||||
|
self.name = self.env['ir.sequence'] \ |
||||
|
.with_context(ir_sequence_date=order_date).next_by_code( |
||||
|
sequence_code) |
||||
|
mail_content = _( |
||||
|
'<h3>Order Confirmed!</h3><br/>Hi %s, <br/> This is to notify that your rental contract has ' |
||||
|
'been confirmed. <br/><br/>' |
||||
|
'Please find the details below:<br/><br/>' |
||||
|
'<table><tr><td>Reference Number<td/><td> %s<td/><tr/>' |
||||
|
'<tr><td>Time Range <td/><td> %s to %s <td/><tr/><tr><td>Vehicle <td/><td> %s<td/><tr/>' |
||||
|
'<tr><td>Point Of Contact<td/><td> %s , %s<td/><tr/><table/>') % \ |
||||
|
(self.customer_id.name, self.name, self.rent_start_date, |
||||
|
self.rent_end_date, |
||||
|
self.vehicle_id.name, self.sales_person.name, |
||||
|
self.sales_person.phone) |
||||
|
main_content = { |
||||
|
'subject': _('Confirmed: %s - %s') % |
||||
|
(self.name, self.vehicle_id.name), |
||||
|
'author_id': self.env.user.partner_id.id, |
||||
|
'body_html': mail_content, |
||||
|
'email_to': self.customer_id.email, |
||||
|
} |
||||
|
self.env['mail.mail'].create(main_content).send() |
||||
|
|
||||
|
def action_cancel(self): |
||||
|
""" |
||||
|
Cancel the rental contract. |
||||
|
Update the state to "cancel" and delete the associated reserved |
||||
|
fleet ID if it exists. |
||||
|
""" |
||||
|
self.state = "cancel" |
||||
|
self.vehicle_id.rental_check_availability = True |
||||
|
if self.reserved_fleet_id: |
||||
|
self.reserved_fleet_id.unlink() |
||||
|
|
||||
|
def force_checking(self): |
||||
|
""" |
||||
|
Force the checking of payment status for associated invoices. |
||||
|
If all invoices are marked as paid, update the state to "checking." |
||||
|
Otherwise, raise a UserError indicating that some invoices are |
||||
|
pending. |
||||
|
""" |
||||
|
invoice_ids = self.env['account.move'].search( |
||||
|
[('fleet_rent_id', '=', self.id)]) |
||||
|
if any(each.payment_state != 'paid' for each in invoice_ids): |
||||
|
raise UserError("Some Invoices are pending") |
||||
|
else: |
||||
|
self.state = "checking" |
||||
|
|
||||
|
def action_view_invoice(self): |
||||
|
""" |
||||
|
Display the associated invoices for the current record. |
||||
|
Construct the appropriate view configurations based on the number |
||||
|
of invoices found. |
||||
|
""" |
||||
|
inv_obj = self.env['account.move'].search( |
||||
|
[('fleet_rent_id', '=', self.id)]) |
||||
|
inv_ids = [] |
||||
|
for each in inv_obj: |
||||
|
inv_ids.append(each.id) |
||||
|
view_id = self.env.ref('account.view_move_form').id |
||||
|
if inv_ids: |
||||
|
if len(inv_ids) <= 1: |
||||
|
value = { |
||||
|
'view_type': 'form', |
||||
|
'view_mode': 'form', |
||||
|
'res_model': 'account.move', |
||||
|
'view_id': view_id, |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': _('Invoice'), |
||||
|
'res_id': inv_ids and inv_ids[0] |
||||
|
} |
||||
|
else: |
||||
|
value = { |
||||
|
'domain': [('fleet_rent_id', '=', self.id)], |
||||
|
'view_type': 'form', |
||||
|
'view_mode': 'tree,form', |
||||
|
'res_model': 'account.move', |
||||
|
'view_id': False, |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': _('Invoice'), |
||||
|
} |
||||
|
return value |
||||
|
|
||||
|
def action_invoice_create(self): |
||||
|
""" |
||||
|
Create an invoice for the rental contract. |
||||
|
Calculate the rental duration and iterate over each day to create |
||||
|
invoices. |
||||
|
Create the first payment invoice, add relevant invoice line data, |
||||
|
and send an email notification for the received payment. |
||||
|
""" |
||||
|
for each in self: |
||||
|
rent_date = self.rent_start_date |
||||
|
if each.cost_frequency != 'no' and rent_date < date.today(): |
||||
|
rental_days = (date.today() - rent_date).days |
||||
|
if each.cost_frequency == 'weekly': |
||||
|
rental_days = int(rental_days / 7) |
||||
|
if each.cost_frequency == 'monthly': |
||||
|
rental_days = int(rental_days / 30) |
||||
|
if each.cost_frequency == 'yearly': |
||||
|
rental_days = int(rental_days / 365) |
||||
|
for each1 in range(0, rental_days + 1): |
||||
|
if rent_date > datetime.strptime(str(each.rent_end_date), |
||||
|
"%Y-%m-%d").date(): |
||||
|
break |
||||
|
each.fleet_scheduler1(rent_date) |
||||
|
if each.cost_frequency == 'daily': |
||||
|
rent_date = rent_date + timedelta(days=1) |
||||
|
if each.cost_frequency == 'weekly': |
||||
|
rent_date = rent_date + timedelta(days=7) |
||||
|
if each.cost_frequency == 'monthly': |
||||
|
rent_date = rent_date + timedelta(days=30) |
||||
|
if each.cost_frequency == 'yearly': |
||||
|
rent_date = rent_date + timedelta(days=365) |
||||
|
self.first_invoice_created = True |
||||
|
inv_obj = self.env['account.move'] |
||||
|
supplier = self.customer_id |
||||
|
inv_data = { |
||||
|
'ref': supplier.name, |
||||
|
'move_type': 'out_invoice', |
||||
|
'partner_id': supplier.id, |
||||
|
'currency_id': self.account_type.company_id.currency_id.id, |
||||
|
'journal_id': self.journal_type.id, |
||||
|
'invoice_origin': self.name, |
||||
|
'fleet_rent_id': self.id, |
||||
|
'company_id': self.account_type.company_id.id, |
||||
|
'invoice_date_due': self.rent_end_date, |
||||
|
'is_first_invoice': True, |
||||
|
} |
||||
|
inv_id = inv_obj.create(inv_data) |
||||
|
self.first_payment_inv = inv_id.id |
||||
|
product_id = self.env['product.product'].browse( |
||||
|
self.env.ref('fleet_rental.fleet_service_product').id) |
||||
|
if product_id.property_account_income_id.id: |
||||
|
income_account = product_id.property_account_income_id.id |
||||
|
elif product_id.categ_id.property_account_income_categ_id.id: |
||||
|
income_account = product_id.categ_id.property_account_income_categ_id.id |
||||
|
else: |
||||
|
raise UserError( |
||||
|
_('Please define income account for this product: "%s" (id:%d).') % ( |
||||
|
product_id.name, |
||||
|
product_id.id)) |
||||
|
|
||||
|
if inv_id: |
||||
|
list_value = [(0, 0, { |
||||
|
'name': self.vehicle_id.name, |
||||
|
'price_unit': self.first_payment, |
||||
|
'quantity': 1.0, |
||||
|
'account_id': income_account, |
||||
|
'product_id': product_id.id, |
||||
|
'move_id': inv_id.id, |
||||
|
})] |
||||
|
inv_id.write({'invoice_line_ids': list_value}) |
||||
|
action = self.env.ref('account.action_move_out_invoice_type') |
||||
|
result = { |
||||
|
'name': action.name, |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'views': [[False, 'form']], |
||||
|
'target': 'current', |
||||
|
'res_id': inv_id.id, |
||||
|
'res_model': 'account.move', |
||||
|
} |
||||
|
return result |
||||
|
|
||||
|
def action_extend_rent(self): |
||||
|
""" |
||||
|
Set the 'read_only' attribute to True, indicating that the rent |
||||
|
extension action is being performed and the corresponding fields |
||||
|
should be made read-only. |
||||
|
|
||||
|
This method is typically used in the context of extending a rental |
||||
|
agreement. |
||||
|
""" |
||||
|
self.read_only = True |
||||
|
|
||||
|
def action_confirm_extend_rent(self): |
||||
|
""" |
||||
|
Confirm the extension of a rental agreement and update the rental |
||||
|
reserved time for the associated vehicle. |
||||
|
|
||||
|
This method sets the 'date_to' field of the rental reserved time |
||||
|
for the vehicle to the specified 'rent_end_date', indicating the |
||||
|
extended rental period. After confirming the extension, the |
||||
|
'read_only' attribute is set to False to allow further |
||||
|
modifications. |
||||
|
|
||||
|
This method is typically called when a user confirms the extension |
||||
|
of a rental. |
||||
|
""" |
||||
|
self.vehicle_id.rental_reserved_time.write( |
||||
|
{ |
||||
|
'date_to': self.rent_end_date, |
||||
|
}) |
||||
|
self.read_only = False |
||||
|
|
||||
|
@api.constrains('start_time', 'end_time', 'rent_start_date', |
||||
|
'rent_end_date') |
||||
|
def validate_time(self): |
||||
|
""" |
||||
|
Validate the time constraints for a rental agreement. |
||||
|
|
||||
|
This method is used as a constraint to ensure that the specified |
||||
|
start and end times are valid, especially when renting by the hour. |
||||
|
If renting by the hour, it checks whether the end time is greater |
||||
|
than the start time when the rental start and end |
||||
|
dates are the same. |
||||
|
|
||||
|
:raises ValidationError: If the time constraints are not met, a |
||||
|
validation error is raised with a relevant |
||||
|
error message. |
||||
|
""" |
||||
|
if self.rent_by_hour: |
||||
|
start_time = datetime.strptime(self.start_time, "%H:%M").time() |
||||
|
end_time = datetime.strptime(self.end_time, "%H:%M").time() |
||||
|
if (self.rent_end_date == self.rent_start_date and |
||||
|
end_time <= start_time): |
||||
|
raise ValidationError("Please choose a different end time") |
||||
|
|
||||
|
@api.constrains('rent_end_date') |
||||
|
def validate_on_read_only(self): |
||||
|
old_date = self.vehicle_id.rental_reserved_time.date_to |
||||
|
if self.read_only: |
||||
|
if self.rent_end_date <= old_date: |
||||
|
raise ValidationError( |
||||
|
f"Please choose a date greater that {old_date}") |
||||
|
|
||||
|
def action_discard_extend(self): |
||||
|
""" |
||||
|
Validate the 'rent_end_date' when the rental agreement is in |
||||
|
read-only mode. |
||||
|
|
||||
|
This constraint checks if the rental agreement is marked as |
||||
|
read-only, indicating that it has been extended or modified. If in |
||||
|
read-only mode, it compares the 'rent_end_date' with the existing |
||||
|
'date_to' value in the rental reserved time of the associated |
||||
|
vehicle. It ensures that the 'rent_end_date' is greater than the |
||||
|
existing date to maintain consistency. |
||||
|
|
||||
|
:raises ValidationError: If the 'rent_end_date' is not greater than |
||||
|
the existing 'date_to', a validation error |
||||
|
is raised with a relevant error message. |
||||
|
""" |
||||
|
self.read_only = False |
||||
|
self.rent_end_date = self.vehicle_id.rental_reserved_time.date_to |
@ -0,0 +1,30 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class CarTools(models.Model): |
||||
|
"""Model to add the tools for the car""" |
||||
|
_name = 'car.tools' |
||||
|
|
||||
|
name = fields.Char(string="Name", help='Name of the car tool') |
||||
|
price = fields.Float(string="Price", help='Price of the car tool') |
@ -0,0 +1,61 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class FleetRentalLine(models.Model): |
||||
|
_name = 'fleet.rental.line' |
||||
|
|
||||
|
name = fields.Char(string='Description', help='Name') |
||||
|
date_today = fields.Date(string='Date', help='Today date') |
||||
|
account_info = fields.Char(string='Account', help='Info of the account') |
||||
|
recurring_amount = fields.Float(string='Amount', |
||||
|
help='Amount of the recurring invoice') |
||||
|
rental_number = fields.Many2one('car.rental.contract', |
||||
|
string='Rental Number', |
||||
|
help='Reference of the rental') |
||||
|
payment_info = fields.Char(compute='paid_info', string='Payment Stage', |
||||
|
default='draft', help='Info of the payment') |
||||
|
invoice_number = fields.Integer(string='Invoice ID', |
||||
|
help='ID of the invoice') |
||||
|
invoice_ref = fields.Many2one('account.move', |
||||
|
string='Invoice Ref', |
||||
|
help='Reference of the invoice') |
||||
|
date_due = fields.Date(string='Due Date', |
||||
|
help='Due date ', |
||||
|
related='invoice_ref.invoice_date_due') |
||||
|
|
||||
|
def paid_info(self): |
||||
|
""" |
||||
|
Retrieve payment information for the current record. |
||||
|
Check the state of the associated invoice based on the provided |
||||
|
invoice number. |
||||
|
If the record exists, set the payment_info field to the state of |
||||
|
the invoice. |
||||
|
Otherwise, set the payment_info field to 'Record Deleted'. |
||||
|
""" |
||||
|
for each in self: |
||||
|
if self.env['account.move'].browse(each.invoice_number): |
||||
|
each.payment_info = self.env['account.move'].browse( |
||||
|
each.invoice_number).state |
||||
|
else: |
||||
|
each.payment_info = 'Record Deleted' |
@ -0,0 +1,47 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class EmployeeFleet(models.Model): |
||||
|
"""Inherit fleet.vehicle""" |
||||
|
_inherit = 'fleet.vehicle' |
||||
|
|
||||
|
rental_check_availability = fields.Boolean(default=True, copy=False) |
||||
|
color = fields.Char(string='Color', default='#FFFFFF') |
||||
|
rental_reserved_time = fields.One2many('rental.fleet.reserved', |
||||
|
'reserved_obj_id', |
||||
|
string='Reserved Time', |
||||
|
help='Reserved rental time', |
||||
|
readonly=1, |
||||
|
ondelete='cascade') |
||||
|
fuel_type = fields.Selection([('gasoline', 'Gasoline'), |
||||
|
('diesel', 'Diesel'), |
||||
|
('electric', 'Electric'), |
||||
|
('hybrid', 'Hybrid'), |
||||
|
('petrol', 'Petrol')], |
||||
|
string='Fuel Type', help='Fuel Used by the vehicle') |
||||
|
|
||||
|
_sql_constraints = [('vin_sn_unique', 'unique (vin_sn)', |
||||
|
"Chassis Number already exists !"), |
||||
|
('license_plate_unique', 'unique (license_plate)', |
||||
|
"License plate already exists !")] |
@ -0,0 +1,38 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class FleetReservedTime(models.Model): |
||||
|
_name = "rental.fleet.reserved" |
||||
|
_description = "Reserved Time" |
||||
|
|
||||
|
customer_id = fields.Many2one('res.partner', |
||||
|
string='Customer', |
||||
|
help='Select customer') |
||||
|
date_from = fields.Date(string='Reserved Date From', |
||||
|
help='Select the start date of rental ') |
||||
|
date_to = fields.Date(string='Reserved Date To', |
||||
|
help='Select the end date of rental') |
||||
|
reserved_obj_id = fields.Many2one('fleet.vehicle', |
||||
|
string='Reserved Object', |
||||
|
help='Reserved Object') |
@ -0,0 +1,39 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResConfigSettings(models.TransientModel): |
||||
|
"""Inherit configuration settings""" |
||||
|
_inherit = 'res.config.settings' |
||||
|
|
||||
|
def _get_default_product(self): |
||||
|
""" |
||||
|
Retrieve the default product ID for fleet services. |
||||
|
""" |
||||
|
return self.env.ref('fleet_rental.fleet_service_product').id |
||||
|
|
||||
|
fleet_service_product_id = fields.Many2one( |
||||
|
'product.template', |
||||
|
string="Product", |
||||
|
config_parameter='fleet_service_product_id', |
||||
|
default=_get_default_product) |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import report_fleet_rental |
@ -0,0 +1,117 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import models, fields, tools |
||||
|
|
||||
|
|
||||
|
class FleetRentalReport(models.Model): |
||||
|
_name = "report.fleet.rental" |
||||
|
_description = "Fleet Rental Analysis" |
||||
|
_order = 'name desc' |
||||
|
_auto = False |
||||
|
|
||||
|
name = fields.Char(string="Name") |
||||
|
customer_id = fields.Many2one('res.partner') |
||||
|
vehicle_id = fields.Many2one('fleet.vehicle') |
||||
|
car_brand = fields.Char(string="Car Brand") |
||||
|
car_color = fields.Char(string="Car Color") |
||||
|
cost = fields.Float(string="Rent Cost") |
||||
|
rent_start_date = fields.Date(string="Rent Start Date") |
||||
|
rent_end_date = fields.Date(string="Rent End Date") |
||||
|
state = fields.Selection( |
||||
|
[('draft', 'Draft'), ('running', 'Running'), ('cancel', 'Cancel'), |
||||
|
('checking', 'Checking'), ('done', 'Done')], string="State") |
||||
|
cost_frequency = fields.Selection( |
||||
|
[('no', 'No'), ('daily', 'Daily'), ('weekly', 'Weekly'), |
||||
|
('monthly', 'Monthly'), |
||||
|
('yearly', 'Yearly')], string="Recurring Cost Frequency") |
||||
|
total = fields.Float(string="Total(Tools)") |
||||
|
tools_missing_cost = fields.Float(string="Tools missing cost") |
||||
|
damage_cost = fields.Float(string="Damage cost") |
||||
|
damage_cost_sub = fields.Float(string="Damage cost") |
||||
|
total_cost = fields.Float(string="Total cost") |
||||
|
|
||||
|
|
||||
|
def _select(self): |
||||
|
""" |
||||
|
Construct a SQL select query string with specific fields. |
||||
|
""" |
||||
|
select_str = """ |
||||
|
SELECT |
||||
|
(select 1 ) AS nbr, |
||||
|
t.id as id, |
||||
|
t.name as name, |
||||
|
t.car_brand as car_brand, |
||||
|
t.customer_id as customer_id, |
||||
|
t.vehicle_id as vehicle_id, |
||||
|
t.car_color as car_color, |
||||
|
t.cost as cost, |
||||
|
t.rent_start_date as rent_start_date, |
||||
|
t.rent_end_date as rent_end_date, |
||||
|
t.state as state, |
||||
|
t.cost_frequency as cost_frequency, |
||||
|
t.total as total, |
||||
|
t.tools_missing_cost as tools_missing_cost, |
||||
|
t.damage_cost as damage_cost, |
||||
|
t.damage_cost_sub as damage_cost_sub, |
||||
|
t.total_cost as total_cost |
||||
|
""" |
||||
|
return select_str |
||||
|
|
||||
|
def _group_by(self): |
||||
|
""" |
||||
|
Construct a SQL GROUP BY query string with specific fields. |
||||
|
""" |
||||
|
group_by_str = """ |
||||
|
GROUP BY |
||||
|
t.id, |
||||
|
name, |
||||
|
car_brand, |
||||
|
customer_id, |
||||
|
vehicle_id, |
||||
|
car_color, |
||||
|
cost, |
||||
|
rent_start_date, |
||||
|
rent_end_date, |
||||
|
state, |
||||
|
cost_frequency, |
||||
|
total, |
||||
|
tools_missing_cost, |
||||
|
damage_cost, |
||||
|
damage_cost_sub, |
||||
|
total_cost |
||||
|
""" |
||||
|
return group_by_str |
||||
|
|
||||
|
def init(self): |
||||
|
""" |
||||
|
Initialize the module and create a database view for reporting |
||||
|
fleet rentals. |
||||
|
Drop the existing 'report_fleet_rental' view if it already exists. |
||||
|
Create a new view with the SQL select and group by queries. |
||||
|
""" |
||||
|
tools.sql.drop_view_if_exists(self._cr, 'report_fleet_rental') |
||||
|
self._cr.execute(""" |
||||
|
CREATE view report_fleet_rental as |
||||
|
%s |
||||
|
FROM car_rental_contract t |
||||
|
%s |
||||
|
""" % (self._select(), self._group_by())) |
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<!-- Report fleet rental pivot view --> |
||||
|
<record id="report_fleet_rental_view_pivot" model="ir.ui.view"> |
||||
|
<field name="name">report.fleet.rental.view.pivot</field> |
||||
|
<field name="model">report.fleet.rental</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<pivot string="Fleet Rental Analysis" display_quantity="true" |
||||
|
disable_linking="True"> |
||||
|
<field name="name" type="row"/> |
||||
|
</pivot> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Action for report fleet rental--> |
||||
|
<record id="action_fleet_rental_analysis" model="ir.actions.act_window"> |
||||
|
<field name="name">Fleet Rental Analysis</field> |
||||
|
<field name="res_model">report.fleet.rental</field> |
||||
|
<field name="view_mode">pivot</field> |
||||
|
<field name="context">{'group_by_no_leaf':1,'group_by':[]}</field> |
||||
|
<field name="help">This report allows you to analyse the performance of your |
||||
|
Fleet Rental. |
||||
|
</field> |
||||
|
</record> |
||||
|
<menuitem name="Fleet Rental Analysis" action="action_fleet_rental_analysis" |
||||
|
id="menu_fleet_rental_analysis" parent="fleet.menu_fleet_reporting" |
||||
|
sequence="1"/> |
||||
|
</data> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,31 @@ |
|||||
|
<?xml version="1.0" ?> |
||||
|
<odoo> |
||||
|
<!-- Group Rental User--> |
||||
|
<record id="fleet_rental_group_user" model="res.groups"> |
||||
|
<field name="name">Rental User</field> |
||||
|
<field name="category_id" ref="fleet.module_fleet_category"/> |
||||
|
<field name="implied_ids" eval="[(4, ref('base.group_user')), (4, ref('fleet.fleet_group_user')), |
||||
|
(4, ref('account.group_account_user'))]"/> |
||||
|
</record> |
||||
|
<!-- Group Manager--> |
||||
|
<record id="fleet.fleet_group_manager" model="res.groups"> |
||||
|
<field name="name">Manager</field> |
||||
|
<field name="implied_ids" |
||||
|
eval="[(4, ref('fleet.fleet_group_user')), (4, ref('fleet_rental_group_user'))]"/> |
||||
|
<field name="category_id" ref="fleet.module_fleet_category"/> |
||||
|
<field name="users" eval="[(4, ref('base.user_root'))]"/> |
||||
|
</record> |
||||
|
<!-- Group User--> |
||||
|
<record id="fleet.fleet_rule_vehicle_visibility_user" model="ir.rule"> |
||||
|
<field name="name">User can only see his/her vehicle</field> |
||||
|
<field name="model_id" ref="fleet.model_fleet_vehicle"/> |
||||
|
<field name="groups" |
||||
|
eval="[(4, ref('fleet.fleet_group_user')), (4, ref('fleet_rental_group_user'))]"/> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="False"/> |
||||
|
<field name="domain_force">[]</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,21 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Record rule for Car Rental Contract multi-company--> |
||||
|
<record id="car_rental_contract_multi_company_rule" model="ir.rule"> |
||||
|
<field name="name">Car Rental Contract multi-company</field> |
||||
|
<field name="model_id" ref="fleet_rental.model_car_rental_contract"/> |
||||
|
<field eval="True" name="global"/> |
||||
|
<field name="domain_force"> |
||||
|
['|',('company_id','=',False),('company_id','in', company_ids)] |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Record rule for Car Rental Checklist multi-company--> |
||||
|
<record id="car_rental_checklist_multi_company_rule" model="ir.rule"> |
||||
|
<field name="name">Car Rental Checklist multi-company</field> |
||||
|
<field name="model_id" ref="fleet_rental.model_car_rental_checklist"/> |
||||
|
<field eval="True" name="global"/> |
||||
|
<field name="domain_force"> |
||||
|
['|',('company_id','=',False),('company_id','in', company_ids)] |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
|
After Width: | Height: | Size: 36 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: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 162 KiB |
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 159 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 324 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 16 KiB |
@ -0,0 +1,905 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
|
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
|
<title>Odoo App 3 Index</title> |
||||
|
<!-- Bootstrap CSS --> |
||||
|
<link rel="stylesheet" |
||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" |
||||
|
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" |
||||
|
crossorigin="anonymous"> |
||||
|
<link rel="stylesheet" |
||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"> |
||||
|
<link rel="preconnect" href="https://fonts.googleapis.com"> |
||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" |
||||
|
rel="stylesheet"> |
||||
|
</head> |
||||
|
<body> |
||||
|
<section> |
||||
|
<div class="container" |
||||
|
style="font-family: 'Inter', sans-serif !important;background-color: #fff !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between flex-wrap align-items-sm-center" |
||||
|
style="border-bottom:1px solid rgba(0, 0, 0, 0.22)"> |
||||
|
<div class="my-3"> |
||||
|
<img src="assets/misc/Cybrosys R.png" |
||||
|
style="width:auto !important; height:40px !important"> |
||||
|
</div> |
||||
|
<div class="my-3 d-flex align-items-center"> |
||||
|
<div class="text-center" |
||||
|
style="background-color:#017E84 !important;font-size: 0.8rem !important; color:#fff !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important; min-width: 120px !important;"> |
||||
|
Community |
||||
|
</div> |
||||
|
<div class="text-center" |
||||
|
style="background-color:#875A7B !important; color:#fff !important;font-size: 0.8rem !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important;min-width: 120px !important;"> |
||||
|
Enterprise |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12 text-center d-flex align-items-center flex-column" |
||||
|
style="margin: 80px 0px !important;"> |
||||
|
<h1 style="font-size: 2.8rem;font-weight: 700; color: |
||||
|
#1A202C;"> |
||||
|
Fleet Rental Management</h1> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
With this module you can give vehicles like car, van, bike, jeep etc. for rent. |
||||
|
</p> |
||||
|
<div style="width: 80%; margin-top: 3rem;"> |
||||
|
<img src="assets/screenshots/hero.png" |
||||
|
class="img-responsive" width="100%" height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5 mb-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-4"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#714b67 !important"> |
||||
|
Key Highlights |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row py-4"> |
||||
|
<div class="col-md-6 col-sm-12 p-3"> |
||||
|
<div class="d-flex h-100" style="padding: 30px;border-radius: 12px; |
||||
|
background: #FFF; |
||||
|
box-shadow: 1px 2px 3px 0px rgba(0, 0, 0, 0.25); "> |
||||
|
<div style="width: 36px; height: 36px; border-radius: 50%; background: #714B67; |
||||
|
display: flex; justify-content: center; align-items: center; |
||||
|
margin-right: 10px; flex-shrink: 0;"> |
||||
|
<i class="fa-solid fa-star " |
||||
|
style="color: #fff;font-size:14px;"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p style="color: #1A202C;font-weight: 600; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Multiple Plans for Rental Contract(Days/Weeks/Months/Years).</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 col-sm-12 p-3"> |
||||
|
<div class="d-flex h-100" style="padding: 30px;border-radius: 12px; |
||||
|
background: #FFF; |
||||
|
box-shadow: 1px 2px 3px 0px rgba(0, 0, 0, 0.25); "> |
||||
|
<div style="width: 36px; height: 36px; border-radius: 50%; background: #714B67; |
||||
|
display: flex; justify-content: center; align-items: center; |
||||
|
margin-right: 10px; flex-shrink: 0;"> |
||||
|
<i class="fa-solid fa-star " |
||||
|
style="color: #fff;font-size:14px;"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p style="color: #1A202C;font-weight: 600; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Integrated with Accounting Module</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 col-sm-12 p-3"> |
||||
|
<div class="d-flex h-100" style="padding: 30px;border-radius: 12px; |
||||
|
background: #FFF; |
||||
|
box-shadow: 1px 2px 3px 0px rgba(0, 0, 0, 0.25); "> |
||||
|
<div style="width: 36px; height: 36px; border-radius: 50%; background: #714B67; |
||||
|
display: flex; justify-content: center; align-items: center; |
||||
|
margin-right: 10px; flex-shrink: 0;"> |
||||
|
<i class="fa-solid fa-star " |
||||
|
style="color: #fff;font-size:14px;"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p style="color: #1A202C;font-weight: 600; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Automatically Create Recurring Invoices</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 col-sm-12 p-3"> |
||||
|
<div class="d-flex h-100" style="padding: 30px;border-radius: 12px; |
||||
|
background: #FFF; |
||||
|
box-shadow: 1px 2px 3px 0px rgba(0, 0, 0, 0.25); "> |
||||
|
<div style="width: 36px; height: 36px; border-radius: 50%; background: #714B67; |
||||
|
display: flex; justify-content: center; align-items: center; |
||||
|
margin-right: 10px; flex-shrink: 0;"> |
||||
|
<i class="fa-solid fa-star " |
||||
|
style="color: #fff;font-size:14px;"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p style="color: #1A202C;font-weight: 600; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Sending email for confirmation, first payment and recurrent invoices</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 col-sm-12 p-3"> |
||||
|
<div class="d-flex h-100" style="padding: 30px;border-radius: 12px; |
||||
|
background: #FFF; |
||||
|
box-shadow: 1px 2px 3px 0px rgba(0, 0, 0, 0.25); "> |
||||
|
<div style="width: 36px; height: 36px; border-radius: 50%; background: #714B67; |
||||
|
display: flex; justify-content: center; align-items: center; |
||||
|
margin-right: 10px; flex-shrink: 0;"> |
||||
|
<i class="fa-solid fa-star " |
||||
|
style="color: #fff;font-size:14px;"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p style="color: #1A202C;font-weight: 600; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Check List Facility</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 col-sm-12 p-3"> |
||||
|
<div class="d-flex h-100" style="padding: 30px;border-radius: 12px; |
||||
|
background: #FFF; |
||||
|
box-shadow: 1px 2px 3px 0px rgba(0, 0, 0, 0.25); "> |
||||
|
<div style="width: 36px; height: 36px; border-radius: 50%; background: #714B67; |
||||
|
display: flex; justify-content: center; align-items: center; |
||||
|
margin-right: 10px; flex-shrink: 0;"> |
||||
|
<i class="fa-solid fa-star " |
||||
|
style="color: #fff;font-size:14px;"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<p style="color: #1A202C;font-weight: 600; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Separate Tree view for Checklist</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container rounded"> |
||||
|
<ul class="nav nav-tabs d-flex" |
||||
|
style="width: fit-content;margin: 0 auto;gap: 1rem;"> |
||||
|
<li class="col text-center py-2 text-nowrap " |
||||
|
style="color: #fff; background-color: #714B67;border-radius: 6px 6px 0px 0px;"> |
||||
|
<a |
||||
|
class="active show" data-toggle="tab" href="#tab1" |
||||
|
style="color: #fff;font-weight: 500; background-color: #714B67; text-decoration: none;"> |
||||
|
<i class="fa-regular fa-image pr-2" |
||||
|
style="color: #fff;"></i> |
||||
|
Screenshots</a></li> |
||||
|
<li class="col text-center py-2 text-nowrap " |
||||
|
style="color: #fff; background-color: #714B67;border-radius: 6px 6px 0px 0px;"> |
||||
|
<a |
||||
|
data-toggle="tab" href="#tab2" |
||||
|
style="color: #fff;font-weight: 500; text-decoration: none;"><i |
||||
|
class="fa-solid fa-star pr-2" |
||||
|
style="color: #fff;"></i>Features</a></li> |
||||
|
<li class="col text-center py-2 text-nowrap " |
||||
|
style="color: #fff; background-color: #714B67;border-radius: 6px 6px 0px 0px;"> |
||||
|
<a |
||||
|
data-toggle="tab" href="#tab3" |
||||
|
style="color: #fff;font-weight: 500; text-decoration: none; background-color: #714B67;"><i |
||||
|
class="fa-solid fa-book-open pr-2" |
||||
|
style="color: #fff;"></i>Released Notes</a></li> |
||||
|
</ul> |
||||
|
<div class="tab-content" |
||||
|
style="background-color: rgba(121, 113, 119, 0.04);"> |
||||
|
<div id="tab1" class="tab-pane fade in active show"> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
Fleet Rental -> Rental Management</h4> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
When you install the module, an extra menu named Rental Management is created under the Fleet Menu, Also "Fleet" menu is replaced as "Fleet Rental". |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/1.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
Fleet Rental -> Rental Management -> Rental Contract</h4> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
This is the Rental Contract form. You can see the Recurring lines created according to the Recurring cost. |
||||
|
And also you can see all the invoices related to this contract from the smart button "Invoices". |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/2.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
Checklist Tab in Rental Contract Form</h4> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
Here you can add the list of tools given with the vehicle. When the vehicle is returned back, the checklist can be validated and helps you to identify the tools that are not returned. The price of unreturned tools will be added to the missing tool cost. The renter have to pay that amount, and you can also add damage cost if any. Check the damages by using the images of vehicle uploaded before the contract. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/3.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
Checklist Easy Access</h4> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
You can also create invoice against the checklist from here. The checklists are those which are in the checking state, that means the ones ready for checking the operation. If there is any damage or any missing tool, then you can charge all that from customer. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/4.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
Email Notifications</h4> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
The system will send email notification to notify the confirmation of contract.<br/> |
||||
|
<b>Note:</b> You should configure outgoing and incoming e-mail settings from your odoo for email service. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/5.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
The system will notify the first payment through email. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/7.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
The system will remind all recurrent invoices through email. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/6.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-lg-12 py-2" |
||||
|
style="padding: 1rem 4rem !important;"> |
||||
|
<div |
||||
|
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="px-3"> |
||||
|
<h4 class="mt-2" |
||||
|
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> |
||||
|
Contract Payment Validations</h4> |
||||
|
<p class="my-3 mb-4" |
||||
|
style="max-width: 80%; font-weight: 400 !important; line-height: 32px; color: #718096;"> |
||||
|
Here you can see you have 5 invoice and this contract is in 'Invoice' state. So you can set this contract to done only if all the invoices are in 'paid' state. Otherwise, it will raise a warning as follows. |
||||
|
</p> |
||||
|
|
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/8.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<div class="row justify-content-center p-3 w-100 m-0"> |
||||
|
<img src="assets/screenshots/9.png" |
||||
|
class="img-responsive" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="tab2" class="tab-pane fade"> |
||||
|
<div class="col-mg-12" style="padding: 1rem 4rem;"> |
||||
|
<ul style="list-style: none; padding: 1rem 0;font-weight: 500;"> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Multiple Plans for Rental Contract(Days/Weeks/Months/Years) |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Integrated with Accounting Module |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Automatically Create Recurring Invoices |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Sending email for confirmation, first payment and recurrent invoices |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Check List Facility |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Separate Tree view for Checklist |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Damage Checking Facility |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Billing Facility for Damages/Check Lists |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Contract Payment Validations |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Detailed Fleet Rental Analysis Report |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Access Rights From Multiple Level |
||||
|
</li> |
||||
|
<li class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<span style="margin-right: 12px;"><img |
||||
|
src="assets/misc/star (1) 2.svg" |
||||
|
alt="" |
||||
|
width="16px"></span>Flexible for further customization |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="tab3" class="tab-pane fade"> |
||||
|
<div class="col-mg-12 active" style="padding: 1rem 4rem;"> |
||||
|
<div class="py-3" |
||||
|
style="font-weight: 500;background-color: #fff; border-radius: 4px; padding: 1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> |
||||
|
<div class="d-flex mb-3" |
||||
|
style="font-size: 0.8rem; font-weight: 500;"><span>Version |
||||
|
17.0.1.0.0</span><span |
||||
|
class="px-2">|</span><span |
||||
|
style="color: #714B67;font-weight: 600;">Released on: 6th March 2024</span> |
||||
|
</div> |
||||
|
<p class="m-0" |
||||
|
style=" color:#718096!important; font-size:1rem !important;line-height: 28px;"> |
||||
|
Initial Commit for Fleet Rental Management.</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-5"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Related Products</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="myCarousel" class="carousel slide py-3" data-ride="carousel"> |
||||
|
<div class="carousel-inner"> |
||||
|
<div class="carousel-item active"> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/whatsapp_redirect/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/1.jpg" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Send Whatsapp Message Odoo17</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/hide_menu_user/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/2.jpg" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Hide Any Menu User Wise</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/project_dashboard_odoo/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/3.png" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Project Dashboard</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="carousel-item"> |
||||
|
<div class="row p-4"> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/login_user_detail/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px; "> |
||||
|
<img src="assets/modules/4.png" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
User Log Details</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/export_view_pdf/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px;"> |
||||
|
<img src="assets/modules/5.jpg" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Export View PDF</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col"> |
||||
|
<div class="p-3"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/17.0/web_login_styles/" |
||||
|
style="color: #000; text-decoration: none;"> |
||||
|
<div style="border:1px solid #CBCBCB !important;border-radius: 4px;"> |
||||
|
<div style="width: 300px;"> |
||||
|
<img src="assets/modules/6.png" |
||||
|
alt="" width="100%" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
<p class="text-center pt-2 text-black font-weight-bold"> |
||||
|
Customize Login Page Style</p> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a class="carousel-control-prev" href="#myCarousel" |
||||
|
data-slide="prev" style="width: 35px; color: #000;"> |
||||
|
<span class="carousel-control-prev-icon"> |
||||
|
<i class="fa fa-chevron-left" |
||||
|
style="font-size: 24px;"></i> |
||||
|
</span> |
||||
|
</a> |
||||
|
<a class="carousel-control-next" href="#myCarousel" |
||||
|
data-slide="next" style="width: 35px; color: #000;"> |
||||
|
<span class="carousel-control-next-icon"> |
||||
|
<i class="fa fa-chevron-right" |
||||
|
style="font-size: 24px;"></i> |
||||
|
</span> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-4"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Our Services</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container my-5"> |
||||
|
<div class="row py-3"> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#13EA36 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/cogs.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Customization</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#DBC711; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/wrench.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Implementation</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative; border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#FF6B6B ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/lifebuoy.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Support</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative; border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#FFA801 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/user.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Hire |
||||
|
Odoo Developer</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative; border-radius: 4px;"> |
||||
|
|
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#54A0FF; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/puzzle.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Integration</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#6D7680 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/update.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Migration</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#786FA6 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/consultation.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Consultancy</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#F8A5C2 ; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/training.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Implementation</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-4 col-sm-6 px-4 py-4"> |
||||
|
<div |
||||
|
style="background-color: #fff; padding: 25px; text-align: center; box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px; position: relative;border-radius: 4px;"> |
||||
|
<div style="position: absolute; top: 0%; left: 50%; transform: translate(-50%, -50%);"> |
||||
|
<div style="background-color:#E6BE26; border-radius: 50%; padding: 15px; width: 68px; |
||||
|
height: 68px; display: inline-block; box-shadow:0px 4px 4px rgba(0, 0, 0, 0.25);"> |
||||
|
<img src="assets/icons/license.png" |
||||
|
alt="service-icon" width="38px" |
||||
|
height="auto"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<p style="margin-top: 20px; font-weight: bold;">Odoo |
||||
|
Licensing Consultancy</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-4"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Our Industries</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container"> |
||||
|
<div class="row my-5 py-4"> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100 " |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); border-bottom: 1px solid rgb(209, 209, 209); padding: 30px; box-shadow: 6px 0 10px rgba(228, 227, 227, 0.373);"> |
||||
|
<img src="assets/icons/trading-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">Trading</p> |
||||
|
<p>Easily procure and sell your products</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209);border-bottom: 1px solid rgb(209, 209, 209); padding: 30px;"> |
||||
|
<img src="assets/icons/pos-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">POS</p> |
||||
|
<p>Easy configuration and convivial experience</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209);border-bottom: 1px solid rgba(0, 0, 0, 0.2); padding: 30px; box-shadow: 0 5px 10px rgba(228, 227, 227, 0.373)"> |
||||
|
<img src="assets/icons/education-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Education</p> |
||||
|
<p>A platform for educational management</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-bottom: 1px solid rgb(209, 209, 209); padding: 30px; "> |
||||
|
<img src="assets/icons/manufacturing-black.png" |
||||
|
width="42px" height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Manufacturing</p> |
||||
|
<p>Plan, track and schedule your operations</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); padding: 30px;"> |
||||
|
<img src="assets/icons/ecom-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">E-commerce & |
||||
|
Website</p> |
||||
|
<p>Mobile friendly, awe-inspiring product pages</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); padding: 30px;box-shadow: 0 -5px 10px rgba(228, 227, 227, 0.373);"> |
||||
|
<img src="assets/icons/service-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">Service |
||||
|
Management</p> |
||||
|
<p>Keep track of services and invoice</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style="border-right: 1px solid rgb(209, 209, 209); padding: 30px; "> |
||||
|
<img src="assets/icons/restaurant-black.png" |
||||
|
width="42px" height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;"> |
||||
|
Restaurant</p> |
||||
|
<p>Run your bar or restaurant methodically</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-3 col-sm-6 p-0"> |
||||
|
<div class="d-flex flex-column h-100" |
||||
|
style=" padding: 30px;box-shadow: -5px 0 10px rgba(228, 227, 227, 0.373);"> |
||||
|
<img src="assets/icons/hotel-black.png" width="42px" |
||||
|
height="auto" alt=""> |
||||
|
<p style="color: #714B67;font-weight: 600; margin-top: 10px; |
||||
|
font-size: 1.2rem; margin-bottom: 2px;">Hotel |
||||
|
Management</p> |
||||
|
<p>An all-inclusive hotel management application</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container mt-5"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center mt-5"> |
||||
|
<p class="m-0" |
||||
|
style="font-weight: 600; font-size: 24px; color:#000 !important"> |
||||
|
Support</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="container my-5"> |
||||
|
<div class="row" style="background-color: #FFFAFE;"> |
||||
|
<div class="col-md-6 pb-4 d-flex align-items-center justify-content-center" |
||||
|
style="border-right: 1px solid #D9D9D9;"> |
||||
|
<div style="padding: 30px;"> |
||||
|
<div class="d-flex align-items-center"> |
||||
|
<img src="assets/misc/support (1) 1.svg" alt="" |
||||
|
width="60px" style="margin-right: 12px;"> |
||||
|
<div style="padding: 0px 8px;"> |
||||
|
<span |
||||
|
style="color: #714B67;font-size: 24px;font-weight: 600;padding-bottom: 1rem;">Need |
||||
|
Help?</span> |
||||
|
<p class="m-0" style="color:#718096;">Got |
||||
|
questions or need help? Get in touch.</p> |
||||
|
<div style="font-weight: 400;"><span><img |
||||
|
src="assets/misc/support-email.svg" |
||||
|
alt="" |
||||
|
width="18px" |
||||
|
style="filter: invert(1);margin-right: 0.8rem;"></span>odoo@cybrosys.com |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-md-6 pb-4 d-flex align-items-center justify-content-center"> |
||||
|
<div style="padding: 30px;"> |
||||
|
<div class="d-flex align-items-center"> |
||||
|
<img src="assets/misc/whatsapp 1.svg" alt="" |
||||
|
width="60px" style="margin-right: 12px;"> |
||||
|
<div> |
||||
|
<span style="color: #714B67;font-size: 24px;font-weight: 600;">WhatsApp</span> |
||||
|
<p class="m-0" style="color:#718096;">Say hi to |
||||
|
us on WhatsApp!</p> |
||||
|
<div style="font-weight: 400; font-size: 16px;"><span><img |
||||
|
src="assets/misc/phone.svg" |
||||
|
alt="" width="14px" |
||||
|
style="filter: invert(1); margin-right: 0.8rem;"></span>+91 |
||||
|
99456767686 |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- Optional JavaScript --> |
||||
|
<!-- jQuery first, then Popper.js, then Bootstrap JS --> |
||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> |
||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,35 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
import { registry } from "@web/core/registry"; |
||||
|
import { useInputField } from "@web/views/fields/input_field_hook"; |
||||
|
const { Component, useRef } = owl; |
||||
|
/** |
||||
|
* We define this module for the function of creating a time picker widget |
||||
|
* |
||||
|
*/ |
||||
|
export class FieldTimePicker extends Component { |
||||
|
setup() { |
||||
|
this.input = useRef('input_time'); |
||||
|
useInputField({ getValue: () => this.props.record.data[this.props.name] || "", refName: "input_time" }); |
||||
|
} |
||||
|
|
||||
|
onBlur(){ |
||||
|
/** |
||||
|
* Handle the blur event for the timepicker input field. |
||||
|
* |
||||
|
* This function is responsible for handling the blur event on the timepicker input field. |
||||
|
* It checks if the close button is present in the timepicker, and if so, it adds a click event |
||||
|
* listener to it to handle the closing of the timepicker. |
||||
|
* |
||||
|
* @returns {void} |
||||
|
*/ |
||||
|
this.props.record.update({ [this.props.name] : this.input.el?.value}) |
||||
|
} |
||||
|
} |
||||
|
// Set the template for the FieldTimePicker component
|
||||
|
FieldTimePicker.template = 'FieldTimePicker'; |
||||
|
FieldTimePicker.supportedTypes = ["char"] |
||||
|
export const timepicker = { |
||||
|
component: FieldTimePicker |
||||
|
} |
||||
|
// Add the timepicker to the fields category
|
||||
|
registry.category("fields").add("timepicker_time", timepicker); |
@ -0,0 +1,3 @@ |
|||||
|
.timepicker-component{ |
||||
|
width:30%; |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<t t-name="FieldTimePicker" owl="1"> |
||||
|
<!-- FieldTimePicker template to add input field--> |
||||
|
<div class="input-group timepicker-component"> |
||||
|
<input type="time" class="time-input" t-ref="input_time" t-on-blur="onBlur"/> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,93 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Checklist Form View--> |
||||
|
<record id="car_rental_contract_checklist_view_form" model="ir.ui.view"> |
||||
|
<field name="name">car.rental.contract.view.form</field> |
||||
|
<field name="model">car.rental.contract</field> |
||||
|
<field name="type">form</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="car_checklist2" create="false"> |
||||
|
<header> |
||||
|
<button name="action_verify" string="Create invoice" type="object" |
||||
|
invisible="(state != 'checking') or (check_verify == True)" |
||||
|
class="oe_highlight"/> |
||||
|
<field name="state" widget="statusbar" |
||||
|
statusbar_visible="checking"/> |
||||
|
</header> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="name" string="Contract" readonly="1"/> |
||||
|
<field name="customer_id" string="Customer" readonly="1"/> |
||||
|
<field name="vehicle_id" string="Vehicle" readonly="1"/> |
||||
|
<field name="check_verify" invisible="1"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="damage_cost"/> |
||||
|
<field name="attachment_ids" widget="many2many_binary" |
||||
|
class="oe_inline" readonly="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page string="Checklist"> |
||||
|
<field name="checklist_line"> |
||||
|
<tree string="Fleet Checklist Lines" create="false" |
||||
|
editable="bottom"> |
||||
|
<field name="name"/> |
||||
|
<field name="checklist_active"/> |
||||
|
<field name="price"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
<div> |
||||
|
<group class="oe_subtotal_footer oe_right"> |
||||
|
<field name="total"/> |
||||
|
<field name="tools_missing_cost"/> |
||||
|
<field name="damage_cost_sub"/> |
||||
|
<field name="total_cost" |
||||
|
class="oe_subtotal_footer_separator"/> |
||||
|
</group> |
||||
|
</div> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Checklist Tree View--> |
||||
|
<record id="car_rental_contract_checklist_view_tree" model="ir.ui.view"> |
||||
|
<field name="name">car.rental.contract.view.tree</field> |
||||
|
<field name="model">car.rental.contract</field> |
||||
|
<field name="type">tree</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="car_contract_result2" create="false"> |
||||
|
<field name="name" string="Contract"/> |
||||
|
<field name="customer_id" string="Renter"/> |
||||
|
<field name="state"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Action for checklist form view--> |
||||
|
<record id="action_fleet_rent_checklist" model="ir.actions.act_window"> |
||||
|
<field name="name">Checklist</field> |
||||
|
<field name="res_model">car.rental.contract</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
<field name="domain">[('state', 'in', ('running', 'checking'))]</field> |
||||
|
<field name="view_id" ref="car_rental_contract_checklist_view_form"/> |
||||
|
</record> |
||||
|
<record id="action_fleet_rent_checklist_form" model="ir.actions.act_window.view"> |
||||
|
<field eval="2" name="sequence"/> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="view_id" ref="car_rental_contract_checklist_view_form"/> |
||||
|
<field name="act_window_id" ref="action_fleet_rent_checklist"/> |
||||
|
</record> |
||||
|
<!-- Action for checklist tree view--> |
||||
|
<record id="action_fleet_rent_checklist_tree" model="ir.actions.act_window.view"> |
||||
|
<field eval="1" name="sequence"/> |
||||
|
<field name="view_mode">tree</field> |
||||
|
<field name="view_id" ref="car_rental_contract_checklist_view_tree"/> |
||||
|
<field name="act_window_id" ref="action_fleet_rent_checklist"/> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem id="menu_car_checklist" parent="menu_car_parent" name="Checklist" |
||||
|
action="action_fleet_rent_checklist" sequence="2"/> |
||||
|
</odoo> |
@ -0,0 +1,233 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Fleet vehicle form view--> |
||||
|
<record id="fleet_vehicle_view_form" model="ir.ui.view"> |
||||
|
<field name="name">fleet.vehicle.view.form.inherit.fleet.rental</field> |
||||
|
<field name="model">fleet.vehicle</field> |
||||
|
<field name="inherit_id" ref="fleet.fleet_vehicle_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="car_value" position="after"> |
||||
|
<field name="rental_check_availability" invisible="1"/> |
||||
|
<field name="rental_reserved_time" invisible="1"/> |
||||
|
</field> |
||||
|
<field name="color" position="replace"> |
||||
|
<field name="color"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Car rental contract form view--> |
||||
|
<record id="car_rental_contract_view_form" model="ir.ui.view"> |
||||
|
<field name="name">car.rental.contract.view.form</field> |
||||
|
<field name="model">car.rental.contract</field> |
||||
|
<field name="type">form</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="car_result"> |
||||
|
<header> |
||||
|
<button name="action_confirm" string="Confirm" type="object" |
||||
|
invisible="state != 'draft'" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="action_run" string="Run" type="object" |
||||
|
invisible="state != 'reserved'" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="action_cancel" string="Cancel" type="object" |
||||
|
invisible="state not in ['draft', 'reserved']" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="action_invoice_create" string="Create Invoice" |
||||
|
invisible="((state != 'running') or (first_invoice_created == True) or (read_only == True))" |
||||
|
type="object" class="oe_highlight"/> |
||||
|
<button name="action_extend_rent" string="Extend Rent" |
||||
|
invisible="((state != 'running') or (read_only == True) or (first_invoice_created == False))" |
||||
|
type="object" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="action_confirm_extend_rent" string="Confirm Extend" |
||||
|
invisible="((state != 'running') or (read_only == False))" type="object" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="action_discard_extend" string="Discard Extend" |
||||
|
invisible="((state != 'running') or (read_only == False))" type="object" |
||||
|
class="oe_highlight"/> |
||||
|
<button name="force_checking" string="Force Checking" |
||||
|
invisible="((state != 'running') or (first_invoice_created == False))" |
||||
|
type="object" class="oe_highlight"/> |
||||
|
<button name="set_to_done" string="Set to Done" |
||||
|
invisible="state not in ['invoice']" type="object" class="oe_highlight"/> |
||||
|
<field name="state" widget="statusbar" |
||||
|
statusbar_visible="draft,running,done"/> |
||||
|
</header> |
||||
|
<sheet> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
<button name="action_view_invoice" class="oe_stat_button" icon="fa-money" type="object"> |
||||
|
<div class="o_form_field o_stat_info"> |
||||
|
<field string="Invoice" name="invoice_count" |
||||
|
widget="statinfo"/> |
||||
|
</div> |
||||
|
</button> |
||||
|
</div> |
||||
|
<field name="image" widget='image' class="oe_avatar"/> |
||||
|
<div class="oe_title"> |
||||
|
<h1> |
||||
|
<field name="name"/> |
||||
|
</h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<separator string="Contract Details " colspan="4"/> |
||||
|
<group> |
||||
|
<field name="customer_id" string="Customer" |
||||
|
readonly="state != 'draft'"/> |
||||
|
<field name="rent_by_hour" readonly="state != 'draft'"/> |
||||
|
<field name="read_only" invisible="1"/> |
||||
|
<field name="rent_start_date" |
||||
|
readonly="state != 'draft'"/> |
||||
|
<field name="start_time" widget="timepicker_time" invisible="rent_by_hour == False" |
||||
|
readonly="state != 'draft'" required="rent_by_hour == True"/> |
||||
|
<field name="rent_end_date" |
||||
|
readonly="((state != 'draft') and (read_only == False))"/> |
||||
|
<field name="end_time" widget="timepicker_time" invisible="rent_by_hour == False" |
||||
|
readonly="(state != 'draft') and (read_only == False)" required="rent_by_hour == True"/> |
||||
|
<field name="vehicle_id" |
||||
|
domain="[('rental_check_availability','=',True),('state_id.name','!=','Inactive')]" |
||||
|
readonly="state != 'draft'" |
||||
|
options="{'no_create': True}"/> |
||||
|
<field name="journal_type" invisible="1"/> |
||||
|
<field name="check_verify" invisible="1"/> |
||||
|
<field name="sales_person" |
||||
|
readonly="state != 'draft'"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="car_brand"/> |
||||
|
<field name="car_color"/> |
||||
|
<field name="company_id"/> |
||||
|
<field name="first_invoice_created" invisible="1"/> |
||||
|
<label for="first_payment"/> |
||||
|
<div> |
||||
|
<field name="first_payment" class="oe_inline" |
||||
|
readonly="((state not in ['draft', 'running']) or (first_invoice_created == True))"/> |
||||
|
<field name="first_payment_inv" style="width:142px;" readonly="1"/> |
||||
|
</div> |
||||
|
<field name="account_type" invisible="1"/> |
||||
|
<field name="cost" invisible="1"/> |
||||
|
<label for="cost_generated"/> |
||||
|
<div> |
||||
|
<field name="cost_frequency" class="oe_inline" |
||||
|
readonly="(state != 'draft')"/> |
||||
|
<field name="cost_generated" style="width:142px;" |
||||
|
invisible="cost_frequency == 'no'" |
||||
|
readonly="state != 'draft'" |
||||
|
required="cost_frequency not in [None, False , 'no']"/> |
||||
|
</div> |
||||
|
</group> |
||||
|
</group> |
||||
|
<notebook> |
||||
|
<page string="Recurring Invoices" |
||||
|
invisible="cost_frequency in [None,False,'no']"> |
||||
|
<field name="recurring_line" mode="tree"> |
||||
|
<tree string="Fleet Reccurring Lines" |
||||
|
colors="#0b7a35:payment_info=='paid';#f20b07:payment_info!='paid'"> |
||||
|
<field name="date_today"/> |
||||
|
<field name="date_due"/> |
||||
|
<field name="name"/> |
||||
|
<field name="account_info"/> |
||||
|
<field name="recurring_amount"/> |
||||
|
<field name="payment_info"/> |
||||
|
<field name="invoice_ref"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</page> |
||||
|
<page string="Checklist"> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="attachment_ids" |
||||
|
widget="many2many_binary" |
||||
|
class="oe_inline"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="damage_cost" |
||||
|
invisible="state != 'checking'"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<field name="checklist_line" readonly="(state == 'invoice') or (state == 'done') or (state == 'cancel')"> |
||||
|
<tree string="Fleet Checklist Lines" |
||||
|
editable="bottom"> |
||||
|
<field name="name"/> |
||||
|
<field name="checklist_active"/> |
||||
|
<field name="checklist_number" invisible="True"/> |
||||
|
<field name="price"/> |
||||
|
</tree> |
||||
|
<form> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<field name="name"/> |
||||
|
<field name="checklist_active" |
||||
|
invisible="1"/> |
||||
|
<field name="checklist_number" |
||||
|
invisible="1"/> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
<div> |
||||
|
<group class="oe_subtotal_footer oe_right"> |
||||
|
<field name="total"/> |
||||
|
<field name="tools_missing_cost"/> |
||||
|
<field name="damage_cost_sub"/> |
||||
|
<field name="total_cost" |
||||
|
class="oe_subtotal_footer_separator"/> |
||||
|
</group> |
||||
|
</div> |
||||
|
<div style="float: right;margin-left: 78%;margin-bottom: 36px;"> |
||||
|
<button name="action_verify" string="Verify" |
||||
|
type="object" |
||||
|
style="width: 100px !important;height: 40px;" |
||||
|
invisible="state != 'checking'" |
||||
|
class="oe_subtotal_footer oe_right oe_highlight"/> |
||||
|
</div> |
||||
|
</page> |
||||
|
</notebook> |
||||
|
<group> |
||||
|
<field name="notes"/> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
<div class="oe_chatter"> |
||||
|
<field name="message_follower_ids" widget="mail_followers"/> |
||||
|
<field name="message_ids" widget="mail_thread"/> |
||||
|
</div> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Car rental contract tree view--> |
||||
|
<record id="car_rental_contract_view_tree" model="ir.ui.view"> |
||||
|
<field name="name">car.rental.contract.view.tree</field> |
||||
|
<field name="model">car.rental.contract</field> |
||||
|
<field name="type">tree</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="car_contract_result" decoration-info="state == 'draft'"> |
||||
|
<field name="name"/> |
||||
|
<field name="customer_id" string="Customer"/> |
||||
|
<field name="vehicle_id"/> |
||||
|
<field name="cost_generated"/> |
||||
|
<field name="car_brand"/> |
||||
|
<field name="car_color"/> |
||||
|
<field name="rent_start_date"/> |
||||
|
<field name="rent_end_date"/> |
||||
|
<field name="state"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Action rental contract--> |
||||
|
<record id="action_car_rental_contract" model="ir.actions.act_window"> |
||||
|
<field name="name">Rental Contract</field> |
||||
|
<field name="res_model">car.rental.contract</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
<field name="view_ids" eval="[(5, 0, 0), |
||||
|
(0, 0, {'view_mode': 'tree', 'view_id': ref('car_rental_contract_view_tree')}), |
||||
|
(0, 0, {'view_mode': 'form', 'view_id': ref('car_rental_contract_view_form')})]"/> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem name="Fleet Rental" id="fleet.menu_root" sequence="115" |
||||
|
groups="fleet.fleet_group_user" |
||||
|
web_icon="fleet_rental,static/description/icon.png"/> |
||||
|
<menuitem id="menu_car_parent" sequence="1" name="Rental Management" |
||||
|
parent="fleet.menu_root"/> |
||||
|
<menuitem id="menu_car_rental_contract" parent="menu_car_parent" |
||||
|
name="Rental Contract" |
||||
|
action="action_car_rental_contract" sequence="1"/> |
||||
|
</odoo> |
@ -0,0 +1,44 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Car tools form view--> |
||||
|
<record id="car_tools_view_form" model="ir.ui.view"> |
||||
|
<field name="name">car.tools.view.form</field> |
||||
|
<field name="model">car.tools</field> |
||||
|
<field name="type">form</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Accessories/Tools"> |
||||
|
<sheet> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="name"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="price"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Car tools tree view--> |
||||
|
<record id="car_tools_view_tree" model="ir.ui.view"> |
||||
|
<field name="name">car.tools.view.tree</field> |
||||
|
<field name="model">car.tools</field> |
||||
|
<field name="type">tree</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Accessories/Tools"> |
||||
|
<field name="name"/> |
||||
|
<field name="price"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Action for car tools--> |
||||
|
<record id="action_fleet_car_tools" model="ir.actions.act_window"> |
||||
|
<field name="name">Accessories/Tools</field> |
||||
|
<field name="res_model">car.tools</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem id="menu_car_tools" parent="menu_car_parent" name="Accessories/Tools" |
||||
|
action="action_fleet_car_tools" sequence="3"/> |
||||
|
</odoo> |
@ -0,0 +1,27 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- Fleet settings form view inherited and added Default Fleet Rental Service Product --> |
||||
|
<record id="res_config_settings_view_form" model="ir.ui.view"> |
||||
|
<field name="name">res.config.settings.view.form.inherit.fleet.rental</field> |
||||
|
<field name="model">res.config.settings</field> |
||||
|
<field name="priority" eval="1"/> |
||||
|
<field name="inherit_id" ref="fleet.res_config_settings_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//block[@id='end_contract_setting']" position="inside"> |
||||
|
<div class="col-12 col-lg-6 o_setting_box" id="discount_limit "> |
||||
|
<div class="o_setting_left_pane"> |
||||
|
</div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<span class="o_form_label">Default Fleet Rental Service Product |
||||
|
</span> |
||||
|
<div class="row mt16"> |
||||
|
<label for="fleet_service_product_id" |
||||
|
class="col-lg-4 o_light_label"/> |
||||
|
<field name="fleet_service_product_id" class="oe_inline"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import account_payment_register |
@ -0,0 +1,50 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
||||
|
# (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import models, _ |
||||
|
|
||||
|
|
||||
|
class AccountPaymentRegister(models.TransientModel): |
||||
|
""" Inherit account.payment.register supering action_create_payments |
||||
|
Sending mail for the first created invoice |
||||
|
""" |
||||
|
_inherit = 'account.payment.register' |
||||
|
|
||||
|
def action_create_payments(self): |
||||
|
res = super().action_create_payments() |
||||
|
invoice_id = self.env['account.move'].search([('name', '=', self.communication)]) |
||||
|
if invoice_id.is_first_invoice: |
||||
|
mail_content = _( |
||||
|
'<h3>First Payment Received!</h3><br/>Hi %s, <br/> This is to notify that your first payment has ' |
||||
|
'been received. <br/><br/>' |
||||
|
'Please find the details below:<br/><br/>' |
||||
|
'<table><tr><td>Invoice Number<td/><td> %s<td/><tr/>' |
||||
|
'<tr><td>Date<td/><td> %s <td/><tr/><tr><td>Amount <td/><td> %s<td/><tr/><table/>') % ( |
||||
|
invoice_id.partner_id.name, invoice_id.payment_reference, |
||||
|
invoice_id.invoice_date, invoice_id.amount_total) |
||||
|
main_content = { |
||||
|
'subject': _('Payment Received: %s') % invoice_id.payment_reference, |
||||
|
'author_id': self.env.user.partner_id.id, |
||||
|
'body_html': mail_content, |
||||
|
'email_to': invoice_id.partner_id.email, |
||||
|
} |
||||
|
self.env['mail.mail'].create(main_content).send() |
||||
|
return res |