# 🧾 Billing Records API Documentation

This document describes the API endpoints for managing Billing Records in the Hotel Billing System.

## 🚀 Base URL
```
http://localhost:4000/api/billing
```

## 🔑 Authentication
All endpoints are **[Protected]** — Admin JWT required.

**Header:** `Authorization: Bearer <your_jwt_token>`

---

## 📡 Endpoints

### 1. Create Billing Record
Creates a new billing entry. The server automatically:
- Computes `total_price` per item (`qty × price`)
- Recalculates `tax_amount` and `total_amount` from `subtotal` and `tax_percentage`
- Assigns the next sequential, gapless `bill_number` (e.g., if previous was #10, this is #11)
- Generates `ticket_number` in format `TableNum-YYYYMMDD-HHMMSS` if not provided.

- **URL:** `/`
- **Method:** `POST`
- **Body:**
  ```json
  {
    "receipt_config_id": 1,
    "ticket_number": "TKT-001",
    "table_number": "T-05",
    "waiter_code": "W-12",
    "pos_terminal": "POS-A",
    "customer_name": "John Doe",
    "items": [
      {
        "id": 3,
        "category_id": 1,
        "name": "Paneer Tikka",
        "qty": 2,
        "price": 250.00
      },
      {
        "id": 7,
        "category_id": 2,
        "name": "Butter Naan",
        "qty": 3,
        "price": 40.00
      }
    ],
    "subtotal": 620.00,
    "tax_percentage": 18.00,
    "payment_method": "card",
    "date": "2026-04-01",
    "time": "13:30:00",
    "is_paid": true
  }
  ```

- **Items Field Rules:**

  | Field | Required | Description |
  |---|---|---|
  | `id` | ✅ Yes | `menu_items.id` from the Menu Items table |
  | `category_id` | ✅ Yes | `menu_categories.id` the item belongs to |
  | `name` | ✅ Yes | Display name of the item |
  | `qty` | ✅ Yes | Quantity ordered (must be > 0) |
  | `price` | ✅ Yes | Unit price of the item (must be > 0) |
  | `total_price` | ❌ Computed | **Do not send.** Server calculates: `qty × price` |

- **Success Response `201 Created`:**
  ```json
  {
    "success": true,
    "message": "Billing record created successfully.",
    "data": {
      "id": 7,
      "bill_number": 11,
      "items": [
        {
          "id": 3,
          "category_id": 1,
          "name": "Paneer Tikka",
          "qty": 2,
          "price": 250.00,
          "total_price": 500.00
        },
        {
          "id": 7,
          "category_id": 2,
          "name": "Butter Naan",
          "qty": 3,
          "price": 40.00,
          "total_price": 120.00
        }
      ],
      "subtotal": 620.00,
      "tax_percentage": 18.00,
      "tax_amount": 111.60,
      "total_amount": 731.60
    }
  }
  ```

- **Error Responses:**
  - `400 Bad Request` — Validation failed, missing required item fields, or `receipt_config_id` not found.
  - `409 Conflict` — Duplicate `ticket_number` already exists.

---

### 2. Get All Billing Records (Paginated)
Returns a paginated list ordered by newest first. Includes hotel name from receipt config.

- **URL:** `/?page=1`
- **Method:** `GET`
- **Query Params:** `page` (optional, default `1`, limit `20`)
- **Success Response `200 OK`:**
  ```json
  {
    "success": true,
    "data": [
      {
        "id": 7,
        "bill_number": 11,
        "ticket_number": "T-05-20260401-133005",
        "table_number": "T-05"
      }
    ],
    "pagination": {
      "total": 55,
      "page": 1,
      "limit": 20,
      "lastPage": 3
    }
  }
  ```

---

### 3. Get Billing Record by ID
Returns the full detail of a billing record including receipt config data (hotel, GST, etc.).
The `items` field is returned as a parsed JSON array with `total_price` per item.

- **URL:** `/:id`
- **Method:** `GET`
- **Success Response `200 OK`:**
  ```json
  {
    "success": true,
    "data": {
      "id": 7,
      "bill_number": 11,
      "ticket_number": "T-05-20260401-133005",
      "items": [
        {
          "id": 3,
          "category_id": 1,
          "name": "Paneer Tikka",
          "qty": 2,
          "price": 250.00,
          "total_price": 500.00
        }
      ],
      "subtotal": 620.00,
      "tax_amount": 111.60,
      "total_amount": 731.60,
      "hotel_name": "Grand Plaza Hotel",
      "gst_number": "22AAAAA0000A1Z5",
      "address": "123 Main St"
    }
  }
  ```
- **Error Responses:**
  - `404 Not Found` — Record does not exist.

---

### 4. Update Billing Record
Updates an existing billing record. Financials are recalculated server-side. Items `total_price` is also recomputed.

- **URL:** `/:id`
- **Method:** `PUT`
- **Body:** Same structure as Create (items array included). `receipt_config_id` cannot be changed.
- **Success Response `200 OK`:**
  ```json
  {
    "success": true,
    "message": "Billing record updated successfully.",
    "data": {
      "id": 7,
      "subtotal": 620.00,
      "tax_amount": 111.60,
      "total_amount": 731.60
    }
  }
  ```

---

### 5. Delete Billing Record
Permanently deletes a billing record. This action is **irreversible**.

> [!IMPORTANT]
> **Gapless Re-sequencing**: Deleting a record triggers an automatic re-numbering of all subsequent bills (e.g., if Bill #2 is deleted, Bill #3 becomes #2, Bill #4 becomes #3) to ensure no gaps are visible in the billing history.

- **URL:** `/:id`
- **Method:** `DELETE`
- **Success Response `200 OK`:**
  ```json
  {
    "success": true,
    "message": "Billing record #7 (Bill #11) permanently deleted and sequence updated."
  }
  ```
- **Error Responses:**
  - `404 Not Found` — Record does not exist.

---

## ⚠️ Important Calculation Rules

> [!IMPORTANT]
> **Per-item `total_price`** is always computed by the server as `qty × price`. Do not send this field.
>
> **`tax_amount`** and **`total_amount`** are always recalculated from `subtotal` and `tax_percentage`. Client-provided values are ignored.

---

## 📊 HTTP Status Code Reference

| Code | Meaning |
|---|---|
| `201` | Record created successfully |
| `200` | Request succeeded |
| `400` | Validation error or bad input |
| `401` | Missing or invalid JWT token |
| `404` | Record not found |
| `409` | Duplicate `ticket_number` |
