diff --git a/app/Http/Controllers/Repuve/ModuleController.php b/app/Http/Controllers/Repuve/ModuleController.php index 35ddc84..ac9db10 100644 --- a/app/Http/Controllers/Repuve/ModuleController.php +++ b/app/Http/Controllers/Repuve/ModuleController.php @@ -21,7 +21,12 @@ class ModuleController extends Controller public function index(Request $request) { try { - $modules = Module::with(['responsible:id,name,email', 'municipality:id,code,name'])->withCount(['packages']); + $modules = Module::with([ + 'responsible:id,name,email', + 'municipality:id,code,name', + 'users:id,name,paternal,maternal,email,module_id', + 'users.roles:id,name,description' + ])->withCount(['packages']); // Filtro por nombre if ($request->filled('name')) { @@ -101,7 +106,12 @@ public function store(ModuleStoreRequest $request) public function show($id) { try { - $modules = Module::with(['responsible:id,name,email', 'municipality:id,code,name'])->withCount(['packages'])->find($id); + $modules = Module::with([ + 'responsible:id,name,email', + 'municipality:id,code,name', + 'users:id,name,paternal,maternal,email,module_id', + 'users.roles:id,name,description' + ])->withCount(['packages'])->find($id); return ApiResponse::OK->response([ 'module' => $modules, diff --git a/app/Http/Controllers/Repuve/TagsController.php b/app/Http/Controllers/Repuve/TagsController.php index 91cfa40..303e4e2 100644 --- a/app/Http/Controllers/Repuve/TagsController.php +++ b/app/Http/Controllers/Repuve/TagsController.php @@ -4,18 +4,26 @@ use App\Http\Controllers\Controller; use App\Models\CatalogTagStatus; +use App\Models\Module; use Illuminate\Http\Request; use App\Models\Tag; use Exception; use Illuminate\Support\Facades\DB; use Notsoweb\ApiResponse\Enums\ApiResponse; +use Barryvdh\DomPDF\Facade\Pdf; +use Carbon\Carbon; class TagsController extends Controller { public function index(Request $request) { try { - $tags = Tag::with('vehicle:id,placa,niv', 'package:id,lot,box_number', 'status:id,name')->orderBy('id', 'ASC'); + $tags = Tag::with([ + 'vehicle:id,placa,niv', + 'package:id,lot,box_number', + 'status:id,code,name', + 'module:id,name' + ])->orderBy('id', 'ASC'); if ($request->has('status')) { $tags->whereHas('status', function ($q) use ($request) { @@ -29,6 +37,10 @@ public function index(Request $request) }); } + if ($request->has('module_id')) { + $tags->where('module_id', $request->module_id); + } + return ApiResponse::OK->response([ 'tag' => $tags->paginate(config('app.pagination')), ]); @@ -91,7 +103,7 @@ public function tagStore(Request $request) DB::beginTransaction(); - $statusAvailable = CatalogTagStatus::where('name', Tag::STATUS_AVAILABLE)->first(); + $statusAvailable = CatalogTagStatus::where('code', Tag::STATUS_AVAILABLE)->first(); if (!$statusAvailable) { return ApiResponse::NOT_FOUND->response([ @@ -99,6 +111,13 @@ public function tagStore(Request $request) ]); } + if ($tag->module_id === null) { + return ApiResponse::BAD_REQUEST->response([ + 'message' => 'El tag no está asignado a ningún módulo. Debe asignarse primero a un módulo antes de poder usarse.', + 'tag_number' => $tagNumber, + ]); + } + $createdTags = []; $errors = []; @@ -197,12 +216,13 @@ public function assignToModule(Request $request) DB::commit(); - return ApiResponse::OK->response([ - 'message' => 'Tags asignados al módulo correctamente.', - 'count' => count($tagIds), - 'module_id' => $request->module_id, - 'tags_assigned' => $tags->pluck('tag_number')->toArray(), - ]); + // Generar PDF de Vale de Entrega + $module = Module::with('users')->findOrFail($request->module_id); + $tagsAssigned = Tag::whereIn('id', $tagIds)->orderBy('folio')->get(); + + $pdf = $this->generateValeEntregaPdf($module, $tagsAssigned); + + return $pdf->download('vale-entrega-modulo-' . $module->id . '-' . date('YmdHis') . '.pdf'); } catch (Exception $e) { DB::rollback(); return ApiResponse::INTERNAL_ERROR->response([ @@ -211,4 +231,28 @@ public function assignToModule(Request $request) ]); } } + + /** + * Generar PDF de Vale de Entrega + */ + private function generateValeEntregaPdf(Module $module, $tags) + { + // Cargar responsables del módulo con sus roles + $responsables = $module->users()->with('roles')->get(); + + // Preparar datos para el PDF + $data = [ + 'module' => $module, + 'responsables' => $responsables, + 'tags' => $tags, + 'total_tags' => $tags->count(), + 'fecha' => Carbon::now()->locale('es')->isoFormat('D [de] MMMM [de] YYYY'), + ]; + + //PDF + $pdf = Pdf::loadView('pdfs.delivery', $data); + $pdf->setPaper('letter', 'portrait'); + + return $pdf; + } } diff --git a/app/Models/Module.php b/app/Models/Module.php index d9ac07a..97120bf 100644 --- a/app/Models/Module.php +++ b/app/Models/Module.php @@ -68,4 +68,9 @@ public function responsible() { return $this->belongsTo(User::class, 'responsible_id'); } + + public function users() + { + return $this->hasMany(User::class, 'module_id'); + } } diff --git a/app/Services/RepuveService.php b/app/Services/RepuveService.php index 44d715d..bc1a882 100644 --- a/app/Services/RepuveService.php +++ b/app/Services/RepuveService.php @@ -3,6 +3,7 @@ namespace App\Services; use Exception; +use App\Models\Error; class RepuveService { @@ -72,10 +73,11 @@ private function parseVehicleResponse(string $soapResponse, string $niv) preg_match('/(.*?)<\/return>/s', $soapResponse, $matches); if (!isset($matches[1])) { + $errorFromDb = Error::where('code', '108')->first(); return [ 'has_error' => true, 'error_code' => '108', - 'error_message' => 'El resultado que devuelve el Web service es de un formato distinto al esperado', + 'error_message' => $errorFromDb ? $errorFromDb->description : 'El resultado que devuelve el Web service es de un formato distinto al esperado', 'timestamp' => now()->toDateTimeString(), 'niv' => $niv, 'repuve_response' => null, @@ -84,21 +86,21 @@ private function parseVehicleResponse(string $soapResponse, string $niv) $contenido = trim($matches[1]); - // Verificar si hay error + // Verificar si hay error de REPUVE Nacional if (str_starts_with($contenido, 'ERROR:')) { $errorMessage = str_replace('ERROR:', '', $contenido); - // Intentar extraer código de error del mensaje (formato: "ERROR:461|Mensaje") - $errorCode = '-1'; // Por defecto: Error Interno + $errorCode = '-1'; if (preg_match('/^(\d+)\|/', $errorMessage, $codeMatch)) { $errorCode = $codeMatch[1]; $errorMessage = substr($errorMessage, strlen($errorCode) + 1); } + // Mensaje directo de REPUVE Nacional return [ 'has_error' => true, 'error_code' => $errorCode, - 'error_message' => trim($errorMessage), + 'error_message' => trim($errorMessage), // Mensaje directo de REPUVE 'timestamp' => now()->toDateTimeString(), 'niv' => $niv, 'repuve_response' => null, @@ -154,10 +156,11 @@ private function parseVehicleResponse(string $soapResponse, string $niv) ]; } + $errorFromDb = Error::where('code', '108')->first(); return [ 'has_error' => true, 'error_code' => '108', - 'error_message' => 'El resultado que devuelve el Web service es de un formato distinto al esperado', + 'error_message' => $errorFromDb ? $errorFromDb->description : 'El resultado que devuelve el Web service es de un formato distinto al esperado', 'timestamp' => now()->toDateTimeString(), 'niv' => $niv, 'repuve_response' => null, @@ -275,10 +278,11 @@ public function inscribirVehiculo(array $datos) ]); if ($curlError) { + $errorFromDb = Error::where('code', '103')->first(); return [ 'has_error' => true, 'error_code' => '103', - 'error_message' => "Error de conexión al Web Service desde el cliente: {$curlError}", + 'error_message' => $errorFromDb ? $errorFromDb->description : "Error de conexión al Web Service: {$curlError}", 'timestamp' => now()->toDateTimeString(), 'http_code' => $httpCode, 'raw_response' => $response, @@ -286,10 +290,11 @@ public function inscribirVehiculo(array $datos) } if ($httpCode !== 200) { + $errorFromDb = Error::where('code', '-1')->first(); return [ 'has_error' => true, 'error_code' => '-1', - 'error_message' => "Error interno del web service. Código HTTP {$httpCode}", + 'error_message' => $errorFromDb ? $errorFromDb->description : "Error interno del web service. Código HTTP {$httpCode}", 'timestamp' => now()->toDateTimeString(), 'http_code' => $httpCode, 'raw_response' => $response, @@ -308,10 +313,11 @@ private function parsearRespuestaInscripcion(string $soapResponse) preg_match('/(.*?)<\/return>/s', $soapResponse, $matches); if (!isset($matches[1])) { + $errorFromDb = Error::where('code', '108')->first(); return [ 'has_error' => true, 'error_code' => '108', - 'error_message' => 'El resultado que devuelve el Web service es de un formato distinto al esperado', + 'error_message' => $errorFromDb ? $errorFromDb->description : 'El resultado que devuelve el Web service es de un formato distinto al esperado', 'timestamp' => now()->toDateTimeString(), 'raw_response' => $soapResponse, 'repuve_response' => null, @@ -329,10 +335,11 @@ private function parsearRespuestaInscripcion(string $soapResponse) $errorMessage = substr($errorMessage, strlen($errorCode) + 1); } + // Mensaje directo de REPUVE Nacional return [ 'has_error' => true, 'error_code' => $errorCode, - 'error_message' => trim($errorMessage), + 'error_message' => trim($errorMessage), // Mensaje directo de REPUVE 'timestamp' => now()->toDateTimeString(), 'raw_response' => $soapResponse, 'repuve_response' => null, @@ -352,10 +359,11 @@ private function parsearRespuestaInscripcion(string $soapResponse) ], ]; } else { + $errorFromDb = Error::where('code', '108')->first(); return [ 'has_error' => true, 'error_code' => '108', - 'error_message' => 'El resultado que devuelve el Web service es de un formato distinto al esperado', + 'error_message' => $errorFromDb ? $errorFromDb->description : 'El resultado que devuelve el Web service es de un formato distinto al esperado', 'timestamp' => now()->toDateTimeString(), 'raw_response' => $soapResponse, 'repuve_response' => null, diff --git a/resources/views/pdfs/damage.blade.php b/resources/views/pdfs/damage.blade.php deleted file mode 100644 index e69de29..0000000 diff --git a/resources/views/pdfs/delivery.blade.php b/resources/views/pdfs/delivery.blade.php new file mode 100644 index 0000000..323ffc0 --- /dev/null +++ b/resources/views/pdfs/delivery.blade.php @@ -0,0 +1,282 @@ + + + + + + Vale de Entrega de Constancias + + + + +
+
+ + + + + + +
+ + + +

+ SEGURIDAD
+ SECRETARIA DE SEGURIDAD
+ Y PROTECCIÓN CIUDADANA +

+
+

+ Dirección General de la Policía Estatal de Caminos
+ Dirección de Servicios al Público
+ Departamento del Registro Público Vehicular +

+
+
+ +
+ Villahermosa, Tabasco a {{ $fecha }} +
+ +
+ VALE DE ENTREGA +
+ +
+ Se realiza la entrega de {{ $total_tags }} + constancias de inscripción de segunda generación (moradas) para la realización de trámites del Registro + Público Vehicular, las cuales se enumeran por folios, a continuación. +
+ +
+
+ @foreach($tags as $index => $tag) +
+ {{ $index + 1 }}. {{ $tag->folio }} +
+ @endforeach +
+
+ +
+ +
+
ENTREGA
+
+
+
+

LIC. MARY ISABEL RAMON MADRIGAL

+

JEFA DEL DEPARTAMENTO REPUVE

+
+
+
+
+ +
+
RECIBEN
+
+ @foreach($responsables as $responsable) +
+
+

+ {{ strtoupper($responsable->full_name) }} +

+

+ {{ strtoupper($responsable->roles->first()->description ?? 'RESPONSABLE') }} MÓDULO {{ $module->id }} +

+
+
+ @endforeach +
+
+ +
+ + +
+ + + diff --git a/routes/api.php b/routes/api.php index 3add0a1..f2df9f8 100644 --- a/routes/api.php +++ b/routes/api.php @@ -72,6 +72,7 @@ Route::resource('tags', TagsController::class); Route::post('tags/import', [TagsController::class, 'tagStore']); Route::post('tags/assign-to-module', [TagsController::class, 'assignToModule']); + Route::get('tags/pdf-vale-entrega', [TagsController::class, 'generateValeEntregaPdf']); //Rutas de nombres de archivos en catálogo Route::resource('catalog-name-imgs', CatalogNameImgController::class);