feat: agregar soporte para la sustitución de tags en la búsqueda de registros de vehículos, correción excel general
This commit is contained in:
parent
525bcc0db7
commit
672b7dd735
@ -170,7 +170,7 @@ public function constanciasSustituidas(Request $request)
|
||||
$sheet->getStyle('B7')->getFont()->setBold(false)->setSize(14);
|
||||
|
||||
$sheet->mergeCells('C7:I7');
|
||||
$sheet->setCellValue('C7', strtoupper($module->name));
|
||||
$sheet->setCellValue('C7', mb_strtoupper($module->name, 'UTF-8'));
|
||||
$sheet->getStyle('C7:I7')->applyFromArray($styleBox);
|
||||
$sheet->getStyle('C7')->getFont()->setBold(true)->setSize(20);
|
||||
|
||||
@ -436,7 +436,7 @@ public function constanciasCanceladas(Request $request)
|
||||
$sheet->getStyle('A7')->getFont()->setBold(false)->setSize(14);
|
||||
|
||||
$sheet->mergeCells('D7:M7');
|
||||
$sheet->setCellValue('D7', strtoupper($module->name ?? 'TODOS LOS MÓDULOS'));
|
||||
$sheet->setCellValue('D7', mb_strtoupper($module->name ?? 'TODOS LOS MÓDULOS', 'UTF-8'));
|
||||
$sheet->getStyle('D7:M7')->applyFromArray($styleBox);
|
||||
$sheet->getStyle('D7')->getFont()->setBold(true)->setSize(20);
|
||||
|
||||
@ -558,20 +558,21 @@ public function constanciasCanceladas(Request $request)
|
||||
|
||||
public function excelGeneral(Request $request)
|
||||
{
|
||||
// 1. VALIDACIÓN Y OBTENCIÓN DE DATOS
|
||||
$request->validate([
|
||||
'fecha_inicio' => 'required|date',
|
||||
'fecha_fin' => 'required|date|after_or_equal:fecha_inicio',
|
||||
'module_id' => 'nullable|exists:modules,id',
|
||||
'fecha_fin' => 'required|date|after_or_equal:fecha_inicio',
|
||||
'module_id' => 'nullable|exists:modules,id',
|
||||
]);
|
||||
|
||||
$fechaInicio = Carbon::parse($request->fecha_inicio)->startOfDay();
|
||||
$fechaFin = Carbon::parse($request->fecha_fin)->endOfDay();
|
||||
$moduleId = $request->module_id;
|
||||
$fechaFin = Carbon::parse($request->fecha_fin)->endOfDay();
|
||||
$moduleId = $request->module_id;
|
||||
|
||||
// Obtener información del módulo
|
||||
$module = $moduleId ? Module::find($moduleId) : null;
|
||||
|
||||
// Obtener logs de cancelación en el rango de fechas
|
||||
// QUERY 1: VehicleTagLogs (Inscripciones, Sustituciones, Cancelaciones de Vehículo)
|
||||
$logs = VehicleTagLog::with([
|
||||
'vehicle.records.module',
|
||||
'tag',
|
||||
@ -588,7 +589,6 @@ public function excelGeneral(Request $request)
|
||||
->whereBetween('cancellation_at', [$fechaInicio, $fechaFin]);
|
||||
});
|
||||
})
|
||||
// DESPUÉS: Aplicar filtro de módulo
|
||||
->when($moduleId, function ($query) use ($moduleId) {
|
||||
$query->whereHas('vehicle.records', function ($q) use ($moduleId) {
|
||||
$q->where('module_id', $moduleId);
|
||||
@ -596,6 +596,7 @@ public function excelGeneral(Request $request)
|
||||
})
|
||||
->get();
|
||||
|
||||
//TagCancellationLogs (Cancelaciones de Tags sueltos)
|
||||
$logsT = TagCancellationLog::with([
|
||||
'tag.module',
|
||||
'tag.vehicle',
|
||||
@ -610,312 +611,262 @@ public function excelGeneral(Request $request)
|
||||
->get();
|
||||
|
||||
if ($logs->isEmpty() && $logsT->isEmpty()) {
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
'message' => 'No se encontraron registros en el periodo especificado',
|
||||
'fecha_inicio' => $fechaInicio->format('Y-m-d'),
|
||||
'fecha_fin' => $fechaFin->format('Y-m-d'),
|
||||
'module_id' => $moduleId,
|
||||
]);
|
||||
return response()->json(['message' => 'No se encontraron registros en el periodo especificado'], 404);
|
||||
}
|
||||
|
||||
// Unificación y Ordenamiento
|
||||
$allLogs = collect();
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$log->sort_date = $log->action_type == 'cancelacion' ? $log->cancellation_at : $log->created_at;
|
||||
$log->source_type = 'vehicle_log'; // Marcador auxiliar
|
||||
$allLogs->push($log);
|
||||
}
|
||||
|
||||
foreach ($logsT as $log) {
|
||||
$log->sort_date = $log->cancellation_at;
|
||||
$log->action_type = 'cancelacion'; // Normalizamos el tipo
|
||||
$log->source_type = 'tag_log'; // Marcador auxiliar
|
||||
$allLogs->push($log);
|
||||
}
|
||||
|
||||
$allLogs = $allLogs->sortBy('sort_date');
|
||||
|
||||
$data = $this->prepareExcelDataGeneral($allLogs);
|
||||
// 2. MAPEO DE DATOS (Normalización A-M)
|
||||
$data = $allLogs->map(function ($log) {
|
||||
// Determinar Vehículo
|
||||
$vehicle = $log->vehicle ?? $log->tag->vehicle ?? null;
|
||||
|
||||
$fileName = 'Reporte_General_' . $fechaInicio->format('Ymd') . '_' . $fechaFin->format('Ymd') . '.xlsx';
|
||||
// Determinar Nombre Módulo
|
||||
// Intentamos sacar el módulo del registro del vehículo o del tag
|
||||
$nombreModulo = 'S/N';
|
||||
if ($log->source_type == 'vehicle_log') {
|
||||
// Lógica aproximada: tomar el último módulo registrado o el actual
|
||||
$nombreModulo = $vehicle->records->last()->module->name ?? 'GENERAL';
|
||||
} else {
|
||||
$nombreModulo = $log->tag->module->name ?? 'GENERAL';
|
||||
}
|
||||
|
||||
// Formatear Acción
|
||||
$accion = ucfirst($log->action_type ?? 'Registro');
|
||||
|
||||
// Fechas
|
||||
$fecha = $log->sort_date ? Carbon::parse($log->sort_date)->format('d/m/Y') : '';
|
||||
|
||||
// Motivo
|
||||
$motivo = $log->cancellationReason->reason ?? $log->cancellationReason->name ?? '';
|
||||
if ($log->action_type == 'sustitucion') $motivo = 'SUSTITUCIÓN';
|
||||
if ($log->action_type == 'inscripcion') $motivo = 'INSCRIPCIÓN';
|
||||
if ($log->action_type == 'cancelacion' && empty($motivo)) $motivo = 'DAÑADA';
|
||||
|
||||
return [
|
||||
'modulo' => mb_strtoupper($nombreModulo, 'UTF-8'),
|
||||
'accion' => mb_strtoupper($accion, 'UTF-8'),
|
||||
'niv' => $vehicle->niv ?? '',
|
||||
'nrpv' => $vehicle->nrpv ?? '',
|
||||
'marca' => $vehicle->marca ?? '',
|
||||
'placa' => $vehicle->placa ?? '',
|
||||
'modelo' => $vehicle->modelo ?? '',
|
||||
'folio' => $log->tag->folio ?? $log->new_tag_folio ?? '',
|
||||
'chip' => $log->tag->rfid ?? '',
|
||||
'fecha' => $fecha,
|
||||
'motivo' => mb_strtoupper($motivo, 'UTF-8'),
|
||||
'observaciones' => $log->observations ?? ''
|
||||
];
|
||||
});
|
||||
|
||||
// 3. CONFIGURACIÓN EXCEL Y ESTILOS
|
||||
$fileName = 'Reporte_General_' . $fechaInicio->format('Ymd') . '.xlsx';
|
||||
$filePath = storage_path('app/temp/' . $fileName);
|
||||
|
||||
if (!file_exists(storage_path('app/temp'))) {
|
||||
mkdir(storage_path('app/temp'), 0755, true);
|
||||
}
|
||||
if (!file_exists(dirname($filePath))) mkdir(dirname($filePath), 0755, true);
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
// Fuente Global: Montserrat
|
||||
$sheet->getParent()->getDefaultStyle()->getFont()->setName('Montserrat');
|
||||
$sheet->getParent()->getDefaultStyle()->getFont()->setSize(10);
|
||||
|
||||
// Estilos Comunes
|
||||
$styleBox = [
|
||||
'borders' => ['allBorders' => ['borderStyle' => PhpSpreadsheetBorder::BORDER_THIN, 'color' => ['rgb' => '000000']]],
|
||||
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER]
|
||||
];
|
||||
$styleLabel = [
|
||||
'font' => ['size' => 14],
|
||||
'alignment' => ['horizontal' => Alignment::HORIZONTAL_RIGHT, 'vertical' => Alignment::VERTICAL_CENTER]
|
||||
];
|
||||
$styleTableHeader = [
|
||||
'font' => ['bold' => true, 'size' => 9, 'color' => ['rgb' => '000000']],
|
||||
'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => 'F2DCDB']],
|
||||
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER, 'wrapText' => true],
|
||||
'borders' => ['allBorders' => ['borderStyle' => PhpSpreadsheetBorder::BORDER_THIN]]
|
||||
];
|
||||
|
||||
// --- ESTRUCTURA DEL DOCUMENTO ---
|
||||
$sheet->getRowDimension(2)->setRowHeight(10);
|
||||
$sheet->getRowDimension(3)->setRowHeight(55); // Logo space
|
||||
$sheet->getRowDimension(5)->setRowHeight(30);
|
||||
$sheet->getRowDimension(7)->setRowHeight(38);
|
||||
$sheet->getRowDimension(9)->setRowHeight(30);
|
||||
|
||||
// LOGO
|
||||
$logoPath = storage_path('app/images/logo-seguridad.png');
|
||||
if (file_exists($logoPath)) {
|
||||
$drawing = new Drawing();
|
||||
$drawing->setName('Logo Seguridad');
|
||||
$drawing->setName('Logo');
|
||||
$drawing->setPath($logoPath);
|
||||
$drawing->setHeight(100);
|
||||
$drawing->setCoordinates('B1');
|
||||
$drawing->setHeight(55);
|
||||
$drawing->setCoordinates('B3');
|
||||
$drawing->setWorksheet($sheet);
|
||||
$sheet->getRowDimension(1)->setRowHeight(45);
|
||||
}
|
||||
|
||||
// Definir estilo de bordes
|
||||
$borderStyle = [
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => PhpSpreadsheetBorder::BORDER_THIN,
|
||||
'color' => ['rgb' => '000000'],
|
||||
],
|
||||
],
|
||||
];
|
||||
// --- BLOQUE DE INFORMACIÓN (Encabezado con Merges A-C) ---
|
||||
|
||||
$row = 5;
|
||||
// Fila 5: ENTIDAD
|
||||
$sheet->mergeCells('A5:C5');
|
||||
$sheet->setCellValue('A5', 'ENTIDAD:');
|
||||
$sheet->getStyle('A5')->applyFromArray($styleLabel);
|
||||
|
||||
// ENTIDAD
|
||||
$sheet->setCellValue('B' . $row, 'ENTIDAD:');
|
||||
$sheet->mergeCells('C' . $row . ':M' . $row);
|
||||
$sheet->setCellValue('C' . $row, 'TABASCO');
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(11);
|
||||
$sheet->getStyle('B' . $row . ':M' . $row)->applyFromArray($borderStyle);
|
||||
$sheet->getStyle('B' . $row . ':M' . $row)->getAlignment()->setWrapText(true);
|
||||
$row++;
|
||||
$sheet->mergeCells('D5:M5');
|
||||
$sheet->setCellValue('D5', 'TABASCO');
|
||||
$sheet->getStyle('D5:M5')->applyFromArray($styleBox);
|
||||
$sheet->getStyle('D5')->getFont()->setBold(true)->setSize(14);
|
||||
|
||||
// MÓDULO
|
||||
$sheet->setCellValue('B' . $row, 'MÓDULO:');
|
||||
$sheet->mergeCells('C' . $row . ':M' . $row);
|
||||
$sheet->setCellValue('C' . $row, $module?->name ?? 'TODOS LOS MÓDULOS');
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(11);
|
||||
$sheet->getStyle('B' . $row . ':M' . $row)->applyFromArray($borderStyle);
|
||||
$sheet->getStyle('B' . $row . ':M' . $row)->getAlignment()->setWrapText(true);
|
||||
$row++;
|
||||
// Fila 7: MÓDULO
|
||||
$sheet->mergeCells('A7:C7');
|
||||
$sheet->setCellValue('A7', 'MÓDULO:');
|
||||
$sheet->getStyle('A7')->applyFromArray($styleLabel);
|
||||
|
||||
// PERIODO
|
||||
$sheet->setCellValue('B' . $row, 'PERIODO A INFORMAR:');
|
||||
$sheet->mergeCells('C' . $row . ':M' . $row);
|
||||
$sheet->setCellValue('C' . $row, $fechaInicio->format('d/m/Y') . ' al ' . $fechaFin->format('d/m/Y'));
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(11);
|
||||
$sheet->getStyle('B' . $row . ':M' . $row)->applyFromArray($borderStyle);
|
||||
$sheet->getStyle('B' . $row . ':M' . $row)->getAlignment()->setWrapText(true);
|
||||
$row++;
|
||||
$sheet->mergeCells('D7:M7');
|
||||
$sheet->setCellValue('D7', mb_strtoupper($module->name ?? 'TODOS LOS MÓDULOS', 'UTF-8'));
|
||||
$sheet->getStyle('D7:M7')->applyFromArray($styleBox);
|
||||
$sheet->getStyle('D7')->getFont()->setBold(true)->setSize(20);
|
||||
|
||||
$row++;
|
||||
// Fila 9: PERIODO
|
||||
$sheet->mergeCells('A9:C9');
|
||||
$sheet->setCellValue('A9', 'PERIODO A INFORMAR:');
|
||||
$sheet->getStyle('A9')->applyFromArray($styleLabel);
|
||||
|
||||
// Título
|
||||
$sheet->mergeCells('B' . $row . ':M' . $row);
|
||||
$sheet->setCellValue('B' . $row, 'REPORTE GENERAL DE CONSTANCIAS');
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(12);
|
||||
$sheet->getStyle('B' . $row)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER)->setWrapText(true);
|
||||
$sheet->getStyle('B' . $row . ':M' . $row)->applyFromArray($borderStyle);
|
||||
$row++;
|
||||
Carbon::setLocale('es');
|
||||
$periodoTexto = 'del ' . $fechaInicio->format('d') . ' al ' . $fechaFin->format('d') . ' de ' . $fechaFin->translatedFormat('F');
|
||||
|
||||
$row++;
|
||||
// Fechas (D-G)
|
||||
$sheet->mergeCells('D9:G9');
|
||||
$sheet->setCellValue('D9', $periodoTexto);
|
||||
$sheet->getStyle('D9:G9')->applyFromArray($styleBox);
|
||||
$sheet->getStyle('D9')->getFont()->setSize(14);
|
||||
|
||||
// Encabezados (12 columnas: A-L)
|
||||
$headers = [
|
||||
'No.',
|
||||
'MÓDULO',
|
||||
'TIPO DE ACCIÓN',
|
||||
'NIV DEL VEHÍCULO',
|
||||
'NRPV/NCI',
|
||||
'MARCA DEL VEHÍCULO',
|
||||
'PLACA',
|
||||
'AÑO MODELO',
|
||||
'FOLIO',
|
||||
'ID DE LA CONSTANCIA (CHIP)',
|
||||
'FECHA',
|
||||
'MOTIVO/RAZÓN',
|
||||
'OBSERVACIONES',
|
||||
];
|
||||
// "de" (H)
|
||||
$sheet->setCellValue('H9', 'de');
|
||||
$sheet->getStyle('H9')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER)->setVertical(Alignment::VERTICAL_CENTER);
|
||||
$sheet->getStyle('H9')->getFont()->setSize(14);
|
||||
|
||||
$col = 'A';
|
||||
foreach ($headers as $header) {
|
||||
$sheet->setCellValue($col . $row, $header);
|
||||
$col++;
|
||||
}
|
||||
// Año (I-J)
|
||||
$sheet->mergeCells('I9:J9');
|
||||
$sheet->setCellValue('I9', $fechaFin->format('Y'));
|
||||
$sheet->getStyle('I9:J9')->applyFromArray($styleBox);
|
||||
$sheet->getStyle('I9')->getFont()->setSize(14);
|
||||
|
||||
$sheet->getStyle('A' . $row . ':M' . $row)->applyFromArray([
|
||||
'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF'], 'size' => 10],
|
||||
'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => '8B0000']],
|
||||
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER, 'wrapText' => true],
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => PhpSpreadsheetBorder::BORDER_THIN,
|
||||
'color' => ['rgb' => '000000'],
|
||||
],
|
||||
],
|
||||
|
||||
// --- TÍTULO Y BARRA ROJA ---
|
||||
$rowTitle = 11;
|
||||
$sheet->mergeCells("A{$rowTitle}:M{$rowTitle}");
|
||||
$sheet->setCellValue("A{$rowTitle}", 'REPORTE GENERAL DE CONSTANCIAS');
|
||||
$sheet->getStyle("A{$rowTitle}")->applyFromArray([
|
||||
'font' => ['bold' => true, 'color' => ['rgb' => '000000'], 'size' => 14],
|
||||
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER],
|
||||
]);
|
||||
$row++;
|
||||
$sheet->getRowDimension($rowTitle)->setRowHeight(25);
|
||||
|
||||
// Agregar datos
|
||||
foreach ($data as $rowData) {
|
||||
$col = 'A';
|
||||
foreach ($rowData as $value) {
|
||||
$sheet->setCellValue($col . $row, $value);
|
||||
$col++;
|
||||
}
|
||||
$sheet->getStyle('A' . $row . ':M' . $row)->applyFromArray([
|
||||
'font' => ['size' => 10],
|
||||
'alignment' => ['wrapText' => true],
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => PhpSpreadsheetBorder::BORDER_THIN,
|
||||
'color' => ['rgb' => '000000'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$row++;
|
||||
$rowRedBar = 13;
|
||||
$sheet->mergeCells("A{$rowRedBar}:M{$rowRedBar}");
|
||||
$sheet->getStyle("A{$rowRedBar}")->applyFromArray([
|
||||
'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => '900000']],
|
||||
]);
|
||||
$sheet->getRowDimension($rowRedBar)->setRowHeight(6);
|
||||
|
||||
|
||||
// --- ENCABEZADOS DE TABLA (A-M) ---
|
||||
$h = 14;
|
||||
$headers = [
|
||||
'A' => 'No.',
|
||||
'B' => 'MÓDULO',
|
||||
'C' => "TIPO DE\nACCIÓN",
|
||||
'D' => "NIV DEL\nVEHÍCULO",
|
||||
'E' => 'NRPV/NCI',
|
||||
'F' => "MARCA DEL\nVEHÍCULO",
|
||||
'G' => 'PLACA',
|
||||
'H' => "AÑO\nMODELO",
|
||||
'I' => 'FOLIO',
|
||||
'J' => "ID DE LA CONSTANCIA\n(CHIP)",
|
||||
'K' => 'FECHA',
|
||||
'L' => "MOTIVO/\nRAZÓN",
|
||||
'M' => 'OBSERVACIONES'
|
||||
];
|
||||
|
||||
foreach ($headers as $col => $text) {
|
||||
$sheet->setCellValue("{$col}{$h}", $text);
|
||||
}
|
||||
|
||||
// Ajustar anchos de columnas
|
||||
$sheet->getColumnDimension('A')->setWidth(6); // No.
|
||||
$sheet->getColumnDimension('B')->setWidth(25); // MÓDULO
|
||||
$sheet->getColumnDimension('C')->setWidth(18); // TIPO DE ACCIÓN
|
||||
$sheet->getColumnDimension('D')->setWidth(25); // NIV
|
||||
$sheet->getColumnDimension('E')->setWidth(15); // NRPV/NCI
|
||||
$sheet->getColumnDimension('F')->setWidth(20); // MARCA
|
||||
$sheet->getColumnDimension('G')->setWidth(12); // PLACA
|
||||
$sheet->getColumnDimension('H')->setWidth(12); // AÑO MODELO
|
||||
$sheet->getColumnDimension('I')->setWidth(25); // FOLIO
|
||||
$sheet->getColumnDimension('J')->setWidth(30); // CHIP
|
||||
$sheet->getColumnDimension('K')->setWidth(20); // FECHA
|
||||
$sheet->getColumnDimension('L')->setWidth(35); // MOTIVO/RAZÓN
|
||||
$sheet->getColumnDimension('M')->setWidth(50); // OBSERVACIONES
|
||||
$sheet->getStyle("A{$h}:M{$h}")->applyFromArray($styleTableHeader);
|
||||
$sheet->getRowDimension($h)->setRowHeight(35);
|
||||
|
||||
|
||||
// --- LLENADO DE DATOS ---
|
||||
$row = 15;
|
||||
$i = 1;
|
||||
|
||||
foreach ($data as $item) {
|
||||
$sheet->setCellValue('A' . $row, $i);
|
||||
$sheet->setCellValue('B' . $row, $item['modulo']);
|
||||
$sheet->setCellValue('C' . $row, $item['accion']);
|
||||
$sheet->setCellValue('D' . $row, $item['niv']);
|
||||
$sheet->setCellValue('E' . $row, $item['nrpv']);
|
||||
$sheet->setCellValue('F' . $row, $item['marca']);
|
||||
$sheet->setCellValue('G' . $row, $item['placa']);
|
||||
$sheet->setCellValue('H' . $row, $item['modelo']);
|
||||
$sheet->setCellValue('I' . $row, $item['folio']);
|
||||
$sheet->setCellValue('J' . $row, $item['chip']);
|
||||
$sheet->setCellValue('K' . $row, $item['fecha']);
|
||||
$sheet->setCellValue('L' . $row, $item['motivo']);
|
||||
$sheet->setCellValue('M' . $row, $item['observaciones']);
|
||||
|
||||
// Estilos de fila
|
||||
$sheet->getStyle("A{$row}:M{$row}")->applyFromArray([
|
||||
'borders' => ['allBorders' => ['borderStyle' => PhpSpreadsheetBorder::BORDER_THIN]],
|
||||
'alignment' => ['vertical' => Alignment::VERTICAL_CENTER, 'wrapText' => true],
|
||||
'font' => ['size' => 9]
|
||||
]);
|
||||
|
||||
// Centrados
|
||||
$sheet->getStyle("A{$row}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // No
|
||||
$sheet->getStyle("H{$row}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // Año
|
||||
$sheet->getStyle("I{$row}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // Folio
|
||||
$sheet->getStyle("K{$row}")->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // Fecha
|
||||
|
||||
$row++;
|
||||
$i++;
|
||||
}
|
||||
|
||||
// --- ANCHOS DE COLUMNA ---
|
||||
$sheet->getColumnDimension('A')->setWidth(5);
|
||||
$sheet->getColumnDimension('B')->setWidth(25);
|
||||
$sheet->getColumnDimension('C')->setWidth(18);
|
||||
$sheet->getColumnDimension('D')->setWidth(22); // NIV
|
||||
$sheet->getColumnDimension('E')->setWidth(15);
|
||||
$sheet->getColumnDimension('F')->setWidth(18);
|
||||
$sheet->getColumnDimension('G')->setWidth(12);
|
||||
$sheet->getColumnDimension('H')->setWidth(10);
|
||||
$sheet->getColumnDimension('I')->setWidth(15);
|
||||
$sheet->getColumnDimension('J')->setWidth(25); // Chip
|
||||
$sheet->getColumnDimension('K')->setWidth(14); // Fecha
|
||||
$sheet->getColumnDimension('L')->setWidth(20); // Motivo
|
||||
$sheet->getColumnDimension('M')->setWidth(30); // Obs
|
||||
|
||||
// Guardar archivo
|
||||
$writer = new Xlsx($spreadsheet);
|
||||
$writer->save($filePath);
|
||||
|
||||
// Descargar archivo y eliminarlo después
|
||||
return response()->download($filePath, $fileName)->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
private function prepareExcelDataGeneral($logs)
|
||||
{
|
||||
$data = [];
|
||||
$no = 1;
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$isVehicleTagLog = isset($log->action_type);
|
||||
|
||||
if ($isVehicleTagLog) {
|
||||
$vehicle = $log->vehicle;
|
||||
$tag = $log->tag;
|
||||
$actionType = strtoupper($log->action_type);
|
||||
|
||||
$moduleName = $vehicle->records->first()?->module?->name ?? 'SIN MODULO ASIGNADO';
|
||||
|
||||
$fecha = $log->action_type == 'cancelacion'
|
||||
? $log->cancellation_at?->format('d/m/Y')
|
||||
: $log->created_at->format('d/m/Y');
|
||||
|
||||
$motivo = match ($log->action_type) {
|
||||
'inscripcion' => 'INSCRIPCIÓN',
|
||||
'sustitucion' => 'SUSTITUCIÓN DE CONSTANCIA',
|
||||
'cancelacion' => $log->cancellationReason?->name ?? 'N/A',
|
||||
default => 'N/A',
|
||||
};
|
||||
|
||||
$data[] = [
|
||||
$no,
|
||||
$moduleName,
|
||||
$actionType,
|
||||
$vehicle->niv ?? 'N/A',
|
||||
$vehicle->nrpv ?? 'N/A',
|
||||
strtoupper($vehicle->marca ?? 'N/A'),
|
||||
strtoupper($vehicle->placa ?? 'N/A'),
|
||||
$vehicle->modelo ?? 'N/A',
|
||||
$tag->folio ?? 'N/A',
|
||||
$tag->tag_number ?? 'N/A',
|
||||
$fecha,
|
||||
$motivo,
|
||||
$log->cancellation_observations ?? 'N/A',
|
||||
];
|
||||
} else {
|
||||
|
||||
$vehicle = $log->tag->vehicle;
|
||||
$tag = $log->tag;
|
||||
$moduleName = $tag->module?->name ?? 'SIN MODULO ASIGNADO';
|
||||
|
||||
$data[] = [
|
||||
$no,
|
||||
$moduleName,
|
||||
'CANCELACION',
|
||||
$vehicle->niv ?? 'N/A',
|
||||
$vehicle->nrpv ?? 'N/A',
|
||||
strtoupper($vehicle->marca ?? 'N/A'),
|
||||
strtoupper($vehicle->placa ?? 'N/A'),
|
||||
$vehicle->modelo ?? 'N/A',
|
||||
$tag->folio ?? 'N/A',
|
||||
$tag->tag_number ?? 'N/A',
|
||||
$log->cancellation_at ? $log->cancellation_at->format('d/m/Y') : 'N/A',
|
||||
$log->cancellationReason?->name ?? 'CANCELACIÓN',
|
||||
$log->cancellation_observations ?? 'N/A',
|
||||
];
|
||||
}
|
||||
$no++;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function prepareExcelData($logs)
|
||||
{
|
||||
$data = [];
|
||||
$no = 1;
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$vehicle = $log->vehicle;
|
||||
$newTag = $log->tag;
|
||||
|
||||
// Extraer el folio anterior de las observaciones
|
||||
$folioAnterior = 'N/A';
|
||||
if ($log->cancellation_observations) {
|
||||
if (preg_match('/Folio:\s*([^)]+)/', $log->cancellation_observations, $matches)) {
|
||||
$folioAnterior = trim($matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$data[] = [
|
||||
$no,
|
||||
$vehicle->niv ?? 'N/A',
|
||||
$vehicle->nrpv ?? 'N/A',
|
||||
strtoupper($vehicle->marca ?? 'N/A'),
|
||||
strtoupper($vehicle->placa ?? 'N/A'),
|
||||
$vehicle->modelo ?? 'N/A',
|
||||
$folioAnterior,
|
||||
$newTag->folio ?? 'N/A',
|
||||
$newTag->tag_number ?? 'N/A',
|
||||
$log->created_at->format('d/m/Y'),
|
||||
$log->cancellation_observations ?? 'CONSTANCIA SUSTITUIDA',
|
||||
];
|
||||
|
||||
$no++;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function prepareExcelDataCanceladas($logs)
|
||||
{
|
||||
$data = [];
|
||||
$no = 1;
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$vehicle = $log->vehicle ?? $log->tag->vehicle;
|
||||
$tag = $log->tag;
|
||||
|
||||
$data[] = [
|
||||
$no,
|
||||
$vehicle->niv ?? 'N/A',
|
||||
$vehicle->nrpv ?? 'N/A',
|
||||
strtoupper($vehicle->marca ?? 'N/A'),
|
||||
strtoupper($vehicle->placa ?? 'N/A'),
|
||||
$vehicle->modelo ?? 'N/A',
|
||||
$tag->folio ?? 'N/A',
|
||||
$tag->tag_number ?? 'N/A',
|
||||
$log->cancellation_at ? $log->cancellation_at->format('d/m/Y') : 'N/A',
|
||||
$log->cancellationReason?->name ?? 'N/A',
|
||||
$log->cancellation_observations ?? 'CONSTANCIA CANCELADA',
|
||||
];
|
||||
|
||||
$no++;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,11 +397,39 @@ public function searchRecord(Request $request)
|
||||
$paginatedRecords->getCollection()->transform(function ($record) {
|
||||
$latestLog = $record->vehicle->vehicleTagLogs->first();
|
||||
|
||||
// Detectar si hubo sustitución y obtener datos del tag anterior
|
||||
$substitutionData = null;
|
||||
|
||||
// Buscar si existe ALGÚN log de sustitución (no solo el último)
|
||||
$substitutionLogs = $record->vehicle->vehicleTagLogs
|
||||
->where('action_type', 'sustitucion')
|
||||
->sortBy('id')
|
||||
->take(2);
|
||||
|
||||
if ($substitutionLogs->count() >= 2) {
|
||||
$oldTagLog = $substitutionLogs->first(); // Tag cancelado
|
||||
$newTagLog = $substitutionLogs->last(); // Tag nuevo
|
||||
|
||||
$substitutionData = [
|
||||
'old_folio' => $oldTagLog->tag?->folio ?? null,
|
||||
'old_tag_number' => $oldTagLog->tag?->tag_number ?? null,
|
||||
'new_folio' => $newTagLog->tag?->folio ?? $record->folio,
|
||||
'new_tag_number' => $newTagLog->tag?->tag_number ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $record->id,
|
||||
'folio' => $record->folio,
|
||||
'created_at' => $record->created_at,
|
||||
|
||||
// TIPO DE TRÁMITE
|
||||
'action_type' => $latestLog?->action_type ?? 'inscripcion',
|
||||
'action_date' => $latestLog?->created_at ?? $record->created_at,
|
||||
|
||||
// SUSTITUCIÓN
|
||||
'substitution' => $substitutionData,
|
||||
|
||||
// MÓDULO
|
||||
'module' => $record->module ? [
|
||||
'id' => $record->module->id,
|
||||
@ -415,12 +443,53 @@ public function searchRecord(Request $request)
|
||||
'email' => $record->user->email,
|
||||
] : null,
|
||||
|
||||
// TIPO DE TRÁMITE
|
||||
'action_type' => $latestLog?->action_type ?? 'inscripcion',
|
||||
'action_date' => $latestLog?->created_at ?? $record->created_at,
|
||||
// VEHÍCULO
|
||||
'vehicle' => [
|
||||
'id' => $record->vehicle->id,
|
||||
'placa' => $record->vehicle->placa,
|
||||
'niv' => $record->vehicle->niv,
|
||||
'marca' => $record->vehicle->marca,
|
||||
'linea' => $record->vehicle->linea,
|
||||
'sublinea' => $record->vehicle->sublinea,
|
||||
'modelo' => $record->vehicle->modelo,
|
||||
'color' => $record->vehicle->color,
|
||||
'numero_motor' => $record->vehicle->numero_motor,
|
||||
'clase_veh' => $record->vehicle->clase_veh,
|
||||
'tipo_servicio' => $record->vehicle->tipo_servicio,
|
||||
'rfv' => $record->vehicle->rfv,
|
||||
'nrpv' => $record->vehicle->nrpv,
|
||||
'reporte_robo' => $record->vehicle->reporte_robo,
|
||||
|
||||
// Vehículo
|
||||
'vehicle' => $record->vehicle,
|
||||
// PROPIETARIO
|
||||
'owner' => $record->vehicle->owner ? [
|
||||
'id' => $record->vehicle->owner->id,
|
||||
'name' => $record->vehicle->owner->name,
|
||||
'paternal' => $record->vehicle->owner->paternal,
|
||||
'maternal' => $record->vehicle->owner->maternal,
|
||||
'full_name' => $record->vehicle->owner->full_name,
|
||||
'rfc' => $record->vehicle->owner->rfc,
|
||||
'curp' => $record->vehicle->owner->curp,
|
||||
'telefono' => $record->vehicle->owner->telefono,
|
||||
'address' => $record->vehicle->owner->address,
|
||||
] : null,
|
||||
|
||||
// TAG ACTUAL
|
||||
'tag' => $record->vehicle->tag ? [
|
||||
'id' => $record->vehicle->tag->id,
|
||||
'folio' => $record->vehicle->tag->folio,
|
||||
'tag_number' => $record->vehicle->tag->tag_number,
|
||||
'status' => $record->vehicle->tag->status ? [
|
||||
'id' => $record->vehicle->tag->status->id,
|
||||
'code' => $record->vehicle->tag->status->code,
|
||||
'name' => $record->vehicle->tag->status->name,
|
||||
] : null,
|
||||
'package' => $record->vehicle->tag->package ? [
|
||||
'id' => $record->vehicle->tag->package->id,
|
||||
'lot' => $record->vehicle->tag->package->lot,
|
||||
'box_number' => $record->vehicle->tag->package->box_number,
|
||||
] : null,
|
||||
] : null,
|
||||
],
|
||||
|
||||
// Archivos
|
||||
'files' => $record->files->map(function ($file) {
|
||||
@ -444,7 +513,6 @@ public function searchRecord(Request $request)
|
||||
'api_response' => $record->api_response,
|
||||
];
|
||||
});
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'records' => $paginatedRecords
|
||||
]);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user