[IMP] fleet: Add a parameter to specify the alert delay

Purpose
=======

An alert is sent when the vehicle contract will be outdated in less than a month.

This could be a parameter than could be set on the res.config.

Specification
=============

Use ir.config.parameter in all the cases

Default value is 30 days

Consider 'diesoon' contract as an 'in progress' contract

closes odoo/odoo#29704
This commit is contained in:
jbm-odoo
2019-01-22 09:44:34 +00:00
committed by Yannick Tivisse
parent 2809fe4258
commit de7c94a335
8 changed files with 84 additions and 38 deletions
+1
View File
@@ -36,6 +36,7 @@ Main Features
'views/fleet_vehicle_cost_views.xml',
'views/fleet_board_view.xml',
'views/mail_activity_views.xml',
'views/res_config_settings_views.xml',
'data/fleet_cars_data.xml',
'data/fleet_data.xml',
'data/mail_data.xml',
+1
View File
@@ -4,3 +4,4 @@
from . import fleet_vehicle
from . import fleet_vehicle_cost
from . import fleet_vehicle_model
from . import res_config_settings
+10 -6
View File
@@ -115,13 +115,15 @@ class FleetVehicle(models.Model):
@api.depends('log_contracts')
def _compute_contract_reminder(self):
params = self.env['ir.config_parameter'].sudo()
delay_alert_contract = int(params.get_param('hr_fleet.delay_alert_contract', default=30))
for record in self:
overdue = False
due_soon = False
total = 0
name = ''
for element in record.log_contracts:
if element.state in ('open', 'expired') and element.expiration_date:
if element.state in ('open', 'diesoon', 'expired') and element.expiration_date:
current_date_str = fields.Date.context_today(record)
due_time_str = element.expiration_date
current_date = fields.Date.from_string(current_date_str)
@@ -130,13 +132,13 @@ class FleetVehicle(models.Model):
if diff_time < 0:
overdue = True
total += 1
if 0 >= diff_time < 30:
if diff_time < delay_alert_contract:
due_soon = True
total += 1
if overdue or due_soon:
log_contract = self.env['fleet.vehicle.log.contract'].search([
('vehicle_id', '=', record.id),
('state', 'in', ('open', 'expired'))
('state', 'in', ('open', 'diesoon', 'expired'))
], limit=1, order='expiration_date asc')
if log_contract:
# we display only the name of the oldest overdue/due soon contract
@@ -148,6 +150,8 @@ class FleetVehicle(models.Model):
record.contract_renewal_name = name
def _search_contract_renewal_due_soon(self, operator, value):
params = self.env['ir.config_parameter'].sudo()
delay_alert_contract = int(params.get_param('hr_fleet.delay_alert_contract', default=30))
res = []
assert operator in ('=', '!=', '<>') and value in (True, False), 'Operation not supported'
if (operator == '=' and value is True) or (operator in ('<>', '!=') and value is False):
@@ -156,7 +160,7 @@ class FleetVehicle(models.Model):
search_operator = 'not in'
today = fields.Date.context_today(self)
datetime_today = fields.Datetime.from_string(today)
limit_date = fields.Datetime.to_string(datetime_today + relativedelta(days=+15))
limit_date = fields.Datetime.to_string(datetime_today + relativedelta(days=+delay_alert_contract))
self.env.cr.execute("""SELECT cost.vehicle_id,
count(contract.id) AS contract_number
FROM fleet_vehicle_cost cost
@@ -164,7 +168,7 @@ class FleetVehicle(models.Model):
WHERE contract.expiration_date IS NOT NULL
AND contract.expiration_date > %s
AND contract.expiration_date < %s
AND contract.state IN ('open', 'expired')
AND contract.state IN ('open', 'diesoon', 'expired')
GROUP BY cost.vehicle_id""", (today, limit_date))
res_ids = [x[0] for x in self.env.cr.fetchall()]
res.append(('id', search_operator, res_ids))
@@ -184,7 +188,7 @@ class FleetVehicle(models.Model):
LEFT JOIN fleet_vehicle_log_contract contract ON contract.cost_id = cost.id
WHERE contract.expiration_date IS NOT NULL
AND contract.expiration_date < %s
AND contract.state IN ('open', 'expired')
AND contract.state IN ('open', 'diesoon', 'expired')
GROUP BY cost.vehicle_id ''', (today,))
res_ids = [x[0] for x in self.env.cr.fetchall()]
res.append(('id', search_operator, res_ids))
+5 -3
View File
@@ -156,7 +156,7 @@ class FleetVehicleLogContract(models.Model):
otherwise return the number of days before the contract expires
"""
for record in self:
if (record.expiration_date and (record.state == 'open' or record.state == 'expired')):
if record.expiration_date and record.state in ['open', 'diesoon', 'expired']:
today = fields.Date.from_string(fields.Date.today())
renew_date = fields.Date.from_string(record.expiration_date)
diff_time = (renew_date - today).days
@@ -267,9 +267,11 @@ class FleetVehicleLogContract(models.Model):
def scheduler_manage_contract_expiration(self):
# This method is called by a cron task
# It manages the state of a contract, possibly by posting a message on the vehicle concerned and updating its status
params = self.env['ir.config_parameter'].sudo()
delay_alert_contract = int(params.get_param('hr_fleet.delay_alert_contract', default=30))
date_today = fields.Date.from_string(fields.Date.today())
in_fifteen_days = fields.Date.to_string(date_today + relativedelta(days=+15))
nearly_expired_contracts = self.search([('state', '=', 'open'), ('expiration_date', '<', in_fifteen_days)])
outdated_days = fields.Date.to_string(date_today + relativedelta(days=+delay_alert_contract))
nearly_expired_contracts = self.search([('state', '=', 'open'), ('expiration_date', '<', outdated_days)])
nearly_expired_contracts.write({'state': 'diesoon'})
for contract in nearly_expired_contracts.filtered(lambda contract: contract.user_id):
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = ['res.config.settings']
delay_alert_contract = fields.Integer(string='Delay alert contract outdated', default=30, config_parameter='hr_fleet.delay_alert_contract')
@@ -171,7 +171,7 @@
<field name="arch" type="xml">
<form string="Contract logs">
<header>
<button name="contract_close" states="open,expired,future" type="object" class="oe_highlight" string="Close Contract" groups="fleet.fleet_group_manager"/>
<button name="contract_close" states="open,diesoon,expired,future" type="object" class="oe_highlight" string="Close Contract" groups="fleet.fleet_group_manager"/>
<button name="contract_open" states="closed" type="object" class="oe_highlight" string="Set Contract In Progress" groups="fleet.fleet_group_manager"/>
<button class="oe_highlight" name="act_renew_contract" type="object" string="Renew Contract" attrs="{'invisible': [('state', '=', 'open')]}" help="Create a new contract automatically with all the same informations except for the date that will start at the end of current contract" groups="fleet.fleet_group_manager"/>
<field name="state" widget="statusbar" />
@@ -270,7 +270,7 @@
<field name="name">fleet.vehicle.log.contract.tree</field>
<field name="model">fleet.vehicle.log.contract</field>
<field name="arch" type="xml">
<tree string="Contract logs" decoration-warning="days_left>0 and days_left&lt;15" decoration-danger="days_left==0" decoration-muted="state=='closed'">
<tree string="Contract logs" decoration-warning="state=='diesoon'" decoration-danger="days_left==0" decoration-muted="state=='closed'">
<field name="active" invisible="1"/>
<field name="start_date" />
<field name="expiration_date" />
@@ -338,7 +338,7 @@
<field name="insurer_id" string="Vendor" filter_domain="[('insurer_id','child_of', self)]"/>
<field name="cost_subtype_id" string="Service Type" filter_domain="[('cost_ids.cost_subtype_id', 'ilike', self)]"/>
<filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
<filter string="In Progress" name="open" domain="[('state', '=', 'open')]"/>
<filter string="In Progress" name="open" domain="[('state', 'in', ['open','diesoon'])]"/>
<filter string="Expired" name="expired" domain="[('state', '=', 'expired')]"/>
<filter string="Expiring Soon" name="expire_soon" domain="[('state', '=', 'diesoon')]"/>
<separator/>
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.hr.fleet</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="90"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" data-string="Fleet" id="fleet" string="Fleet" data-key="fleet" groups="fleet.fleet_group_manager">
<h2>Fleet Management</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">End Date Contract Alert</span>
<div class="text-muted content-group mt16">
<span>Send an alert </span>
<field name="delay_alert_contract" class="text-center oe_inline" />
<span> days before the end date</span>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
<record id="fleet_config_settings_action" model="ir.actions.act_window">
<field name="name">Settings</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.config.settings</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="context">{'module' : 'fleet'}</field>
</record>
<menuitem id="fleet_config_settings_menu" name="Settings"
parent="fleet.fleet_configuration" sequence="0" action="fleet_config_settings_action"
groups="base.group_system"/>
</data>
</odoo>
@@ -7,19 +7,16 @@
<field name="priority" eval="90"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" data-string="Fleet" string="Fleet" data-key="fleet" groups="fleet.fleet_group_manager">
<h2>Fleet Management</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">New Car Request</span>
<div class="text-muted content-group mt16">
<span>An employee cannot request a new car if there are more than </span>
<field name="max_unused_cars" class="text-center oe_inline" />
<span> existing vehicles availables.</span>
</div>
<xpath expr="//div[@id='fleet']" position="inside">
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">New Car Request</span>
<div class="text-muted content-group mt16">
<span>An employee cannot request a new car if there are more than </span>
<field name="max_unused_cars" class="text-center oe_inline" />
<span> existing vehicles availables.</span>
</div>
</div>
</div>
@@ -27,18 +24,5 @@
</xpath>
</field>
</record>
<record id="fleet_config_settings_action" model="ir.actions.act_window">
<field name="name">Settings</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.config.settings</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="context">{'module' : 'fleet'}</field>
</record>
<menuitem id="fleet_config_settings_menu" name="Settings"
parent="fleet.fleet_configuration" sequence="0" action="fleet_config_settings_action"
groups="base.group_system"/>
</data>
</odoo>