# Pickup/Dropoff Locations & Buffer Time Feature

**Date**: October 16, 2025
**Feature Type**: Booking Enhancement

---

## Overview

This feature adds two critical functionalities to the GengSewa rental platform:

1. **Pickup/Dropoff Locations** - For car rentals and other mobile units
2. **Buffer Time (Turnover Time)** - Preparation time between bookings

---

## 1. Pickup/Dropoff Locations

### Purpose

Allow guests to select convenient pickup and dropoff points when booking cars or other mobile rental units. Perfect for:
- Airport pickups/dropoffs
- Hotel deliveries
- Public spots (malls, train stations)
- Custom locations

### Database Structure

**Table: `pickup_locations`**
```sql
- id
- name (e.g., "KLIA Terminal 1")
- address
- type (airport, hotel, public_spot, office, general)
- latitude, longitude (for map display)
- is_active
- created_by (user who created it)
- timestamps
```

**Table: `listing_pickup_locations`** (Pivot)
```sql
- listing_id
- pickup_location_id
```

**Added to `bookings` table**:
```sql
- pickup_location_id
- dropoff_location_id
- pickup_time
- dropoff_time
```

### How It Works

1. **Admin/Host Setup**:
   - Create pickup locations (airports, hotels, public spots)
   - Assign pickup locations to specific listings
   - Only assigned locations are available for that listing

2. **Guest Booking**:
   - Select check-in/check-out dates
   - Choose pickup location from available options
   - Choose dropoff location (can be different from pickup)
   - Optionally set pickup/dropoff times

3. **Receipt/Confirmation**:
   - Booking confirmation shows pickup/dropoff details
   - Host receives pickup location information

### Pre-seeded Locations

12 sample locations across Malaysia:

**Airports**:
- KLIA Terminal 1
- KLIA2
- Langkawi International Airport
- Penang International Airport

**Public Spots**:
- KL Sentral Station
- Pavilion KL
- KLCC Suria KLCC
- Kuah Jetty, Langkawi
- Pantai Cenang, Langkawi
- Georgetown Ferry Terminal

**Hotels**:
- The Westin Langkawi Resort & Spa
- Mandarin Oriental Kuala Lumpur

---

## 2. Buffer Time (Turnover Time)

### Purpose

Prevent back-to-back bookings and allow time for:
- Car cleaning and washing
- House cleaning and preparation
- Equipment maintenance
- Inspection
- Restocking

### Database Structure

**Added to `listings` table**:
```sql
- buffer_hours (integer, default: 0)
  Comment: Hours needed between bookings for cleaning/preparation
```

### How It Works

1. **Host Configuration**:
   - Set buffer hours per listing (e.g., 2 hours for cars, 4 hours for houses)
   - Buffer time is automatically applied between bookings

2. **Availability Checking**:
   - When guest selects dates, system checks for conflicts
   - Previous booking checkout + buffer_hours must be before new check-in
   - Example:
     ```
     Booking A: Oct 15 10:00 - Oct 16 10:00 (buffer: 2 hours)
     Earliest next booking: Oct 16 12:00 (10:00 + 2 hours)
     ```

3. **Double-Booking Prevention**:
   - System automatically blocks dates during buffer period
   - Prevents overlapping confirmed or pending bookings

### Example Scenarios

**Scenario 1: Car Rental**
- Guest A: Books Oct 15-16 (dropoff 10:00 AM Oct 16)
- Buffer: 2 hours (washing, inspection)
- Guest B: Earliest pickup is Oct 16 12:00 PM

**Scenario 2: Houseboat**
- Guest A: Books Oct 10-12 (checkout 11:00 AM Oct 12)
- Buffer: 4 hours (deep cleaning, restocking)
- Guest B: Earliest check-in is Oct 12 3:00 PM

---

## Models & Relationships

### PickupLocation Model

```php
class PickupLocation extends Model
{
    // Relationships
    public function creator();        // User who created
    public function listings();       // Listings using this location

    // Scopes
    public function scopeActive();    // Only active locations
    public function scopeType($type); // Filter by type
}
```

### Listing Model (Updated)

```php
class Listing extends Model
{
    // New field
    protected $fillable = [..., 'buffer_hours'];

    // New relationship
    public function pickupLocations(); // Available pickup locations

    // New methods
    public function isAvailableForDates($checkIn, $checkOut);
    public function getUnavailableDates(); // For calendar display
}
```

### Booking Model (Updated)

```php
class Booking extends Model
{
    // New fields
    protected $fillable = [
        ...
        'pickup_location_id',
        'dropoff_location_id',
        'pickup_time',
        'dropoff_time',
    ];

    // New relationships
    public function pickupLocation();
    public function dropoffLocation();

    // New method
    public function overlapsWithDates($checkIn, $checkOut, $bufferHours);
}
```

---

## Admin Panel Integration

### Manage Pickup Locations

**Access**: `/admin/pickup-locations`

**Features**:
- Create new pickup locations
- Edit existing locations
- Set location type (airport, hotel, public spot)
- Add GPS coordinates for map display
- Activate/deactivate locations
- View which listings use each location

### Manage Listings (Updated)

**New Fields**:
- **Buffer Hours**: Set turnover time (0-24 hours)
- **Pickup Locations**: Select multiple available locations
- Display info: "This listing requires X hours between bookings"

---

## Host Features

### Creating/Editing Listings

**Buffer Time Configuration**:
```
Buffer Time (Preparation Time): [2] hours
ℹ️ This is the time needed between bookings for cleaning/preparation
```

**Pickup Locations** (for cars only):
```
☑ KLIA Terminal 1
☑ KLIA2
☑ KL Sentral Station
☐ Penang Airport
☐ Langkawi Airport
```

### Viewing Bookings

Display pickup/dropoff details:
```
Pickup: KLIA Terminal 1 at 10:00 AM
Dropoff: KL Sentral Station at 5:00 PM
```

---

## Guest Booking Flow (Updated)

### Step 1: Select Dates
- Choose check-in and check-out dates
- System checks availability (including buffer time)
- Blocked dates shown in calendar

### Step 2: Pickup/Dropoff (if applicable)
```
Pickup Location: [Select Location ▼]
Pickup Time: [10:00 AM]

Dropoff Location: [Select Location ▼]
Dropoff Time: [5:00 PM]
```

### Step 3: Confirmation
- Shows all booking details including locations
- Price breakdown (rental + fees)
- Terms and conditions

---

## API / Route Updates

**Admin Routes** (to be added):
```php
Route::middleware(['admin'])->group(function () {
    Route::get('/admin/pickup-locations', PickupLocationsManager::class);
});
```

---

## Migration Command

```bash
# Already run:
php artisan migrate

# Seed sample locations:
php artisan db:seed --class=PickupLocationSeeder
```

---

## Availability Checking Algorithm

```php
// Check if listing is available
function isAvailableForDates($checkIn, $checkOut) {
    1. Check if listing is active
    2. Get all confirmed/pending bookings
    3. For each booking:
       a. Add buffer_hours to booking checkout
       b. Check if requested dates overlap
    4. Return true if no conflicts
}

// Overlap detection
function overlapsWithDates($checkIn, $checkOut, $bufferHours) {
    bufferedCheckout = booking.checkout + buffer_hours
    return (checkIn < bufferedCheckout) && (checkOut > booking.checkin)
}
```

---

## Frontend Integration (To Do)

### Listing Form
- Add buffer_hours input field
- Add pickup locations multi-select (for car rental type only)
- Show warning if buffer < 1 hour for certain types

### Booking Form
- Show pickup location dropdown (if listing has locations)
- Add pickup time selector
- Show dropoff location dropdown
- Add dropoff time selector
- Validate: dropoff location available for selected dates

### Calendar Display
- Shade unavailable dates (including buffer periods)
- Show tooltip: "Unavailable (preparation time)"

---

## Testing Checklist

- [ ] Create new pickup location
- [ ] Assign pickup location to car listing
- [ ] Set buffer_hours to 2
- [ ] Create booking A: Oct 15-16
- [ ] Try booking B: Oct 16 (same day) - should be blocked
- [ ] Try booking B: Oct 16 afternoon - should work (after buffer)
- [ ] Check calendar shows blocked dates correctly
- [ ] Verify receipt shows pickup/dropoff locations
- [ ] Test with different rental types (only cars show locations)

---

## Benefits

### For Hosts
✅ Control preparation time between bookings
✅ No double-bookings or conflicts
✅ Flexible pickup/dropoff arrangements
✅ Better customer service

### For Guests
✅ Convenient pickup options (airport, hotel, etc.)
✅ Clear availability calendar
✅ Flexible dropoff locations
✅ No booking conflicts

### For Platform
✅ Reduced booking conflicts
✅ Better inventory management
✅ Improved user experience
✅ Competitive feature set

---

## Future Enhancements (Optional)

1. **Dynamic Pricing by Location**:
   - Charge extra for airport pickups
   - Premium locations have higher fees

2. **Location Distance Calculation**:
   - Calculate travel distance between pickup/dropoff
   - Show estimated travel time

3. **Location Photos**:
   - Add photos to pickup locations
   - Help guests identify the spot

4. **SMS Notifications**:
   - Send pickup location details via SMS
   - Remind guests 1 day before

5. **Map Integration**:
   - Show pickup locations on Google Maps
   - Directions to pickup point

---

## Files Modified/Created

### Created:
- `database/migrations/2025_10_15_190352_add_pickup_dropoff_locations_system.php`
- `app/Models/PickupLocation.php`
- `database/seeders/PickupLocationSeeder.php`
- `app/Livewire/Admin/PickupLocationsManager.php`
- `resources/views/livewire/admin/pickup-locations-manager.blade.php`

### Modified:
- `app/Models/Listing.php` - Added buffer_hours, pickupLocations(), availability methods
- `app/Models/Booking.php` - Added pickup/dropoff fields, overlap detection
- Database: listings table (added buffer_hours column)
- Database: bookings table (added pickup/dropoff columns)

---

## Support

For questions or issues with this feature, refer to the main `SETUP.md` documentation or contact the development team.

---

**© 2025 GengSewa. All rights reserved.**
