@extends('fragments.fullTemplate') @php $id_usuario = session('id_usuario'); if (! session('id_usuario')) { header('location: /'); die(); } /* * URL limpia de regreso al listado. * Se recibe desde Pendientes o Finalizadas con todos sus filtros en return_url. * Si no viene, usamos el listado de Pendientes como valor seguro por defecto. */ $url_regreso_requisicion = request('return_url'); if (empty($url_regreso_requisicion)) { $url_regreso_requisicion = url('requisicion_compras'); } /* * Validación simple para evitar regresar a URLs ajenas al módulo. */ $host_sistema = parse_url(url('/'), PHP_URL_HOST); $host_regreso = parse_url($url_regreso_requisicion, PHP_URL_HOST); $path_regreso = parse_url($url_regreso_requisicion, PHP_URL_PATH); if (! empty($host_regreso) && $host_regreso !== $host_sistema) { $url_regreso_requisicion = url('requisicion_compras'); } if (empty($path_regreso) || strpos($path_regreso, 'requisicion_compras') === false) { $url_regreso_requisicion = url('requisicion_compras'); } @endphp @section('contenido')
@if(session()->has('success')) @endif @if(session()->has('warning')) @endif @if(session()->has('error')) @endif @if (count($errors) > 0) @endif
@include('Requisicion_compra.Notificacion.notificacion_requisicion_modal')
@if ($permisos->crear == 1)
Crear notificación
@endif
Detalles de requisición de compra

{{$datos_reporte->nombre." ".$datos_reporte->apellidos}}

{{$datos_reporte->caracter}}

{{formatDateForDisplay($datos_reporte->fecha)}}

{{ $datos_linea_trabajo ? $datos_linea_trabajo->linea_trabajo : 'Sin línea de trabajo activa asignada' }}

@foreach($datos_reporte->conceptos as $concepto) {{$concepto->nombre}}
@endforeach

@foreach($datos_reporte->conceptos as $concepto) {{$concepto->descripcion}}
@endforeach

{{ $datos_unidad_negocio ? $datos_unidad_negocio->nombre_unidad_negocio : 'Sin unidad de negocio asignada' }}

{{ $datos_reporte->id_requisicion_reporte }}

{{-- Flujo central de requisición. Esta vista ahora utiliza $flujo_requisicion, calculado en el controlador, para decidir el estatus, bloqueo y modo de consulta de cada sección. Importante: - Para registros nuevos o estructurados se respeta el bloqueo del flujo. - Para registros legacy el controlador puede indicar que no aplica bloqueo estricto, evitando romper requisiciones históricas. --}} @php $flujoSecciones = array(); if (isset($flujo_requisicion) && isset($flujo_requisicion['secciones']) && is_array($flujo_requisicion['secciones'])) { $flujoSecciones = $flujo_requisicion['secciones']; } $aplicaBloqueoEstricto = true; if (isset($flujo_requisicion) && isset($flujo_requisicion['aplica_bloqueo_estricto'])) { $aplicaBloqueoEstricto = (bool) $flujo_requisicion['aplica_bloqueo_estricto']; } /* * Obtiene el estado calculado de una sección. * Si por alguna razón no existe, regresamos un estado seguro. */ $estadoSeccion = function ($clave) use ($flujoSecciones) { if (isset($flujoSecciones[$clave])) { return $flujoSecciones[$clave]; } return array( 'texto' => 'No iniciado', 'clase' => 'danger', 'habilitado' => false, 'solo_consulta' => false, 'bloqueado' => true, 'resumen' => null, 'fecha' => null, 'usuario' => null, 'motivo_bloqueo' => 'Debe completar las secciones anteriores.' ); }; /* * Fecha mostrada en la tabla. * Prioridad: * 1. Fecha calculada por el flujo. * 2. Fecha legacy del registro de requisicion_secciones. * 3. Sin datos. */ $fechaFlujo = function ($estado, $registro = null) { if (isset($estado['fecha']) && $estado['fecha']) { return formatDateForDisplay($estado['fecha']); } if ($registro && isset($registro->created_at1) && $registro->created_at1) { return formatDateForDisplay($registro->created_at1); } return '(Sin datos)'; }; /* * Usuario mostrado en la tabla. * Prioridad: * 1. Usuario calculado por el flujo. * 2. Usuario legacy del registro de requisicion_secciones. * 3. Sin datos. */ $usuarioFlujo = function ($estado, $registro = null) { if (isset($estado['usuario']) && $estado['usuario']) { return $estado['usuario']; } if ($registro && isset($registro->nombre)) { return trim($registro->nombre . ' ' . $registro->apellidos); } return '(Sin datos)'; }; /* * Determina si se debe mostrar una acción de captura/continuación. * * Nota: * - Si una sección está en solo_consulta, ya no se deja modificar desde aquí. * - Si el registro es legacy sin bloqueo estricto, se conserva compatibilidad. */ $puedeCapturar = function ($estado, $puedeUsuario = true) use ($aplicaBloqueoEstricto) { if (!$puedeUsuario) { return false; } if (isset($estado['solo_consulta']) && $estado['solo_consulta']) { return false; } if (isset($estado['habilitado']) && $estado['habilitado']) { return true; } if (!$aplicaBloqueoEstricto && isset($estado['bloqueado']) && !$estado['bloqueado']) { return true; } return false; }; /* * Texto de acción. */ $textoAccion = function ($estado, $existeRegistro = false) { if ($existeRegistro) { return 'Continuar'; } if (isset($estado['texto']) && $estado['texto'] != 'No iniciado') { return 'Continuar'; } return 'Comenzar'; }; @endphp
{{-- ========================================================= 1. Tipo de servicio y suministro ========================================================= --}} @php $estado_1 = $estadoSeccion('1'); @endphp {{-- ========================================================= 2. Especificaciones ========================================================= --}} @php $estado_2 = $estadoSeccion('2'); @endphp {{-- ========================================================= 2.1 Datos de proveedor Visible para usuarios con acceso al detalle; la edicion queda controlada por permisos de backend. ========================================================= --}} @if (isset($id_requisicion_reporte)) @php $estado_21 = $estadoSeccion('2.1'); @endphp {{-- ========================================================= 2.2 Cómo se recibe el suministro y formas de pago Visible para usuarios con acceso al detalle; la edicion queda controlada por permisos de backend. ========================================================= --}} @php $estado_22 = $estadoSeccion('2.2'); @endphp @endif {{-- ========================================================= 2.3 Aprobación ========================================================= --}} @php $estado_23 = $estadoSeccion('2.3'); @endphp {{-- ========================================================= 2.4 Aprobación de pago ========================================================= --}} @php $estado_24 = $estadoSeccion('2.4'); @endphp {{-- ========================================================= 3. Inspección o revisión del producto o servicio contra especificación ========================================================= --}} @php $estado_3 = $estadoSeccion('3'); @endphp
Sección Fecha de elaboración Modificado por Estatus Acciones
1. Tipo de servicio y suministro {{ $fechaFlujo($estado_1, $datos_seccion_1) }} {{ $usuarioFlujo($estado_1, $datos_seccion_1) }} {{ $estado_1['texto'] }} @if(isset($estado_1['resumen']) && $estado_1['resumen'])
{{ $estado_1['resumen'] }} @endif
@if ($puedeCapturar($estado_1, $puede_editar_secciones_base))
@if ($datos_reporte_tipo_servicio) @else @endif
@elseif(isset($estado_1['solo_consulta']) && $estado_1['solo_consulta']) @if ($datos_reporte_tipo_servicio) @else @endif @else @endif
2. Especificaciones {{ $fechaFlujo($estado_2, $datos_seccion_2) }} {{ $usuarioFlujo($estado_2, $datos_seccion_2) }} {{ $estado_2['texto'] }} @if(isset($estado_2['resumen']) && $estado_2['resumen'])
{{ $estado_2['resumen'] }} @endif
@if ($puedeCapturar($estado_2, $puede_editar_secciones_base))
@if ($datos_seccion_2) @else @endif
@elseif(isset($estado_2['solo_consulta']) && $estado_2['solo_consulta']) @else @endif
2.1 Datos de proveedor {{ $fechaFlujo($estado_21, $datos_seccion_2_1) }} {{ $usuarioFlujo($estado_21, $datos_seccion_2_1) }} {{ $estado_21['texto'] }} @if(isset($estado_21['resumen']) && $estado_21['resumen'])
{{ $estado_21['resumen'] }} @endif
@if ($puedeCapturar($estado_21, $puede_editar_secciones_base))
@if ($datos_seccion_2_1) @else @endif
@elseif(isset($estado_21['solo_consulta']) && $estado_21['solo_consulta']) @else @endif
2.2 Como se recibe el suministro y formas de pago {{ $fechaFlujo($estado_22, $datos_seccion_2_2) }} {{ $usuarioFlujo($estado_22, $datos_seccion_2_2) }} {{ $estado_22['texto'] }} @if(isset($estado_22['resumen']) && $estado_22['resumen'])
{{ $estado_22['resumen'] }} @endif
@if ($puedeCapturar($estado_22, $puede_editar_secciones_base))
@if ($datos_seccion_2_2) @else @endif
@elseif(isset($estado_22['solo_consulta']) && $estado_22['solo_consulta']) @else @endif
2.3 Aprobación {{ $fechaFlujo($estado_23, $datos_seccion_2_3) }} {{ $usuarioFlujo($estado_23, $datos_seccion_2_3) }} {{ $estado_23['texto'] }} @if(isset($estado_23['resumen']) && $estado_23['resumen'])
{{ $estado_23['resumen'] }} @endif
@if ($puedeCapturar($estado_23, $puede_gestionar_aprobacion))
@elseif(isset($estado_23['solo_consulta']) && $estado_23['solo_consulta'] && $puede_gestionar_aprobacion)
@elseif(isset($estado_23['solo_consulta']) && $estado_23['solo_consulta']) @else @endif
2.4 Aprobación de pago {{ $fechaFlujo($estado_24, $datos_seccion_2_4) }} {{ $usuarioFlujo($estado_24, $datos_seccion_2_4) }} {{ $estado_24['texto'] }} @if(isset($estado_24['resumen']) && $estado_24['resumen'])
{{ $estado_24['resumen'] }} @endif
@if ($puedeCapturar($estado_24, $puede_gestionar_pagos))
@elseif(!$puede_gestionar_pagos && isset($estado_24['texto']) && $estado_24['texto'] != 'No iniciado' && $estado_24['texto'] != 'N/A') @elseif(isset($estado_24['solo_consulta']) && $estado_24['solo_consulta']) @if(isset($estado_24['texto']) && $estado_24['texto'] == 'N/A') @else {{-- Sección 2.4: Aunque el flujo diga "solo_consulta" por estar finalizada, se deja editable porque puede requerir carga/corrección de facturas, complementos o evidencias de pago. Importante: Se respeta el permiso actualizar. --}} @if ($puede_gestionar_pagos)
@else @endif @endif @else @endif
3. Inspección o revisión del producto o servicio contra especificación {{ $fechaFlujo($estado_3, $datos_seccion_3) }} {{ $usuarioFlujo($estado_3, $datos_seccion_3) }} {{ $estado_3['texto'] }} @if(isset($estado_3['resumen']) && $estado_3['resumen'])
{{ $estado_3['resumen'] }} @endif
@if ($puedeCapturar($estado_3, $puede_editar_seccion3))
@if ($tiene_nueva_estructura_seccion_3) @else @if ($datos_seccion_3 && $datos_reporte_inspeccion) @else @endif @endif
@elseif(isset($estado_3['solo_consulta']) && $estado_3['solo_consulta']) @if(isset($estado_3['texto']) && $estado_3['texto'] == 'N/A') @else {{-- Sección 3: Aunque el flujo diga "solo_consulta" por estar aceptada, se deja editable porque puede requerir carga/corrección de evidencias de entrega. Importante: Se respeta el permiso actualizar. --}} @if ($puede_editar_seccion3)
@if ($tiene_nueva_estructura_seccion_3) @else @if ($datos_reporte_inspeccion) @else @endif @endif
@else @endif @endif @else @endif
@php /* * Las firmas finales solo se habilitan cuando el flujo central indica que: * - 2.4 está en Pago Finalizado. * - 3 está en Aceptado. */ $firmasFinalesHabilitadas = false; $motivoBloqueoFirmasFinales = 'Debe finalizarse el pago y aceptarse la inspección antes de firmar.'; if (isset($flujo_requisicion) && isset($flujo_requisicion['firmas_finales'])) { $firmasFinalesHabilitadas = isset($flujo_requisicion['firmas_finales']['habilitadas']) ? (bool) $flujo_requisicion['firmas_finales']['habilitadas'] : false; if (isset($flujo_requisicion['firmas_finales']['motivo_bloqueo']) && $flujo_requisicion['firmas_finales']['motivo_bloqueo']) { $motivoBloqueoFirmasFinales = $flujo_requisicion['firmas_finales']['motivo_bloqueo']; } } $puedeGestionarFirmasFinales = $firmasFinalesHabilitadas && $puede_editar_seccion3; $motivoBloqueoGestionFirmasFinales = $motivoBloqueoFirmasFinales; if ($firmasFinalesHabilitadas && !$puede_editar_seccion3) { $motivoBloqueoGestionFirmasFinales = 'No tienes permiso para firmar esta requisicion.'; } $obtenerNombreFirmaFinal = function ($firma) { if (!$firma) { return 'Usuario no disponible'; } $nombre = trim((string) $firma->nombre.' '.(string) $firma->apellidos); return $nombre !== '' ? $nombre : 'Usuario no disponible'; }; $obtenerPuestoFirmaFinal = function ($firma) { if (!$firma) { return 'Puesto no registrado'; } $puesto = trim((string) $firma->puesto_firmante); if ($puesto === '') { $puesto = trim((string) $firma->area_firmante); } return $puesto !== '' ? $puesto : 'Puesto no registrado'; }; $obtenerFirmaUrlFinal = function ($nombreFirma) { $nombreFirma = trim((string) $nombreFirma); if ($nombreFirma === '') { return ''; } $rutaFirma = storage_path('app/public/archivos_usuario/'.$nombreFirma); if (!file_exists($rutaFirma) || !is_file($rutaFirma)) { return ''; } $extensionFirma = strtolower(pathinfo($rutaFirma, PATHINFO_EXTENSION)); $mimesPorExtension = array( 'png' => 'image/png', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'webp' => 'image/webp', ); $mime = isset($mimesPorExtension[$extensionFirma]) ? $mimesPorExtension[$extensionFirma] : ''; if ($mime === '' && function_exists('mime_content_type')) { $mimeDetectado = mime_content_type($rutaFirma); if ($mimeDetectado && strpos($mimeDetectado, 'image/') === 0) { $mime = $mimeDetectado; } } if ($mime === '') { return ''; } return 'data:'.$mime.';base64,'.base64_encode(file_get_contents($rutaFirma)); }; @endphp
@if ($firma_inspeccion->estatus_firma == 1)

Firma de quien realizó la inspección

{{ $obtenerPuestoFirmaFinal($firma_inspeccion) }}

@php $firma_inspeccion_url = $obtenerFirmaUrlFinal($firma_inspeccion->firma_digital); @endphp @if ($firma_inspeccion_url)
Firma de inspección
@else

Firma digital no registrada.

@endif

{{ $obtenerNombreFirmaFinal($firma_inspeccion) }}

Firmado
@if ($puede_editar_seccion3) Cancelar firma @endif @else @if ($puedeGestionarFirmasFinales) Nombre y firma de quien realizó inspección @else @endif @endif
@if ($firma_conclusion->estatus_firma == 1)

Revisó conclusión de compra

{{ $obtenerPuestoFirmaFinal($firma_conclusion) }}

@php $firma_conclusion_url = $obtenerFirmaUrlFinal($firma_conclusion->firma_digital); @endphp @if ($firma_conclusion_url)
Firma de conclusión de compra
@else

Firma digital no registrada.

@endif

{{ $obtenerNombreFirmaFinal($firma_conclusion) }}

Firmado
@if ($puede_editar_seccion3) Cancelar revisión @endif @else @if ($puedeGestionarFirmasFinales) Revisó conclusión de compra @else @endif @endif
{{--
{{csrf_field()}}
--}}
@include('Requisicion_compra.create_notificacion_modal') {{-- ========================================================= MODO CONSULTA GLOBAL PARA MODALES DE REQUISICIÓN Objetivo: - Reutilizar las mismas modales actuales. - Permitir abrir la información capturada. - Evitar edición cuando la sección está en "Consulta". - Ocultar botones de guardar, eliminar, pagar, firmar o deshacer. Importante: Este bloque NO modifica datos. Solo afecta la interacción visual dentro de la modal. ========================================================= --}} @include('Requisicion_compra.create_seccion1_modal') @include('Requisicion_compra.update_seccion1_modal') @include('Requisicion_compra.create_seccion2_modal') @include('Requisicion_compra.update_seccion2_modal') @include('Requisicion_compra.create_seccion2_1_modal') @include('Requisicion_compra.update_seccion2_1_modal') @include('Requisicion_compra.create_seccion2_2_modal') @include('Requisicion_compra.update_seccion2_2_modal') {{-- Corrección: La lógica de actualización de la sección 2.2 vive dentro de update_seccion2_2_modal.blade.php. Antes existía aquí otro listener para .update_seccion2_2. Ese listener duplicado abría la modal pero NO llenaba #id_requisicion_reporte_update, provocando que Laravel recibiera: id_requisicion_reporte => null. --}} @include('Requisicion_compra.create_seccion2_3_modal') @include('Requisicion_compra.create_seccion2_4_modal') @include('Requisicion_compra.create_seccion3_modal') @include('Requisicion_compra.update_seccion3_modal')
@include('Requisicion_compra.create_seccion3_entregas_modal')
@include('Requisicion_compra.show_anexos') @include('Requisicion_compra.delete_anexos') @include('Requisicion_compra.delete_notificacion_modal') @endsection