Overview
The Product & Inventory module provides a comprehensive catalog management system designed specifically for vehicle service businesses. Track oils, filters, parts, and services with automatic maintenance frequency calculations based on kilometers.
Key Features
Barcode-based product identification
Category-based organization
Maintenance frequency tracking (km-based)
Unit of measure support (SUNAT compliant)
Tax affectation configuration
Multi-category filtering
Product Data Model
Each product contains detailed information for accurate billing and inventory management:
interface Product {
id : string ;
codigoBarras : string ; // Barcode
nombre : string ; // Product name
categoria : string ; // Category
precioVenta : number ; // Sale price
unidadMedida : string ; // Unit of measure (NIU, GAL, LTR, etc.)
frecuenciaCambioKm ?: number ; // Maintenance frequency in kilometers
afectacionIgv : string ; // Tax affectation ("10" = taxable)
}
Example Product Records
{
id : "prod-001" ,
codigoBarras : "7751234567801" ,
nombre : "Aceite Castrol Magnatec 10W-40 (Galón)" ,
categoria : "Aceites de Motor" ,
precioVenta : 120.00 ,
unidadMedida : "GAL" ,
frecuenciaCambioKm : 5000 ,
afectacionIgv : "10"
}
{
id : "prod-002" ,
codigoBarras : "7751234567802" ,
nombre : "Filtro de Aceite Bosh TOY-01" ,
categoria : "Filtros" ,
precioVenta : 25.00 ,
unidadMedida : "NIU" ,
frecuenciaCambioKm : 5000 ,
afectacionIgv : "10"
}
{
id : "prod-005" ,
codigoBarras : "7751234567805" ,
nombre : "Pastillas de Freno Delanteras Toyota" ,
categoria : "Repuestos" ,
precioVenta : 180.00 ,
unidadMedida : "PAR" ,
frecuenciaCambioKm : 30000 ,
afectacionIgv : "10"
}
Product Categories
The system organizes products into logical categories for easy navigation:
Standard Categories
Aceites de Motor - Engine oils and lubricants
Filtros - Oil, air, and fuel filters
Refrigerantes - Coolants and antifreeze
Repuestos - Parts and replacement components
Dynamic Category Management
Categories are automatically extracted from product records:
const categories = useMemo (() => {
const uniqueCategories = new Set ( db . products . map ( p => p . categoria ));
return [ "TODAS" , ... Array . from ( uniqueCategories )];
}, []);
Maintenance Frequency Tracking
A unique feature of MotorDesk is kilometer-based maintenance frequency tracking:
When products with frecuenciaCambioKm are used in a service, the system automatically calculates the next service interval by adding the frequency to the current mileage.
Frequency Display
// Display frequency badge (src/pages/Products.tsx:54)
{ product . frecuenciaCambioKm ? (
< span className = "flex items-center gap-1.5 bg-orange-50 px-2.5 py-1 rounded-full" >
< Activity size = { 12 } />
{ product . frecuenciaCambioKm . toLocaleString () } KM
</ span >
) : (
< span className = "text-slate-300 text-xs italic" > N/A </ span >
)}
Common Maintenance Intervals
Product Type Typical Frequency Example Products Oil Change 5,000 km Engine oil, oil filters Coolant 20,000 km Antifreeze, coolant Brake Service 30,000 km Brake pads, brake fluid Synthetic Oil 10,000 km High-performance oils
Search and Filtering
The product inventory supports dual filtering:
Text Search
const filteredProducts = useMemo (() => {
return db . products . filter (( p ) => {
// Category filter
const matchCategory = selectedCategory === "TODAS" || p . categoria === selectedCategory ;
// Text search filter
const term = searchTerm . toLowerCase ();
const matchSearch =
p . nombre . toLowerCase (). includes ( term ) ||
p . codigoBarras . toLowerCase (). includes ( term ) ||
p . categoria . toLowerCase (). includes ( term );
return matchCategory && matchSearch ;
});
}, [ searchTerm , selectedCategory ]);
Search by Text
Enter product name, barcode, or category in the search box for instant filtering.
Filter by Category
Use the category dropdown to show only products from a specific category or “TODAS” for all products.
Combined Filtering
Both filters work together - search within a specific category for precise results.
Unit of Measure (SUNAT Compliant)
MotorDesk supports standard SUNAT unit codes for proper electronic billing:
Common Units
NIU - Unidad (Unit) - Default for most items
GAL - Galón (Gallon) - For bulk oils
LTR - Litro (Liter) - For liquids
PAR - Par (Pair) - For matched components
Unit Display
// Product name with unit badge (src/pages/Products.tsx:52)
< td >
< strong className = "block text-slate-800 text-sm" > { product . nombre } </ strong >
< span className = "font-black text-[10px] text-slate-400 uppercase tracking-widest" >
{ product . unidadMedida }
</ span >
</ td >
Barcode System
Each product uses a unique barcode for quick identification:
// Barcode display with icon (src/pages/Products.tsx:51)
< div className = "flex items-center gap-1.5 bg-slate-100 px-2 py-1 border border-slate-200 rounded w-fit font-mono text-xs" >
< Barcode size = { 12 } />
{ product . codigoBarras }
</ div >
Barcodes should follow EAN-13 format (13 digits) for standard retail products, or use internal numbering for custom services.
Product Table Interface
The main product inventory displays comprehensive information:
// Product table structure (src/pages/Products.tsx:44)
< table className = { styles . table } >
< thead >
< tr >
< th > CÓDIGO </ th >
< th > PRODUCTO </ th >
< th > CATEGORÍA </ th >
< th > FREC. CAMBIO </ th >
< th > PRECIO </ th >
< th className = "text-center" > ACCIONES </ th >
</ tr >
</ thead >
< tbody >
{ currentProducts . map (( product : any ) => (
< tr key = { product . id } className = "hover:bg-slate-50 transition-colors" >
< td >
< div className = "flex items-center gap-1.5" >
< Barcode size = { 12 } /> { product . codigoBarras }
</ div >
</ td >
< td >
< strong > { product . nombre } </ strong >
< span className = "text-xs" > { product . unidadMedida } </ span >
</ td >
< td >< span className = { styles . categoryBadge } > { product . categoria } </ span ></ td >
< td >
{ product . frecuenciaCambioKm ? (
< span className = "bg-orange-50 text-orange-600" >
< Activity size = { 12 } /> { product . frecuenciaCambioKm . toLocaleString () } KM
</ span >
) : < span > N/A </ span > }
</ td >
< td > S/ { Number ( product . precioVenta ). toFixed ( 2 ) } </ td >
</ tr >
)) }
</ tbody >
</ table >
Tax Affectation (IGV)
Products are configured with SUNAT tax affectation codes:
Most products use code “10” which means they are subject to 18% IGV (Impuesto General a las Ventas).
The system supports other SUNAT codes like “20” (Exempt), “30” (Unaffected) for specialized products or services.
afectacionIgv : "10" // 10 = Taxable with 18% IGV
Product Actions
Each product supports the following operations:
Action Icon Description View Details Eye View complete product information and usage history Edit Edit2 Modify product details, pricing, or frequency Delete Trash2 Remove product from catalog (with confirmation)
Adding or editing products is handled through a dedicated modal:
// Form data structure
const [ formData , setFormData ] = useState ({
codigoBarras: "" ,
nombre: "" ,
categoria: "" ,
precioVenta: "" ,
unidadMedida: "NIU" ,
frecuenciaCambioKm: "" ,
afectacionIgv: "10"
});
Enter Barcode
Input the product’s barcode or generate an internal code.
Product Details
Fill in product name, select category from dropdown, and set unit of measure.
Pricing and Tax
Set the sale price and confirm tax affectation (default: “10” for taxable).
Maintenance Frequency
For maintenance products, set the kilometer interval (optional).
The product list includes pagination for large catalogs:
const totalPages = Math . ceil ( filteredProducts . length / itemsPerPage );
const currentProducts = useMemo (() => {
const startIndex = ( currentPage - 1 ) * itemsPerPage ;
return filteredProducts . slice ( startIndex , startIndex + itemsPerPage );
}, [ filteredProducts , currentPage , itemsPerPage ]);
Integration with Sales Module
Products are directly searchable and selectable in the sales module:
const filteredProducts = db . products . filter (
( p ) =>
p . nombre . toLowerCase (). includes ( productSearch . toLowerCase ()) ||
p . codigoBarras ?. includes ( productSearch )
);
When a product is added to a sales cart, its precioVenta becomes the precioUnitario and can be adjusted per sale if needed.
Best Practices
Product Management Guidelines
Use descriptive names that include brand and specifications
Always set maintenance frequency for service products
Keep prices updated to reflect current costs
Organize products into logical categories
Use standard SUNAT unit codes for compliance
Include complete barcode information for inventory tracking