269 lines
9.6 KiB
PHP
269 lines
9.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Repuve;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Barryvdh\DomPDF\Facade\Pdf;
|
|
use App\Models\Record;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
|
use Codedge\Fpdf\Fpdf\Fpdf;
|
|
use Illuminate\Http\Request;
|
|
|
|
class RecordController extends Controller
|
|
{
|
|
public function generatePdf($id)
|
|
{
|
|
$record = Record::with('vehicle')->findOrFail($id);
|
|
|
|
$pdf = Pdf::loadView('pdfs.record', compact('record'))
|
|
->setPaper('a4', 'portrait')
|
|
->setOptions([
|
|
'defaultFont' => 'sans-serif',
|
|
'isHtml5ParserEnabled' => true,
|
|
'isRemoteEnabled' => true,
|
|
]);
|
|
|
|
return $pdf->stream('constancia-inscripcion-' . $id . '.pdf');
|
|
}
|
|
|
|
public function generatePdfVerification($id)
|
|
{
|
|
$record = Record::with('vehicle.owner', 'user')->findOrFail($id);
|
|
|
|
$pdf = Pdf::loadView('pdfs.verification', compact('record'))
|
|
->setPaper('a4', 'landscape')
|
|
->setOptions([
|
|
'defaultFont' => 'sans-serif',
|
|
'isHtml5ParserEnabled' => true,
|
|
'isRemoteEnabled' => true,
|
|
]);
|
|
|
|
return $pdf->stream('hoja-verificacion-' . $id . '.pdf');
|
|
}
|
|
|
|
public function generatePdfConstancia($id)
|
|
{
|
|
$record = Record::with('vehicle.owner', 'user')->findOrFail($id);
|
|
|
|
$pdf = Pdf::loadView('pdfs.constancia', compact('record'))
|
|
->setPaper('a4', 'landscape')
|
|
->setOptions([
|
|
'defaultFont' => 'sans-serif',
|
|
'isHtml5ParserEnabled' => true,
|
|
'isRemoteEnabled' => true,
|
|
]);
|
|
|
|
return $pdf->stream('constancia-inscripcion' . $id . '.pdf');
|
|
}
|
|
|
|
/**
|
|
* Generar PDF con las imágenes
|
|
*/
|
|
public function generatePdfImages($id)
|
|
{
|
|
try {
|
|
// Obtener el record con sus archivos
|
|
$record = Record::with(['vehicle.owner', 'files'])->findOrFail($id);
|
|
|
|
// Validar que tenga archivos
|
|
if ($record->files->isEmpty()) {
|
|
return ApiResponse::NOT_FOUND->response([
|
|
'message' => 'El expediente no tiene imágenes adjuntas.',
|
|
'record_id' => $id,
|
|
]);
|
|
}
|
|
|
|
// Crear instancia de FPDF
|
|
$pdf = new Fpdf('P', 'mm', 'A4');
|
|
$pdf->SetAutoPageBreak(false);
|
|
$pdf->SetMargins(10, 10, 10);
|
|
|
|
$currentImage = 0;
|
|
|
|
foreach ($record->files as $file) {
|
|
$currentImage++;
|
|
|
|
// Buscar archivo en disk 'records'
|
|
$diskRecords = Storage::disk('records');
|
|
|
|
$fileContent = null;
|
|
if ($diskRecords->exists($file->path)) {
|
|
$fileContent = $diskRecords->get($file->path);
|
|
}
|
|
|
|
// Si no se encontró el archivo, continuar
|
|
if ($fileContent === null) {
|
|
continue;
|
|
}
|
|
|
|
// Agregar nueva página
|
|
$pdf->AddPage();
|
|
|
|
// Header con folio
|
|
$pdf->SetFillColor(44, 62, 80);
|
|
$pdf->Rect(0, 0, 210, 20, 'F');
|
|
$pdf->SetTextColor(255, 255, 255);
|
|
$pdf->SetFont('Arial', 'B', 14);
|
|
$pdf->SetXY(10, 7);
|
|
$pdf->Cell(0, 6, 'FOLIO: ' . $record->folio, 0, 1, 'L');
|
|
|
|
// Obtener ruta temporal del archivo
|
|
$tempPath = tempnam(sys_get_temp_dir(), 'pdf_img_');
|
|
file_put_contents($tempPath, $fileContent);
|
|
|
|
// Obtener dimensiones de la imagen
|
|
$imageInfo = getimagesize($tempPath);
|
|
|
|
if ($imageInfo !== false) {
|
|
list($originalWidth, $originalHeight) = $imageInfo;
|
|
$imageType = $imageInfo[2];
|
|
|
|
$availableWidth = 190; // 210mm - 20mm márgenes
|
|
$availableHeight = 247; // 297mm - 20mm header - 20mm footer - 10mm márgenes
|
|
|
|
// Calcular dimensiones manteniendo proporción
|
|
$ratio = min($availableWidth / $originalWidth, $availableHeight / $originalHeight);
|
|
$newWidth = $originalWidth * $ratio;
|
|
$newHeight = $originalHeight * $ratio;
|
|
|
|
// Centrar imagen
|
|
$x = (210 - $newWidth) / 2;
|
|
$y = 25 + (($availableHeight - $newHeight) / 2);
|
|
|
|
// Determinar tipo de imagen
|
|
$imageExtension = '';
|
|
switch ($imageType) {
|
|
case IMAGETYPE_JPEG:
|
|
$imageExtension = 'JPEG';
|
|
break;
|
|
case IMAGETYPE_JPEG:
|
|
$imageExtension = 'JPG';
|
|
break;
|
|
case IMAGETYPE_PNG:
|
|
$imageExtension = 'PNG';
|
|
break;
|
|
default:
|
|
// Si no es un formato soportado, continuar
|
|
unlink($tempPath);
|
|
continue 2;
|
|
}
|
|
|
|
// Insertar imagen
|
|
$pdf->Image($tempPath, $x, $y, $newWidth, $newHeight, $imageExtension);
|
|
}
|
|
|
|
// Limpiar archivo temporal
|
|
unlink($tempPath);
|
|
}
|
|
|
|
// Verificar que se agregaron páginas
|
|
if ($pdf->PageNo() == 0) {
|
|
return ApiResponse::NOT_FOUND->response([
|
|
'message' => 'No se pudieron procesar las imágenes del expediente.',
|
|
'record_id' => $id,
|
|
]);
|
|
}
|
|
|
|
// Generar PDF
|
|
$pdfContent = $pdf->Output('S');
|
|
|
|
return response($pdfContent, 200)
|
|
->header('Content-Type', 'application/pdf')
|
|
->header('Content-Disposition', 'inline; filename="expediente-imagenes-' . $record->folio . '.pdf"');
|
|
} catch (\Exception $e) {
|
|
return ApiResponse::INTERNAL_ERROR->response([
|
|
'message' => 'Error al generar el PDF de imágenes',
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function errors(Request $request)
|
|
{
|
|
$request->validate([
|
|
'folio' => 'nullable|string',
|
|
'placa' => 'nullable|string',
|
|
'vin' => 'nullable|string',
|
|
]);
|
|
|
|
$query = Record::with(['vehicle.owner', 'vehicle.tag', 'files', 'user', 'error'])
|
|
->whereNotNull('api_response')
|
|
->whereRaw("JSON_EXTRACT(api_response, '$.has_error') = true")
|
|
->orderBy('error_occurred_at', 'DESC');
|
|
|
|
if ($request->filled('folio')) {
|
|
$query->where('folio', 'LIKE', '%' . $request->input('folio') . '%');
|
|
}
|
|
|
|
if ($request->filled('placa')) {
|
|
$query->whereHas('vehicle', function ($q) use ($request) {
|
|
$q->where('placa', 'LIKE', '%' . $request->input('placa') . '%');
|
|
});
|
|
}
|
|
|
|
if ($request->filled('vin')) {
|
|
$query->whereHas('vehicle', function ($q) use ($request) {
|
|
$q->where('niv', 'LIKE', '%' . $request->input('vin') . '%');
|
|
});
|
|
}
|
|
|
|
$perPage = $request->input('per_page', 20);
|
|
$records = $query->paginate($perPage);
|
|
|
|
if ($records->isEmpty()) {
|
|
return ApiResponse::NOT_FOUND->response([
|
|
'message' => 'No se encontraron expedientes con errores.',
|
|
'records' => [],
|
|
'pagination' => [
|
|
'current_page' => 1,
|
|
'total_pages' => 0,
|
|
'total_records' => 0,
|
|
'per_page' => $perPage,
|
|
],
|
|
]);
|
|
}
|
|
|
|
return ApiResponse::OK->response([
|
|
'message' => 'Expedientes con errores encontrados exitosamente',
|
|
'records' => $records->map(function ($record) {
|
|
return [
|
|
'id' => $record->id,
|
|
'folio' => $record->folio,
|
|
'created_at' => $record->created_at->toDateTimeString(),
|
|
'error_occurred_at' => $record->error_occurred_at?->toDateTimeString(),
|
|
|
|
// Información del vehículo
|
|
'vehicle' => [
|
|
'id' => $record->vehicle->id,
|
|
'placa' => $record->vehicle->placa,
|
|
'niv' => $record->vehicle->niv,
|
|
'marca' => $record->vehicle->marca,
|
|
'modelo' => $record->vehicle->modelo,
|
|
'color' => $record->vehicle->color,
|
|
'clase_veh' => $record->vehicle->clase_veh,
|
|
],
|
|
|
|
// Error del catálogo
|
|
'error' => $record->error ? [
|
|
'id' => $record->error->id,
|
|
'code' => $record->error->code,
|
|
'description' => $record->error->description,
|
|
] : null,
|
|
|
|
// Respuesta completa de la API con el error
|
|
'api_response' => $record->api_response,
|
|
];
|
|
}),
|
|
'pagination' => [
|
|
'current_page' => $records->currentPage(),
|
|
'total_pages' => $records->lastPage(),
|
|
'total_records' => $records->total(),
|
|
'per_page' => $records->perPage(),
|
|
'from' => $records->firstItem(),
|
|
'to' => $records->lastItem(),
|
|
],
|
|
]);
|
|
}
|
|
}
|