Skip to main content

Overview

This guide provides administrators with detailed workflows for managing room reservation requests in Apartado de Salas. Learn how to efficiently review submissions, make informed decisions, and maintain the reservation system.

Prerequisites

To manage requests, you must:
  • Have an administrator account (role = 'admin')
  • Be authenticated to the system
  • Understand the room inventory and scheduling constraints
All request management actions require admin role. Attempting to access these features without proper authorization results in a 403 Forbidden error.

Accessing the Request Management Interface

1

Login as Admin

Authenticate using your administrator credentials.
2

Navigate to Reservations

Go to /reservations from your dashboard. This route is protected by:
Auth::requireRole('admin');
Only users with admin role can access this page.
3

View All Requests

The reservations index page (app/views/reservations/index.php) displays all reservation requests in a table format.

Understanding the Requests List

The main reservations page shows comprehensive information:

Table Columns

ID
integer
Unique identifier for the reservation. Used for tracking and referencing specific requests.
Evento
string
The event name provided by the user. Describes the purpose of the reservation.
Sala
string
The room name being requested. Each reservation is for a single room.
Solicitante
string
Username of the person who submitted the request. Useful for follow-up communication.
Estado
enum
Current status of the request:
  • Pendiente: Awaiting review
  • Aprobado: Approved and confirmed
  • Rechazado: Rejected by administrator
Fecha
datetime
When the request was submitted (created_at timestamp).
Acciones
actions
Available actions based on status:
  • Pendiente: “Revisar” link to detail page
  • Aprobado/Rechazado: Shows current status (no actions)

Filtering Requests by Status

Efficiently manage requests by filtering:
URL: /reservationsShows every reservation regardless of status. Use this for:
  • Overall system overview
  • Historical reporting
  • Checking all reservations for a specific room
$reservations = $reservationModel->getAll();

Filter Implementation

The filtering logic in app/controllers/ReservationController.php:122:
public function index(): void
{
    Auth::requireRole('admin');

    $reservationModel = new Reservation();
    $status = $_GET['status'] ?? null;

    if ($status) {
        $reservations = $reservationModel->getByStatus($status);
    } else {
        $reservations = $reservationModel->getAll();
    }

    require_once dirname(__DIR__) . '/views/reservations/index.php';
}
Bookmark the pending filter URL for quick access to your daily work queue.

Reviewing Individual Requests

For detailed examination of a reservation:
1

Access Request Details

From the reservations list, click “Revisar” (Review) on any pending request. This navigates to /reservations/show?id={reservationId}.
2

Review Complete Information

The detail page shows all aspects of the reservation:
  • Event name and description
  • Room being requested
  • Requester information
  • Current status
  • Creation date
  • All requested time slots
  • Selected materials
  • Additional notes from requester
3

Verify Availability

Check that the requested time slots don’t conflict with existing approved reservations.
4

Assess Resources

Confirm that requested materials are available and appropriate.
5

Make Decision

Based on your review, decide to approve or reject.

Detail Page Data Retrieval

The show method (app/controllers/ReservationController.php:264) gathers all related data:
public function show(): void{
    Auth::requireRole('admin');

    $id = $_GET['id'] ?? null;

    if (!$id) {
        Session::setFlash('error', 'Solicitud no válida.');
        header('Location: ' . BASE_URL . '/reservations');
        exit;
    }

    $reservationModel = new Reservation();

    $reservation = $reservationModel->findById((int)$id);
    $slots = $reservationModel->getSlots((int)$id);
    $materials = $reservationModel->getMaterials((int)$id);

    if (!$reservation) {
        Session::setFlash('error', 'Solicitud no encontrada.');
        header('Location: ' . BASE_URL . '/reservations');
        exit;
    }

    require_once dirname(__DIR__) . '/views/reservations/show.php';
}
The system fetches the main reservation record plus all associated slots and materials in separate queries for complete context.

Approving Requests

To approve a pending reservation:
1

Verify Eligibility

Before approving, confirm:
  • ✓ No scheduling conflicts exist
  • ✓ Room is appropriate for event
  • ✓ Requested materials are available
  • ✓ Time slots are reasonable
  • ✓ Request follows organizational policies
2

Click Approve Button

On the detail page, click “Aprobar” (Approve). This button only appears for pending requests:
<?php if ($reservation['status'] === 'pendiente'): ?>
    <form method="POST" action="<?= BASE_URL ?>/reservations/approve">
        <input type="hidden" name="id" value="<?= $reservation['id'] ?>">
        <button class="approve">Aprobar</button>
    </form>
<?php endif; ?>
3

Confirmation

The system processes your approval and displays a success message.
4

Return to List

You’re redirected back to the reservations list. The approved request now shows “Aprobado” status.

Approval Implementation

The approve method in app/controllers/ReservationController.php:176:
public function approve(): void {
    Auth::requireRole('admin');

    // Validate POST request
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        header('Location: ' . BASE_URL . '/reservations');
        exit;
    }

    // Get reservation ID
    $id = $_POST['id'] ?? null;

    if (!$id) {
        Session::setFlash('error', 'Solicitud inválida.');
        header('Location: ' . BASE_URL . '/reservations');
        exit;
    }

    // Update status to approved
    $reservationModel = new Reservation();
    $reservationModel->updateStatus((int)$id, 'aprobado');

    // Provide feedback
    Session::setFlash('success', 'Solicitud aprobada correctamente.');

    // Redirect to list
    header('Location: ' . BASE_URL . '/reservations');
    exit;
}

What Happens on Approval

  1. Database Update: Reservation status changes from pendiente to aprobado
  2. Time Slot Lock: Those time slots are now considered occupied for conflict checking
  3. Material Reservation: Selected materials are implicitly reserved for those times
  4. User Notification: User can see approval when they check “Mis solicitudes”
Approval is permanent in the current implementation. Reversing an approval requires direct database access.

Rejecting Requests

To reject a reservation that cannot be accommodated:
1

Identify Rejection Reason

Common reasons for rejection:
  • Scheduling conflict with existing reservation
  • Room inappropriate for event type
  • Requested materials unavailable
  • Policy violations
  • Insufficient advance notice
  • Room under maintenance
2

Click Reject Button

On the detail page, click “Rechazar” (Reject):
<?php if ($reservation['status'] === 'pendiente'): ?>
    <form method="POST" action="<?= BASE_URL ?>/reservations/reject">
        <input type="hidden" name="id" value="<?= $reservation['id'] ?>">
        <button class="reject">Rechazar</button>
    </form>
<?php endif; ?>
3

Consider Communication

The system doesn’t store rejection reasons. Consider contacting the user externally to explain the decision and offer alternatives.
4

Confirmation

You’ll see “Solicitud rechazada” and be returned to the reservations list.

Rejection Implementation

The reject method in app/controllers/ReservationController.php:208:
public function reject(): void
{
    Auth::requireRole('admin');

    // Validate POST request
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        header('Location: ' . BASE_URL . '/reservations');
        exit;
    }

    // Get reservation ID
    $id = $_POST['id'] ?? null;

    if (!$id) {
        Session::setFlash('error', 'Solicitud inválida.');
        header('Location: ' . BASE_URL . '/reservations');
        exit;
    }

    // Update status to rejected
    $reservationModel = new Reservation();
    $reservationModel->updateStatus((int)$id, 'rechazado');

    // Provide feedback
    Session::setFlash('success', 'Solicitud rechazada.');

    // Redirect to list
    header('Location: ' . BASE_URL . '/reservations');
    exit;
}
Rejected reservations cannot be re-reviewed in the current system. Users must submit a new request with updated information.

Decision-Making Framework

Use this framework to evaluate requests consistently:

Approval Criteria

Question: Are the requested date/time slots available?
  • Check existing approved reservations for the same room
  • Verify no conflicts exist in the database
  • Consider setup/teardown time between events
Action: If conflicts exist, reject and suggest alternative times.
Question: Are requested materials available?
  • Verify materials exist and are functional
  • Check if materials are already committed elsewhere
  • Assess if material requests are appropriate for event
Action: If materials unavailable, contact user to modify request.
Question: Is the room suitable for this event?
  • Room capacity vs. expected attendance (check notes)
  • Room features match event needs
  • Room location appropriate for event type
Action: If room is inappropriate, suggest better alternatives.
Question: Does the request comply with organizational policies?
  • Advance notice requirements met
  • User authorized to book this room type
  • Event type permitted in this space
  • Duration within allowed limits
Action: If policy violations exist, reject with explanation.
Question: Is there enough information to make a decision?
  • Event name is descriptive
  • Time slots are clear
  • Special requirements understood
Action: If unclear, contact user for clarification before deciding.

Workflow Strategies

Daily Review Process

Establish a routine for managing requests:
1

Morning Review

Start each day by checking pending requests:
/reservations?status=pendiente
This shows your work queue for the day.
2

Prioritize by Date

Sort requests by event date. Process urgent requests (happening soon) first.
3

Batch Process by Room

Group requests for the same room to efficiently check for conflicts.
4

Make Decisions

Review each request thoroughly and approve or reject.
5

Follow Up

For rejections or special cases, contact users externally with explanations.
6

Verify Queue Empty

End the day by confirming all pending requests have been processed.

Conflict Resolution

When multiple requests compete for the same resource:
  1. First Come, First Served: Generally approve based on submission timestamp
  2. Priority Events: Some organizational events may take precedence
  3. Duration Consideration: Shorter requests may be easier to accommodate
  4. Alternative Solutions: Suggest different rooms or times to later requesters
When rejecting due to conflicts, include information about which time slots are available in your follow-up communication.

Common Scenarios

Scenario 1: Clear Approval

Situation: Request for Conference Room A on 2026-03-20 from 10:00-12:00. No conflicts, materials available, clear event description. Action:
1
Review detail page
2
Verify no conflicts in system
3
Click “Aprobar”
4
Done - move to next request

Scenario 2: Scheduling Conflict

Situation: Request for Room B on 2026-03-25 from 14:00-16:00. Existing approved reservation for 13:00-15:00. Action:
1
Identify the conflict
2
Click “Rechazar”
3
Contact user externally: “Your request conflicts with existing reservation. Room available 15:00-17:00 instead. Would that work?”
4
If user agrees, ask them to submit new request

Scenario 3: Material Unavailable

Situation: Request includes video conferencing equipment that’s committed to another event. Action:
1
Note the material conflict
2
Contact user: “Room and time available, but video conferencing system is already booked. Can you proceed without it or choose different date?”
3
If user modifies request, have them submit new one
4
Reject original request

Scenario 4: Insufficient Information

Situation: Event name is vague (“Meeting”), no notes, unclear purpose. Action:
1
Contact user for clarification
2
Ask about: purpose, expected attendees, specific needs
3
Once clarified, make approval decision
4
Consider establishing policy requiring detailed event descriptions

Security and Validation

Role Verification

Every management action includes role checking:
Auth::requireRole('admin');
This prevents unauthorized users from approving or rejecting requests even if they obtain direct URLs.

POST Method Enforcement

State-changing operations require POST requests:
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: ' . BASE_URL . '/reservations');
    exit;
}
This provides protection against CSRF attacks and accidental actions from link clicks.

ID Validation

Reservation IDs are validated before processing:
$id = $_POST['id'] ?? null;

if (!$id) {
    Session::setFlash('error', 'Solicitud inválida.');
    header('Location: ' . BASE_URL . '/reservations');
    exit;
}
The system performs defensive validation at multiple levels to ensure data integrity and prevent manipulation.

Troubleshooting

Cannot Access Reservations Page

Problem: 403 Forbidden error when accessing /reservations Solution:
  • Verify your user account has role = 'admin' in database
  • Check that you’re logged in with admin account
  • Contact system administrator to verify role assignment

Approve/Reject Not Working

Problem: Clicking buttons doesn’t change status Diagnosis:
// Check form is submitting correctly
// Verify POST data includes reservation ID
// Confirm no JavaScript errors in console
Solution:
  • Check browser console for errors
  • Verify session hasn’t expired
  • Try refreshing page and clicking again
  • Check database to confirm status isn’t already changed

Missing Reservations

Problem: Expected requests don’t appear in list Solution:
  • Remove status filter (view /reservations without parameters)
  • Check if requests were created by different users
  • Verify requests exist in database
  • Check date range if time-based filtering is implemented

Action Buttons Not Visible

Problem: “Aprobar” and “Rechazar” buttons don’t appear Cause: Buttons only show for pending requests:
<?php if ($reservation['status'] === 'pendiente'): ?>
    <!-- Buttons rendered here -->
<?php endif; ?>
Solution: Verify the reservation status is actually pendiente. Already approved or rejected requests don’t show action buttons.

Best Practices

Timely Response

Process pending requests within 24-48 hours to provide good user experience.

Clear Communication

For rejections, contact users externally to explain decisions and offer alternatives.

Consistent Criteria

Apply the same evaluation standards to all requests for fairness.

Documentation

Keep external records of approval decisions for organizational auditing.

System Limitations

Be aware of current system constraints:
  • No Rejection Reasons: System doesn’t store why requests were rejected
  • Permanent Decisions: Status changes can’t be undone without database access
  • No User Notifications: Users must manually check status changes
  • No Audit Trail: No record of which admin approved/rejected
  • No Bulk Actions: Must process requests individually

Next Steps

Admin Role Overview

Complete guide to administrator capabilities

Creating Reservations

Understand the user submission process

Build docs developers (and LLMs) love