> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Braian551/viax/llms.txt
> Use this file to discover all available pages before exploring further.

# Pricing Configuration

> Configure base fares, distance/time rates, surge pricing, and commissions

## Overview

Viax implements a sophisticated dual-screen pricing system that allows administrators to configure tariffs by vehicle type, time periods, and apply dynamic pricing based on demand.

<Info>
  Pricing is configured per vehicle type with support for peak hours, nighttime, and holiday surcharges.
</Info>

## Pricing Database Schema

The pricing system uses dedicated database tables:

### Configuration Table

```sql migrations/007_create_configuracion_precios.sql theme={null}
CREATE TABLE configuracion_precios (
  id INT AUTO_INCREMENT PRIMARY KEY,
  tipo_vehiculo ENUM('moto', 'carro', 'moto_carga', 'carro_carga') NOT NULL UNIQUE,
  tarifa_base DECIMAL(10, 2) NOT NULL DEFAULT 0,
  costo_por_km DECIMAL(10, 2) NOT NULL DEFAULT 0,
  costo_por_minuto DECIMAL(10, 2) NOT NULL DEFAULT 0,
  tarifa_minima DECIMAL(10, 2) NOT NULL DEFAULT 0,
  recargo_hora_pico DECIMAL(5, 2) DEFAULT 0,
  recargo_nocturno DECIMAL(5, 2) DEFAULT 0,
  recargo_festivo DECIMAL(5, 2) DEFAULT 0,
  descuento_distancia_mayor_15km DECIMAL(5, 2) DEFAULT 0,
  comision_plataforma DECIMAL(5, 2) DEFAULT 15.00,
  hora_pico_inicio_manana TIME DEFAULT '07:00:00',
  hora_pico_fin_manana TIME DEFAULT '09:00:00',
  hora_pico_inicio_tarde TIME DEFAULT '17:00:00',
  hora_pico_fin_tarde TIME DEFAULT '19:00:00',
  hora_nocturna_inicio TIME DEFAULT '22:00:00',
  hora_nocturna_fin TIME DEFAULT '06:00:00',
  activo BOOLEAN DEFAULT TRUE,
  notas TEXT,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  actualizado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
```

### Price History Table

```sql theme={null}
CREATE TABLE historial_precios (
  id INT AUTO_INCREMENT PRIMARY KEY,
  configuracion_id INT NOT NULL,
  campo_modificado VARCHAR(100) NOT NULL,
  valor_anterior TEXT,
  valor_nuevo TEXT,
  modificado_por INT,
  fecha_modificacion TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (configuracion_id) REFERENCES configuracion_precios(id),
  FOREIGN KEY (modificado_por) REFERENCES usuarios(id)
);
```

## Default Pricing Configuration

<Tabs>
  <Tab title="Motorcycle">
    **Vehicle Type:** `moto`

    | Component           | Value   |
    | ------------------- | ------- |
    | Base Fare           | \$4,000 |
    | Per Kilometer       | \$2,000 |
    | Per Minute          | \$250   |
    | Minimum Fare        | \$6,000 |
    | Peak Hour Surcharge | 15%     |
    | Night Surcharge     | 20%     |
    | Holiday Surcharge   | 25%     |
    | Platform Commission | 15%     |
  </Tab>

  <Tab title="Car">
    **Vehicle Type:** `carro`

    | Component           | Value   |
    | ------------------- | ------- |
    | Base Fare           | \$6,000 |
    | Per Kilometer       | \$3,000 |
    | Per Minute          | \$400   |
    | Minimum Fare        | \$9,000 |
    | Peak Hour Surcharge | 15%     |
    | Night Surcharge     | 20%     |
    | Holiday Surcharge   | 25%     |
    | Platform Commission | 15%     |
  </Tab>

  <Tab title="Cargo Motorcycle">
    **Vehicle Type:** `moto_carga`

    | Component           | Value   |
    | ------------------- | ------- |
    | Base Fare           | \$5,000 |
    | Per Kilometer       | \$2,500 |
    | Per Minute          | \$300   |
    | Minimum Fare        | \$7,500 |
    | Peak Hour Surcharge | 15%     |
    | Night Surcharge     | 20%     |
    | Holiday Surcharge   | 25%     |
    | Platform Commission | 15%     |
  </Tab>

  <Tab title="Cargo Van">
    **Vehicle Type:** `carro_carga`

    | Component           | Value    |
    | ------------------- | -------- |
    | Base Fare           | \$8,000  |
    | Per Kilometer       | \$3,500  |
    | Per Minute          | \$450    |
    | Minimum Fare        | \$12,000 |
    | Peak Hour Surcharge | 15%      |
    | Night Surcharge     | 20%      |
    | Holiday Surcharge   | 25%      |
    | Platform Commission | 15%      |
  </Tab>
</Tabs>

## Price Calculation Formula

The system uses a comprehensive formula to calculate trip costs:

```
Subtotal = Base Fare + (Distance × Cost/km) + (Duration × Cost/min)

Discount = If distance ≥ 15km → Subtotal × 10%

Surcharge = Subtotal × (Percentage based on time period)
  - Peak hours (7-9am, 5-7pm): +15-20%
  - Night (10pm-6am): +20-25%
  - Holidays: +25-30%

Total = Subtotal - Discount + Surcharge
Total = MAX(Total, Minimum Fare)

Platform Commission = Total × (Commission %)
Driver Earnings = Total - Platform Commission
```

### Implementation Example

```dart theme={null}
double calculateTripPrice({
  required double distanceKm,
  required int durationMinutes,
  required String vehicleType,
  required DateTime tripTime,
}) {
  final config = getPricingConfig(vehicleType);
  
  // Base calculation
  double subtotal = config.tarifaBase +
      (distanceKm * config.costoPorKm) +
      (durationMinutes * config.costoPorMinuto);
  
  // Distance discount
  double discount = 0;
  if (distanceKm >= 15) {
    discount = subtotal * (config.descuentoDistancia / 100);
  }
  
  // Time-based surcharge
  double surcharge = 0;
  final period = getCurrentPeriod(tripTime, config);
  
  if (period == 'hora_pico') {
    surcharge = subtotal * (config.recargoHoraPico / 100);
  } else if (period == 'nocturno') {
    surcharge = subtotal * (config.recargoNocturno / 100);
  } else if (isHoliday(tripTime)) {
    surcharge = subtotal * (config.recargoFestivo / 100);
  }
  
  // Final total
  double total = subtotal - discount + surcharge;
  total = max(total, config.tarifaMinima);
  
  return total;
}
```

## Time Periods

### Peak Hours (Hora Pico)

<CardGroup cols={2}>
  <Card title="Morning Peak" icon="sunrise">
    **Default:** 7:00 AM - 9:00 AM

    **Surcharge:** 15%
  </Card>

  <Card title="Evening Peak" icon="sunset">
    **Default:** 5:00 PM - 7:00 PM

    **Surcharge:** 15%
  </Card>
</CardGroup>

### Night Hours (Nocturno)

**Time Range:** 10:00 PM - 6:00 AM

**Surcharge:** 20%

### Normal Hours

**Time Range:** All other hours

**Surcharge:** 0%

## Active Prices View

A database view provides quick access to current pricing with period detection:

```sql theme={null}
CREATE VIEW vista_precios_activos AS
SELECT 
  cp.*,
  CASE
    WHEN CURRENT_TIME BETWEEN cp.hora_pico_inicio_manana AND cp.hora_pico_fin_manana THEN 'hora_pico'
    WHEN CURRENT_TIME BETWEEN cp.hora_pico_inicio_tarde AND cp.hora_pico_fin_tarde THEN 'hora_pico'
    WHEN CURRENT_TIME >= cp.hora_nocturna_inicio OR CURRENT_TIME <= cp.hora_nocturna_fin THEN 'nocturno'
    ELSE 'normal'
  END AS periodo_actual,
  CASE
    WHEN CURRENT_TIME BETWEEN cp.hora_pico_inicio_manana AND cp.hora_pico_fin_manana THEN cp.recargo_hora_pico
    WHEN CURRENT_TIME BETWEEN cp.hora_pico_inicio_tarde AND cp.hora_pico_fin_tarde THEN cp.recargo_hora_pico
    WHEN CURRENT_TIME >= cp.hora_nocturna_inicio OR CURRENT_TIME <= cp.hora_nocturna_fin THEN cp.recargo_nocturno
    ELSE 0
  END AS recargo_actual
FROM configuracion_precios cp
WHERE cp.activo = TRUE;
```

## Backend API Endpoints

### Get Pricing Configuration

```php backend/pricing/get_config.php theme={null}
// GET /pricing/get_config.php?tipo_vehiculo=moto

{
  "success": true,
  "data": {
    "tipo_vehiculo": "moto",
    "tarifa_base": 4000.00,
    "costo_por_km": 2000.00,
    "costo_por_minuto": 250.00,
    "tarifa_minima": 6000.00,
    "recargo_hora_pico": 15.00,
    "recargo_nocturno": 20.00,
    "recargo_festivo": 25.00,
    "periodo_actual": "hora_pico",
    "recargo_actual": 15.00
  }
}
```

### Calculate Trip Quote

```php backend/pricing/calculate_quote.php theme={null}
// POST /pricing/calculate_quote.php

{
  "distancia_km": 8.5,
  "duracion_minutos": 25,
  "tipo_vehiculo": "moto"
}

// Response:
{
  "success": true,
  "data": {
    "distancia_km": 8.5,
    "duracion_minutos": 25,
    "tipo_vehiculo": "moto",
    "tarifa_base": 4000,
    "precio_distancia": 17000,
    "precio_tiempo": 6250,
    "subtotal": 27250,
    "descuento_distancia": 0,
    "recargo_porcentaje": 15,
    "recargo_precio": 4087.5,
    "total": 31337.5,
    "total_formateado": "$31.338",
    "periodo_actual": "hora_pico",
    "comision_plataforma": 4700.63,
    "ganancia_conductor": 26636.87
  }
}
```

## Updating Pricing Configuration

<Steps>
  <Step title="Access Database">
    Connect to the MySQL database as admin
  </Step>

  <Step title="Update Configuration">
    ```sql theme={null}
    UPDATE configuracion_precios 
    SET costo_por_km = 2200.00,
        notas = 'Ajuste por inflación - Octubre 2025'
    WHERE tipo_vehiculo = 'moto';
    ```
  </Step>

  <Step title="Verify Changes">
    ```sql theme={null}
    SELECT * FROM vista_precios_activos 
    WHERE tipo_vehiculo = 'moto';
    ```
  </Step>

  <Step title="Check History">
    Changes are automatically logged in `historial_precios`
  </Step>
</Steps>

<Warning>
  Pricing changes take effect immediately for new trip requests. Active trips use the pricing from when they were created.
</Warning>

## Commission Distribution

Platform commission is calculated per trip:

```dart theme={null}
class TripEarnings {
  final double tripTotal;
  final double platformCommissionPercentage;
  
  double get platformEarnings {
    return tripTotal * (platformCommissionPercentage / 100);
  }
  
  double get driverEarnings {
    return tripTotal - platformEarnings;
  }
  
  double get companyCommission {
    // If driver belongs to a company, company may take additional %
    final companyRate = driver.company?.commissionRate ?? 0;
    return driverEarnings * (companyRate / 100);
  }
  
  double get driverFinalEarnings {
    return driverEarnings - companyCommission;
  }
}
```

### Example Breakdown

**Trip Total:** \$50,000 COP

**Platform Commission (15%):** \$7,500 COP

**Driver Base Earnings:** \$42,500 COP

**Company Commission (10%):** \$4,250 COP

**Driver Final Earnings:** \$38,250 COP

## Distance Discount

Long-distance trips receive automatic discounts:

```dart theme={null}
if (distanceKm >= 15.0) {
  final discountPercentage = 10.0;
  discount = subtotal * (discountPercentage / 100);
}
```

<Info>
  Trips over 15km automatically receive a 10% discount to encourage long-distance rides.
</Info>

## Holiday Pricing

Implement holiday detection for special rates:

```dart theme={null}
bool isHoliday(DateTime date) {
  final holidays = [
    DateTime(date.year, 1, 1),   // New Year
    DateTime(date.year, 5, 1),   // Labor Day
    DateTime(date.year, 7, 20),  // Independence Day
    DateTime(date.year, 8, 7),   // Battle of Boyacá
    DateTime(date.year, 12, 25), // Christmas
    // Add more holidays
  ];
  
  return holidays.any((holiday) => 
    date.year == holiday.year &&
    date.month == holiday.month &&
    date.day == holiday.day
  );
}
```

<Note>
  Holiday surcharges can be configured per vehicle type and override other time-based surcharges.
</Note>

## Testing Pricing Configuration

### Verify Period Detection

```sql theme={null}
SELECT tipo_vehiculo, periodo_actual, recargo_actual 
FROM vista_precios_activos;
```

### Simulate Price Calculation

```sql theme={null}
-- Test pricing for 10km, 20min motorcycle trip
SELECT 
  tarifa_base + (10 * costo_por_km) + (20 * costo_por_minuto) AS subtotal,
  periodo_actual,
  recargo_actual
FROM vista_precios_activos
WHERE tipo_vehiculo = 'moto';
```

### Change Time Periods for Testing

```sql theme={null}
UPDATE configuracion_precios 
SET hora_pico_inicio_manana = '14:00:00',
    hora_pico_fin_manana = '16:00:00'
WHERE tipo_vehiculo = 'moto';
```

## Price Display to Users

Users see estimated pricing before requesting trips:

<Steps>
  <Step title="Enter Route">
    User selects origin and destination
  </Step>

  <Step title="Select Vehicle Type">
    User chooses moto, carro, etc.
  </Step>

  <Step title="View Quote">
    System calculates and displays:

    * Base fare
    * Distance cost
    * Time cost
    * Active surcharges
    * **Total estimated price**
  </Step>

  <Step title="Confirm Request">
    User accepts price and requests trip
  </Step>
</Steps>

## Future Enhancements

<CardGroup cols={2}>
  <Card title="Dynamic Pricing" icon="chart-line">
    Adjust prices based on real-time demand
  </Card>

  <Card title="Zone-Based Pricing" icon="map">
    Different rates for different geographic areas
  </Card>

  <Card title="Promotional Codes" icon="ticket">
    Discount codes and promotional campaigns
  </Card>

  <Card title="Membership Tiers" icon="crown">
    Discounted rates for premium members
  </Card>
</CardGroup>

## Best Practices

<Accordion title="Test Changes Thoroughly">
  Always test pricing changes with the calculate\_quote endpoint before deploying to production.
</Accordion>

<Accordion title="Document Adjustments">
  Use the 'notas' field to document why prices were changed and when.
</Accordion>

<Accordion title="Monitor Competition">
  Regularly compare your rates with competitors to stay competitive.
</Accordion>

<Accordion title="Consider Driver Earnings">
  Ensure drivers earn fair wages after platform and company commissions.
</Accordion>

<Accordion title="Communicate Changes">
  Notify drivers and users before implementing significant price changes.
</Accordion>

## Related Features

<CardGroup cols={3}>
  <Card title="Vehicle Types" icon="car" href="/admin/vehicle-types">
    Manage vehicle categories
  </Card>

  <Card title="Company Management" icon="building" href="/admin/company-management">
    Configure company commissions
  </Card>

  <Card title="Service Areas" icon="map-location-dot" href="/admin/service-areas">
    Define service boundaries
  </Card>
</CardGroup>
