272 lines
13 KiB
Python
272 lines
13 KiB
Python
from odoo import api, fields, models
|
|
from odoo.fields import Domain
|
|
|
|
|
|
class HrVersion(models.Model):
|
|
_inherit = 'hr.version'
|
|
|
|
@api.model
|
|
def _get_available_vehicles_domain(self, driver_ids=None, vehicle_type='car'):
|
|
domain = Domain.AND([
|
|
Domain.OR([
|
|
[('company_id', '=', False)],
|
|
[('company_id', '=', self.company_id.id)],
|
|
]),
|
|
[('model_id.vehicle_type', '=', vehicle_type)],
|
|
Domain.OR([
|
|
[(f'plan_to_change_{vehicle_type}', '=', True)],
|
|
[('future_driver_id', 'in', driver_ids.ids if driver_ids else [])],
|
|
]),
|
|
[('write_off_date', '=', False)],
|
|
])
|
|
waiting_stage = self.env.ref('fleet.fleet_vehicle_state_waiting_list', raise_if_not_found=False)
|
|
if waiting_stage:
|
|
domain = Domain('state_id', '!=', waiting_stage.id) & domain
|
|
return domain
|
|
|
|
@api.model
|
|
def _get_vehicles_without_current_drivers_domain(self, driver_ids=None, vehicle_type='car'):
|
|
"""
|
|
This domain is identical to the one in _get_available_vehicles_domain. The difference is
|
|
that it excludes vehicles that have a driver currently even if the current driver is the
|
|
employee under the contract or the current driver plans to change the car in the future.
|
|
"""
|
|
domain = Domain([
|
|
'|', ('company_id', '=', False), ('company_id', '=', self.company_id.id),
|
|
'|', ('future_driver_id', '=', False), ('future_driver_id', 'in', driver_ids.ids),
|
|
('model_id.vehicle_type', '=', vehicle_type),
|
|
('driver_id', '=', False),
|
|
('write_off_date', '=', False),
|
|
])
|
|
waiting_stage = self.env.ref('fleet.fleet_vehicle_state_waiting_list', raise_if_not_found=False)
|
|
if waiting_stage:
|
|
domain = Domain('state_id', '!=', waiting_stage.id) & domain
|
|
return domain
|
|
|
|
def _get_possible_model_domain(self, vehicle_type='car'):
|
|
return [('can_be_requested', '=', True), ('vehicle_type', '=', vehicle_type)]
|
|
|
|
car_id = fields.Many2one(
|
|
'fleet.vehicle', string='Company Car',
|
|
tracking=True, compute="_compute_car_id", store=True, readonly=False,
|
|
domain=lambda self: [('company_id', 'in', (False, self.env.company.id)), ('vehicle_type', '=', 'car')],
|
|
groups='fleet.fleet_group_manager')
|
|
car_atn = fields.Float(
|
|
compute='_compute_car_atn_and_costs',
|
|
store=True,
|
|
compute_sudo=True,
|
|
groups="hr_payroll.group_hr_payroll_user",
|
|
)
|
|
wishlist_car_total_depreciated_cost = fields.Float(
|
|
compute='_compute_car_atn_and_costs', store=True, compute_sudo=True, groups="hr_payroll.group_hr_payroll_user")
|
|
company_car_total_depreciated_cost = fields.Float(
|
|
compute='_compute_car_atn_and_costs',
|
|
store=True,
|
|
compute_sudo=True,
|
|
groups="hr_payroll.group_hr_payroll_user",
|
|
)
|
|
available_cars_amount = fields.Integer(
|
|
compute='_compute_available_cars_amount',
|
|
string='Number of available cars',
|
|
groups="hr.group_hr_user",
|
|
compute_sudo=True)
|
|
new_car = fields.Boolean('Requested a new car', groups="hr.group_hr_user", tracking=True)
|
|
ordered_car_id = fields.Many2one('fleet.vehicle', string='Ordered New Car',
|
|
tracking=True, store=True, readonly=False,
|
|
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id), ('vehicle_type', '=', 'car')]",
|
|
groups='fleet.fleet_group_manager')
|
|
new_car_model_id = fields.Many2one(
|
|
'fleet.vehicle.model', string="New Company Car", domain=lambda self: self._get_possible_model_domain(),
|
|
groups='hr.group_hr_user', tracking=True)
|
|
# Useful on sign to use only one box to sign the contract instead of 2
|
|
car_model_name = fields.Char(compute='_compute_car_model_name', compute_sudo=True,
|
|
groups='hr.group_hr_user')
|
|
max_unused_cars = fields.Integer(compute='_compute_max_unused_cars', groups='hr.group_hr_user')
|
|
acquisition_date = fields.Date(related='car_id.acquisition_date', readonly=False, groups="fleet.fleet_group_manager")
|
|
car_value = fields.Float(related="car_id.car_value", readonly=False, groups="fleet.fleet_group_manager")
|
|
fuel_type = fields.Selection(selection=lambda self: self.env['fleet.vehicle']._fields['fuel_type']._description_selection(self.env), compute="_compute_fuel_type", readonly=False, groups="fleet.fleet_group_manager")
|
|
co2 = fields.Float(related="car_id.co2", readonly=False, groups="fleet.fleet_group_manager")
|
|
driver_id = fields.Many2one('res.partner', related="car_id.driver_id", readonly=False, groups="fleet.fleet_group_manager")
|
|
car_open_contracts_count = fields.Integer(compute='_compute_car_open_contracts_count', groups="fleet.fleet_group_manager")
|
|
recurring_cost_amount_depreciated = fields.Float(
|
|
groups="fleet.fleet_group_manager",
|
|
compute='_compute_recurring_cost_amount_depreciated',
|
|
inverse="_inverse_recurring_cost_amount_depreciated", tracking=True)
|
|
transport_mode_bike = fields.Boolean('Uses Bike', groups='hr.group_hr_user', tracking=True)
|
|
bike_id = fields.Many2one(
|
|
'fleet.vehicle', string="Company Bike",
|
|
tracking=True,
|
|
compute='_compute_bike_id', store=True, readonly=False,
|
|
domain=lambda self: [('company_id', 'in', (False, self.env.company.id)), ('vehicle_type', '=', 'bike')],
|
|
groups='fleet.fleet_group_manager')
|
|
company_bike_depreciated_cost = fields.Float(
|
|
compute='_compute_company_bike_depreciated_cost', store=True, compute_sudo=True,
|
|
groups='hr.group_hr_user')
|
|
new_bike = fields.Boolean(
|
|
'Requested a new bike', compute='_compute_new_bike', store=True, readonly=False,
|
|
groups='hr.group_hr_user')
|
|
new_bike_model_id = fields.Many2one(
|
|
'fleet.vehicle.model', string="New Bike",
|
|
domain=lambda self: self._get_possible_model_domain(vehicle_type='bike'),
|
|
compute='_compute_new_bike_model_id', store=True, readonly=False, groups='hr.group_hr_user')
|
|
transport_mode_private_car = fields.Boolean(store=True, readonly=False)
|
|
|
|
@api.depends('new_bike', 'new_bike_model_id')
|
|
def _compute_bike_id(self):
|
|
for version in self:
|
|
if version.new_bike or version.new_bike_model_id:
|
|
version.bike_id = False
|
|
|
|
@api.depends('bike_id')
|
|
def _compute_new_bike_model_id(self):
|
|
for version in self:
|
|
if version.bike_id:
|
|
version.update({
|
|
'new_bike_model_id': False,
|
|
'new_bike': False,
|
|
})
|
|
|
|
@api.depends('new_bike_model_id')
|
|
def _compute_new_bike(self):
|
|
for version in self:
|
|
if version.new_bike_model_id:
|
|
version.new_bike = True
|
|
|
|
@api.depends('car_id')
|
|
def _compute_car_model_name(self):
|
|
for version in self:
|
|
if version.car_id:
|
|
version.car_model_name = version.car_id.model_id.display_name
|
|
else:
|
|
version.car_model_name = False
|
|
|
|
@api.depends('employee_id', 'transport_mode_private_car')
|
|
def _compute_car_id(self):
|
|
versions_to_reset = self.filtered(lambda c: c.transport_mode_private_car or not c.transport_mode_car)
|
|
versions_to_reset.car_id = False
|
|
remaining_versions = self - versions_to_reset
|
|
if not remaining_versions:
|
|
return
|
|
employees_partners = remaining_versions.employee_id.work_contact_id
|
|
cars = self.env['fleet.vehicle'].search([
|
|
('vehicle_type', '=', 'car'),
|
|
'|', ('driver_id', 'in', employees_partners.ids), ('future_driver_id', 'in', employees_partners.ids)
|
|
], order='future_driver_id, driver_id')
|
|
dict_car = {
|
|
(car.driver_id or car.future_driver_id).id: car.id for car in cars
|
|
}
|
|
for version in remaining_versions:
|
|
if version.car_id:
|
|
continue
|
|
partner_id = version.employee_id.work_contact_id.id
|
|
if partner_id in dict_car:
|
|
version.car_id = dict_car[partner_id]
|
|
version.transport_mode_car = True
|
|
else:
|
|
version.car_id = False
|
|
|
|
@api.depends('car_id')
|
|
def _compute_fuel_type(self):
|
|
for version in self:
|
|
version.fuel_type = version.car_id.fuel_type if version.car_id else False
|
|
|
|
@api.depends('car_id', 'car_id.total_depreciated_cost', 'car_id.atn')
|
|
def _compute_car_atn_and_costs(self):
|
|
self.car_atn = False
|
|
self.company_car_total_depreciated_cost = False
|
|
for version in self:
|
|
if version.car_id:
|
|
version.car_atn = version.car_id.atn
|
|
version.company_car_total_depreciated_cost = version.car_id.total_depreciated_cost
|
|
|
|
@api.depends('new_bike', 'bike_id', 'new_bike_model_id', 'bike_id.total_depreciated_cost',
|
|
'bike_id.co2_fee', 'new_bike_model_id.default_total_depreciated_cost', 'transport_mode_bike')
|
|
def _compute_company_bike_depreciated_cost(self):
|
|
for version in self:
|
|
version.company_bike_depreciated_cost = False
|
|
if not version.new_bike and version.transport_mode_bike and version.bike_id:
|
|
version.company_bike_depreciated_cost = version.bike_id.total_depreciated_cost
|
|
elif not version.transport_mode_bike and version.new_bike and version.new_bike_model_id:
|
|
version.company_bike_depreciated_cost = version.new_bike_model_id.default_recurring_cost_amount_depreciated
|
|
|
|
@api.depends('car_id.log_contracts.state')
|
|
def _compute_car_open_contracts_count(self):
|
|
for version in self:
|
|
version.car_open_contracts_count = len(version.car_id.log_contracts.filtered(
|
|
lambda c: c.state == 'open').ids)
|
|
|
|
@api.depends('car_open_contracts_count', 'car_id.log_contracts.recurring_cost_amount_depreciated')
|
|
def _compute_recurring_cost_amount_depreciated(self):
|
|
for version in self:
|
|
if version.car_open_contracts_count == 1:
|
|
version.recurring_cost_amount_depreciated = version.car_id.log_contracts.filtered(
|
|
lambda c: c.state == 'open'
|
|
).recurring_cost_amount_depreciated
|
|
else:
|
|
version.recurring_cost_amount_depreciated = 0.0
|
|
|
|
def _inverse_recurring_cost_amount_depreciated(self):
|
|
for version in self:
|
|
if version.car_open_contracts_count == 1:
|
|
version.car_id.log_contracts.filtered(
|
|
lambda c: c.state == 'open'
|
|
).recurring_cost_amount_depreciated = version.recurring_cost_amount_depreciated
|
|
|
|
def _get_available_cars_domain(self):
|
|
return self._get_vehicles_without_current_drivers_domain(
|
|
self.employee_id.work_contact_id,
|
|
)
|
|
|
|
@api.depends('name')
|
|
def _compute_available_cars_amount(self):
|
|
for version in self:
|
|
version.available_cars_amount = self.env['fleet.vehicle'].sudo().search_count(
|
|
version._get_available_cars_domain(),
|
|
)
|
|
|
|
@api.depends('name')
|
|
def _compute_max_unused_cars(self):
|
|
params = self.env['ir.config_parameter'].sudo()
|
|
max_unused_cars = params.get_param('l10n_be_hr_payroll_fleet.max_unused_cars', default=5)
|
|
for version in self:
|
|
version.max_unused_cars = 999999 if version.env.context.get('is_applicant') else int(max_unused_cars)
|
|
|
|
@api.onchange('new_bike')
|
|
def _onchange_new_bike(self):
|
|
if self.new_bike:
|
|
self.bike_id = False
|
|
self.transport_mode_bike = False
|
|
else:
|
|
self.new_bike_model_id = False
|
|
|
|
@api.onchange('transport_mode_bike', 'transport_mode_train', 'transport_mode_public', 'transport_mode_car')
|
|
def _onchange_transport_mode(self):
|
|
super()._onchange_transport_mode()
|
|
if self.transport_mode_bike:
|
|
self.new_bike = False
|
|
self.new_bike_model_id = False
|
|
else:
|
|
self.bike_id = False
|
|
if self.transport_mode_car:
|
|
self.has_bicycle = False
|
|
if self.sudo().car_id:
|
|
self.transport_mode_private_car = False
|
|
|
|
@api.onchange('has_bicycle')
|
|
def _onchange_has_bicycle(self):
|
|
if self.has_bicycle:
|
|
self.transport_mode_car = False
|
|
self.car_id = False
|
|
|
|
def write(self, vals):
|
|
# Force to track cars in employee form if any changes is found after version write
|
|
if not self.env.context.get('tracking_disable'):
|
|
self.employee_id._track_prepare(["car_id", "ordered_car_id", "bike_id"])
|
|
return super().write(vals=vals)
|
|
|
|
def _get_fields_that_recompute_payslip(self):
|
|
# Returns the fields that should recompute the payslip
|
|
return super()._get_fields_that_recompute_payslip() + [
|
|
'car_id',
|
|
]
|