# KPI Tracking System

A comprehensive KPI (Key Performance Indicator) tracking sub-module built with Laravel 12, Livewire, and Flux UI.

## Overview

This system enables organizations to:
- Define master KPI definitions
- Create year-specific KPI instances with goals
- Assign KPIs to departments with custom target values
- Track monthly progress on each KPI assignment
- View dashboards and reports based on user roles

## Database Structure

### Core Tables

1. **departments** - Organizational departments
   - `id`, `name`, `description`

2. **users** - System users (extends Laravel's default users table)
   - Added: `department_id` (nullable for admins)

3. **roles** - User roles (admin, head, staff)
   - `id`, `name`, `description`

4. **role_user** - Pivot table for user-role relationships
   - `id`, `user_id`, `role_id`

5. **kpis** - Master KPI definitions
   - `id`, `title`, `description`

6. **kpi_years** - Year-specific KPI instances
   - `id`, `kpi_id`, `year`, `default_goal_value`

7. **kpi_department_assignments** - Department-specific KPI assignments
   - `id`, `kpi_year_id`, `department_id`, `target_value`

8. **kpi_progress** - Monthly progress tracking
   - `id`, `kpi_department_assignment_id`, `month`, `year`, `progress_value`, `remarks`

## Models & Relationships

### Department Model
```php
// Relationships
hasMany: users, kpiAssignments

// Helper Methods
kpiAssignmentsForYear($year) // Get assignments for specific year
kpiProgressSummary($year)    // Get progress summary for year
```

### User Model
```php
// Relationships
belongsTo: department
belongsToMany: roles

// Helper Methods
hasRole($roleName)           // Check if user has specific role
isAdmin()                    // Check if user is admin
isHead()                     // Check if user is department head
isStaff()                    // Check if user is staff
assignRole($role)            // Assign a role to user
```

### Role Model
```php
// Constants
ADMIN = 'admin'
HEAD = 'head'
STAFF = 'staff'

// Relationships
belongsToMany: users
```

### Kpi Model
```php
// Relationships
hasMany: kpiYears

// Helper Methods
getKpiYear($year)            // Get KPI year instance
getOrCreateKpiYear($year)    // Get or create KPI year
```

### KpiYear Model
```php
// Relationships
belongsTo: kpi
hasMany: departmentAssignments
```

### KpiDepartmentAssignment Model
```php
// Relationships
belongsTo: kpiYear, department
hasMany: progress

// Helper Methods
getProgressForMonth($month, $year)      // Get progress for specific month
getTotalProgress($year)                 // Calculate total progress
getAverageProgress($year)               // Calculate average progress
getCompletionPercentage($year)          // Calculate completion percentage
```

### KpiProgress Model
```php
// Relationships
belongsTo: kpiDepartmentAssignment

// Scopes
forYear($year)               // Filter by year
forMonth($month)             // Filter by month
```

## User Roles & Permissions

### Admin
**Access:** Full system access

**Capabilities:**
- Create, edit, and delete master KPI definitions
- Create year-specific KPI instances
- Assign KPIs to departments with target values
- View comprehensive dashboards across all departments
- Manage all system data

**Routes:**
- `/admin/kpi` - KPI management index
- `/admin/kpi/create` - Create new KPI
- `/admin/kpi/{id}/edit` - Edit KPI
- `/admin/kpi/assignments` - Manage department assignments
- `/admin/kpi/dashboard` - View all KPI progress

### Department Head
**Access:** View-only access to their department's data

**Capabilities:**
- View all KPIs assigned to their department
- See monthly progress for all department KPIs
- Track completion percentages and performance
- Monitor department performance trends

**Routes:**
- `/head/department-kpis` - View department KPIs and progress

### Staff
**Access:** Enter progress for their department's KPIs

**Capabilities:**
- View KPIs assigned to their department
- Enter monthly progress values with remarks
- Edit previously entered progress for current year
- View their department's performance status

**Routes:**
- `/staff/kpis` - View assigned KPIs
- `/staff/progress/entry` - Enter monthly progress

## Livewire Components

### Admin Components

1. **KpiIndex** (`admin.kpi-index`)
   - Lists all master KPIs with search
   - Delete confirmation modal
   - Links to create/edit forms

2. **KpiForm** (`admin.kpi-form`)
   - Create/edit master KPI definitions
   - Form validation
   - Handles both create and update operations

3. **DepartmentAssignmentForm** (`admin.department-assignment-form`)
   - Assign KPIs to multiple departments
   - Set department-specific target values
   - Bulk assignment management

4. **KpiDashboard** (`admin.kpi-dashboard`)
   - Overview of all KPI performance
   - Filter by year and department
   - Summary statistics
   - Completion percentages with color coding

### Head Components

1. **DepartmentKpiView** (`head.department-kpi-view`)
   - Shows all department KPIs
   - Monthly progress visualization
   - Summary statistics for department
   - Year filter

### Staff Components

1. **AssignedKpiView** (`staff.assigned-kpi-view`)
   - Displays assigned KPIs
   - Progress bars and completion status
   - Quick link to progress entry form

2. **ProgressEntryForm** (`staff.progress-entry-form`)
   - Interactive monthly progress grid
   - Modal form for entering values
   - Edit existing progress entries
   - Visual indicators for completed months

## Setup Instructions

### 1. Run Migrations

```bash
php artisan migrate
```

This creates all necessary tables with proper foreign keys and indexes.

### 2. Seed Roles

```bash
php artisan db:seed --class=RoleSeeder
```

Creates three core roles: admin, head, staff.

### 3. Seed Sample Data (Optional)

```bash
php artisan db:seed --class=KpiSeeder
```

Creates sample departments, KPIs, assignments, and progress data for testing.

### 4. Assign Roles to Users

After creating users, assign roles programmatically or via console:

```php
// Assign admin role
$user->assignRole('admin');

// Assign head role
$user->assignRole('head');

// Assign staff role
$user->assignRole('staff');

// Check roles
if ($user->isAdmin()) {
    // Admin logic
}
```

### 5. Assign Users to Departments

```php
$user->department_id = $department->id;
$user->save();
```

## Usage Examples

### Creating a KPI (Admin)

1. Navigate to `/admin/kpi`
2. Click "Create New KPI"
3. Enter KPI title and description
4. Submit form

### Assigning KPI to Departments (Admin)

1. Navigate to `/admin/kpi/assignments`
2. Select year
3. Click "Manage Assignments" on desired KPI
4. Check departments and set target values
5. Save assignments

### Entering Monthly Progress (Staff)

1. Navigate to `/staff/progress/entry`
2. Click on the month box for the KPI
3. Enter progress value and optional remarks
4. Save progress

### Viewing Department Performance (Head)

1. Navigate to `/head/department-kpis`
2. Select year filter
3. View all KPIs with monthly breakdown
4. Monitor completion percentages

## Key Features

### Role-Based Access Control
- Authorization checks in each component's `mount()` method
- Department-scoped data for heads and staff
- Full access for admins

### Data Integrity
- Unique constraints prevent duplicate assignments
- Foreign keys with cascade deletes
- Input validation on all forms

### Helper Methods
- Query methods on models for common operations
- Calculation methods for progress and completion
- Scopes for filtering data

### User Experience
- Flux UI components for consistent design
- Real-time validation with Livewire
- Interactive modals for data entry
- Color-coded status indicators
- Responsive grid layouts

## Integration with External SSO/ACL

The system uses a simple roles table for now. To integrate with external SSO/ACL:

1. **Keep the roles table** for internal role mapping
2. **Add middleware** to sync external roles to local roles:
   ```php
   // In middleware
   $externalRole = $request->user()->getExternalRole();
   $localRole = Role::where('name', $this->mapRole($externalRole))->first();
   $request->user()->roles()->sync([$localRole->id]);
   ```

3. **Map external roles** to local roles (admin, head, staff)
4. **Sync department assignment** from external system

## API Queries

### Get All KPIs for a Department (Specific Year)

```php
use App\Models\Department;

$department = Department::find($departmentId);
$year = 2026;

// Get all assignments with progress
$kpis = $department->kpiAssignmentsForYear($year);

// Or get summary with calculations
$summary = $department->kpiProgressSummary($year);
```

### Get Progress for Specific KPI Assignment

```php
use App\Models\KpiDepartmentAssignment;

$assignment = KpiDepartmentAssignment::find($id);

// Get specific month progress
$progress = $assignment->getProgressForMonth(3, 2026); // March 2026

// Get totals
$total = $assignment->getTotalProgress(2026);
$average = $assignment->getAverageProgress(2026);
$completion = $assignment->getCompletionPercentage(2026);
```

## Testing

Run tests with Pest:

```bash
php artisan test --filter=Kpi
```

## Customization

### Adding New Roles

1. Add role to database via seeder or manually
2. Update Role model constants
3. Add helper methods to User model if needed
4. Create new route group for the role

### Modifying Target Calculations

Update the calculation methods in `KpiDepartmentAssignment` model:
- `getTotalProgress()`
- `getAverageProgress()`
- `getCompletionPercentage()`

### Changing Progress Frequency

Currently set to monthly (1-12). To change:
1. Update `kpi_progress.month` column type
2. Modify progress entry forms
3. Update display grids in views

## Troubleshooting

### Users can't access routes
- Ensure user has correct role assigned
- Check user has department_id set (for head/staff)
- Verify middleware is applied to routes

### KPIs not showing for staff
- Confirm department has KPI assignments for the year
- Check department_id on user matches assignment
- Verify KpiYear exists for selected year

### Progress not saving
- Ensure assignment exists for the department
- Check month/year values are valid
- Verify unique constraint (one entry per assignment/month/year)

## License

This KPI tracking system is part of your Laravel application.
