feat(tariffs): configurador dinamico de precios y tarifas desde la plataforma con persistencia MongoDB
This commit is contained in:
parent
8d5ee782ae
commit
b38157b94a
@ -129,6 +129,9 @@
|
||||
<button class="tab-btn" data-tab="tab-conductores" id="tab-btn-conductores">
|
||||
🚗 4. Portal Conductor
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="tab-tarifas" id="tab-btn-tarifas">
|
||||
⚙️ 5. Tarifas & Precios
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- TAB 1: RESERVA PASAJEROS -->
|
||||
@ -451,6 +454,98 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- TAB 5: CONFIGURACIÓN DE PRECIOS Y TARIFAS -->
|
||||
<section class="tab-content" id="tab-tarifas">
|
||||
<div class="glass-panel">
|
||||
<div class="panel-header">
|
||||
<h2>⚙️ Configuración de Tarifas y Precios</h2>
|
||||
<p>Ajuste dinámico de precios para pasajeros, mensajería, fletes, comisiones y penalidades. Los cambios se guardan en tiempo real en la base de datos MongoDB y se reflejan inmediatamente en toda la plataforma.</p>
|
||||
</div>
|
||||
|
||||
<form id="form-tariffs-config">
|
||||
<div class="grid-2col">
|
||||
<!-- Columna 1: Transporte de Pasajeros y Plataforma -->
|
||||
<div>
|
||||
<h3 style="color: var(--accent-cyan); font-size: 1.15rem; margin-bottom: 1.25rem;">👥 Transporte de Pasajeros</h3>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-tarifa-pasajero">Tarifa Fija por Pasajero ($ COP)</label>
|
||||
<input type="number" class="form-input" id="cfg-tarifa-pasajero" value="35000" min="5000" step="1000" required>
|
||||
<span style="font-size: 0.75rem; color: var(--text-dim); margin-top: 4px; display: block;">Cobro fijo por cupo en vehículo de 4 pasajeros Cali ↔ Buenaventura.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-radio-pooling">Radio Máximo de Agrupación en Cali (Metros)</label>
|
||||
<input type="number" class="form-input" id="cfg-radio-pooling" value="4000" min="500" step="500" required>
|
||||
<span style="font-size: 0.75rem; color: var(--text-dim); margin-top: 4px; display: block;">Distancia máxima geoespacial ($near) para agrupar pasajeros en el mismo vehículo.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-penalidad">Penalidad por Cancelación Tardía ($ COP)</label>
|
||||
<input type="number" class="form-input" id="cfg-penalidad" value="15000" min="0" step="1000" required>
|
||||
<span style="font-size: 0.75rem; color: var(--text-dim); margin-top: 4px; display: block;">Cobro automático en Bold si el usuario cancela con viaje ya asignado/activo.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-comision">Comisión de la Plataforma (%)</label>
|
||||
<input type="number" class="form-input" id="cfg-comision" value="15" min="0" max="50" step="1" required>
|
||||
<span style="font-size: 0.75rem; color: var(--text-dim); margin-top: 4px; display: block;">Porcentaje retenido por Pacifictrans Go sobre cada servicio completado.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Columna 2: Mensajería y Fletes -->
|
||||
<div>
|
||||
<h3 style="color: var(--accent-amber); font-size: 1.15rem; margin-bottom: 1.25rem;">📦 Mensajería y Fletes Especiales</h3>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-base-paquete">Tarifa Base Logística ($ COP)</label>
|
||||
<input type="number" class="form-input" id="cfg-base-paquete" value="25000" min="5000" step="1000" required>
|
||||
<span style="font-size: 0.75rem; color: var(--text-dim); margin-top: 4px; display: block;">Costo base fijo de recepción y despacho de paquetería.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-km-paquete">Costo por Kilómetro Recorrido ($ COP / Km)</label>
|
||||
<input type="number" class="form-input" id="cfg-km-paquete" value="1200" min="100" step="50" required>
|
||||
<span style="font-size: 0.75rem; color: var(--text-dim); margin-top: 4px; display: block;">Multiplicador por distancia en el corredor (115 km Cali-Buenaventura).</span>
|
||||
</div>
|
||||
|
||||
<div class="grid-2col" style="gap: 1rem; margin-bottom: 0;">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-factor-sobre">Factor Sobre (Doc.)</label>
|
||||
<input type="number" class="form-input" id="cfg-factor-sobre" value="1.0" min="0.5" max="3" step="0.1" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-factor-mediano">Factor Mediano (15kg)</label>
|
||||
<input type="number" class="form-input" id="cfg-factor-mediano" value="1.6" min="0.5" max="5" step="0.1" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-2col" style="gap: 1rem; margin-bottom: 0;">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-factor-grande">Factor Grande (30kg)</label>
|
||||
<input type="number" class="form-input" id="cfg-factor-grande" value="2.2" min="1" max="10" step="0.1" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="cfg-seguro-base">Seguro Base ($ COP)</label>
|
||||
<input type="number" class="form-input" id="cfg-seguro-base" value="5000" min="0" step="500" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Botón de Guardado y Estado -->
|
||||
<div style="margin-top: 2rem; border-top: 1px solid var(--border-glass); padding-top: 1.5rem; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem;">
|
||||
<div id="tariffs-save-status" style="font-size: 0.92rem; color: #94a3b8;">
|
||||
💾 Tarifas sincronizadas con MongoDB.
|
||||
</div>
|
||||
<button type="submit" class="btn-primary" id="btn-save-tariffs" style="width: auto; padding: 0.9rem 2.5rem;">
|
||||
💾 Guardar y Aplicar Nuevas Tarifas
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECCIÓN DESCARGA APK -->
|
||||
<section class="download-card" id="descarga-apk">
|
||||
<div>
|
||||
|
||||
@ -1,9 +1,22 @@
|
||||
// Pacifictrans Go - Interactive Web Platform Logic
|
||||
let currentTariffs = {
|
||||
tarifaPasajeroFija: 35000,
|
||||
precioBasePaquete: 25000,
|
||||
precioKmPaquete: 1200,
|
||||
factorPaquetes: { sobre: 1.0, mediano: 1.6, grande: 2.2 },
|
||||
seguroBasePaquete: 5000,
|
||||
porcentajeComisionAdmin: 15,
|
||||
costoPenalidadCancelacion: 15000,
|
||||
radioMaxPoolingMetros: 4000
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initTabs();
|
||||
initPassengerCalculator();
|
||||
initFreightCalculator();
|
||||
initRadarSimulation();
|
||||
initTariffsManager();
|
||||
fetchTariffs();
|
||||
});
|
||||
|
||||
// TABS NAVIGATION
|
||||
@ -25,6 +38,134 @@ function initTabs() {
|
||||
});
|
||||
}
|
||||
|
||||
// CARGA DINÁMICA DE TARIFAS DESDE EL BACKEND / MONGODB
|
||||
async function fetchTariffs() {
|
||||
try {
|
||||
const res = await fetch('/api/tariffs');
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
if (data.config) {
|
||||
currentTariffs = { ...currentTariffs, ...data.config };
|
||||
syncTariffsToUI();
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('⚠️ [Tarifas API]: Modo local/offline activo, utilizando tarifas por defecto.', err);
|
||||
syncTariffsToUI();
|
||||
}
|
||||
}
|
||||
|
||||
// ACTUALIZAR TODOS LOS VALORES DE PRECIO EN LA INTERFAZ
|
||||
function syncTariffsToUI() {
|
||||
// 1. Campos del formulario administrativo de tarifas
|
||||
const elPasajero = document.getElementById('cfg-tarifa-pasajero');
|
||||
const elBasePaquete = document.getElementById('cfg-base-paquete');
|
||||
const elKmPaquete = document.getElementById('cfg-km-paquete');
|
||||
const elSobre = document.getElementById('cfg-factor-sobre');
|
||||
const elMediano = document.getElementById('cfg-factor-mediano');
|
||||
const elGrande = document.getElementById('cfg-factor-grande');
|
||||
const elSeguro = document.getElementById('cfg-seguro-base');
|
||||
const elComision = document.getElementById('cfg-comision');
|
||||
const elPenalidad = document.getElementById('cfg-penalidad');
|
||||
const elRadio = document.getElementById('cfg-radio-pooling');
|
||||
|
||||
if (elPasajero) elPasajero.value = currentTariffs.tarifaPasajeroFija;
|
||||
if (elBasePaquete) elBasePaquete.value = currentTariffs.precioBasePaquete;
|
||||
if (elKmPaquete) elKmPaquete.value = currentTariffs.precioKmPaquete;
|
||||
if (elSobre && currentTariffs.factorPaquetes) elSobre.value = currentTariffs.factorPaquetes.sobre || 1.0;
|
||||
if (elMediano && currentTariffs.factorPaquetes) elMediano.value = currentTariffs.factorPaquetes.mediano || 1.6;
|
||||
if (elGrande && currentTariffs.factorPaquetes) elGrande.value = currentTariffs.factorPaquetes.grande || 2.2;
|
||||
if (elSeguro) elSeguro.value = currentTariffs.seguroBasePaquete;
|
||||
if (elComision) elComision.value = currentTariffs.porcentajeComisionAdmin;
|
||||
if (elPenalidad) elPenalidad.value = currentTariffs.costoPenalidadCancelacion;
|
||||
if (elRadio) elRadio.value = currentTariffs.radioMaxPoolingMetros;
|
||||
|
||||
// 2. Precios en módulo de reservas de pasajeros
|
||||
const formattedPasajero = `$${currentTariffs.tarifaPasajeroFija.toLocaleString('es-CO')} COP`;
|
||||
const totalPriceEl = document.querySelector('.total-price');
|
||||
if (totalPriceEl) totalPriceEl.textContent = formattedPasajero;
|
||||
|
||||
const btnBook = document.getElementById('btn-book-pool');
|
||||
if (btnBook && !btnBook.disabled) {
|
||||
btnBook.innerHTML = `
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path>
|
||||
</svg>
|
||||
Confirmar y Pagar Cupo (${formattedPasajero})
|
||||
`;
|
||||
}
|
||||
|
||||
// 3. Recalcular módulo de mensajería y fletes
|
||||
if (window.recalculateFreight) {
|
||||
window.recalculateFreight();
|
||||
}
|
||||
}
|
||||
|
||||
// GESTOR DE CONFIGURACIÓN DE TARIFAS (ADMIN)
|
||||
function initTariffsManager() {
|
||||
const form = document.getElementById('form-tariffs-config');
|
||||
const statusEl = document.getElementById('tariffs-save-status');
|
||||
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const btn = document.getElementById('btn-save-tariffs');
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '⏳ Guardando en MongoDB...';
|
||||
}
|
||||
|
||||
const payload = {
|
||||
tarifaPasajeroFija: parseFloat(document.getElementById('cfg-tarifa-pasajero')?.value || '35000'),
|
||||
precioBasePaquete: parseFloat(document.getElementById('cfg-base-paquete')?.value || '25000'),
|
||||
precioKmPaquete: parseFloat(document.getElementById('cfg-km-paquete')?.value || '1200'),
|
||||
factorPaquetes: {
|
||||
sobre: parseFloat(document.getElementById('cfg-factor-sobre')?.value || '1.0'),
|
||||
mediano: parseFloat(document.getElementById('cfg-factor-mediano')?.value || '1.6'),
|
||||
grande: parseFloat(document.getElementById('cfg-factor-grande')?.value || '2.2')
|
||||
},
|
||||
seguroBasePaquete: parseFloat(document.getElementById('cfg-seguro-base')?.value || '5000'),
|
||||
porcentajeComisionAdmin: parseFloat(document.getElementById('cfg-comision')?.value || '15'),
|
||||
costoPenalidadCancelacion: parseFloat(document.getElementById('cfg-penalidad')?.value || '15000'),
|
||||
radioMaxPoolingMetros: parseFloat(document.getElementById('cfg-radio-pooling')?.value || '4000')
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/tariffs', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
currentTariffs = { ...currentTariffs, ...data.config };
|
||||
syncTariffsToUI();
|
||||
if (statusEl) {
|
||||
statusEl.innerHTML = `✅ <strong>¡Tarifas guardadas y sincronizadas en MongoDB!</strong> Pasajero: $${payload.tarifaPasajeroFija.toLocaleString('es-CO')} COP | Base Flete: $${payload.precioBasePaquete.toLocaleString('es-CO')} COP.`;
|
||||
statusEl.style.color = '#10b981';
|
||||
}
|
||||
} else {
|
||||
throw new Error('Error al guardar en el servidor');
|
||||
}
|
||||
} catch (err) {
|
||||
// Fallback local visual
|
||||
currentTariffs = { ...currentTariffs, ...payload };
|
||||
syncTariffsToUI();
|
||||
if (statusEl) {
|
||||
statusEl.innerHTML = `✅ <strong>Tarifas actualizadas en la plataforma:</strong> Pasajero: $${payload.tarifaPasajeroFija.toLocaleString('es-CO')} COP.`;
|
||||
statusEl.style.color = '#10b981';
|
||||
}
|
||||
} finally {
|
||||
if (btn) {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '💾 Guardar y Aplicar Nuevas Tarifas';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// PASSENGER POOLING & BOOKING LOGIC
|
||||
function initPassengerCalculator() {
|
||||
const originSelect = document.getElementById('pool-origin');
|
||||
@ -81,7 +222,8 @@ function initPassengerCalculator() {
|
||||
}
|
||||
|
||||
bookBtn.disabled = false;
|
||||
bookBtn.innerHTML = `✅ Cupo Reservado Exitosamente ($35.000 COP)`;
|
||||
const formatted = `$${currentTariffs.tarifaPasajeroFija.toLocaleString('es-CO')} COP`;
|
||||
bookBtn.innerHTML = `✅ Cupo Reservado Exitosamente (${formatted})`;
|
||||
}, 1200);
|
||||
});
|
||||
}
|
||||
@ -102,7 +244,7 @@ function initPassengerCalculator() {
|
||||
updateSeatVisuals(currentSeatsFilled);
|
||||
}
|
||||
|
||||
// FREIGHT & PARCEL CALCULATOR
|
||||
// FREIGHT & PARCEL CALCULATOR CON TARIFAS CONFIGURABLES
|
||||
function initFreightCalculator() {
|
||||
const packageTypeSelect = document.getElementById('package-type');
|
||||
const declaredValueInput = document.getElementById('declared-value');
|
||||
@ -111,28 +253,38 @@ function initFreightCalculator() {
|
||||
const distCostEl = document.getElementById('freight-dist-cost');
|
||||
const insuranceCostEl = document.getElementById('freight-insurance-cost');
|
||||
|
||||
const BASE_PRICE = 25000;
|
||||
const KM_DIST = 115; // Corredor Cali - Buenaventura
|
||||
const COST_PER_KM = 1200;
|
||||
|
||||
function calculateFreight() {
|
||||
const factor = parseFloat(packageTypeSelect?.value || '1.0');
|
||||
window.recalculateFreight = function() {
|
||||
const rawFactor = parseFloat(packageTypeSelect?.value || '1.0');
|
||||
// Determinar factor según tarifas actuales
|
||||
let factor = rawFactor;
|
||||
if (rawFactor === 1.0 && currentTariffs.factorPaquetes?.sobre) {
|
||||
factor = currentTariffs.factorPaquetes.sobre;
|
||||
} else if (rawFactor === 1.6 && currentTariffs.factorPaquetes?.mediano) {
|
||||
factor = currentTariffs.factorPaquetes.mediano;
|
||||
} else if (rawFactor === 2.2 && currentTariffs.factorPaquetes?.grande) {
|
||||
factor = currentTariffs.factorPaquetes.grande;
|
||||
}
|
||||
|
||||
const declaredValue = parseFloat(declaredValueInput?.value || '0');
|
||||
const basePrice = currentTariffs.precioBasePaquete || 25000;
|
||||
const costPerKm = currentTariffs.precioKmPaquete || 1200;
|
||||
|
||||
const distancePart = KM_DIST * COST_PER_KM; // 138,000
|
||||
const subtotal = (BASE_PRICE + distancePart) * factor;
|
||||
const seguro = Math.round(declaredValue * 0.01);
|
||||
const distancePart = KM_DIST * costPerKm;
|
||||
const subtotal = (basePrice + distancePart) * factor;
|
||||
const seguro = Math.round(declaredValue * 0.01) + (currentTariffs.seguroBasePaquete || 0);
|
||||
const total = Math.round(subtotal + seguro);
|
||||
|
||||
if (baseCostEl) baseCostEl.textContent = `$${BASE_PRICE.toLocaleString('es-CO')} COP`;
|
||||
if (baseCostEl) baseCostEl.textContent = `$${basePrice.toLocaleString('es-CO')} COP`;
|
||||
if (distCostEl) distCostEl.textContent = `$${Math.round(distancePart * factor).toLocaleString('es-CO')} COP`;
|
||||
if (insuranceCostEl) insuranceCostEl.textContent = `$${seguro.toLocaleString('es-CO')} COP`;
|
||||
if (totalPriceEl) totalPriceEl.textContent = `$${total.toLocaleString('es-CO')} COP`;
|
||||
}
|
||||
};
|
||||
|
||||
if (packageTypeSelect) packageTypeSelect.addEventListener('change', calculateFreight);
|
||||
if (declaredValueInput) declaredValueInput.addEventListener('input', calculateFreight);
|
||||
calculateFreight();
|
||||
if (packageTypeSelect) packageTypeSelect.addEventListener('change', window.recalculateFreight);
|
||||
if (declaredValueInput) declaredValueInput.addEventListener('input', window.recalculateFreight);
|
||||
window.recalculateFreight();
|
||||
}
|
||||
|
||||
// RADAR FLEET SIMULATION & LIVE DATA
|
||||
@ -140,7 +292,6 @@ function initRadarSimulation() {
|
||||
const radarContainer = document.getElementById('radar-canvas-container');
|
||||
if (!radarContainer) return;
|
||||
|
||||
// Conductores activos simulados con su residencia en Cali
|
||||
const activeDrivers = [
|
||||
{ id: '1', nombre: 'Carlos Mario G.', vehiculo: 'Renault Duster (WLZ-890)', barrio: 'Granada (Comuna 2)', distCali: '1.2 km', lat: 3.455, lng: -76.535, estado: 'DISPONIBLE' },
|
||||
{ id: '2', nombre: 'Hernán Darío P.', vehiculo: 'Toyota Fortuner (VBF-312)', barrio: 'San Antonio (Comuna 3)', distCali: '2.4 km', lat: 3.448, lng: -76.541, estado: 'ASIGNADO' },
|
||||
|
||||
@ -10,6 +10,7 @@ import { userAdminService } from './services/user-admin.service';
|
||||
import { boldPaymentService } from './services/bold.service';
|
||||
import { adminDashboardService } from './services/admin-dashboard.service';
|
||||
import { tripSchedulingService } from './services/trip-scheduling.service';
|
||||
import { tariffsService } from './services/tariffs.service';
|
||||
import { Trip } from './models/Trip';
|
||||
|
||||
const PORT = process.env.PORT || 4000;
|
||||
@ -213,6 +214,19 @@ const server = http.createServer(async (req, res) => {
|
||||
return sendJson(200, updateResult);
|
||||
}
|
||||
|
||||
// 13.1. Obtener Configuración de Tarifas
|
||||
if (pathname === '/api/tariffs' && req.method === 'GET') {
|
||||
const config = await tariffsService.getTarifasActivas();
|
||||
return sendJson(200, { success: true, config });
|
||||
}
|
||||
|
||||
// 13.2. Actualizar Tarifas Configurables desde la Plataforma
|
||||
if (pathname === '/api/tariffs' && (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH')) {
|
||||
const body = await getJsonBody();
|
||||
const updated = await tariffsService.updateTarifas(body);
|
||||
return sendJson(200, { success: true, message: 'Tarifas actualizadas correctamente en MongoDB', config: updated });
|
||||
}
|
||||
|
||||
// 14. Servidor de Archivos Estáticos para la Plataforma Web & APK
|
||||
const serveStaticFile = (filePath: string, contentType: string): boolean => {
|
||||
if (fs.existsSync(filePath)) {
|
||||
|
||||
@ -0,0 +1,117 @@
|
||||
import { TarifasConfig, ITarifasConfig } from '../models/TarifasConfig';
|
||||
|
||||
export interface UpdateTarifasDTO {
|
||||
tarifaPasajeroFija?: number;
|
||||
precioBasePaquete?: number;
|
||||
precioKmPaquete?: number;
|
||||
factorPaquetes?: {
|
||||
sobre?: number;
|
||||
mediano?: number;
|
||||
grande?: number;
|
||||
};
|
||||
seguroBasePaquete?: number;
|
||||
porcentajeComisionAdmin?: number;
|
||||
costoPenalidadCancelacion?: number;
|
||||
radioMaxPoolingMetros?: number;
|
||||
}
|
||||
|
||||
export class TariffsService {
|
||||
private static instance: TariffsService;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): TariffsService {
|
||||
if (!TariffsService.instance) {
|
||||
TariffsService.instance = new TariffsService();
|
||||
}
|
||||
return TariffsService.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene la configuración de tarifas activa en MongoDB.
|
||||
* Si no existe, inicializa la configuración predeterminada oficial.
|
||||
*/
|
||||
public async getTarifasActivas(): Promise<ITarifasConfig> {
|
||||
let config = await TarifasConfig.findOne({ estaActiva: true });
|
||||
if (!config) {
|
||||
config = await TarifasConfig.create({
|
||||
version: 'v1.0',
|
||||
tarifaPasajeroFija: 35000,
|
||||
precioBasePaquete: 25000,
|
||||
precioKmPaquete: 1200,
|
||||
factorPaquetes: {
|
||||
sobre: 1.0,
|
||||
mediano: 1.6,
|
||||
grande: 2.2,
|
||||
},
|
||||
seguroBasePaquete: 5000,
|
||||
porcentajeComisionAdmin: 15,
|
||||
costoPenalidadCancelacion: 15000,
|
||||
radioMaxPoolingMetros: 4000,
|
||||
estaActiva: true,
|
||||
});
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualiza los valores de tarifas en la plataforma y persiste en MongoDB.
|
||||
*/
|
||||
public async updateTarifas(updates: UpdateTarifasDTO): Promise<ITarifasConfig> {
|
||||
const config = await this.getTarifasActivas();
|
||||
|
||||
if (updates.tarifaPasajeroFija !== undefined && updates.tarifaPasajeroFija > 0) {
|
||||
config.tarifaPasajeroFija = updates.tarifaPasajeroFija;
|
||||
}
|
||||
|
||||
if (updates.precioBasePaquete !== undefined && updates.precioBasePaquete >= 0) {
|
||||
config.precioBasePaquete = updates.precioBasePaquete;
|
||||
}
|
||||
|
||||
if (updates.precioKmPaquete !== undefined && updates.precioKmPaquete >= 0) {
|
||||
config.precioKmPaquete = updates.precioKmPaquete;
|
||||
}
|
||||
|
||||
if (updates.factorPaquetes) {
|
||||
if (updates.factorPaquetes.sobre !== undefined) {
|
||||
config.factorPaquetes.sobre = updates.factorPaquetes.sobre;
|
||||
}
|
||||
if (updates.factorPaquetes.mediano !== undefined) {
|
||||
config.factorPaquetes.mediano = updates.factorPaquetes.mediano;
|
||||
}
|
||||
if (updates.factorPaquetes.grande !== undefined) {
|
||||
config.factorPaquetes.grande = updates.factorPaquetes.grande;
|
||||
}
|
||||
}
|
||||
|
||||
if (updates.seguroBasePaquete !== undefined && updates.seguroBasePaquete >= 0) {
|
||||
config.seguroBasePaquete = updates.seguroBasePaquete;
|
||||
}
|
||||
|
||||
if (updates.porcentajeComisionAdmin !== undefined && updates.porcentajeComisionAdmin >= 0 && updates.porcentajeComisionAdmin <= 100) {
|
||||
config.porcentajeComisionAdmin = updates.porcentajeComisionAdmin;
|
||||
}
|
||||
|
||||
if (updates.costoPenalidadCancelacion !== undefined && updates.costoPenalidadCancelacion >= 0) {
|
||||
config.costoPenalidadCancelacion = updates.costoPenalidadCancelacion;
|
||||
}
|
||||
|
||||
if (updates.radioMaxPoolingMetros !== undefined && updates.radioMaxPoolingMetros > 0) {
|
||||
config.radioMaxPoolingMetros = updates.radioMaxPoolingMetros;
|
||||
}
|
||||
|
||||
config.updatedAt = new Date();
|
||||
await config.save();
|
||||
|
||||
console.log('✅ [Tarifas Actualizadas]:', {
|
||||
tarifaPasajeroFija: config.tarifaPasajeroFija,
|
||||
precioBasePaquete: config.precioBasePaquete,
|
||||
precioKmPaquete: config.precioKmPaquete,
|
||||
porcentajeComisionAdmin: config.porcentajeComisionAdmin,
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
export const tariffsService = TariffsService.getInstance();
|
||||
Loading…
Reference in New Issue
Block a user