# Dashboard Formulas & Calculations Documentation

This document provides a comprehensive breakdown of all formulas and calculations used in the Dashboard for both **Admin/Management** users and **Regular Users**.

---

## 📊 **1. REQUEST VOLUME STATISTICS**

### **Admin/Management View**
**Scope:** All requests across the organization

**Formulas:**
```
Total Requests = COUNT(*) 
  WHERE submission_date BETWEEN :start AND :end
  AND is_draft = false
  AND is_deleted = false
  AND submission_date IS NOT NULL

Approved Requests = COUNT(*) 
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND is_draft = false

Rejected Requests = COUNT(*) 
  WHERE status = 'REJECTED'
  AND submission_date BETWEEN :start AND :end
  AND is_draft = false

Pending Requests = COUNT(*) 
  WHERE status IN ('PENDING', 'IN_PROGRESS')
  AND is_draft = false
  (Note: Includes ALL pending requests regardless of creation date)

Draft Requests = COUNT(*) 
  WHERE is_draft = true
```

### **Regular User View**
**Scope:** Only requests initiated by the user

**Formulas:**
```
Total Requests = COUNT(*) 
  WHERE submission_date BETWEEN :start AND :end
  AND is_draft = false
  AND initiator_id = :userId

Approved Requests = COUNT(*) 
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND initiator_id = :userId
  AND is_draft = false

Rejected Requests = COUNT(*) 
  WHERE status = 'REJECTED'
  AND submission_date BETWEEN :start AND :end
  AND initiator_id = :userId
  AND is_draft = false

Pending Requests = COUNT(*) 
  WHERE status IN ('PENDING', 'IN_PROGRESS')
  AND initiator_id = :userId
  AND is_draft = false

Draft Requests = COUNT(*) 
  WHERE is_draft = true
  AND initiator_id = :userId
```

---

## ⏱️ **2. TAT EFFICIENCY & SLA COMPLIANCE**

### **Admin/Management View**
**Scope:** All completed requests in date range

**Formulas:**
```
Completed Requests = COUNT(*) 
  WHERE status IN ('APPROVED', 'REJECTED')
  AND is_draft = false
  AND submission_date IS NOT NULL
  AND (
    (closure_date IS NOT NULL AND closure_date BETWEEN :start AND :end)
    OR (closure_date IS NULL AND updated_at BETWEEN :start AND :end)
  )

Breached Requests = COUNT(DISTINCT request_id)
  WHERE EXISTS (
    SELECT 1 FROM tat_alerts ta 
    WHERE ta.request_id = wf.request_id 
    AND ta.is_breached = true
  )

Compliant Requests = Total Completed - Breached Requests

SLA Compliance % = ROUND((Compliant Requests / Total Completed) × 100, 0)
  If Total Completed = 0, then Compliance = 0%

Average Cycle Time (Hours) = ROUND(SUM(cycle_times) / COUNT(cycle_times), 1)
  Where cycle_time = calculateElapsedWorkingHours(submission_date, completion_date, priority)
  (Respects working hours, weekends, holidays based on priority)

Average Cycle Time (Days) = ROUND(Average Cycle Time (Hours) / 8, 1)
  (Assumes 8 working hours per day)
```

### **Regular User View**
**Scope:** Only completed requests initiated by the user

**Formulas:**
```
Completed Requests = COUNT(*) 
  WHERE status IN ('APPROVED', 'REJECTED')
  AND is_draft = false
  AND submission_date IS NOT NULL
  AND initiator_id = :userId
  AND (
    (closure_date IS NOT NULL AND closure_date BETWEEN :start AND :end)
    OR (closure_date IS NULL AND updated_at BETWEEN :start AND :end)
  )

Breached Requests = COUNT(DISTINCT request_id)
  WHERE initiator_id = :userId
  AND EXISTS (
    SELECT 1 FROM tat_alerts ta 
    WHERE ta.request_id = wf.request_id 
    AND ta.is_breached = true
  )

Compliant Requests = Total Completed - Breached Requests

SLA Compliance % = ROUND((Compliant Requests / Total Completed) × 100, 0)

Average Cycle Time (Hours) = Same calculation as Admin
Average Cycle Time (Days) = Same calculation as Admin
```

**Note:** Breaches are tracked at **approver/level level** but counted at **request level** for SLA compliance.

---

## 👤 **3. APPROVER LOAD STATISTICS**

### **Admin/Management View**
**Not Applicable** - This metric is user-specific

### **Regular User View**
**Scope:** User's approval workload

**Formulas:**
```
Pending Actions = COUNT(DISTINCT level_id)
  WHERE approver_id = :userId
  AND status = 'IN_PROGRESS'
  AND request.status IN ('PENDING', 'IN_PROGRESS')
  AND is_draft = false
  AND level_number = request.current_level
  (Only counts requests at user's current active level)

Completed Today = COUNT(*)
  WHERE approver_id = :userId
  AND status IN ('APPROVED', 'REJECTED')
  AND action_date BETWEEN :start AND :end
  (Date range start/end for "today")

Completed This Week = COUNT(*)
  WHERE approver_id = :userId
  AND status IN ('APPROVED', 'REJECTED')
  AND action_date >= start_of_week
  AND action_date BETWEEN :start AND :end
```

---

## 📝 **4. ENGAGEMENT STATISTICS**

### **Admin/Management View**
**Scope:** All work notes and documents across organization

**Formulas:**
```
Work Notes Added = COUNT(*)
  FROM work_notes wn
  WHERE wn.created_at BETWEEN :start AND :end

Attachments Uploaded = COUNT(*)
  FROM documents d
  WHERE d.uploaded_at BETWEEN :start AND :end
```

### **Regular User View**
**Scope:** Only from requests initiated by the user

**Formulas:**
```
Work Notes Added = COUNT(*)
  FROM work_notes wn
  WHERE wn.created_at BETWEEN :start AND :end
  AND EXISTS (
    SELECT 1 FROM workflow_requests wf 
    WHERE wf.request_id = wn.request_id 
    AND wf.initiator_id = :userId
    AND wf.is_draft = false
  )

Attachments Uploaded = COUNT(*)
  FROM documents d
  WHERE d.uploaded_at BETWEEN :start AND :end
  AND EXISTS (
    SELECT 1 FROM workflow_requests wf 
    WHERE wf.request_id = d.request_id 
    AND wf.initiator_id = :userId
    AND wf.is_draft = false
  )
```

---

## 🤖 **5. AI INSIGHTS**

### **Admin/Management View**
**Scope:** All approved requests with conclusion remarks

**Formulas:**
```
Total with Conclusion = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND conclusion_remark IS NOT NULL
  AND is_draft = false

AI Generated Count = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND ai_generated_conclusion IS NOT NULL
  AND ai_generated_conclusion != ''
  AND is_draft = false

Manual Count = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND (ai_generated_conclusion IS NULL OR ai_generated_conclusion = '')
  AND is_draft = false

AI Adoption % = ROUND((AI Generated Count / Total with Conclusion) × 100, 0)

Average Remark Length = ROUND(AVG(LENGTH(conclusion_remark)), 0)
  WHERE status = 'APPROVED'
  AND conclusion_remark IS NOT NULL
```

### **Regular User View**
**Scope:** Only approved requests initiated by the user

**Formulas:**
```
Total with Conclusion = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND conclusion_remark IS NOT NULL
  AND initiator_id = :userId
  AND is_draft = false

AI Generated Count = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND ai_generated_conclusion IS NOT NULL
  AND ai_generated_conclusion != ''
  AND initiator_id = :userId
  AND is_draft = false

Manual Count = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND (ai_generated_conclusion IS NULL OR ai_generated_conclusion = '')
  AND initiator_id = :userId
  AND is_draft = false

AI Adoption % = ROUND((AI Generated Count / Total with Conclusion) × 100, 0)

Average Remark Length = Same calculation as Admin (filtered by initiator_id)
```

---

## 📈 **6. SUCCESS RATE (Regular Users Only)**

**Formula:**
```
Success Rate % = ROUND((Approved Requests / Total Requests) × 100, 0)
  If Total Requests = 0, then Success Rate = 0%

Where:
  Approved Requests = From Request Volume Statistics
  Total Requests = From Request Volume Statistics
```

---

## 🏢 **7. DEPARTMENT STATISTICS (Admin Only)**

**Scope:** All requests grouped by initiator's department

**Formulas:**
```
Department Stats = GROUP BY initiator.department

Total Requests per Dept = COUNT(*)
  WHERE submission_date BETWEEN :start AND :end
  AND is_draft = false
  GROUP BY initiator.department

Approved per Dept = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND is_draft = false
  GROUP BY initiator.department

Rejected per Dept = COUNT(*)
  WHERE status = 'REJECTED'
  AND submission_date BETWEEN :start AND :end
  AND is_draft = false
  GROUP BY initiator.department

In Progress per Dept = COUNT(*)
  WHERE status IN ('PENDING', 'IN_PROGRESS')
  AND submission_date BETWEEN :start AND :end
  AND is_draft = false
  GROUP BY initiator.department

Approval Rate per Dept = ROUND((Approved / Total Requests) × 100, 0)
  If Total Requests = 0, then Approval Rate = 0%
```

**Note:** Limited to top 10 departments by total requests.

---

## 🎯 **8. PRIORITY DISTRIBUTION (Admin Only)**

**Scope:** All requests grouped by priority (EXPRESS vs STANDARD)

**Formulas:**
```
Total Count per Priority = COUNT(*)
  WHERE submission_date BETWEEN :start AND :end
  AND is_draft = false
  GROUP BY priority

Approved Count per Priority = COUNT(*)
  WHERE status = 'APPROVED'
  AND submission_date BETWEEN :start AND :end
  AND is_draft = false
  GROUP BY priority

Breached Count per Priority = COUNT(DISTINCT request_id)
  WHERE EXISTS (
    SELECT 1 FROM tat_alerts ta 
    WHERE ta.request_id = wf.request_id 
    AND ta.is_breached = true
  )
  GROUP BY priority

Average Cycle Time per Priority = ROUND(SUM(cycle_times) / COUNT(cycle_times), 1)
  Where cycle_time = calculateElapsedWorkingHours(submission_date, completion_date, priority)
  Only for COMPLETED requests (status IN ('APPROVED', 'REJECTED'))
  GROUP BY priority

Compliance Rate per Priority = ROUND(((Total Count - Breached Count) / Total Count) × 100, 0)
  If Total Count = 0, then Compliance Rate = 0%
```

---

## 👥 **9. APPROVER PERFORMANCE (Admin Only)**

**Scope:** All approvers who completed approvals in date range

**Formulas:**
```
Total Approved per Approver = COUNT(DISTINCT level_id)
  WHERE approver_id = :approverId
  AND action_date BETWEEN :start AND :end
  AND status IN ('APPROVED', 'REJECTED')
  AND action_date IS NOT NULL
  AND level_start_time IS NOT NULL
  AND tat_hours > 0
  AND elapsed_hours > 0

Within TAT Count = COUNT(DISTINCT level_id)
  WHERE approver_id = :approverId
  AND action_date BETWEEN :start AND :end
  AND status IN ('APPROVED', 'REJECTED')
  AND elapsed_hours IS NOT NULL
  AND elapsed_hours > 0
  AND (
    elapsed_hours < tat_hours 
    OR (elapsed_hours <= tat_hours AND (tat_breached IS NULL OR tat_breached = false))
    OR (tat_breached IS NOT NULL AND tat_breached = false)
  )

Breached Count = COUNT(DISTINCT level_id)
  WHERE approver_id = :approverId
  AND action_date BETWEEN :start AND :end
  AND status IN ('APPROVED', 'REJECTED')
  AND elapsed_hours IS NOT NULL
  AND elapsed_hours > 0
  AND (
    elapsed_hours > tat_hours 
    OR (tat_breached IS NOT NULL AND tat_breached = true)
  )

TAT Compliance % = ROUND((Within TAT Count / Total Approved) × 100, 0)
  If Total Approved = 0, then TAT Compliance = 0%

Average Response Hours = ROUND(AVG(elapsed_hours), 1)
  WHERE approver_id = :approverId
  AND action_date BETWEEN :start AND :end
  AND status IN ('APPROVED', 'REJECTED')
  AND elapsed_hours IS NOT NULL
  AND elapsed_hours > 0

Pending Count = COUNT(DISTINCT level_id)
  WHERE approver_id = :approverId
  AND status IN ('PENDING', 'IN_PROGRESS')
  AND request.status IN ('PENDING', 'IN_PROGRESS')
  AND is_draft = false
  AND level_number = request.current_level
  (Only current active level for each request)
```

**Sorting Order:**
1. TAT Compliance % (DESC - highest first)
2. Average Response Hours (ASC - fastest first)
3. Total Approved (DESC - most approvals first)

---

## 🤖 **10. AI REMARK UTILIZATION (Admin Only)**

**Scope:** All conclusion remarks generated in date range

**Formulas:**
```
Total Usage = COUNT(*)
  FROM conclusion_remarks cr
  WHERE cr.generated_at BETWEEN :start AND :end

Total Edits = COUNT(*)
  FROM conclusion_remarks cr
  WHERE cr.generated_at BETWEEN :start AND :end
  AND cr.is_edited = true

Edit Rate % = ROUND((Total Edits / Total Usage) × 100, 0)
  If Total Usage = 0, then Edit Rate = 0%

Monthly Trends (Last 7 Months):
  AI Usage = COUNT(*)
    WHERE generated_at >= NOW() - INTERVAL '7 months'
    GROUP BY DATE_TRUNC('month', generated_at)
  
  Manual Edits = COUNT(*)
    WHERE generated_at >= NOW() - INTERVAL '7 months'
    AND is_edited = true
    GROUP BY DATE_TRUNC('month', generated_at)
```

---

## 📅 **11. DATE RANGE CALCULATIONS**

**Date Range Parsing:**
```
Today: 
  start = start_of_day(today)
  end = end_of_day(today)

This Week:
  start = start_of_week(today)
  end = end_of_week(today)

This Month:
  start = start_of_month(today)
  end = end_of_month(today)

This Quarter:
  start = start_of_quarter(today)
  end = end_of_quarter(today)

This Year:
  start = start_of_year(today)
  end = end_of_year(today)

Custom Range:
  start = start_of_day(custom_start_date)
  end = end_of_day(custom_end_date)
  (Capped at current date if future date provided)

Default (if not specified):
  start = 30 days ago (start of day)
  end = today (end of day)
```

---

## 🔍 **12. CRITICAL ALERTS**

### **Admin/Management View**
**Scope:** All requests with critical TAT status

**Formulas:**
```
Critical Requests = Requests where:
  - TAT percentage used >= 80% (approaching deadline)
  - OR TAT percentage used >= 100% (breached)
  - OR has breach alerts (is_breached = true in tat_alerts)

Breached Count = COUNT(*)
  WHERE breachCount > 0
  (From critical requests)

Warning Count = COUNT(*)
  WHERE breachCount = 0
  AND TAT percentage >= 80%
  (From critical requests)
```

### **Regular User View**
**Scope:** Only requests initiated by the user

**Formulas:**
```
Critical Requests = Same logic as Admin, filtered by initiator_id = :userId

Breached Count = Same calculation as Admin (filtered by user)
Warning Count = Same calculation as Admin (filtered by user)
```

---

## 📊 **13. UPCOMING DEADLINES**

**Scope:** Requests with active levels approaching TAT deadline

**Formulas:**
```
Upcoming Deadlines = Requests where:
  - Current level is active (status IN ('PENDING', 'IN_PROGRESS'))
  - remainingHours > 0 (not yet breached)
  - tatPercentageUsed < 100 (not yet breached)

TAT Percentage Used = ROUND((elapsedHours / tatHours) × 100, 0)
  Where elapsedHours = calculateElapsedWorkingHours(level_start_time, current_time, priority)

Remaining Hours = MAX(0, tatHours - elapsedHours)

Elapsed Hours = calculateElapsedWorkingHours(level_start_time, current_time, priority)
  (Respects working hours, weekends, holidays based on priority)
```

**Note:** Only shows requests that are NOT yet breached (remainingHours > 0 and tatPercentage < 100).

---

## 📝 **14. RECENT ACTIVITY**

### **Admin/Management View**
**Scope:** All workflow activities across organization

**Formulas:**
```
Recent Activity = All activities from workflow_requests
  ORDER BY activity.created_at DESC
  (No user filter)
```

### **Regular User View**
**Scope:** Activities from user's requests or where user is a participant

**Formulas:**
```
Recent Activity = Activities where:
  - request.initiator_id = :userId
  - OR user is a participant in the request
  ORDER BY activity.created_at DESC
```

---

## 🔑 **KEY DIFFERENCES: ADMIN vs REGULAR USER**

| Metric | Admin/Management | Regular User |
|--------|------------------|--------------|
| **Request Volume** | All organization requests | Only user-initiated requests |
| **TAT Efficiency** | All completed requests | Only user-initiated completed requests |
| **Approver Load** | N/A | User's own approval workload |
| **Engagement** | All work notes/documents | Only from user's requests |
| **AI Insights** | All approved requests | Only user's approved requests |
| **Department Stats** | ✅ Available | ❌ Not available |
| **Priority Distribution** | ✅ Available | ❌ Not available |
| **Approver Performance** | ✅ Available | ❌ Not available |
| **AI Remark Utilization** | ✅ Available | ❌ Not available |
| **Success Rate** | ❌ Not shown | ✅ Available |

---

## 📌 **IMPORTANT NOTES**

1. **Date Filtering:**
   - Most metrics use `submission_date` (when request was submitted), not `created_at`
   - Completed requests use `closure_date` or `updated_at` for completion date
   - Pending requests are counted regardless of creation date

2. **Working Hours Calculation:**
   - Cycle time uses `calculateElapsedWorkingHours()` which respects:
     - Working hours (9 AM - 6 PM)
     - Weekends (for STANDARD priority)
     - Holidays (configured in system)
     - Priority type (EXPRESS vs STANDARD)

3. **Breach Tracking:**
   - Breaches are tracked at **approver/level level** (each level has its own TAT)
   - But SLA compliance counts at **request level** (if any level breaches, entire request is non-compliant)

4. **Rounding:**
   - Percentages: Rounded to nearest integer (0 decimal places)
   - Hours: Rounded to 1 decimal place
   - Days: Rounded to 1 decimal place

5. **Null Handling:**
   - All COUNT operations handle NULL values
   - Division operations use NULLIF to prevent division by zero
   - Default values are 0 if no data exists

---

## 🔄 **DATA REFRESH**

All calculations are performed in real-time when:
- Dashboard is loaded
- Date range filter is changed
- Refresh button is clicked
- Custom date range is applied

Data is fetched in parallel for optimal performance.

---

**Last Updated:** Based on codebase as of current date
**Version:** 1.0

