# Voucher APIs Documentation

## Overview
The Voucher Management System allows users to create voucher slots using their **commission wallet balance**. Users can only manage their own vouchers with complete security and ownership validation.

---

## 🔑 Key Features

✅ **Wallet Integration** - Uses commission wallet balance to purchase vouchers  
✅ **Balance Validation** - Checks sufficient balance before creating vouchers  
✅ **Automatic Deduction** - Deducts total cost from commission wallet  
✅ **Unique Codes** - Generates unique voucher codes (`VCH-XXXXXXXXXXXX`)  
✅ **Ownership Security** - Users can only view/update their own vouchers  
✅ **Status Management** - Track voucher usage (Unused, Used, Expired, Cancelled)  
✅ **Statistics** - Get detailed voucher statistics and wallet information  

---

## 📊 Database Schema

### Tables Used

#### `vouchers` Table
```sql
CREATE TABLE `vouchers` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `created_at` datetime NOT NULL DEFAULT current_timestamp(),
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  `user_id` int(11) NOT NULL,
  `voucher_type` int(11) NOT NULL,
  `voucher_amount` float NOT NULL,
  `voucher` varchar(150) NOT NULL,
  `status` varchar(50) NOT NULL DEFAULT 'Unused',
  PRIMARY KEY (`id`)
);
```

#### `voucher_type` Table
```sql
CREATE TABLE `voucher_type` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `voucher_name` varchar(50) NOT NULL,
  `voucher_amount` float NOT NULL,
  `status` tinyint(4) NOT NULL DEFAULT 1,
  PRIMARY KEY (`id`)
);
```

---

## 🚀 API Endpoints

### 1. Get Voucher Types
**Endpoint:** `GET /api/voucher/types`  
**Authentication:** Not required (Public)  
**Description:** Get all active voucher types with their amounts

**Response:**
```json
{
  "success": true,
  "message": "Voucher types retrieved successfully",
  "data": [
    {
      "id": 1,
      "voucher_name": "Gold Voucher",
      "voucher_amount": 500,
      "status": 1
    },
    {
      "id": 2,
      "voucher_name": "Silver Voucher",
      "voucher_amount": 200,
      "status": 1
    }
  ]
}
```

---

### 2. Create Voucher Slots ⭐ (Main API)
**Endpoint:** `POST /api/voucher/create-slots`  
**Authentication:** Required (Bearer Token)  
**Description:** Create voucher slots using commission wallet balance

**Request Body:**
```json
{
  "voucher_type_id": 1,
  "quantity": 5
}
```

**Workflow:**
1. Validates voucher type exists and is active
2. Calculates total cost: `voucher_amount × quantity`
3. Checks commission wallet balance
4. Deducts amount from commission wallet
5. Creates voucher entries with unique codes
6. Returns created vouchers and payment details

**Success Response (Sufficient Balance):**
```json
{
  "success": true,
  "message": "Successfully created 5 out of 5 voucher slots",
  "data": {
    "voucher_type_id": 1,
    "voucher_type_name": "Gold Voucher",
    "voucher_amount": 500,
    "requested_quantity": 5,
    "created_count": 5,
    "failed_count": 0,
    "vouchers": [
      {
        "voucher_id": 101,
        "voucher_code": "VCH-A2B3C4D5E6F7",
        "amount": 500
      },
      {
        "voucher_id": 102,
        "voucher_code": "VCH-X9Y8Z7W6V5U4",
        "amount": 500
      }
    ],
    "payment_details": {
      "total_cost": 2500,
      "payment_id": 456,
      "previous_balance": 5000,
      "current_balance": 2500,
      "amount_deducted": 2500
    }
  }
}
```

**Error Response (Insufficient Balance):**
```json
{
  "success": false,
  "message": "Insufficient commission wallet balance",
  "data": {
    "required_amount": 2500,
    "available_balance": 1000,
    "shortfall": 1500,
    "voucher_type": "Gold Voucher",
    "voucher_amount": 500,
    "quantity": 5
  }
}
```

**Payment Entry Created:**
- Recorded in `payment` table
- `fromID` = user_id (deduction from user)
- `toID` = 0 (system)
- `type1` = '1' (commission wallet)
- `details` = "Voucher Purchase - 5x Gold Voucher"
- `status` = 'completed'

---

### 3. Get My Vouchers ⭐ (Main API)
**Endpoint:** `GET /api/voucher/my-vouchers`  
**Authentication:** Required (Bearer Token)  
**Query Parameters:**
- `status` (optional): Filter by status (`Unused`, `Used`, `Expired`, `Cancelled`)

**Example Requests:**
```
GET /api/voucher/my-vouchers           # All vouchers
GET /api/voucher/my-vouchers?status=Unused   # Only unused
GET /api/voucher/my-vouchers?status=Used     # Only used
```

**Response:**
```json
{
  "success": true,
  "message": "Vouchers retrieved successfully",
  "data": {
    "user_id": 123,
    "vouchers": [
      {
        "id": 101,
        "voucher": "VCH-A2B3C4D5E6F7",
        "voucher_amount": 500,
        "status": "Unused",
        "created_at": "2025-11-03T08:15:00.000Z",
        "updated_at": "2025-11-03T08:15:00.000Z",
        "voucher_name": "Gold Voucher",
        "voucher_type_id": 1
      }
    ],
    "statistics": {
      "total_vouchers": 10,
      "total_amount": 5000,
      "unused_vouchers": 7,
      "used_vouchers": 3,
      "unused_amount": 3500
    }
  }
}
```

---

### 4. Update Voucher Status ⭐ (Main API)
**Endpoint:** `PUT /api/voucher/update-status`  
**Authentication:** Required (Bearer Token)  
**Description:** Update voucher status (user can ONLY update their own vouchers)

**Request Body:**
```json
{
  "voucher_id": 101,
  "new_status": "Used"
}
```

**Valid Status Values:**
- `Unused` - Initial state
- `Used` - Voucher has been used
- `Expired` - Voucher expired
- `Cancelled` - Voucher cancelled

**Success Response:**
```json
{
  "success": true,
  "message": "Voucher status updated successfully",
  "data": {
    "voucher_id": 101,
    "voucher_code": "VCH-A2B3C4D5E6F7",
    "voucher_name": "Gold Voucher",
    "voucher_amount": 500,
    "old_status": "Unused",
    "new_status": "Used",
    "updated_at": "2025-11-03T08:30:00.000Z"
  }
}
```

**Error Response (Not Owner):**
```json
{
  "success": false,
  "message": "Voucher not found or you do not have permission to update this voucher"
}
```

---

### 5. Get Voucher Details
**Endpoint:** `GET /api/voucher/details/:voucher_id`  
**Authentication:** Required (Bearer Token)  
**Description:** Get specific voucher details (user can ONLY view their own vouchers)

**Example Request:**
```
GET /api/voucher/details/101
```

**Response:**
```json
{
  "success": true,
  "message": "Voucher details retrieved successfully",
  "data": {
    "id": 101,
    "created_at": "2025-11-03T08:15:00.000Z",
    "updated_at": "2025-11-03T08:15:00.000Z",
    "user_id": 123,
    "voucher_type": 1,
    "voucher_amount": 500,
    "voucher": "VCH-A2B3C4D5E6F7",
    "status": "Unused",
    "voucher_name": "Gold Voucher",
    "voucher_type_id": 1
  }
}
```

---

## 🔒 Security Features

### 1. Authentication
- All protected endpoints require JWT authentication
- Token passed via `Authorization: Bearer <token>` header

### 2. Ownership Validation
- Users can **ONLY** view/update their own vouchers
- Database queries filter by `user_id` from JWT token
- Prevents unauthorized access to other users' vouchers

### 3. Wallet Balance Protection
- Checks balance before deduction
- Atomic transaction: deduct → create vouchers
- Returns detailed error if insufficient balance

### 4. Input Validation
- Validates voucher type exists and is active
- Validates quantity (1-1000 range)
- Validates status values
- Validates required fields

### 5. SQL Injection Protection
- All queries use parameterized statements
- No raw SQL string concatenation

---

## 💡 Usage Examples

### Example 1: Complete Voucher Purchase Flow

```bash
# Step 1: Check commission wallet balance
GET /api/commission/wallet/balance
Authorization: Bearer <token>

Response:
{
  "commission_wallet": 5000,
  "repurchase_wallet": 1000
}

# Step 2: View available voucher types
GET /api/voucher/types

Response:
{
  "data": [
    {"id": 1, "voucher_name": "Gold", "voucher_amount": 500}
  ]
}

# Step 3: Calculate: 500 × 5 = 2500 (have 5000, OK!)
# Create 5 gold vouchers
POST /api/voucher/create-slots
Authorization: Bearer <token>
{
  "voucher_type_id": 1,
  "quantity": 5
}

Response:
{
  "success": true,
  "data": {
    "created_count": 5,
    "payment_details": {
      "total_cost": 2500,
      "previous_balance": 5000,
      "current_balance": 2500
    }
  }
}

# Step 4: View your vouchers
GET /api/voucher/my-vouchers?status=Unused
Authorization: Bearer <token>

# Step 5: Use a voucher (mark as used)
PUT /api/voucher/update-status
Authorization: Bearer <token>
{
  "voucher_id": 101,
  "new_status": "Used"
}
```

---

## 📝 Error Handling

### Common Errors

**1. Insufficient Balance**
```json
{
  "success": false,
  "message": "Insufficient commission wallet balance",
  "data": {
    "required_amount": 2500,
    "available_balance": 1000,
    "shortfall": 1500
  }
}
```

**2. Invalid Voucher Type**
```json
{
  "success": false,
  "message": "Invalid voucher type or voucher type is inactive"
}
```

**3. Unauthorized Access**
```json
{
  "success": false,
  "message": "Voucher not found or you do not have permission to update this voucher"
}
```

**4. Invalid Status**
```json
{
  "success": false,
  "message": "Invalid status. Must be one of: Unused, Used, Expired, Cancelled"
}
```

**5. Missing Token**
```json
{
  "success": false,
  "message": "Access denied. No token provided."
}
```

---

## 🧪 Testing with Postman

The Postman collection has been updated with all voucher endpoints:

**Collection Location:**
`postman/INDI-VOUCH-Backend-APIs.postman_collection.json`

**Folder:** "Voucher APIs" (7 requests)

**Test Sequence:**
1. Login to get auth token
2. Get voucher types
3. Create voucher slots
4. Get my vouchers
5. Update voucher status
6. Get voucher details

---

## 📊 Payment Table Integration

### Commission Wallet Deduction
When vouchers are created, a payment record is inserted:

```sql
INSERT INTO payment (
  date1, date2, amount, fromID, fromName, toID, toName, 
  details, status, type1, note3, schoolid, userid
) VALUES (
  CURDATE(), NOW(), 2500, 123, 'John Doe', 0, 'System',
  'Voucher Purchase - 5x Gold Voucher', 'completed', '1',
  'Voucher Purchase - 5x Gold Voucher', 1, 123
)
```

**Field Mapping:**
- `fromID` = user_id (money going from user)
- `toID` = 0 (system receiving)
- `type1` = '1' (commission wallet)
- `amount` = total cost
- `status` = 'completed'

---

## 🎯 Business Logic Summary

### Creating Vouchers
1. ✅ User must be authenticated
2. ✅ Voucher type must exist and be active
3. ✅ Calculate total cost = amount × quantity
4. ✅ Check commission wallet has sufficient balance
5. ✅ Deduct from commission wallet (recorded in `payment` table)
6. ✅ Create voucher entries with unique codes
7. ✅ Return vouchers + payment details

### Viewing Vouchers
1. ✅ User must be authenticated
2. ✅ Only show user's own vouchers (filtered by user_id)
3. ✅ Optional status filter
4. ✅ Include statistics (total, unused, used amounts)

### Updating Vouchers
1. ✅ User must be authenticated
2. ✅ Verify voucher belongs to user
3. ✅ Validate status value
4. ✅ Update status and timestamp
5. ✅ Return updated details

---

## 🚨 Important Notes

⚠️ **Wallet Type:** Uses **commission wallet only** (type1 = 1)  
⚠️ **Balance Check:** Always validates before deduction  
⚠️ **Ownership:** Users can ONLY manage their own vouchers  
⚠️ **Unique Codes:** Each voucher has a unique VCH-XXXXXXXXXXXX code  
⚠️ **Transaction Recorded:** All purchases logged in payment table  

---

## 📞 Support

For any issues or questions, refer to:
- Main API Documentation: `API_DOCUMENTATION.md`
- Postman Collection: `postman/INDI-VOUCH-Backend-APIs.postman_collection.json`
- Service Code: `services/voucherService.js`
- Routes Code: `routes/voucher.js`
