diff --git a/fleet_rental/__manifest__.py b/fleet_rental/__manifest__.py
index 38b3ec36f..5385dc5c5 100755
--- a/fleet_rental/__manifest__.py
+++ b/fleet_rental/__manifest__.py
@@ -42,6 +42,15 @@
'views/car_tools_view.xml',
'reports/rental_report.xml'
],
+ "assets": {
+ 'web.assets_backend': [
+ 'fleet_rental/static/src/js/time_widget.js',
+ 'fleet_rental/static/src/scss/timepicker.scss'
+ ],
+ 'web.assets_qweb': {
+ 'fleet_rental/static/src/xml/timepicker.xml',
+ },
+ },
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
diff --git a/fleet_rental/doc/RELEASE_NOTES.md b/fleet_rental/doc/RELEASE_NOTES.md
index 1cec69e15..40a795c96 100755
--- a/fleet_rental/doc/RELEASE_NOTES.md
+++ b/fleet_rental/doc/RELEASE_NOTES.md
@@ -17,3 +17,9 @@
#### UPDT
- Reformatted code for invoice cancellation.
+
+#### 22.12.2023
+#### Version 15.0.2.2.1
+#### UPDT
+
+- Reformatted code for hourly payment, extend rent.
\ No newline at end of file
diff --git a/fleet_rental/models/car_rental.py b/fleet_rental/models/car_rental.py
index 97d2ae8d8..0d3e9c310 100755
--- a/fleet_rental/models/car_rental.py
+++ b/fleet_rental/models/car_rental.py
@@ -21,7 +21,7 @@
#############################################################################
from datetime import datetime, date, timedelta
from odoo import api, fields, models, _
-from odoo.exceptions import UserError, Warning
+from odoo.exceptions import UserError, Warning, ValidationError
class CarRentalContract(models.Model):
@@ -29,31 +29,6 @@ class CarRentalContract(models.Model):
_description = 'Fleet Rental Management'
_inherit = 'mail.thread'
- @api.onchange('rent_start_date', 'rent_end_date')
- def check_availability(self):
- """
- Check the availability of rental vehicles based on the provided
- 'rent_start_date' and 'rent_end_date'.
- """
- self.vehicle_id = ''
- fleet_obj = self.env['fleet.vehicle'].search([])
- for i in fleet_obj:
- for each in i.rental_reserved_time:
-
- if str(each.date_from) <= str(self.rent_start_date) <= str(
- each.date_to):
- i.write({'rental_check_availability': False})
- elif str(self.rent_start_date) < str(each.date_from):
- if str(each.date_from) <= str(self.rent_end_date) <= str(
- each.date_to):
- i.write({'rental_check_availability': False})
- elif str(self.rent_end_date) > str(each.date_to):
- i.write({'rental_check_availability': False})
- else:
- i.write({'rental_check_availability': True})
- else:
- i.write({'rental_check_availability': True})
-
image = fields.Binary(related='vehicle_id.image_128',
string="Image of Vehicle")
reserved_fleet_id = fields.Many2one('rental.fleet.reserved',
@@ -81,6 +56,13 @@ class CarRentalContract(models.Model):
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')
@@ -138,8 +120,10 @@ class CarRentalContract(models.Model):
copy=False,
help='This is the total amount of '
'missing tools/accessories')
- damage_cost = fields.Float(string="Damage Cost", copy=False)
- damage_cost_sub = fields.Float(string="Damage Cost", readonly=True,
+ 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',
@@ -148,6 +132,8 @@ class CarRentalContract(models.Model):
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")
def action_run(self):
"""
@@ -182,7 +168,7 @@ class CarRentalContract(models.Model):
'rent_start_date'.
"""
if self.rent_end_date < self.rent_start_date:
- raise Warning("Please select the valid end date.")
+ raise UserError("Please select the valid end date.")
def set_to_done(self):
"""
@@ -193,7 +179,6 @@ class CarRentalContract(models.Model):
[('fleet_rent_id', '=', self.id),
('amount_total_signed', '=', self.total_cost),('invoice_line_ids.name','=','Damage/Tools missing cost')])
if any(each.payment_state == 'paid' for each in invoice_ids) or self.total_cost == 0:
- print('kkkk')
self.state = 'done'
else:
raise UserError("Some Invoices are pending")
@@ -413,6 +398,7 @@ class CarRentalContract(models.Model):
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'].search(
[("name", "=", "Fleet Rental Service")])
if product_id.property_account_income_id.id:
@@ -467,6 +453,7 @@ class CarRentalContract(models.Model):
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:
@@ -525,6 +512,7 @@ class CarRentalContract(models.Model):
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()
@@ -539,7 +527,6 @@ class CarRentalContract(models.Model):
[('fleet_rent_id', '=', self.id),
('amount_total_signed', '=', self.first_payment)])
if any(each.payment_state == 'paid' for each in invoice_ids):
- print('kkkk')
self.state = "checking"
else:
raise UserError("Some Invoices are pending")
@@ -670,8 +657,83 @@ class CarRentalContract(models.Model):
}
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
diff --git a/fleet_rental/static/src/js/time_widget.js b/fleet_rental/static/src/js/time_widget.js
new file mode 100644
index 000000000..be6d5aa18
--- /dev/null
+++ b/fleet_rental/static/src/js/time_widget.js
@@ -0,0 +1,44 @@
+/** @odoo-module **/
+import basicFields from 'web.basic_fields';
+import fieldRegistry from 'web.field_registry';
+/**
+ * Custom field widget for time selection.
+ * Extends the basic input field provided by Odoo.
+ */
+var FieldTimePicker = basicFields.InputField.extend({
+ /**
+ * Template used for rendering the time picker field.
+ */
+ template: 'FieldTimePicker',
+ /**
+ * Events associated with the time picker field, extending the base events.
+ * Adds a blur event for the time input element.
+ * @type {Object}
+ */
+ events:_.extend({}, basicFields.InputField.prototype.events, {
+ 'blur .time-input' : '_onBlur',
+ }),
+ /**
+ * Get the current value of the time picker field.
+ * @returns {string} - The value of the time picker input.
+ * @private
+ */
+ _getValue: function () {
+ var $input = this.$el.find('input');
+ return $input.val();
+ },
+ /**
+ * Handle the blur event on the time picker input.
+ * Update the internal value of the field when blurred.
+ * @param {Event} ev - The blur event.
+ * @private
+ */
+ _onBlur: function(ev) {
+ this.value = ev.target.value
+ }
+});
+// Register the custom time picker field in the Odoo field registry.
+fieldRegistry.add('timepicker_time', FieldTimePicker);
+return {
+ FieldTimePicker: FieldTimePicker
+};
diff --git a/fleet_rental/static/src/scss/timepicker.scss b/fleet_rental/static/src/scss/timepicker.scss
new file mode 100644
index 000000000..8f475435f
--- /dev/null
+++ b/fleet_rental/static/src/scss/timepicker.scss
@@ -0,0 +1,3 @@
+.timepicker-component{
+ width:30%;
+}
diff --git a/fleet_rental/static/src/xml/timepicker.xml b/fleet_rental/static/src/xml/timepicker.xml
new file mode 100644
index 000000000..8c0867d76
--- /dev/null
+++ b/fleet_rental/static/src/xml/timepicker.xml
@@ -0,0 +1,9 @@
+
+
+
+
+