diff --git a/app/Exports/PrestamosExport.php b/app/Exports/PrestamosExport.php index 6a9f724..82c1554 100644 --- a/app/Exports/PrestamosExport.php +++ b/app/Exports/PrestamosExport.php @@ -2,32 +2,55 @@ namespace App\Exports; -use App\Models\Prestamo; use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\WithHeadings; +use Maatwebsite\Excel\Concerns\WithMapping; -class PrestamosExport implements FromCollection, WithHeadings +class PrestamosExport implements FromCollection, WithHeadings, WithMapping { + protected $prestamos; + + public function __construct($prestamos = null) + { + $this->prestamos = $prestamos; + } + public function collection() { - return Prestamo::where('eliminado', 0)->get(); + return $this->prestamos; } public function headings(): array { return [ 'ID', - 'Nombre Solicitante', + 'Solicitante', 'Destino', - 'Fecha y Hora Salida', - 'Fecha y Hora Llegada', + 'Fecha Salida', + 'Fecha Llegada', 'Motivo', 'Domicilio', 'Número de Personas', 'Chofer', 'Estado', - 'Fecha de Creación', - 'Última Actualización' + 'Fecha Actualización' + ]; + } + + public function map($prestamo): array + { + return [ + $prestamo->id, + $prestamo->nombre_solicitante, + $prestamo->destino, + $prestamo->fecha_hora_salida, + $prestamo->fecha_hora_llegada, + $prestamo->motivo, + $prestamo->domicilio, + $prestamo->numero_personas, + $prestamo->chofer ? 'Sí' : 'No', + ucfirst($prestamo->estado), + $prestamo->updated_at->format('d/m/Y H:i') ]; } } \ No newline at end of file diff --git a/app/Http/Controllers/PrestamoController.php b/app/Http/Controllers/PrestamoController.php index e67c655..01c4006 100644 --- a/app/Http/Controllers/PrestamoController.php +++ b/app/Http/Controllers/PrestamoController.php @@ -48,40 +48,18 @@ class PrestamoController extends Controller */ public function store(Request $request) { - /* - // Validación de datos - $request->validate([ - 'nombre_solicitante' => 'required|string|max:255', - 'destino' => 'required|string|max:255', - 'fecha_hora_salida' => 'required|date', - 'fecha_hora_llegada' => 'required|date', - 'motivo' => 'required|string|max:255', - 'domicilio' => 'required|string|max:255', - 'numero_personas' => 'required|integer', - ], [ - 'nombre_solicitante.required' => 'El campo nombre solicitante es obligatorio.', - 'destino.required' => 'El campo destino es obligatorio.', - 'fecha_hora_salida.required' => 'El campo fecha y hora de salida es obligatorio.', - 'fecha_hora_llegada.required' => 'El campo fecha y hora de llegada es obligatorio.', - 'motivo.required' => 'El campo motivo es obligatorio.', - 'domicilio.required' => 'El campo domicilio es obligatorio.', - 'numero_personas.required' => 'El campo número de personas es obligatorio.', - ]); - */ - // Crea un nuevo préstamo - $prestamo = new Prestamo(); - $prestamo->nombre_solicitante = $request->nombre_solicitante; - $prestamo->destino = $request->destino; - $prestamo->fecha_hora_salida = $request->fecha_hora_salida; - $prestamo->fecha_hora_llegada = $request->fecha_hora_llegada; - $prestamo->motivo = $request->motivo; - $prestamo->domicilio = $request->domicilio; - $prestamo->numero_personas = $request->numero_personas; - $prestamo->chofer = $request->has('chofer') ? 1 : 0; // Manejo del checkbox - $prestamo->eliminado = 0; // Marca como activo por defecto + // Preparar los datos + $datos = $request->all(); + $datos['chofer'] = $request->has('chofer') ? 1 : 0; // Convertir 'on' a 1, o ausencia a 0 + + $prestamo = new Prestamo($datos); + $prestamo->estado = 'pendiente'; // Estado inicial $prestamo->save(); - return redirect()->route('prestamos.index')->with('success', 'Préstamo creado exitosamente.'); + // Aquí puedes agregar notificaciones para los administradores + + return redirect()->route('prestamos.index') + ->with('success', 'Préstamo solicitado correctamente. Esperando aprobación.'); } /** @@ -99,7 +77,6 @@ class PrestamoController extends Controller public function update(Request $request, $id) { // Validación de datos - /* $request->validate([ 'nombre_solicitante' => 'required|string|max:255', 'destino' => 'required|string|max:255', @@ -108,16 +85,7 @@ class PrestamoController extends Controller 'motivo' => 'required|string|max:255', 'domicilio' => 'required|string|max:255', 'numero_personas' => 'required|integer', - ], [ - 'nombre_solicitante.required' => 'El campo nombre solicitante es obligatorio.', - 'destino.required' => 'El campo destino es obligatorio.', - 'fecha_hora_salida.required' => 'El campo fecha y hora de salida es obligatorio.', - 'fecha_hora_llegada.required' => 'El campo fecha y hora de llegada es obligatorio.', - 'motivo.required' => 'El campo motivo es obligatorio.', - 'domicilio.required' => 'El campo domicilio es obligatorio.', - 'numero_personas.required' => 'El campo número de personas es obligatorio.', ]); - */ $prestamo = Prestamo::findOrFail($id); // Encuentra el préstamo por ID $prestamo->nombre_solicitante = $request->nombre_solicitante; // Actualiza el nombre del solicitante @@ -163,4 +131,98 @@ class PrestamoController extends Controller $pdf = PDF::loadView('exports.prestamos-pdf', ['prestamos' => $prestamos]); return $pdf->download('prestamos.pdf'); } + + public function aceptados(Request $request) + { + $busqueda = $request->busqueda; + + $prestamos = Prestamo::when($busqueda, function($query) use ($busqueda) { + return $query->where(function($q) use ($busqueda) { + $q->where('nombre_solicitante', 'LIKE', "%{$busqueda}%") + ->orWhere('destino', 'LIKE', "%{$busqueda}%") + ->orWhere('motivo', 'LIKE', "%{$busqueda}%"); + }); + }) + ->orderBy('created_at', 'desc') + ->get(); + + return view('prestamos.aceptar', ['prestamos' => $prestamos]); + } + + public function aceptar($id) + { + $prestamo = Prestamo::findOrFail($id); + $prestamo->estado = 'aceptado'; + $prestamo->save(); + + // Aquí puedes agregar notificaciones si lo deseas + + return redirect()->route('prestamos.aceptados') + ->with('success', 'Préstamo aceptado correctamente'); + } + + public function rechazar($id) + { + $prestamo = Prestamo::findOrFail($id); + $prestamo->estado = 'rechazado'; + $prestamo->save(); + + // Aquí puedes agregar notificaciones si lo deseas + + return redirect()->route('prestamos.aceptados') + ->with('success', 'Préstamo rechazado correctamente'); + } + + public function historial(Request $request) + { + $query = Prestamo::query() + ->whereIn('estado', ['aceptado', 'rechazado']); + + // Aplicar filtros de búsqueda + if ($request->busqueda) { + $query->where(function($q) use ($request) { + $q->where('nombre_solicitante', 'LIKE', "%{$request->busqueda}%") + ->orWhere('destino', 'LIKE', "%{$request->busqueda}%") + ->orWhere('motivo', 'LIKE', "%{$request->busqueda}%"); + }); + } + + // Filtro por estado + if ($request->estado) { + $query->where('estado', $request->estado); + } + + // Filtro por fechas + if ($request->fecha_desde) { + $query->whereDate('created_at', '>=', $request->fecha_desde); + } + if ($request->fecha_hasta) { + $query->whereDate('created_at', '<=', $request->fecha_hasta); + } + + // Ordenar por fecha de actualización + $query->orderBy('updated_at', 'desc'); + + // Paginar resultados + $prestamos = $query->paginate(10); + + return view('prestamos.historial', ['prestamos' => $prestamos]); + } + + public function export($format) + { + $prestamos = Prestamo::whereIn('estado', ['aceptado', 'rechazado']) + ->orderBy('updated_at', 'desc') + ->get(); + + switch($format) { + case 'excel': + return Excel::download(new PrestamosExport($prestamos), 'historial_prestamos.xlsx'); + case 'pdf': + $pdf = PDF::loadView('exports.prestamos-pdf', ['prestamos' => $prestamos]); + return $pdf->download('historial_prestamos.pdf'); + default: + return redirect()->back()->with('error', 'Formato no soportado'); + } + } } diff --git a/app/Http/Controllers/TiposLicenciasController.php b/app/Http/Controllers/TiposLicenciasController.php index 8a14ce6..a117ab5 100644 --- a/app/Http/Controllers/TiposLicenciasController.php +++ b/app/Http/Controllers/TiposLicenciasController.php @@ -59,6 +59,17 @@ class TiposLicenciasController extends Controller */ public function store(Request $request) { + // Verificar si ya existe un tipo de licencia con el mismo nombre + $existe = tiposLicencias::where('tipoLicencia', $request->tipoLicencia) + ->where('eliminado', 1) + ->exists(); + + if ($existe) { + return redirect()->route('tiposLicencias.create') + ->with('error', 'Ya existe un tipo de licencia con el nombre "' . $request->tipoLicencia . '". Por favor, ingrese un nombre diferente.') + ->withInput(); + } + $tipoLicencia = new TiposLicencias(); $tipoLicencia->tipoLicencia = $request->tipoLicencia; $tipoLicencia->eliminado = 1; @@ -81,6 +92,18 @@ class TiposLicenciasController extends Controller */ public function update(Request $request, $id) { + // Verificar si ya existe otro tipo de licencia con el mismo nombre + $existe = tiposLicencias::where('tipoLicencia', $request->tipoLicencia) + ->where('id', '!=', $id) + ->where('eliminado', 1) + ->exists(); + + if ($existe) { + return redirect()->route('tiposLicencias.edit', $id) + ->with('error', 'Ya existe un tipo de licencia con el nombre "' . $request->tipoLicencia . '". Por favor, ingrese un nombre diferente.') + ->withInput(); + } + $tipoLicencia = TiposLicencias::findOrFail($id); $tipoLicencia->tipoLicencia = $request->tipoLicencia; if ($request->has('eliminado')) { diff --git a/app/Models/prestamo.php b/app/Models/prestamo.php index beab890..8cfde19 100644 --- a/app/Models/prestamo.php +++ b/app/Models/prestamo.php @@ -19,6 +19,7 @@ protected $fillable = [ 'domicilio', 'numero_personas', 'chofer', - + 'estado', + 'eliminado' ]; } diff --git a/database/migrations/2025_04_01_191325_add_estado_to_prestamos_table.php b/database/migrations/2025_04_01_191325_add_estado_to_prestamos_table.php new file mode 100644 index 0000000..c47e8b3 --- /dev/null +++ b/database/migrations/2025_04_01_191325_add_estado_to_prestamos_table.php @@ -0,0 +1,28 @@ +enum('estado', ['pendiente', 'aceptado', 'rechazado'])->default('pendiente')->after('chofer'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('prestamos', function (Blueprint $table) { + $table->dropColumn('estado'); + }); + } +}; diff --git a/database/migrations/2025_04_01_192918_add_fecha_aceptacion_to_prestamos_table.php b/database/migrations/2025_04_01_192918_add_fecha_aceptacion_to_prestamos_table.php new file mode 100644 index 0000000..af9986e --- /dev/null +++ b/database/migrations/2025_04_01_192918_add_fecha_aceptacion_to_prestamos_table.php @@ -0,0 +1,28 @@ +timestamp('fecha_aceptacion')->nullable()->after('estado'); + }); + } + + public function down() + { + Schema::table('prestamos', function (Blueprint $table) { + $table->dropColumn('fecha_aceptacion'); + }); + } +} \ No newline at end of file diff --git a/resources/views/exports/prestamos-pdf.blade.php b/resources/views/exports/prestamos-pdf.blade.php index 6c81106..ab6422c 100644 --- a/resources/views/exports/prestamos-pdf.blade.php +++ b/resources/views/exports/prestamos-pdf.blade.php @@ -1,7 +1,7 @@ - Lista de Préstamos + Historial de Préstamos
-

Lista de Préstamos

-

Fecha de generación: {{ date('d/m/Y H:i:s') }}

+

Historial de Préstamos

+

Fecha de generación: {{ now()->format('d/m/Y H:i') }}

@@ -46,12 +44,10 @@ - - + + - - @@ -61,16 +57,16 @@ - - + + - - - + @endforeach
ID Solicitante DestinoSalidaLlegadaFecha SalidaFecha Llegada MotivoDomicilio PersonasChofer Estado
{{ $prestamo->id }} {{ $prestamo->nombre_solicitante }} {{ $prestamo->destino }}{{ $prestamo->fecha_hora_salida }}{{ $prestamo->fecha_hora_llegada }}{{ \Carbon\Carbon::parse($prestamo->fecha_hora_salida)->format('d/m/Y H:i') }}{{ \Carbon\Carbon::parse($prestamo->fecha_hora_llegada)->format('d/m/Y H:i') }} {{ $prestamo->motivo }}{{ $prestamo->domicilio }} {{ $prestamo->numero_personas }}{{ $prestamo->chofer ? 'Sí' : 'No' }}{{ $prestamo->eliminado == 0 ? 'Activo' : 'Inactivo' }} + {{ ucfirst($prestamo->estado) }} +
- \ No newline at end of file + diff --git a/resources/views/prestamos/aceptar.blade.php b/resources/views/prestamos/aceptar.blade.php new file mode 100644 index 0000000..6bdefe7 --- /dev/null +++ b/resources/views/prestamos/aceptar.blade.php @@ -0,0 +1,141 @@ +@extends('layouts.dashboard') + +@section('content') +
+ + @if(session('success')) + + @endif + + @if(session('error')) + + @endif + +
+
+

Aceptar Prestamos

+
+ + +
+
+
+ +
+ +
+
+ + @if(request('busqueda')) + + Limpiar + + @endif +
+
+ +
+ + + + + + + + + + + + + + + + + + @foreach($prestamos as $prestamo) + + + + + + + + + + + + + + @endforeach + +
NúmeroSolicitanteDestinoFecha SalidaFecha LlegadaMotivoDomicilioPersonasChoferEstadoAcciones
{{ $prestamo->id }} + + {{ $prestamo->nombre_solicitante }} + + + {{ $prestamo->destino }} + + + {{ \Carbon\Carbon::parse($prestamo->fecha_hora_salida)->format('d/m/Y H:i') }} + + + {{ \Carbon\Carbon::parse($prestamo->fecha_hora_llegada)->format('d/m/Y H:i') }} + {{ $prestamo->motivo }}{{ $prestamo->domicilio }}{{ $prestamo->numero_personas }}{{ $prestamo->chofer }} + + {{ ucfirst($prestamo->estado) }} + + +
+ @if($prestamo->estado === 'pendiente') +
+ @csrf + +
+
+ @csrf + +
+ @else + + + Procesado + + @endif +
+
+
+
+
+ + +@endsection diff --git a/resources/views/prestamos/historial.blade.php b/resources/views/prestamos/historial.blade.php new file mode 100644 index 0000000..726bd71 --- /dev/null +++ b/resources/views/prestamos/historial.blade.php @@ -0,0 +1,160 @@ +@extends('layouts.dashboard') + +@section('content') +
+ + @if(session('success')) + + @endif + + @if(session('error')) + + @endif + +
+
+

Historial de Préstamos

+ + +
+ + + + + + + +
+
+ + +
+
+
+ +
+ +
+
+ + + + + + + + + + + + @if(request('busqueda') || request('estado') || request('fecha_desde') || request('fecha_hasta')) + + Limpiar + + @endif +
+
+ +
+ + + + + + + + + + + + + + + + + + @foreach($prestamos as $prestamo) + + + + + + + + + + + + + + @endforeach + +
NúmeroSolicitanteDestinoFecha SalidaFecha LlegadaMotivoDomicilioPersonasChoferEstadoFecha Actualización
{{ $prestamo->id }} + + {{ $prestamo->nombre_solicitante }} + + + {{ $prestamo->destino }} + + + {{ \Carbon\Carbon::parse($prestamo->fecha_hora_salida)->format('d/m/Y H:i') }} + + + {{ \Carbon\Carbon::parse($prestamo->fecha_hora_llegada)->format('d/m/Y H:i') }} + {{ $prestamo->motivo }}{{ $prestamo->domicilio }}{{ $prestamo->numero_personas }}{{ $prestamo->chofer }} + + {{ ucfirst($prestamo->estado) }} + + + {{ \Carbon\Carbon::parse($prestamo->updated_at)->format('d/m/Y H:i') }} +
+
+ + +
+ {{ $prestamos->links() }} +
+
+
+ + +@endsection diff --git a/resources/views/tiposLicenciaCrearEditar.blade.php b/resources/views/tiposLicenciaCrearEditar.blade.php index 140a90e..2b44c00 100644 --- a/resources/views/tiposLicenciaCrearEditar.blade.php +++ b/resources/views/tiposLicenciaCrearEditar.blade.php @@ -17,16 +17,12 @@ - @if($errors->any()) -
+ @if(session('error')) +
- -
-
    - @foreach($errors->all() as $error) -
  • {{ $error }}
  • - @endforeach -
+ +
+ {{ session('error') }}
diff --git a/routes/web.php b/routes/web.php index 0629aa1..c18966c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -58,9 +58,11 @@ use App\Http\Controllers\DespartamentoController; // Primero las rutas de exportación (más específicas) Route::get('/prestamos/excel', [PrestamoController::class, 'exportExcel'])->name('prestamos.excel'); Route::get('/prestamos/pdf', [PrestamoController::class, 'exportPDF'])->name('prestamos.pdf'); + Route::get('/prestamos/export/{format}', [PrestamoController::class, 'export'])->name('prestamos.export'); Route::get('/prestamos/aceptados', [PrestamoController::class, 'aceptados'])->name('prestamos.aceptados'); Route::post('/prestamos/{id}/aceptar', [PrestamoController::class, 'aceptar'])->name('prestamos.aceptar'); Route::post('/prestamos/{id}/rechazar', [PrestamoController::class, 'rechazar'])->name('prestamos.rechazar'); + Route::get('/prestamos/historial', [PrestamoController::class, 'historial'])->name('prestamos.historial'); // Después la ruta de recurso (más general) Route::resource('prestamos', PrestamoController::class);