@extends('layouts.app') @section('titulo','Programación') @section('contenido')

Programación de mantenimientos

Paros de planta
{{-- ==== Paros activos ==== --}} @if($parosActivos->count() > 0)
Paros de planta ACTIVOS ({{ $parosActivos->count() }}) Cierra el paro cuando termine para reprogramar automáticamente las OT pendientes.
@foreach($parosActivos as $p) @endforeach
DesdeDías transcurridosMotivoRegistrado porCerrar paro
{{ $p->fecha_inicio->format('d/m/Y') }} {{ $p->fecha_inicio->diffInDays(now()) }} días {{ $p->motivo }}
{{ $p->descripcion }}
{{ optional($p->usuario)->usuario }}
@csrf
@endif {{-- ==== Generación anual ==== --}} @can('programacion.generar') @php $planesPorArea = $planes->groupBy(fn($p) => optional($p->area)->nombre ?: '— Sin área —'); @endphp
Generar planificación anual Crea órdenes preventivas según las frecuencias del plan (quincenal, mensual, semestral, anual).
@csrf
0 / {{ $planes->count() }} seleccionados
@foreach($planesPorArea as $area => $planesArea) @php $areaSlug = 'area_' . md5($area); @endphp
{{ $area }} ({{ $planesArea->count() }} plan{{ $planesArea->count() == 1 ? '' : 'es' }})
@foreach($planesArea as $p)
@endforeach
@endforeach
El sistema no duplica: si re-ejecutas, solo crea las que faltan. Una OT agrupa todos los ítems del plan que comparten frecuencia. Si no marcas ninguno, se procesarán TODOS los planes activos.
@push('scripts_inline') function planesActualizarContador() { const total = document.querySelectorAll('.plan-chk').length; const sel = document.querySelectorAll('.plan-chk:checked').length; const c = document.getElementById('planesContador'); c.textContent = sel + ' / ' + total; c.className = 'badge ' + (sel === 0 ? 'text-bg-warning' : sel === total ? 'text-bg-success' : 'text-bg-primary'); } function planesMarcar(v) { document.querySelectorAll('.plan-chk').forEach(c => c.checked = v); planesActualizarContador(); } function planesInvertir() { document.querySelectorAll('.plan-chk').forEach(c => c.checked = !c.checked); planesActualizarContador(); } function planesSoloVisibles() { document.querySelectorAll('.plan-chk').forEach(c => { const fila = c.closest('.plan-row'); c.checked = fila && !fila.classList.contains('oculto') && !fila.closest('.area-block.oculto'); }); planesActualizarContador(); } function planesAreaMarcar(grupo, v) { document.querySelectorAll('.plan-chk[data-grupo="' + grupo + '"]').forEach(c => c.checked = v); planesActualizarContador(); } function planesAreaToggle(grupo) { const bloque = document.querySelector('.area-planes[data-grupo="' + grupo + '"]'); if (bloque) bloque.style.display = bloque.style.display === 'none' ? '' : 'none'; } document.querySelectorAll('.plan-chk').forEach(c => c.addEventListener('change', planesActualizarContador)); // Buscador en tiempo real document.getElementById('buscaPlan').addEventListener('input', function (e) { const q = e.target.value.trim().toLowerCase(); document.querySelectorAll('.plan-row').forEach(row => { const match = q === '' || row.dataset.busca.includes(q); row.classList.toggle('oculto', !match); }); // Ocultar áreas sin coincidencias document.querySelectorAll('.area-block').forEach(blk => { const algunVisible = [...blk.querySelectorAll('.plan-row')].some(r => !r.classList.contains('oculto')); blk.classList.toggle('oculto', !algunVisible); }); }); planesActualizarContador(); @endpush @endcan {{-- ==== Replanificar manual ==== --}}
Replanificar OT pendientes Empuja OT pendientes N días.
@csrf
+ futuro, − pasado
Registrar paro de planta Queda histórico y desplaza al cerrarse.
@csrf
{{-- ==== Calendario mensual ==== --}}
Cada celda muestra las OT programadas. Click en el código para abrirla.
@foreach(['Lun','Mar','Mié','Jue','Vie','Sáb','Dom'] as $d)@endforeach @php $dia = $inicio->copy()->startOfWeek(); $hoy = \Carbon\Carbon::today(); @endphp @for($w=0; $w<6; $w++) @for($d=0; $d<7; $d++) @php $key = $dia->format('Y-m-d'); $delMes = $dia->month === $mes; $delHoy = $dia->isSameDay($hoy); @endphp @php $dia->addDay(); @endphp @endfor @if($dia->month !== $mes && $dia->gt($fin)) @break @endif @endfor
{{ $d }}
{{ $dia->day }} @foreach($ordenes->get($key, collect()) as $o) {{ $o->codigo }} @endforeach
{{-- ==== Histórico de paros (colapsado) ==== --}} @if($parosHistorial->count() > 0)
Historial de paros ({{ $parosHistorial->count() }} recientes)
@foreach($parosHistorial as $p) @endforeach
#DesdeHastaDíasMotivoOT afectadas
{{ $p->id }} {{ $p->fecha_inicio->format('d/m/Y') }} {{ $p->fecha_fin?->format('d/m/Y') }} {{ $p->duracion_dias }} {{ $p->motivo }} {{ $p->ots_afectadas }}
@endif @endsection