[IMP] fleet: Improve general UX (Back2basics)

Overall UI review of the fleet app.

Also changes the behaviour of shared fields between vehicles and vehicle
models.

Task ID: 2468228

closes odoo/odoo#72943

Related: odoo/upgrade#2601
Related: odoo/enterprise#19356
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
William Braeckman
2021-07-14 14:40:54 +00:00
committed by Yannick Tivisse
parent 4077f5189a
commit c80002f660
4 changed files with 151 additions and 76 deletions
+40 -34
View File
@@ -5,8 +5,17 @@ from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
from odoo.osv import expression
from odoo.addons.fleet.models.fleet_vehicle_model import FUEL_TYPES
#Some fields don't have the exact same name
MODEL_FIELDS_TO_VEHICLE = {
'transmission': 'transmission', 'model_year': 'model_year', 'electric_assistance': 'electric_assistance',
'color': 'color', 'seats': 'seats', 'doors': 'doors', 'trailer_hook': 'trailer_hook',
'default_co2': 'co2', 'co2_standard': 'co2_standard', 'default_fuel_type': 'fuel_type',
'power': 'power', 'horsepower': 'horsepower', 'horsepower_tax': 'horsepower_tax',
}
class FleetVehicle(models.Model):
_inherit = ['mail.thread', 'mail.activity.mixin']
_name = 'fleet.vehicle'
@@ -18,7 +27,7 @@ class FleetVehicle(models.Model):
return state if state and state.id else False
name = fields.Char(compute="_compute_vehicle_name", store=True)
description = fields.Html("Vehicle Description")
description = fields.Html("Vehicle Description", help="Add a note about this vehicle")
active = fields.Boolean('Active', default=True, tracking=True)
fleet_id = fields.Many2one('fleet.category', string='Fleet')
manager_id = fields.Many2one(
@@ -35,10 +44,12 @@ class FleetVehicle(models.Model):
store=True,
)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id')
country_id = fields.Many2one('res.country', related='company_id.country_id')
country_code = fields.Char(related='country_id.code')
license_plate = fields.Char(tracking=True,
help='License plate number of the vehicle (i = plate number for a car)')
vin_sn = fields.Char('Chassis Number', help='Unique number written on the vehicle motor (VIN/SN number)', copy=False)
trailer_hook = fields.Boolean(default=False)
trailer_hook = fields.Boolean(default=False, string='Trailer Hitch', compute='_compute_model_fields', store=True, readonly=False)
driver_id = fields.Many2one('res.partner', 'Driver', tracking=True, help='Driver of the vehicle', copy=False)
future_driver_id = fields.Many2one('res.partner', 'Future Driver', tracking=True, help='Next Driver of the vehicle', copy=False, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
model_id = fields.Many2one('fleet.vehicle.model', 'Model',
@@ -56,15 +67,15 @@ class FleetVehicle(models.Model):
acquisition_date = fields.Date('Immatriculation Date', required=False,
default=fields.Date.today, help='Date when the vehicle has been immatriculated')
first_contract_date = fields.Date(string="First Contract Date", default=fields.Date.today)
color = fields.Char(help='Color of the vehicle')
color = fields.Char(help='Color of the vehicle', compute='_compute_model_fields', store=True, readonly=False)
state_id = fields.Many2one('fleet.vehicle.state', 'State',
default=_get_default_state, group_expand='_read_group_stage_ids',
tracking=True,
help='Current state of the vehicle', ondelete="set null")
location = fields.Char(help='Location of the vehicle (garage, ...)')
seats = fields.Integer('Seats Number', help='Number of seats of the vehicle')
model_year = fields.Char('Model Year', help='Year of the model')
doors = fields.Integer('Doors Number', help='Number of doors of the vehicle', compute="_compute_doors", store=True, readonly=True)
seats = fields.Integer('Seats Number', help='Number of seats of the vehicle', compute='_compute_model_fields', store=True, readonly=False)
model_year = fields.Char('Model Year', help='Year of the model', compute='_compute_model_fields', store=True, readonly=False)
doors = fields.Integer('Doors Number', help='Number of doors of the vehicle', compute='_compute_model_fields', store=True, readonly=False)
tag_ids = fields.Many2many('fleet.vehicle.tag', 'fleet_vehicle_vehicle_tag_rel', 'vehicle_tag_id', 'tag_id', 'Tags', copy=False)
odometer = fields.Float(compute='_get_odometer', inverse='_set_odometer', string='Last Odometer',
help='Odometer measure of the vehicle at the moment of this log')
@@ -74,23 +85,13 @@ class FleetVehicle(models.Model):
], 'Odometer Unit', default='kilometers', help='Unit of the odometer ', required=True)
transmission = fields.Selection(
[('manual', 'Manual'), ('automatic', 'Automatic')], 'Transmission', help='Transmission Used by the vehicle',
compute='_compute_transmission', store=True, readonly=False)
fuel_type = fields.Selection([
('gasoline', 'Gasoline'),
('diesel', 'Diesel'),
('lpg', 'LPG'),
('electric', 'Electric'),
('hybrid', 'Hybrid'),
('plug_in_hybrid_diesel', 'Plug-in Hybrid Diesel'),
('plug_in_hybrid_gasoline', 'Plug-in Hybrid Gasoline'),
('full_hybrid_gasoline', 'Full Hybrid Gasoline'),
('cng', 'CNG'),
('hydrogen', 'Hydrogen'),
], 'Fuel Type', help='Fuel Used by the vehicle')
horsepower = fields.Integer()
horsepower_tax = fields.Float('Horsepower Taxation')
power = fields.Integer('Power', help='Power in kW of the vehicle')
co2 = fields.Float('CO2 Emissions', help='CO2 emissions of the vehicle')
compute='_compute_model_fields', store=True, readonly=False)
fuel_type = fields.Selection(FUEL_TYPES, 'Fuel Type', help='Fuel Used by the vehicle', compute='_compute_model_fields', store=True, readonly=False)
horsepower = fields.Integer(compute='_compute_model_fields', store=True, readonly=False)
horsepower_tax = fields.Float('Horsepower Taxation', compute='_compute_model_fields', store=True, readonly=False)
power = fields.Integer('Power', help='Power in kW of the vehicle', compute='_compute_model_fields', store=True, readonly=False)
co2 = fields.Float('CO2 Emissions', help='CO2 emissions of the vehicle', compute='_compute_model_fields', store=True, readonly=False)
co2_standard = fields.Char(compute='_compute_model_fields', store=True, readonly=False)
image_128 = fields.Image(related='model_id.image_128', readonly=True)
contract_renewal_due_soon = fields.Boolean(compute='_compute_contract_reminder', search='_search_contract_renewal_due_soon',
string='Has Contracts to renew')
@@ -111,7 +112,7 @@ class FleetVehicle(models.Model):
plan_to_change_bike = fields.Boolean(related='driver_id.plan_to_change_bike', store=True, readonly=False)
vehicle_type = fields.Selection(related='model_id.vehicle_type')
frame_type = fields.Selection([('diamant', 'Diamant'), ('trapez', 'Trapez'), ('wave', 'Wave')], help="Frame type of the bike")
electric_assistance = fields.Boolean()
electric_assistance = fields.Boolean(compute='_compute_model_fields', store=True, readonly=False)
frame_size = fields.Float()
@api.depends('fleet_id')
@@ -126,10 +127,21 @@ class FleetVehicle(models.Model):
if record.fleet_id:
record.company_id = record.fleet_id.company_id
@api.depends('vehicle_type')
def _compute_doors(self):
for record in self:
record.doors = 5 if record.model_id.vehicle_type == 'car' else 0
@api.depends('model_id')
def _compute_model_fields(self):
'''
Copies all the related fields from the model to the vehicle
'''
model_values = dict()
for vehicle in self.filtered('model_id'):
if vehicle.model_id.id in model_values:
write_vals = model_values[vehicle.model_id.id]
else:
# copy if value is truthy
write_vals = {MODEL_FIELDS_TO_VEHICLE[key]: vehicle.model_id[key] for key in MODEL_FIELDS_TO_VEHICLE\
if vehicle.model_id[key]}
model_values[vehicle.model_id.id] = write_vals
vehicle.write(write_vals)
@api.depends('model_id.brand_id.name', 'model_id.name', 'license_plate')
def _compute_vehicle_name(self):
@@ -201,12 +213,6 @@ class FleetVehicle(models.Model):
record.contract_renewal_name = name
record.contract_state = state
@api.depends('model_id')
def _compute_transmission(self):
for vehicle in self:
if vehicle.model_id:
vehicle.transmission = vehicle.model_id.transmission
def _get_analytic_name(self):
# This function is used in fleet_account and is overrided in l10n_be_hr_payroll_fleet
return self.license_plate or _('No plate')
@@ -4,6 +4,13 @@
from odoo import _, api, fields, models
FUEL_TYPES = [
('gasoline', 'Gasoline'), ('diesel', 'Diesel'), ('lpg', 'LPG'),
('electric', 'Electric'), ('hybrid', 'Hybrid'), ('plug_in_hybrid_diesel', 'Plug-in Hybrid Diesel'),
('plug_in_hybrid_gasoline', 'Plug-in Hybrid Gasoline'), ('full_hybrid_gasoline', 'Full Hybrid Gasoline'),
('cng', 'CNG'), ('hydrogen', 'Hydrogen'),
]
class FleetVehicleModel(models.Model):
_name = 'fleet.vehicle.model'
_description = 'Model of a vehicle'
@@ -18,6 +25,18 @@ class FleetVehicleModel(models.Model):
vehicle_type = fields.Selection([('car', 'Car'), ('bike', 'Bike')], default='car', required=True)
transmission = fields.Selection([('manual', 'Manual'), ('automatic', 'Automatic')], 'Transmission', help='Transmission Used by the vehicle')
vehicle_count = fields.Integer(compute='_compute_vehicle_count')
model_year = fields.Integer()
color = fields.Char()
seats = fields.Integer(string='Seats Number')
doors = fields.Integer(string='Doors Number')
trailer_hook = fields.Boolean(default=False, string='Trailer Hitch')
default_co2 = fields.Float('CO2 Emissions')
co2_standard = fields.Char()
default_fuel_type = fields.Selection(FUEL_TYPES, 'Fuel Type', default='diesel')
power = fields.Integer('Power')
horsepower = fields.Integer()
horsepower_tax = fields.Float('Horsepower Taxation')
electric_assistance = fields.Boolean(default=False)
@api.depends('name', 'brand_id')
def name_get(self):
@@ -32,21 +32,57 @@
</group>
</group>
<notebook>
<page string="Information" name="information" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}">
<group string="Vehicle Information">
<field name="transmission"/>
<page string="Information" name="information">
<group>
<group string="Model" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}">
<field name="seats"/>
<field name="doors"/>
<field name="color"/>
<field name="model_year"/>
<field name="trailer_hook"/>
</group>
<group id="vehicle_information" string="Vehicle Information" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}">
<field name="electric_assistance"/>
</group>
</group>
<group string="Engine" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}">
<group>
<field name="default_fuel_type" required="1"/>
<label for="default_co2"/>
<div class="o_row" name="default_co2">
<field name="default_co2"/><span>g/km</span>
</div>
<field name="co2_standard"/>
<field name="transmission"/>
</group>
<group>
<label for="power"/>
<div class="o_row">
<field name="power"/><span>kW</span>
</div>
<field name="horsepower"/>
<field name="horsepower_tax"/>
</group>
</group>
</page>
<page string="Vendors" name="vendors">
<field name="vendors">
<kanban quick_create="false" create="true">
<field name="name"/>
<field name="phone"/>
<field name="email"/>
<templates>
<t t-name="kanban-box">
<div style="position: relative" class="oe_kanban_global_click">
<div>
<div class="o_kanban_record_title">
<field name="name"/>
<div class="o_kanban_details float-right">
<span class="text-muted">
<t t-if="record.phone.raw_value"><field name="phone"/><br/></t>
<t t-if="record.email.raw_value"><field name="email"/></t>
</span>
</div>
</div>
</div>
</div>
+53 -39
View File
@@ -16,6 +16,7 @@
</header>
<sheet>
<field name="currency_id" invisible="1"/>
<field name="country_code" invisible="1"/>
<div class="oe_button_box" name="button_box">
<button name="open_assignation_logs"
type="object"
@@ -76,53 +77,66 @@
<field name="location"/>
</group>
<group string="Vehicle">
<field name="acquisition_date" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<field name="vin_sn"/>
<label for="odometer" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<div class="o_row" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}">
<field name="odometer"/>
<field name="odometer_unit"/>
</div>
<field name="acquisition_date" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<field name="vin_sn"/>
<field name="trailer_hook"/>
<field name="car_value" widget="monetary"/>
<field name="net_car_value" widget="monetary"/>
<field name="residual_value" widget="monetary"/>
<field name="manager_id" domain="[('share', '=', False)]"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group string="Contract" name="contract">
<field name="manager_id" domain="[('share', '=', False)]"/>
<field name="first_contract_date"/>
</group>
<group string="Model">
<field name="seats" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<field name="doors" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<field name="color"/>
<field name="model_year"/>
<field name="frame_type" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}"/>
<label for="frame_size" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}"/>
<div class="o_row" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}">
<field name="frame_size" /><span>cm</span>
</div>
<field name="electric_assistance" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}"/>
</group>
<group string="Engine" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}">
<field name="transmission"/>
<field name="fuel_type"/>
<label for="co2"/>
<div class="o_row" name="co2">
<field name="co2"/><span>g/km</span>
</div>
<field name="horsepower"/>
<field name="horsepower_tax" widget="monetary"/>
<label for="power"/>
<div class="o_row">
<field name="power"/><span>kW</span>
</div>
</group>
<group string="Description">
<field name="description" nolabel="1" placeholder="Write here any other information related to this vehicle" />
</group>
</group>
<notebook>
<page string="Tax Info">
<group>
<group string="Fiscality">
<field name="horsepower_tax" widget="monetary"/>
</group>
<group string="Contract">
<field name="first_contract_date"/>
<field name="car_value" widget="monetary"/>
<field name="net_car_value" widget="monetary"/>
<field name="residual_value" widget="monetary"/>
</group>
</group>
</page>
<page string="Model">
<group>
<group string="Model">
<field name="model_year"/>
<field name="transmission"/>
<field name="color"/>
<field name="seats" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<field name="doors" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<field name="trailer_hook" attrs="{'invisible': [('vehicle_type', '!=', 'car')]}"/>
<field name="frame_type" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}"/>
<label for="frame_size" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}"/>
<div class="o_row" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}">
<field name="frame_size" /><span>cm</span>
</div>
<field name="electric_assistance" attrs="{'invisible': [('vehicle_type', '!=', 'bike')]}"/>
</group>
<group string="Engine">
<field name="horsepower"/>
<label for="power"/>
<div class="o_row">
<field name="power"/><span>kW</span>
</div>
<field name="fuel_type"/>
<label for="co2"/>
<div class="o_row" name="co2">
<field name="co2"/><span>g/km</span>
</div>
<field name="co2_standard"/>
</group>
</group>
</page>
<page string="Note">
<field name="description" nolabel="1" placeholder="Write here any other information related to this vehicle" />
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids"/>