feat: agregar manejo de archivos duplicados en la actualización de datos del vehículo

This commit is contained in:
Juan Felipe Zapata Moreno 2025-12-20 11:39:13 -06:00
parent a18f028a3d
commit 908ba8aaf1

View File

@ -860,6 +860,7 @@ public function updateData(VehicleUpdateRequest $request, $id)
$uploadedFiles = [];
$replacedFiles = [];
$deletedFiles = [];
$skippedFiles = [];
// Manejar eliminación de archivos
if ($request->has('delete_files')) {
@ -898,14 +899,30 @@ public function updateData(VehicleUpdateRequest $request, $id)
$nameIds = $request->input('name_id', []);
$observations = $request->input('observations', []);
// Normalizar arrays
if (!is_array($nameIds)) {
$nameIds = [$nameIds];
}
if (!is_array($observations)) {
$observations = [$observations];
}
if (!is_array($files)) {
$files = [$files];
}
if (!empty($nameIds)) {
$validIds = CatalogNameImg::whereIn('id', $nameIds)->pluck('id')->toArray();
if (count($validIds) !== count($nameIds)) {
// Obtener IDs únicos para validar
$uniqueNameIds = array_unique($nameIds);
$validIds = CatalogNameImg::whereIn('id', $uniqueNameIds)->pluck('id')->toArray();
// Verificar que todos los IDs únicos existan en el catálogo
if (count($validIds) !== count($uniqueNameIds)) {
$invalidIds = array_diff($uniqueNameIds, $validIds);
DB::rollBack();
return ApiResponse::BAD_REQUEST->response([
'message' => 'Algunos ids del catálogo de nombres no son válidos',
'provided_id' => $nameIds,
'valid_id' => $validIds,
'provided_ids' => $nameIds,
'invalid_ids' => array_values($invalidIds),
]);
}
}
@ -913,10 +930,10 @@ public function updateData(VehicleUpdateRequest $request, $id)
foreach ($files as $indx => $file) {
$nameId = $nameIds[$indx] ?? null;
if ($nameId === null) {
if ($nameId === null || $nameId === '') {
DB::rollBack();
return ApiResponse::BAD_REQUEST->response([
'message' => "Falta el nombre para el archivo, busca en el catálogo de nombres",
'message' => "Falta el nombre para el archivo en el índice {$indx}",
]);
}
@ -933,24 +950,96 @@ public function updateData(VehicleUpdateRequest $request, $id)
$extension = $file->getClientOriginalExtension();
$isEvidenciaAdicional = $catalogName->name === 'EVIDENCIA ADICIONAL';
// Si NO es Evidencia Adicional, verificar si existe y reemplazar
// Calcular MD5 antes de guardar para verificar duplicados
$md5 = md5_file($file->getRealPath());
// Verificar si el archivo ya existe por MD5 en este expediente
$existingByMd5 = File::where('record_id', $record->id)
->where('md5', $md5)
->first();
if ($existingByMd5) {
// Archivo duplicado detectado, registrar y omitir
$skippedFiles[] = [
'index' => $indx,
'catalog_name' => $catalogName->name,
'md5' => $md5,
'reason' => 'Archivo duplicado ya existe en el expediente',
'existing_file_id' => $existingByMd5->id,
'existing_file_path' => $existingByMd5->path,
];
continue; // Salta al siguiente archivo sin guardarlo
}
// Verificar si existe archivo para reemplazar
$existingFile = null;
if (!$isEvidenciaAdicional) {
// Para archivos estándar (FACTURA, INE, etc.), buscar por name_id
$existingFile = File::where('record_id', $record->id)
->where('name_id', $nameId)
->first();
} else {
// Para EVIDENCIA ADICIONAL con observación, buscar por name_id + observations
$observation = $observations[$indx] ?? null;
if ($existingFile) {
Storage::disk('public')->delete($existingFile->path);
$replacedFiles[] = [
'id' => $existingFile->id,
'name_id' => $nameId,
'old_path' => $existingFile->path,
];
$existingFile->delete();
if (!empty($observation)) {
$existingFile = File::where('record_id', $record->id)
->where('name_id', $nameId)
->where('observations', $observation)
->first();
}
// Si no tiene observación o no se encuentra, se creará nuevo archivo
}
// Si existe archivo, reemplazarlo
if ($existingFile) {
$oldPath = $existingFile->path;
$oldMd5 = $existingFile->md5;
// Eliminar archivo físico viejo
Storage::disk('public')->delete($oldPath);
// Mantener el mismo nombre de archivo pero actualizar extensión si cambió
$pathInfo = pathinfo($oldPath);
$fileName = $pathInfo['filename'] . '.' . $extension;
$directory = $pathInfo['dirname'];
// Guardar nuevo archivo con el mismo nombre
$path = $file->storeAs($directory, $fileName, 'public');
// Actualizar registro existente
$existingFile->update([
'path' => $path,
'md5' => $md5,
'observations' => $observations[$indx] ?? $existingFile->observations,
]);
$replacedFiles[] = [
'file_id' => $existingFile->id,
'name' => $catalogName->name,
'old_path' => $oldPath,
'new_path' => $path,
'old_md5' => $oldMd5,
'new_md5' => $md5,
'replaced_by' => 'observation_match',
];
// Agregar a uploadedFiles también para mantener compatibilidad
$uploadedFiles[] = [
'file_id' => $existingFile->id,
'name' => $catalogName->name,
'path' => $path,
'md5' => $md5,
'observations' => $existingFile->observations,
'action' => 'replaced',
];
continue; // Siguiente archivo
}
// Si no existe, crear nuevo archivo
if (!$isEvidenciaAdicional) {
$fileName = $catalogName->name . '_' . date('dmY_His') . '.' . $extension;
} else {
// Si es Evidencia Adicional, contar cuántas ya existen y agregar número
@ -962,7 +1051,6 @@ public function updateData(VehicleUpdateRequest $request, $id)
}
$path = $file->storeAs("records/{$record->folio}", $fileName, 'public');
$md5 = md5_file($file->getRealPath());
$fileRecord = File::create([
'name_id' => $nameId,
@ -1060,6 +1148,9 @@ public function updateData(VehicleUpdateRequest $request, $id)
$message = 'Expediente actualizado exitosamente';
if (!$hasVehicleChanges && !$hasOwnerChanges && !$hasFolioChange && empty($uploadedFiles) && empty($deletedFiles)) {
$message = 'No se detectaron cambios. Los datos ya estaban actualizados.';
if (!empty($skippedFiles)) {
$message .= ' Se omitieron ' . count($skippedFiles) . ' archivo(s) duplicado(s).';
}
} elseif ($hasFolioChange) {
$message = 'Folio actualizado exitosamente de "' . $oldFolio . '" a "' . $record->folio . '".';
if ($hasVehicleChanges || $hasOwnerChanges) {
@ -1068,12 +1159,24 @@ public function updateData(VehicleUpdateRequest $request, $id)
if (!empty($uploadedFiles) || !empty($deletedFiles)) {
$message .= ' Archivos modificados.';
}
if (!empty($skippedFiles)) {
$message .= ' Se omitieron ' . count($skippedFiles) . ' archivo(s) duplicado(s).';
}
} elseif (($hasVehicleChanges || $hasOwnerChanges) && (!empty($uploadedFiles) || !empty($deletedFiles))) {
$message = 'Datos del vehículo/propietario y archivos actualizados exitosamente.';
if (!empty($skippedFiles)) {
$message .= ' Se omitieron ' . count($skippedFiles) . ' archivo(s) duplicado(s).';
}
} elseif (($hasVehicleChanges || $hasOwnerChanges) && empty($uploadedFiles) && empty($deletedFiles)) {
$message = 'Datos del vehículo/propietario actualizados exitosamente. No se modificaron archivos.';
if (!empty($skippedFiles)) {
$message .= ' Se omitieron ' . count($skippedFiles) . ' archivo(s) duplicado(s).';
}
} elseif (!$hasVehicleChanges && !$hasOwnerChanges && (!empty($uploadedFiles) || !empty($deletedFiles))) {
$message = 'Archivos modificados exitosamente. No hubo cambios en los datos del vehículo/propietario.';
if (!empty($skippedFiles)) {
$message .= ' Se omitieron ' . count($skippedFiles) . ' archivo(s) duplicado(s).';
}
}
@ -1085,12 +1188,10 @@ public function updateData(VehicleUpdateRequest $request, $id)
'owner_updated' => $hasOwnerChanges,
'files_uploaded' => count($uploadedFiles) > 0,
'files_deleted' => count($deletedFiles) > 0,
'files_skipped' => count($skippedFiles) > 0,
'files_replaced' => count($replacedFiles) > 0,
],
'record' => $record,
'uploaded_files' => $uploadedFiles,
'deleted_files' => $deletedFiles,
'replaced_count' => count($replacedFiles),
'total_files' => File::where('record_id', $record->id)->count(),
]);
} catch (Exception $e) {
DB::rollBack();
@ -1245,4 +1346,5 @@ private function moveRecordFiles(int $recordId, string $oldFolio, string $newFol
Storage::disk('public')->deleteDirectory($oldDirectory);
}
}
}