Taller Ortúzar

¿Agendar en el calendario?

{{ agendarOTForm.otId }} · {{ agendarOTForm.clienteNombre }} · {{ agendarOTForm.vehiculoPatente }}

Taller Ortuzar
{{ currentUser.username.charAt(0) }}
{{ currentUser.username }}
⚙ Configuración del sistema
Stock obligatorio en OT

Las OT deben tener materiales antes de completarse.


🔔 Alertas por email

Resumen diario de alertas vencidas y próximas.

Separá múltiples emails con coma.

Notificaciones
Sin notificaciones

{{ notif.mensaje }}

{{ formatRelativeTime(notif.created_at) }}

Opciones de Clientes

Clientes Registrados Recientemente

{{ cliente.id }} - {{ cliente.nombre }}

Vehículos: {{ cliente.vehiculos.map(v => v.patente).join(', ') }}

No hay clientes registrados.

Detalles de: {{ selectedClientFromSubmenu.nombre }}

ID: {{ selectedClientFromSubmenu.id }}

Nombre: {{ selectedClientFromSubmenu.nombre }}

Domicilio: {{ selectedClientFromSubmenu.domicilio || 'N/A' }}

Teléfono: {{ selectedClientFromSubmenu.telefono || 'N/A' }}

Email: {{ selectedClientFromSubmenu.email || 'N/A' }}

Vehículos Registrados:

  • {{ vehiculo.patente }} - {{ vehiculo.marca }} {{ vehiculo.modelo }} ({{ vehiculo.anio }}) - {{ vehiculo.kilometraje ? vehiculo.kilometraje.toLocaleString() + ' km' : 'N/A km' }} - Comb: {{ vehiculo.tipoCombustible || 'N/A' }}

Sin vehículos registrados.

Opciones de Proveedores

{{ viewTitle }}

{{ currentPeriodTitle }}

{{ day.slice(0,3) }}
{{ day.dayOfMonth }}
🔧 {{ event.tarea.slice(0,8) }}

{{ day.dayNameShort }}

{{ day.dayOfMonth }}

🔧 {{ event.tarea }}

{{ formatFullDate(selectedDate) }}

{{ hour }}:00

🔧 {{ event.tarea }}

{{ event.horaProgramada }} · {{ event.clienteNombre }} ({{ event.vehiculoPatente }})

{{ addEventForm.id ? 'Detalles del Evento' : 'Programar Nuevo Servicio' }}

{{ addEventForm.clienteNombre }} - {{ addEventForm.vehiculoDescripcion }} ({{ addEventForm.vehiculoPatente }})

{{ viewTitle }}

Órdenes de Trabajo Activas {{ ordenesDeTrabajoActivas.length }}

Orden ID: {{ orden.id }}

Vehículo: {{ orden.vehiculo?.patente || 'N/A' }} - {{ orden.vehiculo?.marca || 'N/A' }} {{ orden.vehiculo?.modelo || 'N/A' }}

Cliente: {{ orden.cliente?.nombre || 'N/A' }}

{{ orden.estado }}
Compañía: {{ orden.companiaSeguroOrden }}
Tipo Orden: Particular

Técnico Asignado: {{ getEmpleadoNombre(orden.tecnico_asignado_id) }}

Fecha Ingreso: {{ formatDate(orden.fechaEntrada) }}

Tareas Completadas: {{ orden.tareas.filter(t => t.completado).length }} / {{ orden.tareas.length }}

Progreso: {{ calcularProgresoOrden(orden) }}%

No hay órdenes de trabajo activas en este momento.

Mis Órdenes Asignadas {{ misOrdenesTecnico.length }}

Orden ID: {{ orden.id }}

Vehículo: {{ orden.vehiculo?.patente || 'N/A' }} - {{ orden.vehiculo?.marca || 'N/A' }} {{ orden.vehiculo?.modelo || 'N/A' }}

Cliente: {{ orden.cliente?.nombre || 'N/A' }}

{{ orden.estado }}

Fecha Ingreso: {{ formatDate(orden.fechaEntrada) }}

Tareas Completadas: {{ orden.tareas.filter(t => t.completado).length }} / {{ orden.tareas.length }}

Progreso: {{ calcularProgresoOrden(orden) }}%

No tienes órdenes asignadas activas.

Órdenes Completadas Hoy {{ ordenesCompletadasHoy.length }}

Orden ID: {{ orden.id }}

Vehículo: {{ orden.vehiculo?.patente || 'N/A' }} - {{ orden.vehiculo?.marca || 'N/A' }} {{ orden.vehiculo?.modelo || 'N/A' }}

Cliente: {{ orden.cliente?.nombre || 'N/A' }}

{{ orden.estado }}

Fecha Ingreso: {{ formatDate(orden.fechaEntrada) }}

Fecha Completado: {{ formatDate(orden.fechaCompletado) }}

No se completaron órdenes de trabajo hoy.

OT Cliente Vehículo Ingreso Completado Estado
{{ orden.id }} {{ orden.cliente?.nombre || '—' }} {{ orden.vehiculo?.patente || '—' }} {{ orden.vehiculo?.marca }} {{ orden.vehiculo?.modelo }} {{ formatDate(orden.fechaEntrada) }} {{ formatDate(orden.fechaCompletado) || '—' }} {{ orden.estado }}

{{ historialOTsBusqueda ? 'Sin resultados para "' + historialOTsBusqueda + '".' : 'No hay órdenes completadas registradas.' }}

Presupuestos Pendientes {{ presupuestosPendientes.length }}

{{ p.numero }}

{{ p.vehiculo_patente }} — {{ p.vehiculo_marca }} {{ p.vehiculo_modelo }}

Cliente: {{ p.cliente_nombre }}

{{ formatCurrency(p.total) }}

Vence: {{ formatDate(p.fecha_vencimiento) }}

Sin vencimiento

No hay presupuestos pendientes.


Modificando Orden ID: {{ newOrdenMantenimiento.id }}

1. Seleccionar Vehículo

No se encontraron resultados.
{{ r.vehiculo.patente }} — {{ r.vehiculo.marca }} {{ r.vehiculo.modelo }} ({{ r.vehiculo.anio }}) · {{ r.cliente.nombre }}

{{ newPresupuesto.vehiculoObj.patente }} — {{ newPresupuesto.vehiculoObj.marca }} {{ newPresupuesto.vehiculoObj.modelo }}

{{ newPresupuesto.clienteObj.nombre }}

2. Datos del Presupuesto

3. Ítems del Presupuesto

Descripción Tipo Cant. Precio unit. Subtotal
{{ item.descripcion }} {{ item.tipo === 'mano_de_obra' ? 'Mano de obra' : item.tipo === 'repuesto' ? 'Repuesto' : 'Otro' }} {{ item.cantidad }} {{ formatCurrency(item.precioUnitario) }} {{ formatCurrency(item.cantidad * item.precioUnitario) }}
TOTAL: {{ formatCurrency(presupuestoTotal) }}

1. Seleccionar Vehículo para la Orden

No se encontraron vehículos o clientes con esos criterios.

  • {{ item.vehiculo?.patente || 'N/A' }} - {{ item.vehiculo?.marca || 'N/A' }} {{ item.vehiculo?.modelo || 'N/A' }} ({{item.vehiculo?.anio || 'N/A'}})

    Cliente: {{ item.cliente?.nombre || 'N/A' }} (ID: {{ item.cliente?.id || 'N/A' }})

Vehículo Seleccionado para Orden:

Cliente: {{ newOrdenMantenimiento.cliente?.nombre || 'N/A' }} (ID: {{ newOrdenMantenimiento.cliente?.id || 'N/A' }})

Vehículo: {{ newOrdenMantenimiento.vehiculo?.patente || 'N/A' }} - {{ newOrdenMantenimiento.vehiculo?.marca || 'N/A' }} {{ newOrdenMantenimiento.vehiculo?.modelo || 'N/A' }} ({{newOrdenMantenimiento.vehiculo?.anio || 'N/A'}}) - {{ newOrdenMantenimiento.vehiculo?.kilometraje ? newOrdenMantenimiento.vehiculo.kilometraje.toLocaleString() + ' km' : 'N/A km' }} - Comb: {{ newOrdenMantenimiento.vehiculo?.tipoCombustible || 'N/A' }}

Fecha de Ingreso: {{ formatDate(newOrdenMantenimiento.fechaEntrada) }}

Kilometraje Actual:

2. Tareas de la Orden

No hay técnicos cargados en el sistema.

hs

Costo estimado: {{ formatCurrency(newOrdenMantenimiento.horasTrabajadas * (empleados.find(e => e.id === newOrdenMantenimiento.tecnico_asignado_id)?.valorHora || 0)) }} ({{ newOrdenMantenimiento.horasTrabajadas }} hs × ${{ Number(empleados.find(e => e.id === newOrdenMantenimiento.tecnico_asignado_id)?.valorHora || 0).toLocaleString('es-AR') }}/h)

Asigná un técnico con valor hora cargado para calcular el costo.

⏳ Guardando... ✓ Guardado automáticamente ✗ Error al guardar
Por favor, seleccione una compañía de seguros para continuar con la carga de tareas.

Tareas Agregadas:

Progreso de la Orden: {{ progresoOrdenActual.toFixed(0) }}% ({{ newOrdenMantenimiento.tareas.filter(t => t.completado).length }} de {{ newOrdenMantenimiento.tareas.length }} tareas)
{{ tarea.nombre }}

No hay tareas agregadas a esta orden.

Materiales y Repuestos

Obligatorio Opcional
Producto Cant. P. Unit. Subtotal
{{ mat.nombre_item }} {{ mat.cantidad }} ${{ Number(mat.precio_unitario).toFixed(2) }} ${{ (mat.cantidad * Number(mat.precio_unitario)).toFixed(2) }}
Total materiales: ${{ otMaterialesTotalCalc.toFixed(2) }}

Sin materiales registrados. ⚠ Requerido antes de completar.

Entregar Vehículo al Cliente

Km de entrada: {{ newOrdenMantenimiento.kilometrajeEntrada ? newOrdenMantenimiento.kilometrajeEntrada.toLocaleString() + ' km' : 'No registrado' }}

Mis Tareas Técnicas

Órdenes Disponibles para Tomar {{ ordenesDisponiblesParaTomar.length }}

{{ orden.id }}

{{ orden.cliente?.nombre || 'N/A' }} - {{ orden.vehiculo?.patente || 'N/A' }}

Estado: {{ orden.estado }} | Tareas: {{ orden.tareas.length }}

No hay órdenes disponibles para tomar en este momento.

Mis Órdenes Tomadas {{ misOrdenesTecnico.length }}

{{ orden.id }}

{{ orden.cliente?.nombre || 'N/A' }} - {{ orden.vehiculo?.patente || 'N/A' }}

Estado: {{ orden.estado }} | Tareas: {{ orden.tareas.length }}

Todavía no tienes órdenes tomadas.

Filtros

OT Tarea Cliente / Vehículo Estado Acción
{{ tarea.ordenId }}

{{ tarea.nombre }}

{{ tarea.comentario }}

{{ tarea.clienteNombre }}

{{ tarea.vehiculoPatente }}

{{ tarea.completado ? 'Completada' : 'Pendiente' }}

No hay tareas para los filtros seleccionados.

{{ currentEmpleadoView === 'list' ? 'Gestión de Empleados' : (currentEmpleadoView === 'form' ? (editingEmpleadoId ? 'Editar Empleado' : 'Agregar Nuevo Empleado') : (currentEmpleadoView === 'detalle_empleado' && newEmpleado ? `Ficha de Empleado: ${newEmpleado.nombreCompleto}` : (currentEmpleadoView === 'licencias_empleado' && newEmpleado ? `Gestionar Licencias para: ${newEmpleado.nombreCompleto}` : 'Gestión de Empleados') ) ) }}

Buscar Empleado

No se encontraron empleados con esos criterios.

Mostrando empleados dados de baja. Estos registros se conservan para consulta histórica.

{{ empleado.nombreCompleto }} (ID: {{ empleado.id }})

BAJA

Puesto: {{ empleado.puesto || 'No especificado' }}

CUIL: {{ empleado.cuil || 'N/A' }}

Fecha Ingreso: {{ empleado.fechaIngreso ? formatDate(empleado.fechaIngreso) : 'N/A' }}

Fecha Baja: {{ formatDate(empleado.fechaBaja) }}

Antigüedad: {{ empleado.antiguedad || 'N/A' }}

Días de Vacaciones: {{ calcularDiasVacaciones(empleado.fechaIngreso, empleado.fechaBaja) }} días

{{ verEmpleadosBaja ? 'No hay empleados dados de baja.' : 'No hay empleados activos registrados.' }}

Datos Personales

Datos Laborales

Obra Social y Datos Bancarios

ART (Aseguradora de Riesgos del Trabajo)

Empleado dado de baja

Este empleado fue dado de baja el {{ formatDate(newEmpleado.fechaBaja) }}. No es posible cargar nuevas licencias. El historial se muestra a continuación solo para consulta.

Cargar Nueva Licencia

Resumen de Vacaciones

Días Anuales Otorgados: {{ newEmpleado.diasVacacionesAnualesOtorgados }} días

Días Utilizados (Periodo Actual): {{ newEmpleado.diasVacacionesUtilizados }} días

Días Disponibles: {{ newEmpleado.diasVacacionesAnualesOtorgados - newEmpleado.diasVacacionesUtilizados }} días

Nota: Los días otorgados se basan en la antigüedad calculada. El descuento de vacaciones se aplica al guardar una licencia de tipo "Vacaciones".

Historial de Licencias

{{ tiposDeLicencia.find(t => t.valor === licencia.tipo)?.texto || licencia.tipo }} - ID: {{ licencia.id }}

Desde: {{ formatDate(licencia.fechaDesde) }} - Hasta: {{ formatDate(licencia.fechaHasta) }} ({{ licencia.diasCalculados }} día{{ licencia.diasCalculados !== 1 ? 's' : '' }})

Comentario: {{ licencia.comentario }}

Registrado: {{ formatDate(licencia.fechaRegistro) }}

No hay licencias registradas para este empleado.

Datos Personales

Nombre: {{ newEmpleado.nombreCompleto || 'N/A' }}

DNI: {{ newEmpleado.dni || 'N/A' }}

CUIL: {{ newEmpleado.cuil || 'N/A' }}

Nacimiento: {{ newEmpleado.fechaNacimiento ? formatDate(newEmpleado.fechaNacimiento) : 'N/A' }}

Domicilio: {{ newEmpleado.domicilio || 'N/A' }}

Localidad: {{ newEmpleado.localidad || 'N/A' }}

Código Postal: {{ newEmpleado.codigoPostal || 'N/A' }}

Teléfono: {{ newEmpleado.telefono || 'N/A' }}

Email: {{ newEmpleado.email || 'N/A' }}

Datos Laborales

Puesto: {{ newEmpleado.puesto || 'N/A' }}

Fecha de Ingreso: {{ newEmpleado.fechaIngreso ? formatDate(newEmpleado.fechaIngreso) : 'N/A' }}

Fecha de Baja: {{ newEmpleado.fechaBaja ? formatDate(newEmpleado.fechaBaja) : 'N/A' }}

Antigüedad: {{ newEmpleado.antiguedad || 'N/A' }}

Tipo de Contrato: {{ newEmpleado.tipoContrato || 'N/A' }}

Forma de Pago: {{ newEmpleado.formaPago || 'N/A' }}

Valor Hora: {{ newEmpleado.valorHora ? '$' + Number(newEmpleado.valorHora).toLocaleString('es-AR') : 'N/A' }}

Vacaciones Otorgadas: {{ newEmpleado.diasVacacionesAnualesOtorgados ?? 0 }} días

Vacaciones Utilizadas: {{ newEmpleado.diasVacacionesUtilizados ?? 0 }} días

Vacaciones Disponibles: {{ (newEmpleado.diasVacacionesAnualesOtorgados ?? 0) - (newEmpleado.diasVacacionesUtilizados ?? 0) }} días

Cobertura y Bancarios

Obra Social: {{ newEmpleado.obraSocial?.nombre || 'N/A' }}

N° Afiliado: {{ newEmpleado.obraSocial?.numeroAfiliado || 'N/A' }}

Banco: {{ newEmpleado.datosBancarios?.banco || 'N/A' }}

CBU/CVU: {{ newEmpleado.datosBancarios?.cbu || 'N/A' }}

Alias: {{ newEmpleado.datosBancarios?.alias || 'N/A' }}

ART: {{ newEmpleado.art?.nombre || 'N/A' }}

N° Póliza/Socio ART: {{ newEmpleado.art?.numeroSocio || 'N/A' }}

Historial de Licencias

{{ tiposDeLicencia.find(t => t.valor === licencia.tipo)?.texto || licencia.tipo }}

Desde: {{ formatDate(licencia.fechaDesde) }} - Hasta: {{ formatDate(licencia.fechaHasta) }} ({{ licencia.diasCalculados }} día{{ licencia.diasCalculados !== 1 ? 's' : '' }})

Comentario: {{ licencia.comentario }}

Registrado: {{ formatDate(licencia.fechaRegistro) }}

No hay licencias registradas para este empleado.

{{ viewTitle }}

Buscar Vehículo

  • {{ item.vehiculo?.patente || 'N/A' }} - {{ item.vehiculo?.marca || 'N/A' }} {{ item.vehiculo?.modelo || 'N/A' }}

    Cliente: {{ item.cliente?.nombre || 'N/A' }} (ID: {{ item.cliente?.id || 'N/A' }})

No se encontraron vehículos con esos criterios.

Últimos Servicios Realizados en el Taller

Orden ID: {{ orden.id }}

Vehículo: {{ orden.vehiculo?.patente || 'N/A' }} - {{ orden.vehiculo?.marca || 'N/A' }} {{ orden.vehiculo?.modelo || 'N/A' }}

Cliente: {{ orden.cliente?.nombre || 'N/A' }}

{{ orden.estado }}

Fecha Ingreso: {{ formatDate(orden.fechaEntrada) }}

Fecha Completado: {{ formatDate(orden.fechaCompletado) }}

Tareas Principales:
  • {{ tarea.nombre }} (Completada)
  • ... y {{ orden.tareas.length - 3 }} más.

No hay servicios completados recientemente.

Detalles del Cliente y Vehículo

Cliente: {{ vehiculoSeleccionadoGlobal.cliente?.nombre || 'N/A' }}

ID Cliente: {{ vehiculoSeleccionadoGlobal.cliente?.id || 'N/A' }}

Domicilio: {{ vehiculoSeleccionadoGlobal.cliente?.domicilio || 'N/A' }}

Teléfono: {{ vehiculoSeleccionadoGlobal.cliente?.telefono || 'N/A' }}

Email: {{ vehiculoSeleccionadoGlobal.cliente?.email || 'N/A' }}

Patente: {{ vehiculoSeleccionadoGlobal.vehiculo?.patente || 'N/A' }}

Marca: {{ vehiculoSeleccionadoGlobal.vehiculo?.marca || 'N/A' }}

Modelo: {{ vehiculoSeleccionadoGlobal.vehiculo?.modelo || 'N/A' }}

Año: {{ vehiculoSeleccionadoGlobal.vehiculo?.anio || 'N/A' }}

Kilometraje: {{ vehiculoSeleccionadoGlobal.vehiculo?.kilometraje ? vehiculoSeleccionadoGlobal.vehiculo.kilometraje.toLocaleString() + ' km' : 'N/A' }}

Combustible: {{ vehiculoSeleccionadoGlobal.vehiculo?.tipoCombustible || vehiculoSeleccionadoGlobal.vehiculo?.tipo_combustible || 'N/A' }}

VTV / RTO: {{ vehiculoSeleccionadoGlobal.vehiculo.fecha_vtv.slice(0, 10) }} No registrada

Patente: {{ vehiculoSeleccionadoGlobal.vehiculo?.patente }} (no editable)

Historial de Mantenimientos

Orden ID: {{ orden.id }} - Fecha Ingreso: {{ orden.fechaEntrada }}

Estado: {{ orden.estado }}

Tareas Realizadas:

  • {{ tarea.nombre }}

    Obs: {{ tarea.comentario }}

No hay historial de mantenimiento registrado para este vehículo.

🔔 Alertas de Mantenimiento {{ alertasMantenimientoVehiculo.filter(a => a.estado === 'activa').length }}

Cargando...
No hay alertas registradas para este vehículo.

{{ al.tipo_servicio_nombre }}

📅 {{ al.fecha_proxima.slice(0, 10) }} 🔢 {{ al.km_proximo.toLocaleString('es-AR') }} km · {{ al.notas }}

{{ al.estado }}

Programar Próximo Servicio

Gestión de Inventario

⚠ {{ inventarioAlertasCount }} bajo stock
{{ inventarioFiltrado.length }} de {{ itemsInventario.length }}
ID Cód. Parte Nombre Marca Categoría Ubic. Stock Mín. P.Compra P.Venta Proveedor Acciones
{{ item.id }} {{ item.numero_parte || '—' }} {{ item.nombre }} {{ item.marca_repuesto || '—' }} {{ item.categoria }} {{ item.ubicacion_deposito || '—' }} {{ item.stock }} {{ item.unidad_medida || 'un.' }} {{ item.stock_minimo || 0 }} $ {{ item.precio_compra ? Number(item.precio_compra).toFixed(2) : '—' }} {{ item.precio_venta ? '$ ' + Number(item.precio_venta).toFixed(2) : '—' }} {{ item.proveedor_nombre || item.proveedor_id || '—' }}

No hay productos en el inventario. Agregue el primero o importe desde Excel.

No hay productos que coincidan con los filtros.

Importar desde Excel

Columnas: ID_Producto (opcional), Nombre, Categoria, Stock, StockMinimo, PrecioCompra, PrecioVenta, NumeroParte, MarcaRepuesto, UnidadMedida, UbicacionDeposito, Compatibilidad, ProveedorID.

No hay productos con stock bajo. ¡Todo en orden!

{{ inventarioAlertas.length }} producto(s) con stock igual o por debajo del mínimo configurado.

{{ item.nombre }} {{ item.numero_parte }} {{ item.categoria }}
Stock actual: {{ item.stock }} {{ item.unidad_medida || 'un.' }} Mínimo: {{ item.stock_minimo }} Déficit: {{ item.stock_minimo - item.stock }} Proveedor: {{ item.proveedor_nombre || item.proveedor_id }}

{{ isEditingInventarioItem ? 'Editar Producto' : 'Nuevo Producto' }}

Cálculo de Precios

$
%
$
{{ precioVentaCalculado ? precioVentaCalculado.toFixed(2) : '—' }}

costo × (1+gan%) × (1+IVA%)

Costo: ${{ Number(newInventarioItem.precio_compra).toFixed(2) }} + Ganancia {{ newInventarioItem.margen_ganancia }}%: ${{ (newInventarioItem.precio_compra * newInventarioItem.margen_ganancia / 100).toFixed(2) }} Subtotal: ${{ (newInventarioItem.precio_compra * (1 + newInventarioItem.margen_ganancia / 100)).toFixed(2) }} + IVA {{ newInventarioItem.iva_porcentaje }}%: ${{ (newInventarioItem.precio_compra * (1 + newInventarioItem.margen_ganancia / 100) * newInventarioItem.iva_porcentaje / 100).toFixed(2) }} = Venta: ${{ precioVentaCalculado.toFixed(2) }}

Registrar Movimiento de Stock

{{ inventarioMovimientoItemNombre }}

Stock actual: {{ inventarioMovimientoItemStock }}

Stock actual: {{ inventarioMovimientoItemStock }} → nuevo valor: {{ movimientoForm.cantidad || '?' }}

Historial de Movimientos

{{ inventarioHistorialItemNombre }}

Sin movimientos registrados.
Fecha Tipo Cant. Ant. Post. Motivo OT
{{ mov.fecha ? mov.fecha.slice(0,16).replace('T',' ') : '—' }} {{ mov.tipo }} {{ mov.tipo === 'salida' ? '-' : (mov.tipo === 'ajuste' ? '→' : '+') }}{{ mov.cantidad }} {{ mov.stock_anterior }} {{ mov.stock_posterior }} {{ mov.motivo || '—' }} {{ mov.orden_trabajo_id || '—' }}

{{ viewTitle }}

🔔 Alertas de Mantenimiento {{ alertasMantenimientoCounts.total }}

Sin alertas pendientes en los próximos 30 días.

{{ alertasMantenimientoCounts.vencidas }}

Vencidas

{{ alertasMantenimientoCounts.esta_semana }}

Esta semana

{{ alertasMantenimientoCounts.este_mes }}

Este mes

Vehículo Servicio Fecha
{{ al.vehiculo_patente }} {{ al.tipo_servicio_nombre }} {{ al.fecha_proxima ? al.fecha_proxima.slice(0, 10) : '—' }}

Dashboard Operativo

Actualizado: {{ formatDateTime(dashboardReportes.generatedAt) }}

Órdenes Mes

{{ dashboardReportes.kpis.ordenesMesActual }}

vs mes anterior: {{ formatVariacion(dashboardReportes.kpis.variacionMensualPct) }}

Completadas Mes

{{ dashboardReportes.kpis.completadasMesActual }}

Cumplimiento: {{ dashboardReportes.kpis.tasaCumplimientoMesPct.toFixed(2) }}%

Mat. Mes ($)

${{ Number(dashboardReportes.kpis.costoMaterialesMesActual).toLocaleString('es-AR', {minimumFractionDigits:0, maximumFractionDigits:0}) }}

Costo materiales en OTs completadas

Servicios Prog. Mes

{{ dashboardReportes.kpis.serviciosProgramadosMesActual }}

Agenda del mes en curso

Órdenes Año

{{ dashboardReportes.kpis.ordenesAnioActual }}

vs año anterior: {{ formatVariacion(dashboardReportes.kpis.variacionAnualPct) }}

Completadas Año

{{ dashboardReportes.kpis.completadasAnioActual }}

Completadas + entregadas

Mat. Año ($)

${{ Number(dashboardReportes.kpis.costoMaterialesAnioActual).toLocaleString('es-AR', {minimumFractionDigits:0, maximumFractionDigits:0}) }}

Costo materiales en el año

Alertas de Tendencia

{{ alerta.titulo }}

{{ alerta.descripcion }}

Top Técnicos (Mes)

Sin registros este mes.

#{{ idx + 1 }} {{ t.tecnico_nombre }}

Completadas: {{ t.ordenes_completadas }} | Prom. cierre: {{ t.promedio_dias_cierre || 0 }} d

Gráfico de Tareas Más Realizadas (Mes actual)

Lógica: OT + tipo de trabajo + categoría + tarea específica.

Top {{ dashboardReportes.tareasMasRealizadasMes.length }}

Sin resultados para los filtros seleccionados en el mes actual.

{{ abreviarEtiquetaTarea(t.etiqueta) }} {{ t.etiqueta }}: {{ t.total }} {{ t.total }}

Estadística Mensual (vista {{ dashboardVista.monthsWindow }} meses)

Mejor mes (ingresadas)

{{ dashboardResumenMensual.mejorMes.periodo }}: {{ dashboardResumenMensual.mejorMes.ordenes_ingresadas }}

Sin datos

Mes más bajo (ingresadas)

{{ dashboardResumenMensual.peorMes.periodo }}: {{ dashboardResumenMensual.peorMes.ordenes_ingresadas }}

Sin datos

Cumplimiento promedio

{{ dashboardResumenMensual.promedioCumplimientoPct.toFixed(2) }}%

Comparativo mensual (ingresadas, completadas, programadas)

{{ m.periodo }} Ingresadas: {{ m.ordenes_ingresadas }} {{ m.periodo }} Completadas: {{ m.ordenes_completadas }} {{ m.periodo }} Programadas: {{ m.servicios_programados }} {{ formatPeriodoCorto(m.periodo) }}
● Ingresadas ● Completadas ● Programadas
{{ m.periodo }} {{ formatVariacion(m.variacion_ingresadas_pct) }}
Ingresadas{{ m.ordenes_ingresadas }}
Completadas{{ m.ordenes_completadas }}
Programadas{{ m.servicios_programados }}

Estadística Anual ({{ dashboardReportes.horizon.yearsBack }} años)

Comparativo anual por barras

{{ y.anio }} Ingresadas: {{ y.ordenes_ingresadas }} {{ y.anio }} Completadas: {{ y.ordenes_completadas }} {{ y.anio }} Programadas: {{ y.servicios_programados }} {{ y.anio }}
● Ingresadas ● Completadas ● Programadas
Año Ingresadas Completadas Programadas Var. Ingresadas
{{ y.anio }} {{ y.ordenes_ingresadas }} {{ y.ordenes_completadas }} {{ y.servicios_programados }} {{ formatVariacion(y.variacion_ingresadas_pct) }}

Distribución de Estados (Mes actual)

Sin datos

{{ e.estado }} {{ e.total }}

Distribución de Estados (Año actual)

Sin datos

{{ e.estado }} {{ e.total }}

Top Técnicos (Año)

Sin registros este año.

#{{ idx + 1 }} {{ t.tecnico_nombre }}

Completadas: {{ t.ordenes_completadas }} | Prom. cierre: {{ t.promedio_dias_cierre || 0 }} d

Auditoría de Asignaciones (Tomar/Soltar)

Fecha OT Acción Técnico Usuario Rol
{{ formatDateTime(evento.fecha_evento) }} {{ evento.orden_id }} {{ evento.accion }} {{ evento.tecnico_id || 'N/A' }} {{ evento.username || 'N/A' }} {{ evento.rol || 'N/A' }}

No hay eventos para los filtros seleccionados.

Total registros: {{ auditoriaTotal }}

Página {{ auditoriaPaginaActual }} de {{ auditoriaTotalPages }}

💵 Cierres de Caja

Días cerrados

{{ cajaCierres.length }}

Total Ingresos

{{ formatCurrency(cajaCierres.reduce((s, c) => s + parseFloat(c.total_ingresos || 0), 0)) }}

Total Egresos

{{ formatCurrency(cajaCierres.reduce((s, c) => s + parseFloat(c.total_egresos || 0), 0)) }}

Resultado Neto

{{ formatCurrency(cajaCierres.reduce((s, c) => s + parseFloat(c.total_ingresos||0) - parseFloat(c.total_egresos||0), 0)) }}

Sin cierres para el período seleccionado. Consultá desde el módulo Caja → Cierre Diario.
Fecha Apertura Ingresos Egresos Saldo Cierre Acciones
{{ c.fecha ? c.fecha.split('-').reverse().join('/') : '' }} {{ formatCurrency(c.saldo_apertura) }} {{ formatCurrency(c.total_ingresos) }} {{ formatCurrency(c.total_egresos) }} {{ formatCurrency(c.saldo_cierre) }}

📈 Rentabilidad por OT

Margen neto = cobrado − materiales − mano de obra

OTs cobradas

{{ rentabilidadData.resumen.ots_cobradas }}

Sin cobrar

{{ rentabilidadData.resumen.ots_sin_cobrar }}

Total cobrado

{{ formatCurrency(rentabilidadData.resumen.total_cobrado) }}

Costo materiales

{{ formatCurrency(rentabilidadData.resumen.total_costo_materiales) }}

Mano de obra

{{ formatCurrency(rentabilidadData.resumen.total_costo_mano_obra) }}

Margen neto

{{ formatCurrency(rentabilidadData.resumen.margen_neto) }}

% Margen

{{ rentabilidadData.resumen.margen_pct }}%

Por técnico

Técnico OTs Cobrado Materiales Margen neto %
{{ t.tecnico_nombre }} {{ t.ots_cobradas }} {{ formatCurrency(t.total_cobrado) }} {{ formatCurrency(t.total_costo_materiales) }} {{ formatCurrency(t.margen_neto) }} {{ t.margen_pct }}%

Detalle por OT

OT Cliente Cobrado $ Margen neto %
{{ ot.id }} {{ ot.cliente_nombre || '—' }} {{ formatCurrency(ot.monto_cobrado) }} {{ formatCurrency(ot.margen_neto) }} {{ ot.margen_pct }}%

No hay OTs cobradas para el período seleccionado.

Gestión de Usuarios

Buscar y Filtrar Usuarios

Username Rol Módulos Usuario Empleado Asociado Estado Acciones
{{ user.username }} {{ user.role }} {{ user.modulos.length }} módulos Por rol (sin override) {{ getEmpleadoNombre(user.empleado_id) }} {{ user.is_active ? 'Activo' : 'Inactivo' }}

No se encontraron usuarios con los criterios de búsqueda.

{{ editingUserId ? 'Editar Usuario' : 'Agregar Nuevo Usuario' }}

Si no seleccionas módulos, el usuario hereda permisos por su rol.

Resetear Contraseña para {{ resetPasswordForm.username }}

Permisos por Rol

Define qué módulos puede acceder cada rol. Los cambios aplican a todos los usuarios que usen ese rol sin asignación individual.

Crear Nuevo Rol

El nombre se normalizará a minúsculas sin espacios. Los roles del sistema (admin, tecnico, recepcionista) no pueden duplicarse.

Cargando permisos...

{{ roleInfo.name }}

sistema personalizado

El rol admin siempre tiene acceso total independientemente de esta configuración.

{{ (permisosEditando[roleInfo.name] || []).length }} de {{ permisosData.modulos.length }} módulos activos

{{ moduloNombre(modulo) }}

💰 Caja del Taller

⚠ Vencimientos próximos (próximos 7 días)

{{ g.nombre }} — día {{ g.dia_vencimiento }} (vencido hace {{ Math.abs(g.diasRestantes) }} días) (vence hoy) (en {{ g.diasRestantes }} días)

Saldo General

{{ formatCurrency(cajaBalance.saldo_general) }}

Ingresos del mes

{{ formatCurrency(cajaBalance.ingresos_mes) }}

Egresos del mes

{{ formatCurrency(cajaBalance.egresos_mes) }}

Ingresos hoy

{{ formatCurrency(cajaBalance.ingresos_hoy) }}

OTs a cobrar

{{ cajaBalance.ots_pendientes_cobro || 0 }}

Ingresos: {{ formatCurrency(cajaTotalesPeriodo.ingresos) }} Egresos: {{ formatCurrency(cajaTotalesPeriodo.egresos) }} Neto: {{ formatCurrency(cajaTotalesPeriodo.neto) }}
Fecha Tipo Categoría Descripción Medio pago Monto Acciones
No hay movimientos para el período seleccionado.
{{ mov.fecha }} {{ mov.tipo }} {{ mov.categoria }} {{ mov.descripcion || '—' }} {{ mov.medio_pago }} {{ mov.tipo === 'ingreso' ? '+' : '-' }}{{ formatCurrency(mov.monto) }}

Servicios y gastos recurrentes del taller con recordatorio de vencimiento mensual.

{{ editingGastoFijoId ? 'Editar' : 'Nuevo' }} gasto fijo

No hay gastos fijos configurados. Agregá alquiler, luz, internet, impuestos, etc.

{{ g.nombre }}

{{ g.categoria }} · Vence el día {{ g.dia_vencimiento }} de cada mes · {{ formatCurrency(g.monto_estimado) }}

{{ g.pagado_este_mes ? '✓ Pagado este mes' : 'Pendiente' }}

Órdenes de trabajo completadas o entregadas que aún no tienen cobro registrado.

¡Todas las OTs están cobradas!

OT Cliente Vehículo Estado Completado Mat. usados Acción
{{ ot.id }} {{ ot.cliente_nombre }} {{ ot.vehiculo_patente }} {{ ot.vehiculo_marca }} {{ ot.vehiculo_modelo }} {{ ot.estado }} {{ ot.fecha_completado || '—' }} {{ formatCurrency(ot.costo_materiales) }}

El cierre diario congela los movimientos del día y calcula el saldo final.

Este día ya tiene cierre registrado

ID #{{ cajaCierrePreview.cierre_existente }} — podés ver el detalle en el historial abajo.

Saldo Apertura

{{ formatCurrency(cajaCierrePreview.saldo_apertura) }}

Ingresos del día

{{ formatCurrency(cajaCierrePreview.total_ingresos) }}

Egresos del día

{{ formatCurrency(cajaCierrePreview.total_egresos) }}

Saldo Cierre

{{ formatCurrency(cajaCierrePreview.saldo_cierre) }}

Por categoría

{{ cat }} +{{ formatCurrency(v.ingreso) }} -{{ formatCurrency(v.egreso) }}

Por medio de pago

{{ medio }} +{{ formatCurrency(v.ingreso) }} -{{ formatCurrency(v.egreso) }}

No hay movimientos registrados para este día.

Historial de Cierres

Sin cierres registrados aún.
Fecha Apertura Ingresos Egresos Cierre Mov. Acciones
{{ c.fecha ? c.fecha.split('-').reverse().join('/') : '' }} {{ formatCurrency(c.saldo_apertura) }} {{ formatCurrency(c.total_ingresos) }} {{ formatCurrency(c.total_egresos) }} {{ formatCurrency(c.saldo_cierre) }} {{ c.cantidad_movimientos }}

Confirmar Cierre Diario

Se registrará el cierre del {{ cajaCierrePreview.fecha ? cajaCierrePreview.fecha.split('-').reverse().join('/') : '' }}. Esta acción es definitiva.

Ingresos

{{ formatCurrency(cajaCierrePreview.total_ingresos) }}

Egresos

{{ formatCurrency(cajaCierrePreview.total_egresos) }}

Movimientos

{{ cajaCierrePreview.cantidad_movimientos }}

Saldo Final

{{ formatCurrency(cajaCierrePreview.saldo_cierre) }}

{{ editingMovimientoId ? 'Editar movimiento' : 'Nuevo movimiento' }}

Registrar cobro de OT

{{ cajaCobrarOT.otLabel }}

Registrar pago

{{ cajaPagarGasto.nombre }}

Cierre del {{ cajaCierreDetalle.fecha ? cajaCierreDetalle.fecha.split('-').reverse().join('/') : '' }}

Apertura

{{ formatCurrency(cajaCierreDetalle.saldo_apertura) }}

Ingresos

{{ formatCurrency(cajaCierreDetalle.total_ingresos) }}

Egresos

{{ formatCurrency(cajaCierreDetalle.total_egresos) }}

Cierre

{{ formatCurrency(cajaCierreDetalle.saldo_cierre) }}

Por categoría

{{ cat }} +{{ formatCurrency(v.ingreso) }} -{{ formatCurrency(v.egreso) }}

Por medio de pago

{{ medio }} +{{ formatCurrency(v.ingreso) }} -{{ formatCurrency(v.egreso) }}

Movimientos ({{ cajaCierreDetalle.movimientos.length }})

Hora Tipo Categoría Descripción Monto Medio
{{ m.hora }} {{ m.tipo }} {{ m.categoria }} {{ m.descripcion || '—' }} {{ formatCurrency(m.monto) }} {{ m.medio_pago || 'efectivo' }}

Notas: {{ cajaCierreDetalle.notas }}

Registrado por {{ cajaCierreDetalle.username || 'N/A' }} el {{ cajaCierreDetalle.created_at }}

{{ suscripcionStatus.effective === 'PAUSED' ? 'Suscripción pausada' : 'Suscripción vencida' }}

El acceso al sistema está temporalmente suspendido. Contactá al administrador para regularizar la situación.

Renovar suscripción

{{ suscripcionStatus.effective === 'GRACE_PERIOD' ? 'Período de gracia' : 'Suscripción por vencer' }}

La suscripción venció. Quedan {{ suscripcionStatus.graceRemaining }} día(s) de gracia antes del bloqueo.

La suscripción vence en {{ suscripcionStatus.days }} día(s).

Contactá al administrador para renovarla.

Renovar suscripción

Enviar por email

{{ emailModalLabel }}