Fix: Correciones de cancelacion y logs, creación del excel tag sustituidos
This commit is contained in:
parent
975c6863ff
commit
f25901ed9d
@ -5,6 +5,7 @@
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Repuve\CancelConstanciaRequest;
|
||||
use App\Models\Record;
|
||||
use App\Models\Tag;
|
||||
use App\Models\VehicleTagLog;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@ -49,23 +50,73 @@ public function cancelarConstancia(CancelConstanciaRequest $request)
|
||||
]);
|
||||
}
|
||||
|
||||
// Crear registro en el log de cancelaciones
|
||||
// Guardar información del tag anterior ANTES de cancelarlo
|
||||
$oldTagNumber = $tag->tag_number;
|
||||
$oldFolio = $tag->folio;
|
||||
|
||||
// Crear registro en el log de vehiculos
|
||||
$cancellationLog = VehicleTagLog::create([
|
||||
'vehicle_id' => $vehicle->id,
|
||||
'tag_id' => $tag->id,
|
||||
'action_type' => 'cancelacion',
|
||||
'cancellation_reason' => $request->cancellation_reason,
|
||||
'cancellation_observations' => $request->cancellation_observations,
|
||||
'cancellation_at' => now(),
|
||||
'cancelled_by' => Auth::id(),
|
||||
'performed_by' => Auth::id(),
|
||||
]);
|
||||
|
||||
// Actualizar estado del tag a 'cancelled' y desasignar vehículo
|
||||
$tag->markAsCancelled();
|
||||
|
||||
$newTag = null;
|
||||
$substitutionLog = null;
|
||||
$isSubstitution = $request->filled('new_tag_number');
|
||||
|
||||
if ($isSubstitution) {
|
||||
$newTag = Tag::where('tag_number', $request->new_tag_number)->first();
|
||||
|
||||
if(!$newTag){
|
||||
DB::rollBack();
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
'message' => 'El nuevo tag proporcionado no existe.',
|
||||
'new_tag_number' => $request->new_tag_number,
|
||||
]);
|
||||
}
|
||||
|
||||
if(!$newTag->isAvailable()) {
|
||||
DB::rollBack();
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
'message' => 'El nuevo tag no está disponible para asignación',
|
||||
'new_tag_number' => $request->new_tag_number,
|
||||
'current_status' => $newTag->status->name,
|
||||
]);
|
||||
}
|
||||
|
||||
// Usar el folio del NUEVO TAG
|
||||
$newTag->markAsAssigned($vehicle->id, $newTag->folio);
|
||||
|
||||
$substitutionLog = VehicleTagLog::create([
|
||||
'vehicle_id' => $vehicle->id,
|
||||
'tag_id' => $newTag->id,
|
||||
'action_type' => 'sustitucion',
|
||||
'cancellation_reason' => $request->cancellation_reason,
|
||||
'cancellation_observations' => 'Tag sustituido. Tag anterior: ' . $oldTagNumber . 'Motivo: ' . ($request->cancellation_observations ?? ''),
|
||||
'performed_by' => Auth::id(),
|
||||
]);
|
||||
|
||||
$record->update(['folio' => $newTag->folio]);
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
$message = $isSubstitution
|
||||
? 'Tag cancelado y sustituido exitosamente'
|
||||
: 'Constancia cancelada exitosamente';
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'message' => 'Constancia cancelada exitosamente',
|
||||
'message' => $message,
|
||||
'is_substitution' => $isSubstitution,
|
||||
'cancellation' => [
|
||||
'id' => $cancellationLog->id,
|
||||
'vehicle' => [
|
||||
@ -73,12 +124,18 @@ public function cancelarConstancia(CancelConstanciaRequest $request)
|
||||
'placa' => $vehicle->placa,
|
||||
'niv' => $vehicle->niv,
|
||||
],
|
||||
'tag' => [
|
||||
'old_tag' => [
|
||||
'id' => $tag->id,
|
||||
'folio' => $tag->folio,
|
||||
'old_status' => $tag->status->name,
|
||||
'tag_number' => $tag->tag_number,
|
||||
'new_status' => 'Cancelado',
|
||||
],
|
||||
'new_tag' => $newTag ? [
|
||||
'id' => $newTag->id,
|
||||
'folio' => $newTag->folio,
|
||||
'tag_number' => $newTag->tag_number,
|
||||
'status' => $newTag->status->name,
|
||||
] : null,
|
||||
'cancellation_reason' => $request->cancellation_reason,
|
||||
'cancellation_observations' => $request->cancellation_observations,
|
||||
'cancelled_at' => $cancellationLog->cancellation_at->toDateTimeString(),
|
||||
|
||||
262
app/Http/Controllers/Repuve/ExcelController.php
Normal file
262
app/Http/Controllers/Repuve/ExcelController.php
Normal file
@ -0,0 +1,262 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Repuve;
|
||||
|
||||
/**
|
||||
* @copyright (c) 2025 Notsoweb Software (https://notsoweb.com) - All Rights Reserved
|
||||
*/
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\VehicleTagLog;
|
||||
use App\Models\Tag;
|
||||
use App\Models\Module;
|
||||
use Carbon\Carbon;
|
||||
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border as PhpSpreadsheetBorder;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
|
||||
|
||||
|
||||
/**
|
||||
* Descripción
|
||||
*/
|
||||
class ExcelController extends Controller
|
||||
{
|
||||
public function constanciasSustituidas(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'fecha_inicio' => 'required|date',
|
||||
'fecha_fin' => 'required|date|after_or_equal:fecha_inicio',
|
||||
'module_id' => 'required|exists:modules,id',
|
||||
]);
|
||||
|
||||
$fechaInicio = Carbon::parse($request->fecha_inicio)->startOfDay();
|
||||
$fechaFin = Carbon::parse($request->fecha_fin)->endOfDay();
|
||||
$moduleId = $request->module_id;
|
||||
|
||||
// Obtener información del módulo
|
||||
$module = Module::findOrFail($moduleId);
|
||||
|
||||
// Obtener logs de sustitución en el rango de fechas
|
||||
$logs = VehicleTagLog::with([
|
||||
'vehicle',
|
||||
'tag',
|
||||
])
|
||||
->where('action_type', 'sustitucion')
|
||||
->whereHas('vehicle.records', function ($query) use ($moduleId) {
|
||||
$query->where('module_id', $moduleId);
|
||||
})
|
||||
->whereBetween('created_at', [$fechaInicio, $fechaFin])
|
||||
->orderBy('created_at', 'asc')
|
||||
->get();
|
||||
|
||||
if ($logs->isEmpty()) {
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
'message' => 'No se encontraron constancias sustituidas en el periodo especificado',
|
||||
'fecha_inicio' => $fechaInicio->format('Y-m-d'),
|
||||
'fecha_fin' => $fechaFin->format('Y-m-d'),
|
||||
'module_id' => $moduleId,
|
||||
]);
|
||||
}
|
||||
|
||||
// Preparar datos para el Excel
|
||||
$data = $this->prepareExcelData($logs);
|
||||
|
||||
// Generar archivo Excel
|
||||
$fileName = 'Constancias_Sustituidas_' . $fechaInicio->format('Ymd') . '_' . $fechaFin->format('Ymd') . '.xlsx';
|
||||
$filePath = storage_path('app/temp/' . $fileName);
|
||||
|
||||
// Crear directorio temporal si no existe
|
||||
if (!file_exists(storage_path('app/temp'))) {
|
||||
mkdir(storage_path('app/temp'), 0755, true);
|
||||
}
|
||||
|
||||
// Crear Excel
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
// Agregar logo
|
||||
$logoPath = storage_path('app/images/logo-seguridad.png');
|
||||
if (file_exists($logoPath)) {
|
||||
$drawing = new Drawing();
|
||||
$drawing->setName('Logo Seguridad');
|
||||
$drawing->setDescription('Logo Seguridad Pública');
|
||||
$drawing->setPath($logoPath);
|
||||
$drawing->setHeight(100); // Altura del logo en pixeles
|
||||
$drawing->setCoordinates('B1'); // Posición del logo
|
||||
$drawing->setWorksheet($sheet);
|
||||
|
||||
// Ajustar altura de las filas del logo
|
||||
$sheet->getRowDimension(1)->setRowHeight(45);
|
||||
}
|
||||
|
||||
// Definir estilo de bordes
|
||||
$borderStyle = [
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => PhpSpreadsheetBorder::BORDER_THIN,
|
||||
'color' => ['rgb' => '000000'],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// Empezar después del logo
|
||||
$row = 5;
|
||||
|
||||
// Fila 1: ENTIDAD (empieza en B)
|
||||
$sheet->setCellValue('B' . $row, 'ENTIDAD:');
|
||||
$sheet->mergeCells('C' . $row . ':K' . $row);
|
||||
$sheet->setCellValue('C' . $row, 'TABASCO');
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(11);
|
||||
$sheet->getStyle('B' . $row . ':K' . $row)->applyFromArray($borderStyle);
|
||||
$sheet->getStyle('B' . $row . ':K' . $row)->getAlignment()->setWrapText(true);
|
||||
$row++;
|
||||
|
||||
// Fila 2: MÓDULO (empieza en B)
|
||||
$sheet->setCellValue('B' . $row, 'MÓDULO:');
|
||||
$sheet->mergeCells('C' . $row . ':K' . $row);
|
||||
$sheet->setCellValue('C' . $row, $module->name ?? 'MÓDULO 1. BASE 4');
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(11);
|
||||
$sheet->getStyle('B' . $row . ':K' . $row)->applyFromArray($borderStyle);
|
||||
$sheet->getStyle('B' . $row . ':K' . $row)->getAlignment()->setWrapText(true);
|
||||
$row++;
|
||||
|
||||
// Fila 3: PERIODO A INFORMAR (empieza en B, fecha completa con año)
|
||||
$sheet->setCellValue('B' . $row, 'PERIODO A INFORMAR:');
|
||||
$sheet->mergeCells('C' . $row . ':K' . $row);
|
||||
$sheet->setCellValue('C' . $row, 'del ' . $fechaInicio->format('d') . ' al ' . $fechaFin->format('d') . ' de ' . $fechaInicio->translatedFormat('F') . ' de ' . $fechaInicio->year);
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(11);
|
||||
$sheet->getStyle('B' . $row . ':K' . $row)->applyFromArray($borderStyle);
|
||||
$sheet->getStyle('B' . $row . ':K' . $row)->getAlignment()->setWrapText(true);
|
||||
$row++;
|
||||
|
||||
// Fila vacía
|
||||
$row++;
|
||||
|
||||
// Título: CONSTANCIAS SUSTITUIDAS (combinada B:K)
|
||||
$sheet->mergeCells('B' . $row . ':K' . $row);
|
||||
$sheet->setCellValue('B' . $row, 'CONSTANCIAS SUSTITUIDAS');
|
||||
$sheet->getStyle('B' . $row)->getFont()->setBold(true)->setSize(12);
|
||||
$sheet->getStyle('B' . $row)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER)->setWrapText(true);
|
||||
$sheet->getStyle('B' . $row . ':K' . $row)->applyFromArray($borderStyle);
|
||||
$row++;
|
||||
|
||||
// Fila vacía
|
||||
$row++;
|
||||
|
||||
// Encabezados de la tabla
|
||||
$headers = [
|
||||
'No.',
|
||||
'NIV DEL VEHÍCULO',
|
||||
'NRPV/NCI',
|
||||
'MARCA DEL VEHÍCULO',
|
||||
'PLACA',
|
||||
'AÑO MODELO',
|
||||
'FOLIO ANTERIOR',
|
||||
'FOLIO ACTUAL',
|
||||
'ID DE LA CONSTANCIA (CHIP)',
|
||||
'FECHA DE REEMPLAZO',
|
||||
'OBSERVACIONES (MOTIVO DEL REEMPLAZO)',
|
||||
];
|
||||
|
||||
$col = 'A';
|
||||
foreach ($headers as $header) {
|
||||
$sheet->setCellValue($col . $row, $header);
|
||||
$col++;
|
||||
}
|
||||
|
||||
$sheet->getStyle('A' . $row . ':K' . $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'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$row++;
|
||||
|
||||
// Agregar datos
|
||||
foreach ($data as $rowData) {
|
||||
$col = 'A';
|
||||
foreach ($rowData as $value) {
|
||||
$sheet->setCellValue($col . $row, $value);
|
||||
$col++;
|
||||
}
|
||||
$sheet->getStyle('A' . $row . ':K' . $row)->applyFromArray([
|
||||
'font' => ['size' => 10],
|
||||
'alignment' => ['wrapText' => true],
|
||||
'borders' => [
|
||||
'allBorders' => [
|
||||
'borderStyle' => PhpSpreadsheetBorder::BORDER_THIN,
|
||||
'color' => ['rgb' => '000000'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$row++;
|
||||
}
|
||||
|
||||
// Ajustar anchos de columnas
|
||||
$sheet->getColumnDimension('A')->setWidth(6);
|
||||
$sheet->getColumnDimension('B')->setWidth(25);
|
||||
$sheet->getColumnDimension('C')->setWidth(15);
|
||||
$sheet->getColumnDimension('D')->setWidth(20);
|
||||
$sheet->getColumnDimension('E')->setWidth(12);
|
||||
$sheet->getColumnDimension('F')->setWidth(15);
|
||||
$sheet->getColumnDimension('G')->setWidth(18);
|
||||
$sheet->getColumnDimension('H')->setWidth(18);
|
||||
$sheet->getColumnDimension('I')->setWidth(30);
|
||||
$sheet->getColumnDimension('J')->setWidth(20);
|
||||
$sheet->getColumnDimension('K')->setWidth(50);
|
||||
|
||||
// Guardar archivo
|
||||
$writer = new Xlsx($spreadsheet);
|
||||
$writer->save($filePath);
|
||||
|
||||
// Descargar archivo y eliminarlo después
|
||||
return response()->download($filePath, $fileName)->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
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 DAÑADA',
|
||||
];
|
||||
|
||||
$no++;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,7 @@
|
||||
use App\Models\File;
|
||||
use App\Models\Tag;
|
||||
use App\Models\Error;
|
||||
use App\Models\VehicleTagLog;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Services\RepuveService;
|
||||
@ -129,6 +130,13 @@ public function vehicleInscription(VehicleStoreRequest $request)
|
||||
// Asignar Tag al vehículo
|
||||
$tag->markAsAssigned($vehicle->id, $folio);
|
||||
|
||||
VehicleTagLog::create([
|
||||
'vehicle_id' => $vehicle->id,
|
||||
'tag_id' => $tag->id,
|
||||
'action_type' => 'inscripcion',
|
||||
'performed_by' => Auth::id(),
|
||||
]);
|
||||
|
||||
// Crear registro
|
||||
$record = Record::create([
|
||||
'folio' => $folio,
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
use App\Models\Owner;
|
||||
use App\Models\Error;
|
||||
use App\Models\CatalogNameImg;
|
||||
use App\Models\Tag;
|
||||
use App\Models\VehicleTagLog;
|
||||
use App\Services\RepuveService;
|
||||
use App\Services\PadronEstatalService;
|
||||
@ -64,16 +63,16 @@ public function vehicleData(Request $request)
|
||||
'user:id,name,email',
|
||||
'error:id,code,description'
|
||||
])
|
||||
->select([
|
||||
'id',
|
||||
'folio',
|
||||
'vehicle_id',
|
||||
'user_id',
|
||||
'error_id',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
])->where('folio', $folio)
|
||||
->first();
|
||||
->select([
|
||||
'id',
|
||||
'folio',
|
||||
'vehicle_id',
|
||||
'user_id',
|
||||
'error_id',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
])->where('folio', $folio)
|
||||
->first();
|
||||
|
||||
if (!$record) {
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
@ -158,28 +157,15 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
}
|
||||
|
||||
$vehicle = $record->vehicle;
|
||||
$currentTag = $vehicle->tag;
|
||||
$newTag = Tag::where('tag_number', $tagNumber)->first();
|
||||
$tag = $vehicle->tag;
|
||||
|
||||
if (!$newTag) {
|
||||
if (!$tag) {
|
||||
return ApiResponse::NOT_FOUND->response([
|
||||
'message' => 'No se encontró el tag con el tag_number proporcionado',
|
||||
'tag_number' => $tagNumber,
|
||||
]);
|
||||
}
|
||||
|
||||
$isTagReplacement = false;
|
||||
if($currentTag && $currentTag->id !== $newTag->id) {
|
||||
if(!$newTag->isAvailable()) {
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
'message' => 'El tag proporcionado no está disponible para asignación',
|
||||
'tag_number' => $tagNumber,
|
||||
'current_status' => $newTag->status->name,
|
||||
]);
|
||||
}
|
||||
$isTagReplacement = true;
|
||||
}
|
||||
|
||||
if ($vehicle->niv !== $niv) {
|
||||
return ApiResponse::BAD_REQUEST->response([
|
||||
'message' => 'El NIV no coincide con el registrado en el expediente',
|
||||
@ -257,26 +243,6 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
]);
|
||||
}
|
||||
|
||||
$tagReplacementLog = null;
|
||||
if($isTagReplacement) {
|
||||
$tagReplacementLog = VehicleTagLog::create([
|
||||
'vehicle_id' => $vehicle->id,
|
||||
'tag_id' => $currentTag->id,
|
||||
'cancellation_reason' => 'Otro',
|
||||
'cancellation_observations' => 'Reemplazo automático al actualizar datos del vehículo: '. $newTag->tag_number,
|
||||
'cancellation_at' => now(),
|
||||
'cancelled_by' => Auth::id(),
|
||||
]);
|
||||
|
||||
$currentTag->markAsCancelled();
|
||||
|
||||
$newTag->markAsAssigned($vehicle->id, $folio);
|
||||
|
||||
$tag = $newTag;
|
||||
}else{
|
||||
$tag = $currentTag;
|
||||
}
|
||||
|
||||
$uploadedFiles = [];
|
||||
$replacedFiles = [];
|
||||
|
||||
@ -346,8 +312,17 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) {
|
||||
VehicleTagLog::create([
|
||||
'vehicle_id' => $vehicle->id,
|
||||
'tag_id' => $tag->id,
|
||||
'action_type' => 'actualizacion',
|
||||
'performed_by' => Auth::id(),
|
||||
]);
|
||||
}
|
||||
|
||||
// Solo enviar a REPUVE Nacional si hay cambios
|
||||
if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0|| $isTagReplacement) {
|
||||
if ($hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0) {
|
||||
//Envio de datos
|
||||
$apiResponse = $this->sendToRepuveNacional($niv);
|
||||
$apiResponse["repuve_response"]["folio_ci"] = $record->folio;
|
||||
@ -411,15 +386,17 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
|
||||
DB::commit();
|
||||
|
||||
$sentToRepuve = $hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0 || $isTagReplacement;
|
||||
$sentToRepuve = $hasVehicleChanges || $hasOwnerChanges || count($uploadedFiles) > 0;
|
||||
|
||||
$message = 'Vehículo actualizado exitosamente';
|
||||
if (!$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles)) {
|
||||
$message = 'No se detectaron cambios. Los datos ya estaban actualizados.';
|
||||
} elseif (!$hasVehicleChanges && !$hasOwnerChanges && !$isTagReplacement) {
|
||||
} elseif (!$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles)) {
|
||||
$message = 'Solo se actualizaron archivos. Los datos del vehículo/propietario no cambiaron.';
|
||||
} elseif ($isTagReplacement && !$hasVehicleChanges && !$hasOwnerChanges && empty($uploadedFiles)) {
|
||||
$message = 'Tag reemplazado exitosamente. Los datos del vehículo/propietario no cambiaron.';
|
||||
} elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles)) {
|
||||
$message = 'Datos del vehículo/propietario actualizados exitosamente. No se subieron archivos.';
|
||||
} elseif ((!$hasVehicleChanges && !$hasOwnerChanges) && !empty($uploadedFiles)) {
|
||||
$message = 'Archivos subidos exitosamente. No hubo cambios en los datos del vehículo/propietario.';
|
||||
}
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
@ -430,20 +407,7 @@ public function vehicleUpdate(VehicleUpdateRequest $request)
|
||||
'vehicle_updated' => $hasVehicleChanges,
|
||||
'owner_updated' => $hasOwnerChanges,
|
||||
'files_uploaded' => count($uploadedFiles) > 0,
|
||||
'tag_replaced' => $isTagReplacement,
|
||||
],
|
||||
'tag_replacement' => $isTagReplacement ? [
|
||||
'old_tag' => [
|
||||
'id' => $currentTag->id,
|
||||
'tag_number' => $currentTag->tag_number,
|
||||
'status' => $currentTag->status->name,
|
||||
],
|
||||
'new_tag' => [
|
||||
'id' => $newTag->id,
|
||||
'tag_number' => $newTag->tag_number,
|
||||
'status' => $newTag->status->name,
|
||||
],
|
||||
] : null,
|
||||
'record' => [
|
||||
'id' => $record->id,
|
||||
'folio' => $record->folio,
|
||||
|
||||
@ -20,9 +20,10 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'record_id' => 'required|integer|exists:records,id',
|
||||
'record_id' => 'required|exists:records,id',
|
||||
'cancellation_reason' => 'required|in:fallo_lectura_handheld,cambio_parabrisas,roto_al_pegarlo,extravio,otro',
|
||||
'cancellation_observations' => 'nullable|string|max:1000',
|
||||
'cancellation_observations' => 'nullable|string',
|
||||
'new_tag_number' => 'nullable|exists:tags,tag_number',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'record_id' => ['required', 'integer', 'exists:records,id'],
|
||||
'files' => ['nullable', 'array', 'min:1'],
|
||||
'files.*' => ['file', 'mimes:jpeg,png,jpg,pdf', 'max:10240'],
|
||||
'names' => ['nullable', 'array'],
|
||||
@ -24,8 +23,6 @@ public function rules(): array
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'record_id.required' => 'El id del expediente es requerido',
|
||||
'record_id.exists' => 'El expediente no existe en el sistema',
|
||||
'files.*.mimes' => 'Solo se permiten archivos JPG, PNG o JPEG',
|
||||
'files.*.max' => 'El archivo no debe superar 3MB',
|
||||
];
|
||||
|
||||
@ -72,6 +72,7 @@ public function markAsCancelled(): void
|
||||
$this->update([
|
||||
'status_id' => $statusCancelled->id,
|
||||
'vehicle_id' => null,
|
||||
'folio' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -14,10 +14,12 @@ class VehicleTagLog extends Model
|
||||
protected $fillable = [
|
||||
'vehicle_id',
|
||||
'tag_id',
|
||||
'action_type',
|
||||
'cancellation_reason',
|
||||
'cancellation_observations',
|
||||
'cancellation_at',
|
||||
'cancelled_by',
|
||||
'performed_by',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
@ -39,4 +41,24 @@ public function cancelledBy() {
|
||||
return $this->belongsTo(User::class, 'cancelled_by');
|
||||
}
|
||||
|
||||
public function isInscription()
|
||||
{
|
||||
return $this->action_type === 'inscripcion';
|
||||
}
|
||||
|
||||
public function isUpdate()
|
||||
{
|
||||
return $this->action_type === 'actualizacion';
|
||||
}
|
||||
|
||||
public function isSubstitution()
|
||||
{
|
||||
return $this->action_type === 'sustitucion';
|
||||
}
|
||||
|
||||
public function isCancellation()
|
||||
{
|
||||
return $this->action_type === 'cancelacion';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ private function consultarPadron(string $tipo, string $valor): array
|
||||
curl_close($ch);
|
||||
|
||||
if ($error) {
|
||||
throw new Exception("Error en la petición SOAP al padrón estatal: {$error}");
|
||||
throw new Exception("Error en la petición al padrón estatal: {$error}");
|
||||
}
|
||||
|
||||
if ($httpCode !== 200) {
|
||||
@ -86,7 +86,7 @@ private function parsearRespuesta(string $soapResponse): array
|
||||
preg_match('/<result>(.*?)<\/result>/s', $soapResponse, $matches);
|
||||
|
||||
if (!isset($matches[1])) {
|
||||
throw new Exception("No se pudo extraer el resultado del SOAP del padrón estatal");
|
||||
throw new Exception("No se pudo extraer el resultado del padrón estatal");
|
||||
}
|
||||
|
||||
$jsonContent = trim($matches[1]);
|
||||
|
||||
@ -16,8 +16,10 @@
|
||||
"laravel/tinker": "^2.10",
|
||||
"milon/barcode": "^12.0",
|
||||
"notsoweb/laravel-core": "dev-main",
|
||||
"phpoffice/phpspreadsheet": "*",
|
||||
"setasign/fpdf": "^1.8",
|
||||
"spatie/laravel-permission": "^6.16",
|
||||
"spatie/simple-excel": "^3.8",
|
||||
"tightenco/ziggy": "^2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
526
composer.lock
generated
526
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ddec2d00c4e2c1ad362c8e28c77eb079",
|
||||
"content-hash": "7a79a1a1e064bf49d5a8cfcf7ee4c69c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "barryvdh/laravel-dompdf",
|
||||
@ -397,6 +397,85 @@
|
||||
},
|
||||
"time": "2025-03-14T15:54:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<1.11.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.12 || ^2",
|
||||
"phpstan/phpstan-strict-rules": "^1 || ^2",
|
||||
"phpunit/phpunit": "^8 || ^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Pcre\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||
"keywords": [
|
||||
"PCRE",
|
||||
"preg",
|
||||
"regex",
|
||||
"regular expression"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-12T16:29:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "defuse/php-encryption",
|
||||
"version": "v2.4.0",
|
||||
@ -3258,6 +3337,191 @@
|
||||
],
|
||||
"time": "2025-07-17T05:12:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maennchen/zipstream-php",
|
||||
"version": "3.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/maennchen/ZipStream-PHP.git",
|
||||
"reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/9712d8fa4cdf9240380b01eb4be55ad8dcf71416",
|
||||
"reference": "9712d8fa4cdf9240380b01eb4be55ad8dcf71416",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"ext-zlib": "*",
|
||||
"php-64bit": "^8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"brianium/paratest": "^7.7",
|
||||
"ext-zip": "*",
|
||||
"friendsofphp/php-cs-fixer": "^3.16",
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"php-coveralls/php-coveralls": "^2.5",
|
||||
"phpunit/phpunit": "^12.0",
|
||||
"vimeo/psalm": "^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"guzzlehttp/psr7": "^2.4",
|
||||
"psr/http-message": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ZipStream\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paul Duncan",
|
||||
"email": "pabs@pablotron.org"
|
||||
},
|
||||
{
|
||||
"name": "Jonatan Männchen",
|
||||
"email": "jonatan@maennchen.ch"
|
||||
},
|
||||
{
|
||||
"name": "Jesse Donat",
|
||||
"email": "donatj@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "András Kolesár",
|
||||
"email": "kolesar@kolesar.hu"
|
||||
}
|
||||
],
|
||||
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
|
||||
"keywords": [
|
||||
"stream",
|
||||
"zip"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
|
||||
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/maennchen",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-17T11:15:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"version": "3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"keywords": [
|
||||
"complex",
|
||||
"mathematics"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
|
||||
},
|
||||
"time": "2022-12-06T16:21:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/matrix",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phploc/phploc": "^4.0",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"sebastian/phpcpd": "^4.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Matrix\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@demon-angel.eu"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with matrices",
|
||||
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||
"keywords": [
|
||||
"mathematics",
|
||||
"matrix",
|
||||
"vector"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
|
||||
},
|
||||
"time": "2022-12-02T22:17:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.10.0",
|
||||
@ -4067,6 +4331,99 @@
|
||||
],
|
||||
"time": "2024-09-09T07:06:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "openspout/openspout",
|
||||
"version": "v4.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/openspout/openspout.git",
|
||||
"reference": "41f045c1f632e1474e15d4c7bc3abcb4a153563d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/openspout/openspout/zipball/41f045c1f632e1474e15d4c7bc3abcb4a153563d",
|
||||
"reference": "41f045c1f632e1474e15d4c7bc3abcb4a153563d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-filter": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-zip": "*",
|
||||
"php": "~8.3.0 || ~8.4.0 || ~8.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-zlib": "*",
|
||||
"friendsofphp/php-cs-fixer": "^3.86.0",
|
||||
"infection/infection": "^0.31.2",
|
||||
"phpbench/phpbench": "^1.4.1",
|
||||
"phpstan/phpstan": "^2.1.22",
|
||||
"phpstan/phpstan-phpunit": "^2.0.7",
|
||||
"phpstan/phpstan-strict-rules": "^2.0.6",
|
||||
"phpunit/phpunit": "^12.3.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)",
|
||||
"ext-mbstring": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OpenSpout\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Adrien Loison",
|
||||
"email": "adrien@box.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way",
|
||||
"homepage": "https://github.com/openspout/openspout",
|
||||
"keywords": [
|
||||
"OOXML",
|
||||
"csv",
|
||||
"excel",
|
||||
"memory",
|
||||
"odf",
|
||||
"ods",
|
||||
"office",
|
||||
"open",
|
||||
"php",
|
||||
"read",
|
||||
"scale",
|
||||
"spreadsheet",
|
||||
"stream",
|
||||
"write",
|
||||
"xlsx"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/openspout/openspout/issues",
|
||||
"source": "https://github.com/openspout/openspout/tree/v4.32.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://paypal.me/filippotessarotto",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/Slamdunk",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-03T16:03:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v3.1.3",
|
||||
@ -4282,6 +4639,112 @@
|
||||
},
|
||||
"time": "2025-10-06T08:47:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "5.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "4d597c1aacdde1805a33c525b9758113ea0d90df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/4d597c1aacdde1805a33c525b9758113ea0d90df",
|
||||
"reference": "4d597c1aacdde1805a33c525b9758113ea0d90df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/pcre": "^1||^2||^3",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": "*",
|
||||
"maennchen/zipstream-php": "^2.1 || ^3.0",
|
||||
"markbaker/complex": "^3.0",
|
||||
"markbaker/matrix": "^3.0",
|
||||
"php": "^8.1",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
|
||||
"dompdf/dompdf": "^2.0 || ^3.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"mitoteam/jpgraph": "^10.5",
|
||||
"mpdf/mpdf": "^8.1.1",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpstan/phpstan": "^1.1 || ^2.0",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
|
||||
"phpunit/phpunit": "^10.5",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"tecnickcom/tcpdf": "^6.5"
|
||||
},
|
||||
"suggest": {
|
||||
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
|
||||
"ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard",
|
||||
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
|
||||
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Maarten Balliauw",
|
||||
"homepage": "https://blog.maartenballiauw.be"
|
||||
},
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"homepage": "https://markbakeruk.net"
|
||||
},
|
||||
{
|
||||
"name": "Franck Lefevre",
|
||||
"homepage": "https://rootslabs.net"
|
||||
},
|
||||
{
|
||||
"name": "Erik Tilt"
|
||||
},
|
||||
{
|
||||
"name": "Adrien Crivelli"
|
||||
}
|
||||
],
|
||||
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
||||
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
|
||||
"keywords": [
|
||||
"OpenXML",
|
||||
"excel",
|
||||
"gnumeric",
|
||||
"ods",
|
||||
"php",
|
||||
"spreadsheet",
|
||||
"xls",
|
||||
"xlsx"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.3.0"
|
||||
},
|
||||
"time": "2025-11-24T15:47:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
"version": "1.9.4",
|
||||
@ -6000,6 +6463,67 @@
|
||||
],
|
||||
"time": "2025-07-23T16:08:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/simple-excel",
|
||||
"version": "3.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/simple-excel.git",
|
||||
"reference": "80c2fd16090d28e1d0036bfac1afc6bfd8452ea3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/simple-excel/zipball/80c2fd16090d28e1d0036bfac1afc6bfd8452ea3",
|
||||
"reference": "80c2fd16090d28e1d0036bfac1afc6bfd8452ea3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^9.0|^10.0|^11.0|^12.0",
|
||||
"openspout/openspout": "^4.30",
|
||||
"php": "^8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"pestphp/pest-plugin-laravel": "^1.3|^2.3|^3.0",
|
||||
"phpunit/phpunit": "^9.4|^10.5|^11.0|^12.0",
|
||||
"spatie/pest-plugin-snapshots": "^1.1|^2.1",
|
||||
"spatie/phpunit-snapshot-assertions": "^4.0|^5.1",
|
||||
"spatie/temporary-directory": "^1.2|^2.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\SimpleExcel\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Read and write simple Excel and CSV files",
|
||||
"homepage": "https://github.com/spatie/simple-excel",
|
||||
"keywords": [
|
||||
"simple-excel",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/spatie/simple-excel/tree/3.8.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-24T06:40:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v7.3.0",
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('vehicle_tags_logs', function (Blueprint $table) {
|
||||
$table->enum('action_type', [
|
||||
'inscripcion',
|
||||
'actualizacion',
|
||||
'sustitucion',
|
||||
'cancelacion'
|
||||
])->after('tag_id')->default('cancelacion');
|
||||
|
||||
$table->foreignId('performed_by')->nullable()->after('action_type')->constrained('users')->nullOnDelete();
|
||||
$table->index('action_type');
|
||||
$table->index('vehicle_id', 'action_type');
|
||||
$table->index('performed_by');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('vehicle_tags_logs', function (Blueprint $table) {
|
||||
$table->dropIndex(['action_type']);
|
||||
$table->dropIndex(['vehicle_id', 'action_type']);
|
||||
$table->dropIndex(['performed_by']);
|
||||
|
||||
$table->dropForeign(['performed_by']);
|
||||
$table->dropColumn(['action_type', 'performed_by']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -9,6 +9,7 @@
|
||||
use App\Http\Controllers\Repuve\UpdateController;
|
||||
use App\Http\Controllers\Repuve\CatalogNameImgController;
|
||||
use App\Http\Controllers\Repuve\DeviceController;
|
||||
use App\Http\Controllers\Repuve\ExcelController;
|
||||
use App\Http\Controllers\Repuve\PackageController;
|
||||
use App\Http\Controllers\Repuve\TagsController;
|
||||
|
||||
@ -72,5 +73,6 @@
|
||||
|
||||
/** Rutas públicas */
|
||||
// Tus rutas públicas
|
||||
Route::get('excel/constancias-sustituidas', [ExcelController::class, 'constanciasSustituidas']);
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user