@vite(['resources/css/app.css', 'resources/js/app.js'])
Jefatura de Taller

Panel de Taller @php $totalAlertas = $alertasPendientes->count() + $repuestosStockBajo->count(); @endphp @if ($totalAlertas > 0) 🔔 {{ $totalAlertas }} {{ $totalAlertas === 1 ? 'alerta' : 'alertas' }} @endif

Presupuestos, órdenes de trabajo y credenciales de la red de mantenimiento.

@if (session('status'))
{{ session('status') }}
@endif @if ($errors->any())
{{ $errors->first() }}
@endif @if ($alertasPendientes->isNotEmpty() || $repuestosStockBajo->isNotEmpty())

🔔 Centro de Alertas

Unidades lejos del taller el día del turno, OTs que ya alcanzaron su km objetivo, y repuestos por debajo del stock mínimo.

@foreach ($alertasPendientes as $alerta)
{{ $alerta->tipo === 'distancia_taller' ? 'Distancia al taller' : 'Km objetivo alcanzado' }} {{ $alerta->created_at->diffForHumans() }}

{{ $alerta->mensaje }}

@if ($alerta->tipo === 'distancia_taller' && $alerta->orden_trabajo_id)
@csrf
@csrf
@endif
@csrf
@endforeach @if ($repuestosStockBajo->isNotEmpty())
Stock bajo Ir a Repuestos →
@foreach ($repuestosStockBajo as $r) {{ $r->nombre }} ({{ $r->stock_actual }}/{{ $r->stock_minimo }}) @endforeach
@endif
@endif

Unidades en taller ahora

Tractores y semis con estado "En Taller" en este momento, y quién los está atendiendo.

@if (!empty($unidadesEnTaller))
@endif
@forelse ($unidadesEnTaller as $u)

{{ $u['interno'] }}

{{ ucfirst($u['tipo']) }}

{{ $u['detalle'] }}

Trabajo: {{ $u['componentes'] ?? 'Sin detalle' }}

Mecánico: {{ $u['mecanico'] ?? 'Sin asignar' }}

Taller: {{ $u['taller'] ?? 'Taller propio / sin dato' }}

@if ($u['desde'])

Desde: {{ $u['desde'] }}

@endif @if ($u['tiempo_estimado_horas'])

Tiempo estimado: {{ $u['tiempo_estimado_horas'] }} hs

@endif @if ($u['costo_total'])

Presupuestado: $ {{ number_format($u['costo_total'], 2, ',', '.') }}

@endif @if ($u['fecha_programada'])

📅 Programada para el {{ $u['fecha_programada'] }}

@endif
@empty

No hay unidades en taller en este momento.

@endforelse

Presupuestos pendientes de aprobación

@forelse ($presupuestosPendientes as $ot)

OT #{{ $ot->id }} · {{ $ot->unidadPatente() ?? 'Sin patente' }} ({{ $ot->unidad_type }})

@foreach ($ot->componentes as $c)

· {{ $c->nombre }} (obj. {{ number_format($c->km_objetivo, 0, ',', '.') }} km @if($c->horas_estimadas) · {{ $c->horas_estimadas }} hs @endif)

@endforeach

Mecánico: {{ $ot->mecanico?->nombre ?? 'N/D' }} @if ($ot->mecanico?->tallerExterno) · {{ $ot->mecanico->tallerExterno->nombre }} @endif · Tiempo estimado: {{ $ot->tiempo_estimado_horas }} hs

@foreach ($ot->repuestos as $r)

· {{ $r->descripcion }} ({{ $r->marca }} {{ $r->modelo }}) x{{ $r->cantidad }} — $ {{ number_format($r->costo_total, 2, ',', '.') }} @if ($r->catalogoRepuesto && $r->cantidad > $r->catalogoRepuesto->stock_actual) ⚠ stock insuficiente ({{ $r->catalogoRepuesto->stock_actual }} disp.) @endif

@endforeach
@if ($ot->costo_mano_obra > 0)

Mano de obra: $ {{ number_format($ot->costo_mano_obra, 2, ',', '.') }}

@endif

Total: $ {{ number_format($ot->costoTotal(), 2, ',', '.') }}

@csrf
@csrf
@csrf
@empty

No hay presupuestos pendientes.

@endforelse

Compras pendientes (esperando insumos)

@forelse ($otsEsperandoInsumos as $ot) @php $faltantes = $ot->faltantes(); @endphp

OT #{{ $ot->id }} · {{ $ot->unidad()?->interno }} — {{ $ot->componentesResumen() }}

Mecánico: {{ $ot->mecanico?->nombre ?? 'N/D' }} · Trabajo aprobado, esperando repuestos

@if (!empty($faltantes))
@foreach ($faltantes as $f)

· {{ $f['nombre'] }} — faltan {{ $f['faltante'] }} (stock {{ $f['stock_actual'] }} / pedido {{ $f['cantidad_pedida'] }}) @if ($f['en_camino'] > 0) · {{ $f['en_camino'] }} en camino @endif

@endforeach
+ Generar orden de compra @endif @if ($ot->ordenesCompra->isNotEmpty()) @php $cotizando = $ot->ordenesCompra->where('estado', \App\Models\OrdenCompra::ESTADO_COTIZANDO); $masEconomicaId = $cotizando->count() > 1 ? $cotizando->sortBy(fn ($o) => $o->costoTotal())->first()->id : null; @endphp

{{ $ot->ordenesCompra->count() }} {{ $ot->ordenesCompra->count() === 1 ? 'cotización cargada' : 'cotizaciones cargadas' }} @if ($cotizando->count() > 0 && $cotizando->count() < 3) · se recomiendan 3 para comparar @endif

@foreach ($ot->ordenesCompra as $oc)

OC #{{ $oc->id }} · {{ $oc->proveedor?->nombre }} · {{ $oc->tiempo_estimado_entrega_dias }} días · $ {{ number_format($oc->costoTotal(), 2, ',', '.') }}

@if ($oc->id === $masEconomicaId) Más económica @endif {{ $oc->estadoLabel() }}
@foreach ($oc->items as $item)

· x{{ $item->cantidad }} — $ {{ number_format($item->costo_real_total, 2, ',', '.') }}

@endforeach
@if (!in_array($oc->estado, ['recibida', 'cancelada', 'descartada']))
@if ($oc->estado === 'cotizando')
count() > 1) onsubmit="return confirm('¿Adjudicar esta cotización? Las demás cotizaciones cargadas para esta OT van a quedar descartadas.');" @endif> @csrf
@endif
@csrf
@csrf
@endif
@endforeach
@endif
@empty

No hay OTs esperando insumos.

@endforelse

Órdenes de trabajo activas

@if ($otsActivas->isNotEmpty())
@endif
@forelse ($otsActivas as $ot) @php $urgencia = $ot->urgenciaKm(); $estadoBadge = match ($ot->estado) { \App\Models\OrdenTrabajo::ESTADO_EN_EJECUCION => 'border-amber-500/30 bg-amber-500/10 text-amber-300', \App\Models\OrdenTrabajo::ESTADO_APROBADA => 'border-blue-500/30 bg-blue-500/10 text-blue-300', default => 'border-slate-600 bg-slate-800/60 text-slate-300', }; $esperandoDesde = $ot->estado === \App\Models\OrdenTrabajo::ESTADO_APROBADA ? $ot->aprobada_at?->diffForHumans() : ($ot->estado === \App\Models\OrdenTrabajo::ESTADO_PENDIENTE_PRESUPUESTO ? $ot->created_at?->diffForHumans() : null); @endphp

OT #{{ $ot->id }} · {{ $ot->unidadPatente() ?? 'Sin patente' }}

{{ $ot->estadoLabel() }} @if ($urgencia['etiqueta'] !== 'Sin dato') {{ $urgencia['etiqueta'] }} @endif
@forelse ($ot->componentes as $c)

· {{ $c->nombre }} (obj. {{ number_format($c->km_objetivo, 0, ',', '.') }} km @if($c->horas_estimadas) · {{ $c->horas_estimadas }} hs @endif)

@empty

· {{ $ot->componentesResumen() }}

@endforelse

Mecánico: {{ $ot->mecanico?->nombre ?? 'Sin asignar' }} · Origen: {{ $ot->origen }}

Km unidad: {{ number_format($ot->unidad()?->kilometraje ?? 0, 0, ',', '.') }} / objetivo {{ number_format($ot->km_objetivo, 0, ',', '.') }} km @if ($ot->tiempo_estimado_horas) Tiempo estimado: {{ $ot->tiempo_estimado_horas }} hs @endif @if ($ot->costoTotal() > 0) Presupuestado: $ {{ number_format($ot->costoTotal(), 2, ',', '.') }} @endif @if ($ot->fecha_hora_programada) 📅 Turno el {{ $ot->fecha_hora_programada->format('d/m/Y H:i') }}hs
reprogramar / cancelar
@csrf
@csrf
@endif @if ($esperandoDesde) {{ $ot->estado === \App\Models\OrdenTrabajo::ESTADO_APROBADA ? 'Aprobada' : 'Creada' }} hace {{ $esperandoDesde }} @endif
@if (!$ot->mecanico_id)
@csrf
@endif
@empty

No hay OTs activas.

@endforelse

Historial reciente

@forelse ($otsResueltas as $ot) @empty @endforelse
Unidad Componente Estado Resuelto por
{{ $ot->unidadPatente() ?? 'Sin patente' }} {{ $ot->componente }} {{ $ot->estadoLabel() }} {{ $ot->aprobadaPor?->name ?? '—' }}
Sin historial todavía.