# Restaurant Management System - API Documentation

Base URL: `http://localhost:8000/api`
Version: 1.0
Last Updated: April 08, 2026

## Table of Contents

1. Authentication
2. Menu Management
3. Floors & Tables
4. Orders
5. Kitchen Display System
6. Reservations
7. Offers & Discounts
8. Customers (CRM)
9. Loyalty Points
10. Payments
11. Inventory Management
12. Suppliers & Purchases
13. Financial Reports
14. Expenses

## Authentication

### Login

POST `/auth/login`

Authenticate and get access token.

Request:

    {
      "email": "user@example.com",
      "password": "password123"
    }

Response (200):

    {
      "message": "Login successful",
      "data": {
        "token": "token_here",
        "user": {
          "id": 1,
          "name": "John Doe",
          "email": "user@example.com",
          "roles": ["manager"]
        }
      }
    }

### Logout

POST `/auth/logout`

Invalidate current token.

Headers: `Authorization: Bearer {token}`

Response (200):

    {
      "message": "Logout successful"
    }

### Get Current User

GET `/auth/me`

Response (200):

    {
      "data": {
        "id": 1,
        "name": "John Doe",
        "email": "user@example.com",
        "branch_id": 1
      }
    }

### Get Permissions

GET `/auth/permissions`

Response (200):

    {
      "data": {
        "permissions": ["read:orders", "write:orders"],
        "roles": ["manager"]
      }
    }

## Menu Management

### Categories

#### List Categories

GET `/categories?per_page=15&search=beverages`

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "Beverages",
          "slug": "beverages",
          "description": "All drinks",
          "image_url": "https://...",
          "sort_order": 1,
          "status": "active",
          "items_count": 12,
          "created_at": "2026-03-30 10:00:00"
        }
      ],
      "pagination": {
        "current_page": 1,
        "total": 5
      }
    }

#### Create Category

POST `/categories`

Required Roles: admin, manager

Request:

    {
      "name": "Beverages",
      "description": "All drinks",
      "image_url": "https://...",
      "sort_order": 1,
      "status": "active"
    }

Response (201):

    {
      "message": "Category created successfully",
      "data": {
        "id": 5,
        "name": "Beverages",
        "slug": "beverages",
        "description": "All drinks",
        "image_url": "https://...",
        "sort_order": 1,
        "status": "active",
        "items_count": 0,
        "created_at": "2026-03-31 10:00:00"
      }
    }

#### Get Category

GET `/categories/{id}`

Response (200):

    {
      "data": {
        "id": 1,
        "name": "Beverages",
        "slug": "beverages",
        "items": [...]
      }
    }

#### Update Category

PUT `/categories/{id}`

Request:

    {
      "name": "Beverages Updated",
      "status": "active"
    }

Response (200):

    {
      "message": "Category updated successfully",
      "data": {...}
    }

#### Delete Category

DELETE `/categories/{id}`

Response (200):

    {
      "message": "Category deleted successfully"
    }

#### Restore Category

POST `/categories/{id}/restore`

Response (200):

    {
      "message": "Category restored successfully",
      "data": {...}
    }

#### Get Categories with Items

GET `/categories/with-items`

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "Beverages",
          "items": [
            {
              "id": 10,
              "name": "Coffee",
              "price": 150,
              "status": "active"
            }
          ]
        }
      ]
    }

### Menu Items

#### List Menu Items

GET `/menu-items?per_page=15&category=beverages&status=active&search=coffee`

Query Parameters:

- `per_page` (integer): Items per page (default: 15)
- `category` (string): Filter by category slug
- `status` (string): Filter by status (active, inactive)
- `search` (string): Search by name

Response (200):

    {
      "data": [
        {
          "id": 10,
          "name": "Espresso Coffee",
          "price": 150.00,
          "description": "Strong black coffee",
          "image_url": "https://...",
          "category": {
            "id": 1,
            "name": "Beverages"
          },
          "is_vegetarian": true,
          "is_vegan": true,
          "is_spicy": false,
          "preparation_time": 5,
          "status": "active",
          "variants": [
            {
              "id": 1,
              "name": "Size",
              "items": ["Small", "Medium", "Large"]
            }
          ],
          "created_at": "2026-03-30 10:00:00"
        }
      ],
      "pagination": {
        "current_page": 1,
        "total": 45
      }
    }

#### Create Menu Item

POST `/menu-items`

Request:

    {
      "category_id": 1,
      "name": "Cappuccino",
      "price": 200,
      "description": "Espresso with milk foam",
      "image_url": "https://...",
      "is_vegetarian": true,
      "is_vegan": false,
      "is_spicy": false,
      "preparation_time": 5,
      "status": "active"
    }

Response (201):

    {
      "message": "Menu item created successfully",
      "data": {
        "id": 11,
        "name": "Cappuccino",
        "price": 200.00,
        ...
      }
    }

#### Update Menu Item

PUT `/menu-items/{id}`

Response (200):

    {
      "message": "Menu item updated successfully",
      "data": {...}
    }

#### Toggle Status

PATCH `/menu-items/{id}/status`

Response (200):

    {
      "message": "Status updated successfully",
      "data": {...}
    }

#### Get Menu Item Variants

GET `/menu-items/{id}/variants`

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "Size",
          "description": "Choose size",
          "price_modifier": 0,
          "is_required": true,
          "options": [
            {"id": 1, "name": "Small", "price_modifier": 0},
            {"id": 2, "name": "Medium", "price_modifier": 50},
            {"id": 3, "name": "Large", "price_modifier": 100}
          ]
        }
      ]
    }

#### Add Variant

POST `/menu-items/{id}/variants`

Request:

    {
      "name": "Temperature",
      "description": "Choose temperature",
      "price_modifier": 0,
      "is_required": false,
      "sort_order": 1,
      "status": "active",
      "options": [
        {"name": "Hot", "price_modifier": 0},
        {"name": "Iced", "price_modifier": 20}
      ]
    }

Response (201):

    {
      "message": "Variant added successfully",
      "data": {...}
    }

#### Delete Variant

DELETE `/menu-items/{id}/variants/{variantId}`

Response (200):

    {
      "message": "Variant deleted successfully"
    }

#### Get Items by Category

GET `/menu-items/category/{categoryId}`

Response (200):

    {
      "data": [...]
    }

## Floors & Tables

### Floors

#### List Floors

GET `/floors?per_page=15`

Response (200):

    {
      "data": [
        {
          "id": 1,
          "branch_id": 1,
          "name": "Ground Floor",
          "description": "Main dining area",
          "floor_number": 1,
          "tables_count": 12,
          "status": "active",
          "created_at": "2026-03-30 10:00:00"
        }
      ]
    }

#### Create Floor

POST `/floors`

Request:

    {
      "name": "First Floor",
      "description": "Private dining area",
      "floor_number": 2,
      "status": "active"
    }

Response (201):

    {
      "message": "Floor created successfully",
      "data": {...}
    }

#### Get Floors with Tables

GET `/floors/with-tables`

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "Ground Floor",
          "tables": [
            {
              "id": 1,
              "name": "Table 1",
              "capacity": 4,
              "status": "available"
            }
          ]
        }
      ]
    }

### Tables

#### List Tables

GET `/tables?per_page=20&status=available`

Query Parameters:

- `status` (string): available, occupied, reserved, maintenance

Response (200):

    {
      "data": [
        {
          "id": 1,
          "floor_id": 1,
          "floor_name": "Ground Floor",
          "name": "Table 1",
          "capacity": 4,
          "status": "available",
          "current_occupancy": 0,
          "qr_code_url": "https://...",
          "created_at": "2026-03-30 10:00:00"
        }
      ]
    }

#### Create Table

POST `/tables`

Request:

    {
      "floor_id": 1,
      "name": "Table 1",
      "capacity": 4,
      "status": "available"
    }

Response (201):

    {
      "message": "Table created successfully",
      "data": {...}
    }

#### Get Available Tables

GET `/tables/available`

Response (200):

    {
      "data": [...]
    }

#### Get Occupied Tables

GET `/tables/occupied`

Response (200):

    {
      "data": [...]
    }

#### Update Table Status

PATCH `/tables/{id}/status`

Request:

    {
      "status": "occupied"
    }

Response (200):

    {
      "message": "Table status updated successfully",
      "data": {...}
    }

#### Get Tables by Floor

GET `/tables/floor/{floorId}`

Response (200):

    {
      "data": [...]
    }

## Orders

### List Orders

GET `/orders?per_page=15&status=pending&from_date=2026-03-01&to_date=2026-03-31&search=101`

Query Parameters:

- `status` (string): pending, preparing, ready, completed, cancelled
- `from_date` (date): Filter from date
- `to_date` (date): Filter to date
- `search` (string): Search by order ID or customer name

Response (200):

    {
      "data": [
        {
          "id": 101,
          "order_number": "ORD-2026-001",
          "branch_id": 1,
          "customer_name": "John Doe",
          "customer_phone": "9876543210",
          "order_type": "dine-in",
          "table_id": 1,
          "table_name": "Table 1",
          "status": "pending",
          "items_count": 3,
          "subtotal": 500.00,
          "discount": 50.00,
          "tax": 81.00,
          "total_amount": 531.00,
          "notes": "Extra spicy",
          "created_at": "2026-03-31 12:00:00",
          "updated_at": "2026-03-31 12:05:00"
        }
      ],
      "pagination": {
        "current_page": 1,
        "total": 42
      }
    }

### Create Order

POST `/orders`

Request:

    {
      "customer_name": "John Doe",
      "customer_phone": "9876543210",
      "order_type": "dine-in",
      "table_id": 1,
      "items": [
        {
          "menu_item_id": 10,
          "quantity": 2,
          "notes": "Extra spicy",
          "variant_selections": {
            "size": "Large",
            "temperature": "Hot"
          }
        }
      ],
      "delivery_address": null,
      "special_requests": "No onions"
    }

Response (201):

    {
      "message": "Order created successfully",
      "data": {
        "id": 101,
        "order_number": "ORD-2026-001",
        "status": "pending",
        "items": [
          {
            "id": 1,
            "menu_item_name": "Cappuccino",
            "quantity": 2,
            "price": 200,
            "subtotal": 400,
            "notes": "Extra spicy"
          }
        ],
        "total_amount": 531.00
      }
    }

### Get Order Details

GET `/orders/{id}/details`

Response (200):

    {
      "message": "Order details retrieved successfully",
      "data": {
        "order": {...},
        "items": [
          {
            "id": 1,
            "menu_item_id": 10,
            "menu_item_name": "Cappuccino",
            "quantity": 2,
            "price": 200.00,
            "subtotal": 400.00,
            "notes": "Extra spicy"
          }
        ]
      }
    }

### Update Order Status

PATCH `/orders/{id}/status`

Request:

    {
      "status": "preparing"
    }

Response (200):

    {
      "message": "Order status updated successfully",
      "data": {...}
    }

### Get Pending Orders

GET `/orders/pending`

Response (200):

    {
      "data": [...]
    }

### Get Orders by Status

GET `/orders/status/{status}`

Status Values: pending, preparing, ready, completed, cancelled

Response (200):

    {
      "data": [...]
    }

### Get Orders by Date Range

GET `/orders/by-date-range?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "data": [...]
    }

### Add Item to Order

POST `/orders/{id}/add-item`

Request:

    {
      "menu_item_id": 10,
      "quantity": 1,
      "special_requests": "No sugar"
    }

Response (200):

    {
      "message": "Item added to order successfully",
      "data": {...}
    }

### Remove Item from Order

POST `/orders/{id}/remove-item/{itemId}`

Response (200):

    {
      "message": "Item removed from order successfully",
      "data": {...}
    }

### Get Top Menu Items

GET `/orders/top-menu-items?days=30&limit=10`

Response (200):

    {
      "message": "Top menu items retrieved successfully",
      "data": [
        {
          "menu_item_id": 10,
          "name": "Cappuccino",
          "total_orders": 156,
          "total_qty": 280,
          "revenue": 56000.00
        }
      ]
    }

### Get Order Summary

GET `/orders/summary?days=7`

Response (200):

    {
      "message": "Order summary retrieved successfully",
      "data": {
        "total_orders": 42,
        "completed_orders": 40,
        "total_revenue": 21580.00,
        "average_order_value": 514.29,
        "most_popular_item": "Cappuccino"
      }
    }

## Kitchen Display System

### Dashboard

GET `/kitchen/dashboard`

Response (200):

    {
      "message": "Dashboard retrieved successfully",
      "data": {
        "pending_count": 3,
        "preparing_count": 5,
        "ready_count": 2,
        "pending_orders": [...],
        "preparing_orders": [...],
        "ready_orders": [...]
      }
    }

### Pending Orders (KOT)

GET `/kitchen/pending`

Kitchen orders to prepare (KOT).

Response (200):

    {
      "data": [
        {
          "id": 101,
          "order_number": "ORD-2026-001",
          "table_name": "Table 1",
          "items": [
            {
              "id": 1,
              "name": "Cappuccino",
              "quantity": 2,
              "notes": "Extra spicy"
            }
          ],
          "created_at": "2026-03-31 12:00:00"
        }
      ]
    }

### Preparing Orders

GET `/kitchen/preparing`

Orders currently being prepared.

Response (200):

    {
      "data": [...]
    }

### Ready Orders

GET `/kitchen/ready`

Orders ready for service/delivery.

Response (200):

    {
      "data": [...]
    }

### Get Order Details

GET `/kitchen/{id}`

Response (200):

    {
      "data": {
        "id": 101,
        "order_number": "ORD-2026-001",
        "items": [...],
        "notes": "Extra spicy",
        "created_at": "2026-03-31 12:00:00"
      }
    }

### Mark as Preparing

PATCH `/kitchen/{id}/preparing`

Response (200):

    {
      "message": "Order marked as preparing",
      "data": {...}
    }

### Mark as Ready

PATCH `/kitchen/{id}/ready`

Response (200):

    {
      "message": "Order marked as ready",
      "data": {...}
    }

## Reservations

### List Reservations

GET `/reservations?per_page=15&status=pending&from_date=2026-03-31`

Query Parameters:

- `status` (string): pending, confirmed, checked-in, cancelled
- `from_date` (date): From date
- `to_date` (date): To date
- `customer_id` (integer): Filter by customer

Response (200):

    {
      "data": [
        {
          "id": 1,
          "customer_id": 1,
          "customer_name": "John Doe",
          "customer_phone": "9876543210",
          "table_id": 1,
          "table_name": "Table 1",
          "reservation_date": "2026-04-05",
          "reservation_time": "19:00",
          "guests_count": 4,
          "status": "confirmed",
          "special_requests": "Window seat preferred",
          "created_at": "2026-03-31 10:00:00",
          "checked_in_at": null
        }
      ]
    }

### Create Reservation

POST `/reservations`

Request:

    {
      "customer_id": 1,
      "table_id": 1,
      "reservation_date": "2026-04-05",
      "reservation_time": "19:00",
      "guests_count": 4,
      "special_requests": "Window seat preferred"
    }

Response (201):

    {
      "message": "Reservation created successfully",
      "data": {...}
    }

### Get Upcoming Reservations

GET `/reservations/upcoming?limit=10`

Response (200):

    {
      "data": [...]
    }

### Confirm Reservation

PATCH `/reservations/{id}/confirm`

Response (200):

    {
      "message": "Reservation confirmed successfully",
      "data": {...}
    }

### Check-in Reservation

PATCH `/reservations/{id}/check-in`

Response (200):

    {
      "message": "Reservation checked in successfully",
      "data": {
        ...
        "checked_in_at": "2026-04-05 19:05:00"
      }
    }

### Get Available Tables

GET `/reservations/available-tables?date=2026-04-05&time=19:00&capacity=4`

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "Table 1",
          "capacity": 4,
          "floor_name": "Ground Floor"
        }
      ]
    }

### Get Reservations Summary

GET `/reservations/summary?date=2026-04-05`

Response (200):

    {
      "data": {
        "total_reservations": 12,
        "confirmed": 10,
        "pending": 2,
        "total_guests": 48
      }
    }

### Cancel Reservation

POST `/reservations/{id}/cancel`

Response (200):

    {
      "message": "Reservation cancelled successfully",
      "data": {...}
    }

## Offers & Discounts

### List Offers

GET `/offers?per_page=15&status=active`

Query Parameters:

- `status` (string): active, inactive
- `type` (string): percentage, fixed

Response (200):

    {
      "data": [
        {
          "id": 1,
          "code": "SUMMER20",
          "title": "Summer Discount",
          "description": "20% off on all items",
          "discount_type": "percentage",
          "discount_value": 20,
          "start_date": "2026-03-01",
          "end_date": "2026-06-30",
          "minimum_order_amount": 500,
          "max_usage": 100,
          "usage_count": 45,
          "status": "active",
          "created_at": "2026-03-01 10:00:00"
        }
      ]
    }

### Create Offer

POST `/offers`

Request:

    {
      "code": "SUMMER20",
      "title": "Summer Discount",
      "description": "20% off on all items",
      "discount_type": "percentage",
      "discount_value": 20,
      "start_date": "2026-03-01",
      "end_date": "2026-06-30",
      "minimum_order_amount": 500,
      "max_usage": 100,
      "status": "active"
    }

Response (201):

    {
      "message": "Offer created successfully",
      "data": {...}
    }

### Validate Offer Code

POST `/offers/validate`

Request:

    {
      "code": "SUMMER20",
      "order_amount": 1000
    }

Response (200):

    {
      "success": true,
      "message": "Offer is valid",
      "data": {
        "code": "SUMMER20",
        "discount_value": 20,
        "discount_type": "percentage",
        "discount_amount": 200,
        "final_amount": 800
      }
    }

### Apply Offer

POST `/offers/apply`

Request:

    {
      "code": "SUMMER20",
      "order_amount": 1000
    }

Response (200):

    {
      "message": "Offer applied successfully",
      "data": {
        "discount_amount": 200,
        "final_amount": 800
      }
    }

### Get Active Offers

GET `/offers/active`

Only active and valid offers.

Response (200):

    {
      "data": [...]
    }

### Get Offer Statistics

GET `/offers/{id}/statistics`

Response (200):

    {
      "data": {
        "total_usage": 45,
        "percentage_of_max": 45,
        "total_discount_given": 9000,
        "average_order_value": 1000
      }
    }

## Customers (CRM)

### List Customers

GET `/customers?per_page=15&search=john&tier=gold`

Query Parameters:

- `search` (string): Search by name, email, phone
- `tier` (string): bronze, silver, gold, vip

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "John Doe",
          "email": "john@example.com",
          "phone": "9876543210",
          "address": "123 Main St",
          "city": "New York",
          "state": "NY",
          "postal_code": "10001",
          "date_of_birth": "1990-05-15",
          "gender": "male",
          "loyalty_points": 2500,
          "tier": "silver",
          "preferences": "Vegetarian options preferred",
          "status": "active",
          "created_at": "2026-01-15 10:00:00"
        }
      ],
      "pagination": {
        "current_page": 1,
        "total": 256
      }
    }

### Create Customer

POST `/customers`

Request:

    {
      "name": "John Doe",
      "email": "john@example.com",
      "phone": "9876543210",
      "address": "123 Main St",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "date_of_birth": "1990-05-15",
      "gender": "male",
      "preferences": "Vegetarian options preferred",
      "status": "active"
    }

Response (201):

    {
      "message": "Customer created successfully",
      "data": {...}
    }

### Get Customer

GET `/customers/{id}`

Response (200):

    {
      "data": {...}
    }

### Update Customer

PUT `/customers/{id}`

Request:

    {
      "name": "John Doe Updated",
      "preferences": "No spicy food"
    }

Response (200):

    {
      "message": "Customer updated successfully",
      "data": {...}
    }

### Search Customer

GET `/customers/search?q=john`

Response (200):

    {
      "message": "Customers search results",
      "data": [...]
    }

### Get Customer by Phone

GET `/customers/by-phone?phone=9876543210`

Response (200):

    {
      "data": {...}
    }

### Get Repeat Customers

GET `/customers/repeat-customers?min_orders=2&limit=50`

Customers with multiple orders.

Response (200):

    {
      "message": "Repeat customers retrieved successfully",
      "data": [...]
    }

### Get Top Customers

GET `/customers/top-customers?limit=20`

Customers by spending.

Response (200):

    {
      "message": "Top customers retrieved successfully",
      "data": [...]
    }

### Get Customers by Tier

GET `/customers/tier/{tier}`

Tier Values: bronze, silver, gold, vip

Response (200):

    {
      "message": "Customers by tier retrieved successfully",
      "data": [...]
    }

### Get Customer Order History

GET `/customers/{id}/orders?per_page=20`

Response (200):

    {
      "message": "Customer order history retrieved successfully",
      "data": [
        {
          "id": 101,
          "order_number": "ORD-2026-001",
          "total_amount": 531.00,
          "status": "completed",
          "created_at": "2026-03-30 12:00:00"
        }
      ]
    }

### Get Customer Payment History

GET `/customers/{id}/payments?per_page=20`

Response (200):

    {
      "message": "Customer payment history retrieved successfully",
      "data": [
        {
          "id": 50,
          "amount": 531.00,
          "method": "card",
          "status": "completed",
          "paid_at": "2026-03-30 12:05:00"
        }
      ]
    }

### Get Customer Analytics

GET `/customers/{id}/analytics`

Response (200):

    {
      "message": "Customer analytics retrieved successfully",
      "data": {
        "total_orders": 25,
        "total_spent": 12825.00,
        "average_order_value": 513.00,
        "first_order_date": "2026-01-15",
        "last_order_date": "2026-03-30",
        "items_ordered": 156
      }
    }

## Loyalty Points

### List Loyalty Transactions

GET `/loyalty?per_page=15&customer_id=1`

Query Parameters:

- `customer_id` (integer): Filter by customer

Response (200):

    {
      "message": "Loyalty transactions retrieved successfully",
      "data": [
        {
          "id": 1,
          "customer_id": 1,
          "customer_name": "John Doe",
          "order_id": 101,
          "payment_id": null,
          "points": 531,
          "type": "earn",
          "reason": "Order completed",
          "description": "Earned 531 points from order #101",
          "available_balance": 2531,
          "processed_at": "2026-03-30 12:05:00"
        }
      ],
      "pagination": {
        "current_page": 1,
        "total": 42
      }
    }

### Redeem Points

POST `/loyalty/redeem`

Request:

    {
      "customer_id": 1,
      "points": 500,
      "reason": "Redeemed for discount"
    }

Response (201):

    {
      "message": "Points redeemed successfully",
      "data": {
        "transaction": {
          "id": 2,
          "points": -500,
          "type": "redeem",
          "available_balance": 2031
        },
        "new_balance": 2031,
        "tier": "silver"
      }
    }

### Adjust Points (Admin)

POST `/loyalty/adjust`

Request:

    {
      "customer_id": 1,
      "adjustment": 100,
      "reason": "Promotional adjustment"
    }

Response (201):

    {
      "message": "Points adjusted successfully",
      "data": {
        "transaction": {...},
        "new_balance": 2131,
        "tier": "silver"
      }
    }

### Get Loyalty Summary

GET `/loyalty/{customerId}/summary`

Response (200):

    {
      "message": "Loyalty summary retrieved successfully",
      "data": {
        "customer_id": 1,
        "current_balance": 2131,
        "tier": "silver",
        "total_earned": 3000,
        "total_redeemed": 900,
        "total_adjusted": 31,
        "transaction_count": 25
      }
    }

### Get Transactions by Type

GET `/loyalty/{customerId}/type/{type}`

Type Values: earn, redeem, adjust, expire

Response (200):

    {
      "message": "Loyalty transactions retrieved successfully",
      "data": [...]
    }

### Get Customer Loyalty Details

GET `/loyalty/customer/{customerId}`

Response (200):

    {
      "message": "Customer loyalty details retrieved successfully",
      "data": {
        "customer": {...},
        "loyalty_summary": {...}
      }
    }

## Payments

### List Payments

GET `/payments?per_page=15&status=completed&method=card&from_date=2026-03-01&to_date=2026-03-31`

Query Parameters:

- `status` (string): completed, failed, refunded, cancelled, pending
- `method` (string): cash, card, cheque, bank_transfer, digital_wallet
- `from_date` (date): From date
- `to_date` (date): To date

Response (200):

    {
      "data": [
        {
          "id": 50,
          "order_id": 101,
          "customer_id": 1,
          "customer_name": "John Doe",
          "amount": 531.00,
          "method": "card",
          "status": "completed",
          "transaction_id": "TXN-12345",
          "reference_number": "REF-12345",
          "paid_at": "2026-03-30 12:05:00",
          "payment_method_name": "Credit Card",
          "created_at": "2026-03-30 12:00:00"
        }
      ],
      "pagination": {
        "current_page": 1,
        "total": 156
      }
    }

### Record Payment

POST `/payments`

Request:

    {
      "order_id": 101,
      "amount": 531.00,
      "payment_method_id": 1,
      "transaction_id": "TXN-12345",
      "reference_number": "REF-12345",
      "notes": "Payment for order #101"
    }

Response (201):

    {
      "message": "Payment processed successfully",
      "data": {...}
    }

### Get Payment by Order

GET `/payments/order/{orderId}/summary`

Response (200):

    {
      "data": {
        "order_id": 101,
        "order_total": 531.00,
        "total_paid": 531.00,
        "remaining_amount": 0,
        "payment_status": "completed",
        "payment_count": 1,
        "payments": [...]
      }
    }

### Get Customer Payments

GET `/payments?customer_id=1`

Response (200):

    {
      "data": [...]
    }

### Get Payments by Method

GET `/payments?method=card&per_page=20`

Response (200):

    {
      "data": [...]
    }

### Get Payments by Status

GET `/payments?status=completed&per_page=20`

Response (200):

    {
      "data": [...]
    }

### Refund Payment

POST `/payments/{id}/refund`

Request:

    {
      "reason": "Customer request"
    }

Response (201):

    {
      "message": "Payment refunded successfully",
      "data": {
        "original_payment": {...},
        "refund_payment": {...}
      }
    }

### Get Payment Summary

GET `/payments/summary?days=7`

Response (200):

    {
      "data": {
        "total_revenue": 25000.00,
        "completed_count": 45,
        "average_transaction": 555.56,
        "revenue_by_method": [
          {
            "method": "Card",
            "total": 15000,
            "count": 30
          }
        ]
      }
    }

## Inventory Management

### List Inventory Items

GET `/inventory?per_page=15&search=flour&low_stock=true`

Query Parameters:

- `search` (string): Search by name
- `low_stock` (boolean): Show low stock items

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "Flour",
          "description": "All-purpose flour",
          "current_stock": 50,
          "minimum_stock": 100,
          "unit": "kg",
          "unit_price": 50.00,
          "stock_value": 2500.00,
          "reorder_level": 100,
          "supplier_id": 1,
          "status": "low_stock",
          "last_updated": "2026-03-31 10:00:00"
        }
      ]
    }

### Add Inventory

POST `/inventory`

Request:

    {
      "name": "Flour",
      "description": "All-purpose flour",
      "current_stock": 500,
      "minimum_stock": 100,
      "unit": "kg",
      "unit_price": 50.00,
      "reorder_level": 100,
      "supplier_id": 1,
      "status": "in_stock"
    }

Response (201):

    {
      "message": "Inventory item added successfully",
      "data": {...}
    }

### Get Low Stock Items

GET `/inventory/low-stock`

Response (200):

    {
      "data": [...]
    }

### Get Out of Stock Items

GET `/inventory/out-of-stock`

Response (200):

    {
      "data": [...]
    }

### Update Inventory

PUT `/inventory/{id}`

Request:

    {
      "current_stock": 300,
      "unit_price": 55.00
    }

Response (200):

    {
      "message": "Inventory updated successfully",
      "data": {...}
    }

### Get Inventory Summary

GET `/inventory/summary`

Response (200):

    {
      "data": {
        "total_items": 45,
        "in_stock": 40,
        "low_stock": 4,
        "out_of_stock": 1,
        "total_value": 125000.00
      }
    }

## Suppliers & Purchases

### List Suppliers

GET `/suppliers?per_page=15&status=active`

Response (200):

    {
      "data": [
        {
          "id": 1,
          "name": "Fresh Produce Co",
          "contact_person": "Mr. Smith",
          "email": "supplier@example.com",
          "phone": "9876543210",
          "address": "123 Supplier St",
          "city": "Chicago",
          "payment_terms": "Net 30",
          "status": "active",
          "created_at": "2026-01-01 10:00:00"
        }
      ]
    }

### Create Supplier

POST `/suppliers`

Request:

    {
      "name": "Fresh Produce Co",
      "contact_person": "Mr. Smith",
      "email": "supplier@example.com",
      "phone": "9876543210",
      "address": "123 Supplier St",
      "city": "Chicago",
      "payment_terms": "Net 30",
      "status": "active"
    }

Response (201):

    {
      "message": "Supplier created successfully",
      "data": {...}
    }

### List Purchases

GET `/purchases?per_page=15&status=pending&from_date=2026-03-01&to_date=2026-03-31`

Query Parameters:

- `status` (string): pending, confirmed, received, cancelled
- `supplier_id` (integer): Filter by supplier

Response (200):

    {
      "data": [
        {
          "id": 1,
          "purchase_number": "PO-2026-001",
          "supplier_id": 1,
          "supplier_name": "Fresh Produce Co",
          "items_count": 5,
          "total_amount": 5000.00,
          "status": "pending",
          "expected_delivery": "2026-04-05",
          "created_at": "2026-03-31 10:00:00"
        }
      ]
    }

### Create Purchase Order

POST `/purchases`

Request:

    {
      "supplier_id": 1,
      "items": [
        {
          "inventory_item_id": 1,
          "quantity": 100,
          "unit_price": 50.00
        }
      ],
      "expected_delivery": "2026-04-05",
      "notes": "Urgent order"
    }

Response (201):

    {
      "message": "Purchase order created successfully",
      "data": {...}
    }

### Get Pending Purchases

GET `/purchases/pending`

Response (200):

    {
      "data": [...]
    }

### Confirm Purchase Order

POST `/purchases/{id}/confirm`

Response (200):

    {
      "message": "Purchase order confirmed successfully",
      "data": {...}
    }

### Get Purchases by Supplier

GET `/purchases/by-supplier/{supplierId}`

Response (200):

    {
      "data": [...]
    }

## Financial Reports

### Profit & Loss Summary

GET `/financial-reports/profit-and-loss?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Profit & Loss summary retrieved successfully",
      "data": {
        "period": {
          "from_date": "2026-03-01",
          "to_date": "2026-03-31"
        },
        "revenue": {
          "total": 125000.00,
          "formatted": "₹125000.00"
        },
        "expenses": {
          "total": 45000.00,
          "formatted": "₹45000.00"
        },
        "net_profit": {
          "total": 80000.00,
          "formatted": "₹80000.00"
        },
        "profit_margin": 64.00,
        "status": "profitable"
      }
    }

### Revenue by Payment Method

GET `/financial-reports/revenue-by-method?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Revenue by payment method retrieved successfully",
      "data": [
        {
          "method": "Card",
          "total": 75000.00,
          "count": 150,
          "percentage": 60.00
        },
        {
          "method": "Cash",
          "total": 50000.00,
          "count": 100,
          "percentage": 40.00
        }
      ]
    }

### Daily Financial Summary

GET `/financial-reports/daily-summary?date=2026-03-31`

Response (200):

    {
      "message": "Daily financial summary retrieved successfully",
      "data": {
        "date": "2026-03-31",
        "revenue": {
          "total": 5000.00,
          "formatted": "₹5000.00"
        },
        "expenses": {
          "total": 1500.00,
          "formatted": "₹1500.00"
        },
        "net_profit": {
          "total": 3500.00,
          "formatted": "₹3500.00"
        }
      }
    }

### Monthly Financial Summary

GET `/financial-reports/monthly-summary?year=2026&month=3`

Response (200):

    {
      "message": "Monthly financial summary retrieved successfully",
      "data": {
        ...same as profit-and-loss...
      }
    }

### Branch-wise Profit Comparison (Admin Only)

GET `/financial-reports/branch-comparison?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Branch-wise profit comparison retrieved successfully",
      "data": [
        {
          "branch_id": 1,
          "branch_name": "Main Branch",
          "revenue": 125000.00,
          "expenses": 45000.00,
          "net_profit": 80000.00,
          "profit_margin": 64.00
        }
      ]
    }

### Financial Dashboard

GET `/financial-reports/dashboard?from_date=2026-03-01&to_date=2026-03-31`

Complete financial overview.

Response (200):

    {
      "message": "Financial dashboard retrieved successfully",
      "data": {
        "profit_and_loss": {...},
        "revenue_by_method": [...],
        "expense_summary": {
          "total_expenses": 45000.00,
          "formatted_total": "₹45000.00",
          "by_category": [
            {
              "category": "Salaries",
              "total": 20000.00,
              "count": 1
            }
          ]
        }
      }
    }

### Total Revenue

GET `/financial-reports/total-revenue?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Total revenue retrieved successfully",
      "data": {
        "total": 125000.00,
        "formatted": "₹125000.00"
      }
    }

### Expense Summary

GET `/financial-reports/expense-summary?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Expense summary retrieved successfully",
      "data": {
        "total_expenses": 45000.00,
        "formatted_total": "₹45000.00",
        "by_category": [
          {
            "category": "Salaries",
            "total": 20000.00,
            "count": 1
          },
          {
            "category": "Utilities",
            "total": 15000.00,
            "count": 3
          },
          {
            "category": "Rent",
            "total": 10000.00,
            "count": 1
          }
        ],
        "category_count": 3
      }
    }

## Expenses

### List Expenses

GET `/expenses?per_page=15&category=utilities&from_date=2026-03-01&to_date=2026-03-31`

Query Parameters:

- `category` (string): Filter by category slug
- `from_date` (date): From date
- `to_date` (date): To date

Response (200):

    {
      "message": "Expenses retrieved successfully",
      "data": [
        {
          "id": 1,
          "branch_id": 1,
          "category": {
            "id": 1,
            "name": "Utilities",
            "slug": "utilities"
          },
          "title": "March Electricity Bill",
          "amount": 5000.00,
          "expense_date": "2026-03-31",
          "notes": "Monthly electricity",
          "receipt_url": "https://...",
          "created_by": "John Doe",
          "updated_by": null,
          "created_at": "2026-03-31 10:00:00"
        }
      ],
      "pagination": {
        "current_page": 1,
        "total": 45
      }
    }

### Add Expense

POST `/expenses`

Request:

    {
      "expense_category_id": 1,
      "title": "March Electricity Bill",
      "amount": 5000,
      "expense_date": "2026-03-31",
      "notes": "Monthly electricity",
      "receipt_url": "https://..."
    }

Response (201):

    {
      "message": "Expense created successfully",
      "data": {...}
    }

### Update Expense

PUT `/expenses/{id}`

Request:

    {
      "amount": 5200,
      "notes": "Updated electricity bill"
    }

Response (200):

    {
      "message": "Expense updated successfully",
      "data": {...}
    }

### Delete Expense

DELETE `/expenses/{id}`

Response (200):

    {
      "message": "Expense deleted successfully"
    }

### Get Expense Summary

GET `/expenses/summary?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Expense summary retrieved successfully",
      "data": {
        "total_expenses": 45000.00,
        "breakdown_by_category": [
          {
            "category": "Salaries",
            "total": 20000.00,
            "count": 1
          }
        ],
        "category_count": 5
      }
    }

### Get Daily Expense Totals

GET `/expenses/daily-totals?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Daily expense totals retrieved successfully",
      "data": [
        {
          "date": "2026-03-31",
          "total": 1500.00
        }
      ]
    }

### Get Expenses by Category

GET `/expenses/category/{category}?from_date=2026-03-01&to_date=2026-03-31`

Response (200):

    {
      "message": "Expenses by category retrieved successfully",
      "data": [...]
    }

## Error Responses

All endpoints may return the following error responses:

### 400 Bad Request

    {
      "message": "Validation failed",
      "errors": {
        "email": ["Email field is required"],
        "amount": ["Amount must be greater than 0"]
      }
    }

### 401 Unauthorized

    {
      "message": "Unauthorized - Please login first"
    }

### 403 Forbidden

    {
      "message": "Forbidden - You don't have permission to access this resource"
    }

### 404 Not Found

    {
      "message": "Resource not found"
    }

### 422 Unprocessable Entity

    {
      "message": "Error processing request",
      "errors": {
        "field": ["Error message"]
      }
    }

### 500 Internal Server Error

    {
      "message": "Internal server error",
      "error": "Error details"
    }

## Rate Limiting

- Rate limit: 1000 requests per hour per user
- Rate limit headers return: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`

## Support

For API support, contact: `api-support@restaurant-rms.com`

Version 1.0 | Last Updated: March 31, 2026