|
|
@@ -0,0 +1,213 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Jobs;
|
|
|
+
|
|
|
+use Illuminate\Contracts\Queue\ShouldQueue;
|
|
|
+use Illuminate\Foundation\Queue\Queueable;
|
|
|
+use Illuminate\Queue\InteractsWithQueue;
|
|
|
+use Illuminate\Queue\SerializesModels;
|
|
|
+use App\Services\WebSocketService;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+use App\Http\Controllers\ValidateLoadArchivesController;
|
|
|
+use App\Http\Controllers\DocumentManagementController;
|
|
|
+use App\Http\Controllers\EncryptionController;
|
|
|
+use Illuminate\Http\Request;
|
|
|
+use Illuminate\Http\UploadedFile;
|
|
|
+use Illuminate\Support\Facades\Storage;
|
|
|
+use ZipArchive;
|
|
|
+
|
|
|
+class ValidateLoadArchives implements ShouldQueue
|
|
|
+{
|
|
|
+ use Queueable, InteractsWithQueue, SerializesModels;
|
|
|
+
|
|
|
+ protected $requestData;
|
|
|
+ protected $userId;
|
|
|
+ protected $jobId;
|
|
|
+
|
|
|
+ public function __construct($requestData, $userId, $jobId)
|
|
|
+ {
|
|
|
+ $this->requestData = $requestData;
|
|
|
+ $this->userId = $userId;
|
|
|
+ $this->jobId = $jobId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function handle(): void
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // Etapa 1: Inicio (0%)
|
|
|
+ $this->broadcastProgress(0, 'processing', 'Iniciando validación de archivos...');
|
|
|
+
|
|
|
+ // Procesar archivos
|
|
|
+ $result = $this->processFiles();
|
|
|
+
|
|
|
+ // Etapa final: Completado (100%)
|
|
|
+ $this->broadcastProgress(100, 'completed', 'Archivos subidos exitosamente', $result);
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('ValidateLoadArchives Job Error: ' . $e->getMessage());
|
|
|
+ $this->broadcastProgress(0, 'failed', 'Error en la validación: ' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function processFiles()
|
|
|
+ {
|
|
|
+ // Etapa 1: Subida Excel a temp (30%)
|
|
|
+ $this->broadcastProgress(30, 'processing', 'Subiendo archivo Excel a almacenamiento temporal...');
|
|
|
+ $tempFiles = [];
|
|
|
+
|
|
|
+ if (isset($this->requestData['temp_paths']['excel_file'])) {
|
|
|
+ $excelTempId = $this->uploadFileToTemp($this->requestData['temp_paths']['excel_file'], 'excel');
|
|
|
+ if ($excelTempId) {
|
|
|
+ $tempFiles['excel'] = $excelTempId;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Etapa 2: Subida ZIP a temp (60%)
|
|
|
+ $this->broadcastProgress(60, 'processing', 'Subiendo archivo ZIP a almacenamiento temporal...');
|
|
|
+
|
|
|
+ if (isset($this->requestData['temp_paths']['zip_file'])) {
|
|
|
+ $zipTempId = $this->uploadFileToTemp($this->requestData['temp_paths']['zip_file'], 'zip');
|
|
|
+ if ($zipTempId) {
|
|
|
+ $tempFiles['zip'] = $zipTempId;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Etapa 3: Extracción archivos individuales (90%)
|
|
|
+ $this->broadcastProgress(90, 'processing', 'Extrayendo y subiendo archivos individuales...');
|
|
|
+
|
|
|
+ $individualFiles = [];
|
|
|
+ if (isset($this->requestData['temp_paths']['zip_file'])) {
|
|
|
+ $individualFiles = $this->extractAndUploadIndividualFiles($this->requestData['temp_paths']['zip_file']);
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'temp_files' => $tempFiles,
|
|
|
+ 'individual_temp_files' => $individualFiles
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ private function broadcastProgress($progress, $status, $message, $data = null)
|
|
|
+ {
|
|
|
+ $progressData = [
|
|
|
+ 'progress' => $progress,
|
|
|
+ 'status' => $status,
|
|
|
+ 'message' => $message,
|
|
|
+ 'data' => $data,
|
|
|
+ 'jobId' => $this->jobId
|
|
|
+ ];
|
|
|
+
|
|
|
+ $webSocketService = new WebSocketService();
|
|
|
+ $webSocketService->emitToUser($this->userId, 'file_validation_progress', $progressData);
|
|
|
+ Log::info("Job Progress: {$progress}% - {$message}");
|
|
|
+ }
|
|
|
+
|
|
|
+ private function uploadFileToTemp($tempPath, $type)
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $filePath = Storage::path($tempPath);
|
|
|
+ $fileName = basename($tempPath);
|
|
|
+
|
|
|
+ $uploadedFile = new UploadedFile(
|
|
|
+ $filePath,
|
|
|
+ $fileName,
|
|
|
+ mime_content_type($filePath),
|
|
|
+ null,
|
|
|
+ true
|
|
|
+ );
|
|
|
+
|
|
|
+ $request = new Request();
|
|
|
+ $request->files->set('file', $uploadedFile);
|
|
|
+ $request->merge([
|
|
|
+ 'id_user' => $this->requestData['id_user'],
|
|
|
+ 'linea' => $this->requestData['linea'] ?? 1
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $documentController = new DocumentManagementController();
|
|
|
+ $response = $documentController->uploadTempFile($request);
|
|
|
+ $data = json_decode($response->getContent());
|
|
|
+
|
|
|
+ // Limpiar archivo temporal
|
|
|
+ Storage::delete($tempPath);
|
|
|
+
|
|
|
+ return $data->error ? false : $data->response->idArchivo;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("Error uploading {$type} to temp: " . $e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function extractAndUploadIndividualFiles($zipTempPath)
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $zipPath = Storage::path($zipTempPath);
|
|
|
+ $zip = new ZipArchive();
|
|
|
+
|
|
|
+ if ($zip->open($zipPath) !== TRUE) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $tempFiles = [];
|
|
|
+ $tempDir = storage_path('app/temp_extracted_' . time());
|
|
|
+ mkdir($tempDir, 0755, true);
|
|
|
+
|
|
|
+ for ($i = 0; $i < min($zip->numFiles, 10); $i++) { // Limitar a 10 archivos
|
|
|
+ $fileName = $zip->getNameIndex($i);
|
|
|
+
|
|
|
+ if (substr($fileName, -1) === '/') continue;
|
|
|
+
|
|
|
+ $fileContent = $zip->getFromIndex($i);
|
|
|
+ if ($fileContent !== false) {
|
|
|
+ $extractPath = $tempDir . '/' . basename($fileName);
|
|
|
+
|
|
|
+ if (file_put_contents($extractPath, $fileContent)) {
|
|
|
+ $tempFileId = $this->uploadExtractedFileToTemp($extractPath, basename($fileName));
|
|
|
+ if ($tempFileId) {
|
|
|
+ $tempFiles[] = [
|
|
|
+ 'original_name' => basename($fileName),
|
|
|
+ 'temp_id' => $tempFileId
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ unlink($extractPath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $zip->close();
|
|
|
+ rmdir($tempDir);
|
|
|
+
|
|
|
+ return $tempFiles;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('Error extracting individual files: ' . $e->getMessage());
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function uploadExtractedFileToTemp($filePath, $fileName)
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $uploadedFile = new UploadedFile(
|
|
|
+ $filePath,
|
|
|
+ $fileName,
|
|
|
+ mime_content_type($filePath),
|
|
|
+ null,
|
|
|
+ true
|
|
|
+ );
|
|
|
+
|
|
|
+ $request = new Request();
|
|
|
+ $request->files->set('file', $uploadedFile);
|
|
|
+ $request->merge([
|
|
|
+ 'id_user' => $this->requestData['id_user'],
|
|
|
+ 'linea' => $this->requestData['linea'] ?? 1
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $documentController = new DocumentManagementController();
|
|
|
+ $response = $documentController->uploadTempFile($request);
|
|
|
+ $data = json_decode($response->getContent());
|
|
|
+
|
|
|
+ return $data->error ? false : $data->response->idArchivo;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("Error uploading extracted file {$fileName}: " . $e->getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|