# OT Authorization Form & COC Tracking — API Reference

> **Integration Guide:** See [`ot-authorization-frontend-integration.md`](./ot-authorization-frontend-integration.md) for the frontend-orchestrated approval flow with ms-general.

## Base URLs

| Environment | Prefix | Auth |
|-------------|--------|------|
| Internal (v1) | `/api/v1` | None (internal network) |
| API Gateway (v2) | `/api/v2` | `verify.service.token` middleware (JWT) |

> **Note:** Both route files map to the same controllers. Use the gateway for external requests, v1 for internal.

---

## 1. OT Authorization (Filing Authority)

### 1.1 Create OT Authorization

Creates a pre-approval overtime authorization. Supports **multiple employees × multiple dates** in one request.

```
POST /api/v1/filing_authority/overtime
```

**Request Body:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `employee_id` | `string[]` | **yes** | Array of employee codes |
| `date_filed` | `date` (Y-m-d) | **yes** | Date the form was filed |
| `date_overtime` | `date[]` | **yes** | Array of OT dates (supports expansion via `broken_date`) |
| `time_start` | `time` (H:i:s) | **yes** | OT start time |
| `time_end` | `time` (H:i:s) | **yes** | OT end time (must be after `time_start`) |
| `total_hours` | `number` | **yes** | Total OT hours |
| `ot_type` | `string` | no | `weekday_ot`, `holiday_rest_day_ot`, `emergency_ot` |
| `compensation_mode` | `string` | no | `cash_payment`, `compensatory_overtime_credit` |
| `reason` | `string` | no | Purpose/justification |
| `broken_date` | `boolean` | **yes** | `true` = single date, `false` = treat dates as a range to expand |

**Example — Single employee, single date:**
```json
{
  "employee_id": ["EMP001"],
  "date_filed": "2026-05-25",
  "date_overtime": ["2026-05-27"],
  "time_start": "17:00:00",
  "time_end": "20:00:00",
  "total_hours": 3,
  "ot_type": "weekday_ot",
  "compensation_mode": "compensatory_overtime_credit",
  "reason": "Project deadline extension",
  "broken_date": true
}
```

**Example — Multiple employees, date range:**
```json
{
  "employee_id": ["EMP001", "EMP002", "EMP003"],
  "date_filed": "2026-05-25",
  "date_overtime": ["2026-05-27", "2026-05-28"],
  "time_start": "17:00:00",
  "time_end": "20:00:00",
  "total_hours": 3,
  "ot_type": "weekday_ot",
  "compensation_mode": "cash_payment",
  "reason": "System migration weekend",
  "broken_date": false
}
```

**Response (201):**
```json
{
  "success": true,
  "data": {
    "id": 42,
    "employee_id": "EMP001",
    "date_overtime": "2026-05-27",
    "with_authorization": true,
    "authorization_status": "pending",
    "is_retroactive": false,
    "ot_type": "weekday_ot",
    "compensation_mode": "compensatory_overtime_credit",
    "...": "..."
  },
  "message": "Overtime created successfully"
}
```

> **Note:** When creating multiple records (multi-employee or multi-date), only the **last created record** is returned in the response.

### 1.2 List OT Authorizations

Retrieves all OT authorization entries (those with `with_authorization=true`).

```
GET /api/v1/filing_authority/overtime
```

**Query Parameters:**

| Param | Type | Operator Support | Description |
|-------|------|-----------------|-------------|
| `employee_id` | string | yes | Filter by employee |
| `date_overtime` | date (Y-m-d) | yes | Filter by OT date |
| `authorization_status` | string | yes | `pending`, `approved`, `rejected` |
| `ot_type` | string | yes | `weekday_ot`, `holiday_rest_day_ot`, `emergency_ot` |
| `compensation_mode` | string | yes | `cash_payment`, `compensatory_overtime_credit` |
| `is_retroactive` | boolean | yes | `true` or `false` |
| `page` | integer | no | Page number (default: 1) |
| `limit` | integer | no | Items per page (max: 1000) |

**Operator prefix examples:**
```
?employee_id=eq:EMP001     → exact match
?date_overtime=gte:2026-01-01 → greater than or equal
?total_hours=gt:2          → greater than
?authorization_status=neq:rejected → not equal
```

**Response (200):**
```json
{
  "success": true,
  "data": [
    {
      "id": 42,
      "employee_id": "EMP001",
      "employee": { "employee_code": "EMP001", "name": "Juan Dela Cruz" },
      "date_overtime": "2026-05-27",
      "ot_type": "weekday_ot",
      "compensation_mode": "compensatory_overtime_credit",
      "authorization_status": "approved",
      "is_retroactive": false,
      "total_hours": 3,
      "...": "..."
    }
  ],
  "message": "Overtimes for authority retrieved successfully"
}
```

### 1.3 Get Single OT Authorization

```
GET /api/v1/filing_authority/overtime/{id}
```

**Response (200):**
```json
{
  "success": true,
  "data": { "...same structure as list item..." },
  "message": "Overtime for authority retrieved successfully"
}
```

**Response (404):**
```json
{
  "success": false,
  "message": "Overtime not found or does not require authority approval"
}
```

### 1.4 Update OT Authorization

```
PUT /api/v1/filing_authority/overtime/{id}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `time_start` | `time` | no | Updated OT start |
| `time_end` | `time` | no | Updated OT end |
| `total_hours` | `number` | no | Updated hours |
| `ot_type` | `string` | no | `weekday_ot`, `holiday_rest_day_ot`, `emergency_ot` |
| `compensation_mode` | `string` | no | `cash_payment`, `compensatory_overtime_credit` |
| `reason` | `string` | no | Updated reason |

> **Note:** Cannot update `authorization_status` here (use approval endpoint instead).

### 1.5 Delete OT Authorization

```
DELETE /api/v1/filing_authority/overtime/{id}
```

Soft-deletes the entry.

**Response (200):**
```json
{
  "success": true,
  "data": null,
  "message": "Overtime deleted successfully"
}
```

---

## 2. Approval Flow

Approves/rejects OT authorization(s) in a single synchronous call.

```
POST /api/v1/approval/filing_authority/overtime
```

**Request Body:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | `int[]` | **yes** | Array of OT authorization IDs |
| `authorization_status` | `string` | **yes** | `approved` or `rejected` |
| `remarks` | `string` | no | Approval remarks |

**Behavior on `approved`:**
1. Updates `authorization_status` → `approved`
2. Creates/updates `time_entry` linked to this OT (OT appears in DTR)
3. Auto-generates schedule/shift if employee has none for that date
4. Creates COC entry (`+` operator in CTO list) only if `compensation_mode = compensatory_overtime_credit`
5. If `compensation_mode = cash_payment`, no COC entry is created (handled separately via payable endpoint)

**Example:**
```json
{
  "id": [42, 43, 44],
  "authorization_status": "approved",
  "remarks": "Approved per division head"
}
```

**Response (200):**
```json
{
  "success": true,
  "data": {
    "success": true,
    "updated": [42, 43, 44],
    "count": 3
  },
  "message": "Overtime approval processed successfully"
}
```

---

## 3. COC (Compensatory Overtime Credit) Tracking

### 3.1 Available COC Hours

Get an employee's current available COC balance.

```
GET /api/v1/available_hours/cto?employee_id=EMP001
```

**Response (200):**
```json
{
  "success": true,
  "data": {
    "employee_id": "EMP001",
    "available_hours": 12.5,
    "remaining": [
      {
        "id": 1,
        "employee_id": "EMP001",
        "operator": "+",
        "hours": 8,
        "remaining_hours": 8,
        "date_expiry": "2027-05-25",
        "overtime_id": 42,
        "...": "..."
      },
      {
        "id": 2,
        "employee_id": "EMP001",
        "operator": "+",
        "hours": 5,
        "remaining_hours": 4.5,
        "date_expiry": "2027-06-01",
        "overtime_id": 55,
        "...": "..."
      }
    ]
  },
  "message": "Available compensatory time off hours retrieved successfully"
}
```

> **Note:** Only returns entries where `remaining_hours > 0` and not expired (`date_expiry >= today` or null).

### 3.2 CTO List (Full Ledger)

```
GET /api/v1/cto
```

**Query Parameters:**

| Param | Type | Operator Support | Description |
|-------|------|-----------------|-------------|
| `employee_id` | string | yes | Filter by employee |
| `operator` | string | yes | `+` (credit) or `-` (deduction) |
| `date_expiry` | date | yes | Filter by expiry date |
| `page` | integer | no | Page number |
| `limit` | integer | no | Items per page (max: 1000) |

**Response (200):**
```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "employee_id": "EMP001",
      "operator": "+",
      "hours": 8,
      "remaining_hours": 8,
      "date_expiry": "2027-05-25",
      "overtime_id": 42,
      "remarks": null,
      "created_at": "2026-05-25T10:00:00.000000Z"
    }
  ],
  "message": "Compensatory Time Off entries retrieved successfully"
}
```

### 3.3 Create CTO Entry (Manual Filing)

```
POST /api/v1/cto
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `employee_id` | `string` | **yes** | Employee code |
| `date_cto` | `date` (Y-m-d) | **yes** | CTO date |
| `time_start` | `time` | **yes** | CTO start |
| `time_end` | `time` | **yes** | CTO end |
| `total_hours` | `number` | **yes** | Hours to use |
| `remaining_id` | `object[]` | **yes** | Array of `{id, hours}` referencing CTO list entries to consume |

### 3.4 CTO Approval

```
POST /api/v1/approval/cto
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | `int[]` | **yes** | Array of CTO entry IDs |
| `status` | `string` | **yes** | `approved` or `rejected` |

### 3.5 CTO Manual Adjustment (HR Only)

```
POST /api/v1/operator_update/cto
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `employee_id` | `string[]` | **yes** | Array of employee codes |
| `operator` | `string` | **yes** | `+` (add hours) or `-` (deduct) |
| `hours` | `number` | **yes** | Hours to add/deduct |
| `reason` | `string` | no | Reason for adjustment |

> Deduction uses FIFO: subtracts from earliest-expiring CTO entries first.

---

## 4. OT Summary Report

### 4.1 View Report (Paginated)

```
GET /api/v1/overtime-report
```

**Query Parameters:**

| Param | Type | Valid Values | Description |
|-------|------|--------------|-------------|
| `name` | string | — | Employee name (partial match) |
| `year` | integer | 2000–2100 | Filter by year |
| `month` | integer | 1–12 | Filter by month |
| `date_from` | date (Y-m-d) | — | Start of date range |
| `date_to` | date (Y-m-d) | — | End of date range (must be >= date_from) |
| `ot_type` | string | `weekday_ot`, `holiday_rest_day_ot`, `emergency_ot` | Filter by OT type |
| `employee_id` | string | — | Filter by specific employee |
| `page` | integer | min: 1 | Page number |
| `limit` | integer | 1–500 | Items per page |
| `export` | string | `excel`, `pdf`, `csv` | Export format (returns file download) |

**Example — Filtered view:**
```
GET /api/v1/overtime-report?date_from=2026-05-01&date_to=2026-05-31&ot_type=weekday_ot&employee_id=EMP001
```

**Response (200):**
```json
{
  "data": [
    {
      "employee_code": "EMP001",
      "employee_name": "Juan Dela Cruz",
      "year": 2026,
      "month": 5,
      "month_name": "May",
      "total_overtime_hours": "12.00",
      "rest_ot": "0.50",
      "total_payable_hours_remaining": "11.50",
      "total_payable_hours": "12.00"
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 15,
    "total": 3
  }
}
```

### 4.2 Export to Excel

```
GET /api/v1/overtime-report?export=excel&date_from=2026-05-01&date_to=2026-05-31
```

Returns a `.xlsx` file download.

### 4.3 Export to PDF

```
GET /api/v1/overtime-report?export=pdf&date_from=2026-05-01&date_to=2026-05-31
```

Returns a `.pdf` file download (landscape A4).

### 4.4 Export to CSV

```
GET /api/v1/overtime-report?export=csv&date_from=2026-05-01&date_to=2026-05-31
```

Returns a `.csv` file download.

**CSV Columns:** Employee Name, Year, Month, Total Overtime Hours Rendered, Rest/Break Time (hours), Total Payable Hours

---

## 5. Error Handling

All endpoints follow the same error format:

### Validation Error (422)
```json
{
  "success": false,
  "message": "The time_end must be after time_start."
}
```

### Not Found (404)
```json
{
  "success": false,
  "message": "Overtime entry not found or not under authorization."
}
```

### Unauthorized (401) — Callback only
```json
{
  "success": false,
  "message": "Unauthorized"
}
```

### Server Error (500)
```json
{
  "success": false,
  "message": "Server error description here"
}
```

---

## 6. Field Reference

### ot_type Values

| Value | Display Label |
|-------|---------------|
| `weekday_ot` | Weekday OT |
| `holiday_rest_day_ot` | Holiday / Rest Day OT |
| `emergency_ot` | Emergency OT |

### compensation_mode Values

| Value | Display Label |
|-------|---------------|
| `cash_payment` | Cash Payment |
| `compensatory_overtime_credit` | Compensatory Overtime Credit (COC) |

### authorization_status Values

| Value | Description |
|-------|-------------|
| `pending` | Awaiting approval |
| `approved` | Approved — OT authorized |
| `rejected` | Rejected |

### is_retroactive Behavior

- Auto-flagged as `true` when `date_overtime < today`
- Retroactive filings are **not blocked** but are flagged for HR visibility
- Frontend can display a warning banner: *"This is a retroactive OT filing"*

---

## 7. Complete Endpoint Summary

| # | Method | Endpoint | Purpose | Auth |
|---|--------|----------|---------|------|
| 1 | GET | `/api/v1/filing_authority/overtime` | List OT authorizations | — |
| 2 | GET | `/api/v1/filing_authority/overtime/{id}` | Get single OT authorization | — |
| 3 | POST | `/api/v1/filing_authority/overtime` | Create OT authorization | — |
| 4 | PUT | `/api/v1/filing_authority/overtime/{id}` | Update OT authorization | — |
| 5 | DELETE | `/api/v1/filing_authority/overtime/{id}` | Delete OT authorization | — |
| 6 | POST | `/api/v1/approval/filing_authority/overtime` | Direct batch approval | — |
| 7 | GET | `/api/v1/available_hours/cto?employee_id=X` | Get COC balance | — |
| 8 | GET | `/api/v1/cto` | List CTO ledger | — |
| 9 | POST | `/api/v1/cto` | Create CTO filing | — |
| 10 | POST | `/api/v1/approval/cto` | Approve/reject CTO | — |
| 11 | POST | `/api/v1/operator_update/cto` | Manual CTO adjustment | — |
| 12 | GET | `/api/v1/overtime-report` | OT summary report | — |
| 13 | GET | `/api/v1/overtime-report?export=excel` | Export OT report (Excel) | — |
| 14 | GET | `/api/v1/overtime-report?export=pdf` | Export OT report (PDF) | — |
| 15 | GET | `/api/v1/overtime-report?export=csv` | Export OT report (CSV) | — |

> **Note:** All endpoints are also available via API gateway at `/api/v2/...` with `verify.service.token` middleware.

---

## 8. Frontend Implementation Guide

### Recommended UI Form Fields

```
┌─────────────────────────────────────────────┐
│  OT Authorization Form                       │
├─────────────────────────────────────────────┤
│  Employee           [dropdown ▼]            │
│  OT Type            [dropdown ▼]            │
│                     ├─ Weekday OT           │
│                     ├─ Holiday / Rest Day OT│
│                     └─ Emergency OT         │
│  Date of OT         [date picker]           │
│  Time Start         [time picker]           │
│  Time End           [time picker]           │
│  Number of Hours    [number input]          │
│  Compensation Mode  [dropdown ▼]            │
│                     ├─ Cash Payment         │
│                     └─ COC (Comp. OT Credit)│
│  Purpose/Justification [textarea]           │
│                                              │
│  ⚠ Retroactive filing (OT date is in past)   │
│                                              │
│  [Submit] [Cancel]                           │
└─────────────────────────────────────────────┘
```

### Retroactive Warning

When user selects a past `date_overtime`, show warning:
> **"This OT authorization is for a past date. Please ensure proper justification."**

The backend handles flagging (`is_retroactive` is set automatically), so this is optional UI polish.

### COC Balance Display

Use `GET /api/v1/available_hours/cto?employee_id=X` to show the employee's current COC balance. Display:

- **Available COC Hours:** 12.5 hrs
- Each entry with its expiry date for transparency

### Report Filtering UI

```
┌─────────────────────────────────────────────┐
│  OT Summary Report Filters                   │
├─────────────────────────────────────────────┤
│  Employee        [dropdown/search ▼]        │
│  OT Type         [dropdown ▼]               │
│                  ├─ All                      │
│                  ├─ Weekday OT              │
│                  ├─ Holiday / Rest Day OT   │
│                  └─ Emergency OT            │
│  Date From       [date picker]              │
│  Date To         [date picker]              │
│                                              │
│  [Apply] [Reset] [Export Excel]             │
│                    [Export PDF]             │
│                    [Export CSV]             │
└─────────────────────────────────────────────┘
```
