# BO Approval KPI System - Integration Guide

## Overview

This KPI system tracks how long each user takes to process and approve BO (Back Office) account requests at each stage of the approval workflow.

## Key Features

✅ **Automatic KPI Logging** - Logs processing time when approvals happen
✅ **Comprehensive Dashboard** - Multiple endpoints for different KPI views
✅ **Performance Tracking** - Track individual user performance, stage bottlenecks, and leaderboards
✅ **Data Integrity** - Prevents duplicate KPI logs

## Database Schema

The `officeuser_bo_kpi_log` table stores:
- `user_id`: The user who approved/processed
- `bo_in_id`: The BO initial ID
- `key`: The stage (S, FI, FA, FD, FM, C)
- `duration`: Processing time in hours (decimal)
- `timestamps`: When the KPI was logged

## Integration Steps

### Step 1: Add KPI Logging to Approval Updates

Since the controllers use `DB::table()` instead of Eloquent models, you need to explicitly call the KPI logging service after each approval update.

**Example Integration in BOStatusUpdateController:**

```php
// After updating approval_log entry (around line 235)
DB::table('approval_log')
    ->where('id', $existingLog->id)
    ->update([
        'comment' => $comment,
        'flag' => 'A',
        'update_by' => $userId,
        'updated_at' => now()
    ]);

// Add this line to log KPI
\App\Services\BOApprovalKPIService::logKPIFromApprovalLog($existingLog->id);
```

**Locations to Add KPI Logging:**

1. `BOStatusUpdateController.php`:
   - After FI approval (line ~235)
   - After FA approval (line ~279)
   - After FD approval (line ~325)
   - After FM approval (line ~365)
   - After C approval (line ~190) - Note: Don't log for status 'A'

2. `UpdateQuickBOAccountController.php`:
   - After S approval (line ~553) - Use `logInitialSubmissionKPI()` instead

3. Any other controllers that update approval_log with flag='A'

### Step 2: Add Routes

Add these routes to `routes/api.php`:

```php
// KPI Dashboard Routes
Route::middleware(['jwt.auth', 'check.token', 'dynamic.permission'])->group(function () {
    Route::get('/kpi/bo/overall', [BOApprovalKPIController::class, 'overallKPI']);
    Route::get('/kpi/bo/user/{user_id}', [BOApprovalKPIController::class, 'userKPI']);
    Route::get('/kpi/bo/leaderboard', [BOApprovalKPIController::class, 'leaderboard']);
    Route::get('/kpi/bo/bottlenecks', [BOApprovalKPIController::class, 'bottleneckAnalysis']);
    Route::get('/kpi/bo/dashboard', [BOApprovalKPIController::class, 'dashboard']);
    Route::post('/kpi/bo/recalculate/{bo_in_id}', [BOApprovalKPIController::class, 'recalculateKPI']);
});
```

### Step 3: Test Integration

1. Create a test BO approval workflow
2. Check that KPI logs are created in `officeuser_bo_kpi_log` table
3. Test the dashboard endpoints

## API Endpoints

### 1. Overall KPI Statistics
```
GET /api/kpi/bo/overall?start_date=2026-01-01&end_date=2026-01-31
```
Returns aggregate metrics across all BOs.

### 2. User-Specific KPI
```
GET /api/kpi/bo/user/4?start_date=2026-01-01&end_date=2026-01-31
```
Returns KPI statistics for a specific user.

### 3. Leaderboard
```
GET /api/kpi/bo/leaderboard?sort=fastest&limit=10
```
Options:
- `sort`: fastest, slowest, or busiest
- `limit`: Number of results (default: 10)

### 4. Bottleneck Analysis
```
GET /api/kpi/bo/bottlenecks?start_date=2026-01-01&end_date=2026-01-31
```
Identifies stages that take the longest.

### 5. Dashboard Summary
```
GET /api/kpi/bo/dashboard?start_date=2026-01-01&end_date=2026-01-31
```
Comprehensive dashboard with all key metrics.

### 6. Recalculate KPI
```
POST /api/kpi/bo/recalculate/{bo_in_id}
```
Recalculates KPI for a specific BO (useful for data migration).

### 7. BO-Specific Approval Log
```
GET /api/kpi/bo/approval-log?bo_in_id=604
```
Existing endpoint now also returns KPI logs.

## Stage Codes

- **S**: Initial Submission (Client → Initiator)
- **FI**: For Initiator (Processing by Initiator)
- **FA**: For Accountant (Accounting review)
- **FD**: For DMD (Deputy Managing Director)
- **FM**: For MD (Managing Director)
- **C**: For Completor (Final processing)
- **A**: Approved (Final status - no KPI logged)

## User Roles Reference

- **Initiator/Completor**: user_id = 4
- **Accountant**: user_id = 38
- **MD**: user_id = 13
- **DMD**: user_id = 52
- **Clients**: Any 3-digit user_id

## Data Migration

If you need to backfill KPI data for existing approvals:

```php
use App\Services\BOApprovalKPIService;

// Recalculate for a specific BO
$result = BOApprovalKPIService::recalculateKPIForBO(604);

// Or batch process
$boIds = DB::table('approval_log')
    ->where('type', 'BOA')
    ->distinct()
    ->pluck('reference_id');

foreach ($boIds as $boId) {
    BOApprovalKPIService::recalculateKPIForBO($boId);
}
```

## Notes

- KPI logging only happens when `flag` changes to 'A' (Approved)
- Final status 'A' is not logged (it's just a completion marker)
- Duplicate prevention: KPI logs check for existing entries to prevent duplicates
- Duration is calculated in hours with 2 decimal precision
- All timestamps are automatically handled

## Troubleshooting

**Issue**: KPI logs not being created
- **Solution**: Ensure you're calling `logKPIFromApprovalLog()` after approval updates
- Check that `update_by` is set when flag changes to 'A'

**Issue**: Duplicate KPI logs
- **Solution**: The service has duplicate prevention built-in. If duplicates exist, they may be from manual inserts before the prevention was added.

**Issue**: Incorrect duration calculations
- **Solution**: Use `recalculateKPIForBO()` to recalculate for specific BOs
