2025-10-23 17:01:49 -06:00

310 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers\Repuve;
use App\Http\Controllers\Controller;
use App\Http\Requests\Repuve\ModuleStoreRequest;
use App\Http\Requests\Repuve\ModuleUpdateRequest;
use App\Models\Module;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Notsoweb\ApiResponse\Enums\ApiResponse;
class ModuleController extends Controller
{
/**
* Listar módulos existentes
*/
public function index(Request $request)
{
try {
$query = Module::query('responsible')->withCount(['packages']);
// Validar que se envíe al menos un parámetro de búsqueda
if (!$request->filled('name') && !$request->filled('municipality')) {
return ApiResponse::BAD_REQUEST->response([
'message' => 'Debe proporcionar al menos uno de los siguientes parámetros: nombre o municipio.'
]);
}
// Filtro por nombre
if ($request->filled('name')) {
$query->where('name', 'like', '%' . $request->input('name') . '%');
}
// Filtro por municipio
if ($request->filled('municipality')) {
$query->where('municipality', 'like', '%' . $request->input('municipality') . '%');
}
// Cargar relaciones para contar
$query->withCount(['packages']);
// Ordenar
$sortBy = $request->input('sort_by', 'created_at');
$sortOrder = $request->input('sort_order', 'desc');
$query->orderBy($sortBy, $sortOrder);
// Paginación
$perPage = $request->input('per_page', 20);
$modules = $query->paginate($perPage);
return ApiResponse::OK->response([
'modules' => $modules->map(function ($module) {
return [
'id' => $module->id,
'name' => $module->name,
'responsible' => $module->responsible ? [
'id' => $module->responsible->id,
'name' => $module->responsible->full_name,
'email' => $module->responsible->email,
] : null,
'municipality' => $module->municipality,
'address' => $module->address,
'colony' => $module->colony,
'cp' => $module->cp,
'longitude' => $module->longitude,
'latitude' => $module->latitude,
'status' => $module->status,
'status_text' => $module->status ? 'Activo' : 'Inactivo',
'packages_count' => $module->packages_count ?? 0,
'created_at' => $module->created_at->format('Y-m-d H:i:s'),
'updated_at' => $module->updated_at->format('Y-m-d H:i:s'),
];
}),
'pagination' => [
'current_page' => $modules->currentPage(),
'total_pages' => $modules->lastPage(),
'per_page' => $modules->perPage(),
'total' => $modules->total(),
'from' => $modules->firstItem(),
'to' => $modules->lastItem(),
],
]);
} catch (\Exception $e) {
return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al listar módulos',
'error' => $e->getMessage(),
]);
}
}
/**
* Crear un nuevo módulo
*/
public function store(ModuleStoreRequest $request)
{
try {
DB::beginTransaction();
// Crear el módulo
$module = Module::create([
'name' => $request->input('name'),
'responsible_id' => $request->input('responsible_id'),
'municipality' => $request->input('municipality'),
'address' => $request->input('address'),
'colony' => $request->input('colony'),
'cp' => $request->input('cp'),
'longitude' => $request->input('longitude'),
'latitude' => $request->input('latitude'),
'status' => $request->input('status', true), // Por defecto activo
]);
DB::commit();
return ApiResponse::CREATED->response([
'message' => 'Módulo creado exitosamente',
'module' => [
'id' => $module->id,
'name' => $module->name,
'municipality' => $module->municipality,
'responsible_id' => $module->responsible_id,
'address' => $module->address,
'colony' => $module->colony,
'cp' => $module->cp,
'longitude' => $module->longitude,
'latitude' => $module->latitude,
'status' => $module->status,
'status_text' => $module->status ? 'Activo' : 'Inactivo',
'created_at' => $module->created_at->format('Y-m-d H:i:s'),
],
]);
} catch (\Exception $e) {
DB::rollBack();
return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al crear módulo',
'error' => $e->getMessage(),
]);
}
}
/**
* Actualizar un módulo existente
*/
public function update(ModuleUpdateRequest $request, int $id)
{
try {
$module = Module::findOrFail($id);
DB::beginTransaction();
// Actualizar solo los campos que vienen en el request
$module->update($request->only([
'name',
'responsible_id',
'municipality',
'address',
'colony',
'cp',
'longitude',
'latitude',
'status',
]));
DB::commit();
return ApiResponse::OK->response([
'message' => 'Módulo actualizado exitosamente',
'module' => [
'id' => $module->id,
'name' => $module->name,
'responsible_id' => $module->responsible_id,
'municipality' => $module->municipality,
'address' => $module->address,
'colony' => $module->colony,
'cp' => $module->cp,
'longitude' => $module->longitude,
'latitude' => $module->latitude,
'status' => $module->status,
'status_text' => $module->status ? 'Activo' : 'Inactivo',
'updated_at' => $module->updated_at->format('Y-m-d H:i:s'),
],
]);
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
return ApiResponse::NOT_FOUND->response([
'message' => 'Módulo no encontrado',
]);
} catch (\Exception $e) {
DB::rollBack();
Log::error('Error al actualizar módulo: ' . $e->getMessage(), [
'module_id' => $id,
'request' => $request->all(),
'trace' => $e->getTraceAsString()
]);
return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al actualizar módulo',
'error' => $e->getMessage(),
]);
}
}
/**
* Cambiar solo el status de un módulo
*/
public function toggleStatus(int $id)
{
try {
$module = Module::findOrFail($id);
DB::beginTransaction();
// Cambiar el status al valor opuesto
$module->update([
'status' => !$module->status,
]);
DB::commit();
return ApiResponse::OK->response([
'message' => $module->status
? 'Módulo activado exitosamente'
: 'Módulo desactivado exitosamente',
'module' => [
'id' => $module->id,
'name' => $module->name,
'status' => $module->status,
'status_text' => $module->status ? 'Activo' : 'Inactivo',
'updated_at' => $module->updated_at->format('Y-m-d H:i:s'),
],
]);
} catch (ModelNotFoundException $e) {
return ApiResponse::NOT_FOUND->response([
'message' => 'Módulo no encontrado',
]);
} catch (\Exception $e) {
DB::rollBack();
Log::error('Error al cambiar status del módulo: ' . $e->getMessage(), [
'module_id' => $id,
'trace' => $e->getTraceAsString()
]);
return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al cambiar status del módulo',
'error' => $e->getMessage(),
]);
}
}
public function getAvailableUsers()
{
try {
$users = User::select('id', 'name', 'paternal', 'maternal', 'email')
->orderBy('name')
->get();
return ApiResponse::OK->response([
'users' => $users->map(function ($user) {
return [
'id' => $user->id,
'name' => $user->full_name,
'email' => $user->email,
];
}),
]);
} catch (\Exception $e) {
Log::error('Error al obtener usuarios: ' . $e->getMessage());
return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al obtener lista de usuarios',
'error' => $e->getMessage(),
]);
}
}
/**
* Obtener lista simplificada de módulos para dropdown
*/
public function listForDropdown()
{
try {
$modules = Module::where('status', true) // Solo activos
->orderBy('name')
->get(['id', 'name', 'municipality']);
return ApiResponse::OK->response([
'modules' => $modules->map(fn($m) => [
'id' => $m->id,
'name' => $m->name,
'municipality' => $m->municipality,
'label' => "{$m->name} - {$m->municipality}", // Para mostrar en dropdown
]),
]);
} catch (\Exception $e) {
return ApiResponse::INTERNAL_ERROR->response([
'message' => 'Error al obtener módulos',
]);
}
}
}