# Complete Booking System Implementation Guide

## Overview
The booking system has been fully implemented with support for:
- Multiple booking contacts (Booked By, Billing Contact, Emergency Contact)
- Additional passengers
- Special requirements and preferences
- Saved addresses for quick booking
- Complete data persistence and ORM relationships

## Database Tables Created

### 1. **booking_contacts**
Stores contact information for multiple people associated with a booking.
- Booking contact (person who made the reservation)
- Billing contact (invoice recipient)
- Emergency contact (for emergencies)

```sql
CREATE TABLE booking_contacts (
    id BIGINT PRIMARY KEY,
    booking_id BIGINT FOREIGN KEY,
    tenant_id BIGINT FOREIGN KEY,
    first_name VARCHAR(255),
    last_name VARCHAR(255),
    email VARCHAR(255),
    phone VARCHAR(20),
    is_primary BOOLEAN DEFAULT false,
    contact_type ENUM('booking_contact', 'billing_contact', 'emergency_contact'),
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### 2. **additional_passengers**
Stores information about passengers beyond the primary passenger.
```sql
CREATE TABLE additional_passengers (
    id BIGINT PRIMARY KEY,
    booking_id BIGINT FOREIGN KEY,
    tenant_id BIGINT FOREIGN KEY,
    first_name VARCHAR(255),
    last_name VARCHAR(255),
    email VARCHAR(255),
    phone VARCHAR(20),
    notes TEXT,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### 3. **booking_special_requirements**
Stores special requirements and preferences for a booking (one per booking).
```sql
CREATE TABLE booking_special_requirements (
    id BIGINT PRIMARY KEY,
    booking_id BIGINT FOREIGN KEY UNIQUE,
    tenant_id BIGINT FOREIGN KEY,
    wheelchair_accessible BOOLEAN DEFAULT false,
    child_safety_seat BOOLEAN DEFAULT false,
    extra_luggage BOOLEAN DEFAULT false,
    pet_friendly BOOLEAN DEFAULT false,
    additional_notes TEXT,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### 4. **saved_addresses**
Stores frequently used addresses for users (supports address reuse).
```sql
CREATE TABLE saved_addresses (
    id BIGINT PRIMARY KEY,
    tenant_id BIGINT FOREIGN KEY,
    user_id BIGINT FOREIGN KEY,
    label VARCHAR(100),
    address VARCHAR(500),
    address_2 VARCHAR(500),
    city VARCHAR(100),
    state VARCHAR(100),
    postal_code VARCHAR(20),
    country VARCHAR(100),
    latitude DECIMAL(10,8),
    longitude DECIMAL(11,8),
    place_id VARCHAR(255),
    is_favorite BOOLEAN DEFAULT false,
    address_type ENUM('home', 'work', 'custom') DEFAULT 'custom',
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

## Models

### Updated Models
- **App\Models\Booking** - Added relationships:
  - `bookingContacts()` - HasMany
  - `additionalPassengers()` - HasMany
  - `specialRequirements()` - HasOne

### New Models
- **App\Models\BookingContact** - Booking contact management
- **App\Models\AdditionalPassenger** - Additional passengers
- **App\Models\BookingSpecialRequirement** - Special requirements
- **App\Models\SavedAddress** - Saved addresses for users

## API Endpoints

### Create Booking (Comprehensive)
**POST** `/api/bookings`

Request body includes all form fields:
```json
{
  "pickup_address": "123 Main St",
  "pickup_latitude": 40.7128,
  "pickup_longitude": -74.0060,
  "dropoff_address": "456 Park Ave",
  "dropoff_latitude": 40.7614,
  "dropoff_longitude": -73.9776,
  "scheduled_at": "2026-03-20 14:30:00",
  "trip_type": "comfort",
  "estimated_distance": 5.2,
  "estimated_duration_minutes": 25,
  "estimated_fare": 45.50,
  "payment_method": "card",
  "booked_by_first_name": "John",
  "booked_by_last_name": "Smith",
  "booked_by_email": "john@example.com",
  "booked_by_phone": "+1-555-0123",
  "billing_first_name": "Sarah",
  "billing_last_name": "Smith",
  "billing_email": "sarah@example.com",
  "billing_phone": "+1-555-0456",
  "wheelchair_accessible": false,
  "child_safety_seat": false,
  "extra_luggage": true,
  "pet_friendly": false,
  "special_requirements_notes": "Has luggage",
  "additional_passengers": [
    {
      "first_name": "Emily",
      "last_name": "Smith",
      "email": "emily@example.com",
      "phone": "+1-555-0789"
    }
  ]
}
```

### Get Booking Details
**GET** `/api/bookings/{id}`

Returns complete booking with all relationships:
```json
{
  "success": true,
  "data": {
    "id": 1,
    "booking_number": "BK202603160001",
    "status": "pending",
    "passenger": { ... },
    "bookingContacts": [ ... ],
    "additionalPassengers": [ ... ],
    "specialRequirements": { ... },
    ...
  }
}
```

### Get Saved Addresses
**GET** `/api/bookings/saved-addresses`

Query parameters:
- `user_id` (optional) - defaults to authenticated user

Response: Array of saved addresses ordered by favorite status

### Create Saved Address
**POST** `/api/bookings/saved-addresses`

Request body:
```json
{
  "label": "Home",
  "address": "123 Main Street",
  "city": "New York",
  "state": "NY",
  "postal_code": "10001",
  "country": "USA",
  "latitude": 40.7128,
  "longitude": -74.0060,
  "address_type": "home",
  "is_favorite": true
}
```

### Get Booking Contacts
**GET** `/api/bookings/{bookingId}/contacts`

Response: Array of all contacts for the booking

### Add Booking Contact
**POST** `/api/bookings/{bookingId}/contacts`

Request body:
```json
{
  "first_name": "Emergency",
  "last_name": "Contact",
  "email": "emergency@example.com",
  "phone": "+1-555-9999",
  "contact_type": "emergency_contact",
  "is_primary": false
}
```

## Frontend Form Integration

The form shown at `localhost:4200/operator-admin/bookings` now supports:

### Tab: "Bill To & Pay"
- Account selection dropdown
- Billing contact information
- Payment method selection

### Tab: "Payment Info"
- Payment method details
- Discount and tax information
- Cost estimate calculation

### Tab: "Reservation Log" / "Dispatch Log" / "Trip Details"
- Display booking status and history
- Show assigned driver and vehicle
- Display trip details

### Account Section
- Links to corporate accounts if needed

### Location/Address Section
- Pickup and dropoff address inputs
- Stored addresses dropdown for quick selection
- City, state, postal code, country fields

### Booked By Section
- First name, last name, phone, email
- Captures who made the reservation

### Passenger Section
- Primary passenger details
- First name, last name, phone, email

### Additional Passengers Section
- Add/remove additional passengers
- Group name and occasion tracking

### Special Requirements Checkboxes
- Wheelchair accessible
- Child safety seat
- Extra luggage
- Pet friendly
- Additional notes field

### Assignment Section
- Assign driver dropdown
- Assign vehicle dropdown
- Auto-assignment option

### Billing Contact Section
- Separate billing contact info if needed
- E-mail copy option

## Usage Examples

### Example 1: Create a Simple Booking
```php
POST /api/bookings
{
    "pickup_address": "123 Main St",
    "pickup_latitude": 40.7128,
    "pickup_longitude": -74.0060,
    "dropoff_address": "456 Park Ave",
    "dropoff_latitude": 40.7614,
    "dropoff_longitude": -73.9776,
    "scheduled_at": "2026-03-20 14:30:00",
    "trip_type": "economy",
    "estimated_fare": 25.00,
    "payment_method": "cash",
    "booked_by_first_name": "John",
    "booked_by_last_name": "Doe",
    "booked_by_email": "john@example.com",
    "booked_by_phone": "+1-555-0100"
}
```

### Example 2: Create Booking with Multiple Passengers
```php
POST /api/bookings
{
    "pickup_address": "123 Main St",
    "pickup_latitude": 40.7128,
    "pickup_longitude": -74.0060,
    "dropoff_address": "456 Park Ave",
    "dropoff_latitude": 40.7614,
    "dropoff_longitude": -73.9776,
    "scheduled_at": "2026-03-20 14:30:00",
    "trip_type": "premium",
    "estimated_fare": 75.00,
    "payment_method": "card",
    "booked_by_first_name": "John",
    "booked_by_last_name": "Smith",
    "booked_by_email": "john@example.com",
    "booked_by_phone": "+1-555-0123",
    "additional_passengers": [
        {
            "first_name": "Jane",
            "last_name": "Smith",
            "email": "jane@example.com",
            "phone": "+1-555-0124"
        },
        {
            "first_name": "Tom",
            "last_name": "Smith",
            "email": "tom@example.com",
            "phone": "+1-555-0125"
        }
    ],
    "wheelchair_accessible": false,
    "child_safety_seat": false,
    "extra_luggage": true,
    "pet_friendly": false
}
```

### Example 3: Save an Address for Future Use
```php
POST /api/bookings/saved-addresses
{
    "label": "Office",
    "address": "789 Business Blvd",
    "address_2": "Suite 500",
    "city": "New York",
    "state": "NY",
    "postal_code": "10002",
    "country": "USA",
    "latitude": 40.7200,
    "longitude": -73.9800,
    "address_type": "work",
    "is_favorite": true
}
```

### Example 4: Get Booking with All Details
```php
GET /api/bookings/1

Response includes:
- Main booking data
- All booking contacts (booking contact, billing contact, emergency contact)
- All additional passengers
- All special requirements
- Related trip tracking and ratings
```

## Form Field Mapping

| Form Section | State Key | API Field |
|---|---|---|
| Account | selectedAccount | passenger_id / operator_id |
| Booked By First | bookedByFirstName | booked_by_first_name |
| Booked By Last | bookedByLastName | booked_by_last_name |
| Booked By Email | bookedByEmail | booked_by_email |
| Booked By Phone | bookedByPhone | booked_by_phone |
| Billing First | billingFirstName | billing_first_name |
| Billing Last | billingLastName | billing_last_name |
| Billing Email | billingEmail | billing_email |
| Billing Phone | billingPhone | billing_phone |
| Pickup Address 1 | pickupAddress | pickup_address |
| Pickup Lat/Long | pickupCoords | pickup_latitude, pickup_longitude |
| Dropoff Address | dropoffAddress | dropoff_address |
| Dropoff Lat/Long | dropoffCoords | dropoff_latitude, dropoff_longitude |
| Scheduled Time | scheduledAt | scheduled_at |
| Trip Type | tripType | trip_type |
| Wheelchair | wheelchairAccessible | wheelchair_accessible |
| Child Seat | childSafetySeat | child_safety_seat |
| Extra Luggage | extraLuggage | extra_luggage |
| Pet Friendly | petFriendly | pet_friendly |
| Special Requests | specialRequirements | special_requests / special_requirements_notes |
| Assigned Driver | selectedDriver | driver_id |
| Assigned Vehicle | selectedVehicle | vehicle_id |
| Payment Method | paymentMethod | payment_method |
| Estimated Fare | estimatedFare | estimated_fare |
| Discount | discountAmount | discount_amount |
| Tax | taxAmount | tax_amount |

## Data Validation

All inputs are validated:
- Email fields: Valid email format
- Phone fields: Up to 20 characters
- Text fields: Maximum character limits enforced
- Numeric fields: Min/max value validation
- Foreign keys: Existence validation
- Enum fields: Only valid values accepted

## Database Relationships Diagram

```
┌─────────────┐
│   Bookings  │
└──────┬──────┘
       │
       ├─ HasMany(BookingContact)
       │
       ├─ HasMany(AdditionalPassenger)
       │
       ├─ HasOne(BookingSpecialRequirement)
       │
       ├─ BelongsTo(User/Passenger)
       │
       ├─ BelongsTo(Driver)
       │
       └─ BelongsTo(Vehicle)
```

## Testing

See `BOOKING_API_EXAMPLE.php` for complete example request/response.

To test the API:
1. Get authentication token via `/api/auth/login`
2. Set `X-Tenant-ID` header (usually 1 for single tenant)
3. Set `Authorization` header with Bearer token
4. POST to `/api/bookings` with full form data
5. Verify response includes all nested relationships

## Next Steps for Frontend

1. Update the React/Vue form component to submit all fields
2. Add saved addresses dropdown in location section
3. Implement additional passenger management (add/remove rows)
4. Add contact management interface
5. Display all contacts and passengers on booking details view
6. Add special requirements section to booking details

## Example cURL Test

```bash
curl -X POST http://localhost:8000/api/bookings \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Tenant-ID: 1" \
  -H "Content-Type: application/json" \
  -d '{
    "pickup_address": "123 Main St",
    "pickup_latitude": 40.7128,
    "pickup_longitude": -74.0060,
    "dropoff_address": "456 Park Ave",
    "dropoff_latitude": 40.7614,
    "dropoff_longitude": -73.9776,
    "scheduled_at": "2026-03-20 14:30:00",
    "trip_type": "comfort",
    "estimated_distance": 5.2,
    "estimated_duration_minutes": 25,
    "estimated_fare": 45.50,
    "payment_method": "card",
    "booked_by_first_name": "John",
    "booked_by_last_name": "Smith",
    "booked_by_email": "john@example.com",
    "booked_by_phone": "+1-555-0123"
  }'
```

## Performance Considerations

- All booking-related data is loaded with `load()` to eager-load relationships
- Indexes are created on foreign keys for fast queries
- Use pagination for listing bookings (default: 15 per page)
- SavedAddresses are indexed by tenant_id and user_id for quick lookups

---

**Created:** March 16, 2026
**Framework:** Laravel 11
**API Style:** RESTful JSON
