Overview
The Vehicle Management module is the core of MotorDesk’s fleet management system. It tracks vehicle information, maintenance schedules, kilometer-based service intervals, and provides complete service history with direct integration to the billing module.
Core Capabilities
Fleet registry with detailed vehicle information
Owner and driver relationship management
Kilometer-based maintenance tracking
Service history with product details
Direct sales invoice generation
Maintenance alerts for upcoming services
Vehicle Data Model
Each vehicle record contains comprehensive information:
interface Vehicle {
id : string ;
propietarioId : string ; // Owner (customer ID)
conductorHabitualId : string | null ; // Habitual driver (customer ID)
placa : string ; // License plate
marca : string ; // Brand
modelo : string ; // Model
anio : number ; // Year
color : string ; // Color
kilometrajeActual : number ; // Current mileage
createdAt : string ;
syncedAt : string ;
isDeleted : boolean ;
}
Example Vehicle Record
{
id : "veh-001" ,
propietarioId : "cust-001" ,
conductorHabitualId : "cust-002" ,
placa : "ABC-123" ,
marca : "Toyota" ,
modelo : "Hilux" ,
anio : 2020 ,
color : "Blanco" ,
kilometrajeActual : 45000 ,
createdAt : "2023-10-25T10:00:00Z" ,
syncedAt : "2023-10-25T10:01:00Z" ,
isDeleted : false
}
Enhanced Vehicle Data Mapping
The system enriches vehicle data with relational information from customers, sales, and products:
const mappedVehicles = useMemo (() => {
return vehiclesData . vehicles . filter ( v => ! v . isDeleted ). map ( v => {
// Get owner and driver information
const cliente = customersData . customers . find ( c => c . id === v . propietarioId );
const chofer = customersData . customers . find ( c => c . id === v . conductorHabitualId );
// Get all sales for this vehicle, sorted by date (newest first)
const vehSales = salesData . sales
. filter ( s => s . vehicleId === v . id )
. sort (( a , b ) => new Date ( b . fechaEmision ). getTime () - new Date ( a . fechaEmision ). getTime ());
const latestSale = vehSales [ 0 ];
// Build complete service history with product details
const historialConProductos = vehSales . map ( sale => {
const items = saleDetailsData . saleDetails
. filter ( si => si . saleId === sale . id )
. map ( si => {
const prod = productsData . products . find ( p => p . id === si . productId );
return { ... si , productName: prod ?. nombre || 'Producto no encontrado' };
});
return { ... sale , items };
});
return {
... v ,
clienteNombre: cliente ?. nombreRazonSocial || 'Desconocido' ,
clienteDocumento: cliente ?. numeroDocumento || '' ,
choferNombre: chofer ?. nombreRazonSocial || 'Sin chofer' ,
kmActual: latestSale ?. kilometrajeIngreso || v . kilometrajeActual || 0 ,
kmProximo: latestSale ?. proximoCambioKm || 0 ,
historial: historialConProductos ,
};
});
}, []);
Vehicle Fleet Table
The main fleet view displays vehicles with real-time maintenance status:
Vehicle Identification
Shows license plate prominently with brand, model, and year information.
Customer Relationships
Displays both the vehicle owner (building icon) and habitual driver (user icon).
Mileage Tracking
Current mileage and next service interval with visual alerts when maintenance is due.
Quick Actions
View details, edit information, or delete vehicle records.
Table Implementation
// Vehicle table row (src/pages/Vehicles.tsx:92)
< tr key = { vehicle . id } className = { styles . tableRow } >
< td >
< strong className = { styles . vehiclePlaca } >
{ vehicle . placa }
</ strong >
< span className = { styles . vehicleDetails } >
{ vehicle . marca } { vehicle . modelo } ( { vehicle . anio } )
</ span >
</ td >
< td >
< span className = { styles . customerInfo } >
< Building2 className = { styles . customerIcon } />
{ vehicle . clienteNombre }
</ span >
< span className = { styles . driverInfo } >
< User className = { styles . driverIcon } />
{ vehicle . choferNombre }
</ span >
</ td >
< td >
< span className = { styles . kmActualBadge } >
Act: { vehicle . kmActual . toLocaleString () } km
</ span >
< span className = { ` ${ styles . kmNextBadgeBase } ${
vehicle . kmActual >= vehicle . kmProximo - 1000
? styles . kmNextBadgeAlert
: styles . kmNextBadgeNormal
} ` } >
Próx: { vehicle . kmProximo . toLocaleString () } km
{ vehicle . kmActual >= vehicle . kmProximo - 1000 && (
< AlertTriangle className = { styles . kmAlertIcon } />
) }
</ span >
</ td >
</ tr >
Maintenance Alerts
The system automatically displays an alert icon when a vehicle is within 1,000 km of its next scheduled service, helping prevent missed maintenance.
Alert Logic
// Alert when within 1000km of next service
{ vehicle . kmActual >= vehicle . kmProximo - 1000 && (
< AlertTriangle className = {styles. kmAlertIcon } />
)}
Search and Filtering
The vehicle module supports multi-field search:
const filteredVehicles = useMemo (() => {
return mappedVehicles . filter (( v ) => {
const term = searchTerm . toLowerCase ();
return (
v . placa . toLowerCase (). includes ( term ) ||
v . clienteNombre . toLowerCase (). includes ( term ) ||
v . marca . toLowerCase (). includes ( term ) ||
v . modelo . toLowerCase (). includes ( term )
);
});
}, [ mappedVehicles , searchTerm ]);
Searchable Fields
License plate (placa)
Owner name (clienteNombre)
Vehicle brand (marca)
Vehicle model (modelo)
Service History and Billing Integration
One of MotorDesk’s most powerful features is the seamless integration between vehicle service history and the billing module.
Generating New Sales
const handleEmitirFactura = ( vehicle : any , pastSale ?: any ) => {
closeModal ();
let productosParaCart : any [] = [];
let observacionSugerida = "" ;
// Repeat past service - pre-populate cart with previous products
if ( pastSale && pastSale . items && pastSale . items . length > 0 ) {
pastSale . items . forEach (( item : any ) => {
const fullProduct = productsData . products . find ( p => p . id === item . productId );
if ( fullProduct ) {
productosParaCart . push ({
... fullProduct ,
cantidad: item . cantidad ,
precioUnitario: fullProduct . precioVenta
});
}
});
observacionSugerida = `Servicio basado en el historial del ${ new Date ( pastSale . fechaEmision ). toLocaleDateString () } .` ;
} else {
// New blank sale
observacionSugerida = `Atención al vehículo placa ${ vehicle . placa } .` ;
}
// Navigate to sales module with pre-filled data
navigate ( '/sales' , {
state: {
prefillData: {
vehicleId: vehicle . id ,
customerId: vehicle . propietarioId ,
choferId: vehicle . conductorHabitualId ,
placa: vehicle . placa ,
cartItems: productosParaCart ,
observacionSugerida ,
kilometrajeActual: vehicle . kmActual || 0 ,
kmProximo: pastSale ? pastSale . proximoCambioKm : 0
}
}
});
};
Creates a blank sales invoice with the vehicle’s plate number and current mileage pre-filled, ready for adding new services.
Automatically populates the shopping cart with products from a previous service, maintaining the same quantities and suggesting the next service interval.
Vehicle CRUD Operations
Adding Vehicles
The vehicle form modal allows creating new vehicle records:
const handleSaveVehicle = ( data : any ) => {
console . log ( "Datos a guardar:" , data );
alert ( `Vehículo ${ data . placa } guardado correctamente (Simulación)` );
closeModal ();
};
Editing Vehicles
Edit existing vehicle information while maintaining service history and relationships.
Deleting Vehicles
Vehicle deletion is a soft delete operation (sets isDeleted: true) to preserve service history and maintain data integrity.
const handleDeleteVehicle = ( id : string ) => {
console . log ( "Eliminando vehículo con ID:" , id );
alert ( "Vehículo eliminado correctamente (Simulación)" );
closeModal ();
};
The vehicle list supports configurable pagination:
const totalPages = Math . ceil ( filteredVehicles . length / itemsPerPage );
const currentVehicles = useMemo (() => {
const startIndex = ( currentPage - 1 ) * itemsPerPage ;
return filteredVehicles . slice ( startIndex , startIndex + itemsPerPage );
}, [ filteredVehicles , currentPage , itemsPerPage ]);
Page Size Options Display 5, 10, 20, or 50 vehicles per page for optimal viewing based on your fleet size.
Modal Components
The vehicle module uses three specialized modals:
VehicleDetailsModal
Complete vehicle profile including:
Full vehicle specifications
Owner and driver information
Complete service history with products
Direct billing buttons for new or repeat services
VehicleFormModal
Add or edit vehicle information with customer selection dropdowns for owner and driver assignment.
VehicleDeleteModal
Confirmation dialog before soft-deleting a vehicle record.
Best Practices
Fleet Management Tips
Update mileage with each service to maintain accurate maintenance schedules
Use the repeat service feature to ensure consistent maintenance
Monitor alert indicators for upcoming services
Assign habitual drivers to improve service record accuracy
Review service history before scheduling new maintenance