Re_Figma_Code/DASHBOARD_FORMULAS.md
2025-11-17 11:00:17 +05:30

17 KiB
Raw Blame History

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