withCount('tags')->orderBy('id', 'ASC'); if ($request->filled('lote')) { Log::info('PackageController@index - Filtro lote aplicado', ['lote' => $request->lote]); $packages->where('lot', 'LIKE', '%' . $request->lote . '%'); } if ($request->filled('caja')) { Log::info('PackageController@index - Filtro caja aplicado', ['caja' => $request->caja]); $packages->where('box_number', 'LIKE', '%' . $request->caja . '%'); } Log::info('PackageController@index - Ejecutando query de paginación'); $paginatedPackages = $packages->paginate(config('app.pagination')); Log::info('PackageController@index - Query ejecutado exitosamente', [ 'total' => $paginatedPackages->total(), 'per_page' => $paginatedPackages->perPage(), 'current_page' => $paginatedPackages->currentPage(), ]); // Validación si no hay resultados if ($paginatedPackages->isEmpty()) { Log::info('PackageController@index - No se encontraron resultados'); return ApiResponse::NOT_FOUND->response([ 'message' => 'No se encontraron tags con los criterios de búsqueda proporcionados.', 'filters_applied' => array_filter($request->only(['lot', 'box_number'])) ]); } Log::info('PackageController@index - Respuesta exitosa'); return ApiResponse::OK->response([ 'Paquetes' => $paginatedPackages, ]); } catch (\Exception $e) { Log::error('PackageController@index - Error capturado', [ 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), 'trace' => $e->getTraceAsString(), ]); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al obtener los paquetes', 'error' => $e->getMessage(), ]); } } public function store(PackageStoreRequest $request) { try { DB::beginTransaction(); $package = Package::create([ 'lot' => $request->lot, 'box_number' => $request->box_number, 'starting_page' => $request->starting_page, 'ending_page' => $request->ending_page, ]); // Obtener el status "available" para los tags $statusAvailable = CatalogTagStatus::where('code', 'available')->first(); if (!$statusAvailable) { throw new \Exception('No se encontró el status "Disponible" para los tags'); } $existingTags = Tag::whereHas('package', function ($query) use ($request) { $query->where('box_number', $request->box_number); }) ->whereBetween('folio', [$request->starting_page, $request->ending_page]) ->get(['folio', 'package_id']); if ($existingTags->isNotEmpty()) { DB::rollBack(); return ApiResponse::BAD_REQUEST->response([ 'message' => 'Ya existen tags en esta caja con folios en el rango especificado.', 'box_number' => $request->box_number, 'starting_page' => $request->starting_page, 'ending_page' => $request->ending_page, 'folios_conflictivos' => $existingTags->pluck('folio')->toArray(), 'total_folios_conflictivos' => $existingTags->count(), ]); } // Crear los tags según el rango de páginas for ($page = $request->starting_page; $page <= $request->ending_page; $page++) { Tag::create([ 'folio' => $page, 'tag_number' => null, 'package_id' => $package->id, 'status_id' => $statusAvailable->id, ]); } DB::commit(); return ApiResponse::CREATED->response([ 'message' => 'Paquete registrado exitosamente con sus tags', 'package' => $package->load('tags'), 'tags_created' => $package->tags()->count(), ]); } catch (QueryException $e) { DB::rollBack(); if ($e->getCode() == 23000 && str_contains($e->getMessage(), 'packages_lot_box_unique')) { return ApiResponse::BAD_REQUEST->response([ 'message' => "Ya existe un paquete con el lote '{$request->lot}' y caja número '{$request->box_number}'.", ]); } return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al crear el paquete', 'error' => $e->getMessage(), ]); } catch (\Exception $e) { DB::rollBack(); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al crear el paquete', 'error' => $e->getMessage(), ]); } } public function show($id) { try { $package = Package::with(['tags'])->findOrFail($id); return ApiResponse::OK->response([ 'package' => $package, ]); } catch (\Exception $e) { return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al obtener el paquete', 'error' => $e->getMessage(), ]); } } public function update(PackageUpdateRequest $request, $id) { try { $package = Package::findOrFail($id); DB::beginTransaction(); $package->update($request->validated()); DB::commit(); return ApiResponse::OK->response([ 'message' => 'Paquete actualizado exitosamente', 'package' => [ 'id' => $package->id, 'lot' => $package->lot, 'box_number' => $package->box_number, 'starting_page' => $package->starting_page, 'ending_page' => $package->ending_page, 'updated_at' => $package->updated_at->format('Y-m-d H:i:s'), ], ]); } catch (\Exception $e) { DB::rollBack(); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al actualizar el paquete', 'error' => $e->getMessage(), ]); } } public function destroy($id) { try { DB::beginTransaction(); $package = Package::findOrFail($id); if ($package->tags()->count() > 0) { return ApiResponse::BAD_REQUEST->response([ 'message' => 'No se puede eliminar el paquete porque tiene tags asociados.', 'tags_count' => $package->tags()->count(), ]); } $package->delete(); DB::commit(); return ApiResponse::OK->response([ 'message' => 'Paquete eliminado exitosamente.', ]); } catch (\Exception $e) { DB::rollBack(); return ApiResponse::INTERNAL_ERROR->response([ 'message' => 'Error al eliminar el paquete.', 'error' => $e->getMessage(), ]); } } }