Status Codes
Employee status codes and filtering constants used for employee lifecycle management and reporting in the WorkPayCore frontend application.
Overview
The status codes constants define the various states an employee can have within the system and provide filtering criteria for active employee identification. This ensures consistent employee status handling across all features and reports.
Employee Status Constants
EMPLOYEE_STATUSES_CONSIDERED_ACTIVE
Comma-separated string defining which employee statuses should be considered "active" for various business operations and reporting purposes.
export const EMPLOYEE_STATUSES_CONSIDERED_ACTIVE =
'ACTIVE,ON_LEAVE,ON_NOTICE_OF_EXIT';
Active Status Types:
- ACTIVE: Employee is currently working and available
- ON_LEAVE: Employee is on approved leave but still employed
- ON_NOTICE_OF_EXIT: Employee has given notice but is still working
Use Cases:
- Payroll processing inclusion
- Active headcount reporting
- Benefits eligibility checking
- Access control decisions
Status Code Definitions
Employee Lifecycle States
While not explicitly defined in the constants file, the system recognizes these employee states:
Active States (Included in Active Filter)
- ACTIVE: Standard working status
- ON_LEAVE: Temporary absence with job protection
- ON_NOTICE_OF_EXIT: Resignation period
Inactive States (Excluded from Active Filter)
- TERMINATED: Employment ended by company
- RESIGNED: Employee left voluntarily
- SUSPENDED: Temporarily barred from work
- PROBATION: Initial employment period
- INACTIVE: General inactive status
Usage Examples
Active Employee Filtering
import { EMPLOYEE_STATUSES_CONSIDERED_ACTIVE } from '@/utils/constants/statuses';
const getActiveEmployees = employees => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
return employees.filter(employee => activeStatuses.includes(employee.status));
};
// Usage
const allEmployees = [
{ id: 1, name: 'John Doe', status: 'ACTIVE' },
{ id: 2, name: 'Jane Smith', status: 'ON_LEAVE' },
{ id: 3, name: 'Bob Johnson', status: 'TERMINATED' },
{ id: 4, name: 'Alice Brown', status: 'ON_NOTICE_OF_EXIT' },
];
const activeEmployees = getActiveEmployees(allEmployees);
// Returns: John Doe, Jane Smith, Alice Brown
Payroll Processing Filter
import { EMPLOYEE_STATUSES_CONSIDERED_ACTIVE } from '@/utils/constants/statuses';
const PayrollProcessor = {
getEligibleEmployees: (employees, payrollDate) => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
return employees.filter(employee => {
// Check if employee is in active status
if (!activeStatuses.includes(employee.status)) {
return false;
}
// Additional checks for payroll eligibility
if (employee.status === 'ON_NOTICE_OF_EXIT') {
// Check if notice period hasn't ended yet
return new Date(employee.last_working_day) >= payrollDate;
}
if (employee.status === 'ON_LEAVE') {
// Check if it's paid leave
return employee.leave_type === 'PAID' || employee.include_in_payroll;
}
return true;
});
},
calculatePayroll: (employees, payrollDate) => {
const eligibleEmployees = PayrollProcessor.getEligibleEmployees(
employees,
payrollDate,
);
return eligibleEmployees.map(employee => ({
employee_id: employee.id,
status: employee.status,
base_salary: employee.base_salary,
adjustments: PayrollProcessor.getStatusAdjustments(employee),
}));
},
getStatusAdjustments: employee => {
switch (employee.status) {
case 'ON_LEAVE':
return {
leave_deduction:
employee.leave_type === 'UNPAID'
? employee.daily_rate * employee.leave_days
: 0,
};
case 'ON_NOTICE_OF_EXIT':
return {
notice_period_bonus: employee.notice_period_bonus || 0,
exit_benefits: employee.exit_benefits || 0,
};
default:
return {};
}
},
};
Employee Status Validation
import { EMPLOYEE_STATUSES_CONSIDERED_ACTIVE } from '@/utils/constants/statuses';
const EmployeeStatusValidator = {
isActiveStatus: status => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
return activeStatuses.includes(status);
},
canAccessSystem: employee => {
// Active employees can access the system
if (EmployeeStatusValidator.isActiveStatus(employee.status)) {
return true;
}
// Special cases for system access
const limitedAccessStatuses = ['SUSPENDED', 'PROBATION'];
return limitedAccessStatuses.includes(employee.status);
},
canReceiveBenefits: employee => {
// Only active status employees receive full benefits
return EmployeeStatusValidator.isActiveStatus(employee.status);
},
validateStatusTransition: (currentStatus, newStatus) => {
const validTransitions = {
PROBATION: ['ACTIVE', 'TERMINATED'],
ACTIVE: ['ON_LEAVE', 'ON_NOTICE_OF_EXIT', 'SUSPENDED', 'TERMINATED'],
ON_LEAVE: ['ACTIVE', 'TERMINATED'],
ON_NOTICE_OF_EXIT: ['RESIGNED', 'TERMINATED', 'ACTIVE'],
SUSPENDED: ['ACTIVE', 'TERMINATED'],
};
const allowedTransitions = validTransitions[currentStatus] || [];
return allowedTransitions.includes(newStatus);
},
};
Reporting and Analytics
import { EMPLOYEE_STATUSES_CONSIDERED_ACTIVE } from '@/utils/constants/statuses';
const EmployeeReporting = {
getHeadcountReport: employees => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
const report = {
total_employees: employees.length,
active_employees: 0,
inactive_employees: 0,
status_breakdown: {},
};
employees.forEach(employee => {
const status = employee.status;
// Count by active/inactive
if (activeStatuses.includes(status)) {
report.active_employees++;
} else {
report.inactive_employees++;
}
// Count by specific status
report.status_breakdown[status] =
(report.status_breakdown[status] || 0) + 1;
});
return report;
},
getActiveEmployeesTrend: (employees, startDate, endDate) => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
// Group employees by status change date
const dailyTrend = {};
employees.forEach(employee => {
employee.status_history?.forEach(history => {
const date = history.change_date;
if (date >= startDate && date <= endDate) {
if (!dailyTrend[date]) {
dailyTrend[date] = { active: 0, inactive: 0 };
}
if (activeStatuses.includes(history.new_status)) {
dailyTrend[date].active++;
} else {
dailyTrend[date].inactive++;
}
}
});
});
return dailyTrend;
},
};
API Query Building
import { EMPLOYEE_STATUSES_CONSIDERED_ACTIVE } from '@/utils/constants/statuses';
const EmployeeAPI = {
buildActiveEmployeesQuery: (additionalFilters = {}) => {
const baseQuery = {
status__in: EMPLOYEE_STATUSES_CONSIDERED_ACTIVE,
...additionalFilters,
};
return baseQuery;
},
fetchActiveEmployees: async (filters = {}) => {
const query = EmployeeAPI.buildActiveEmployeesQuery(filters);
const queryString = new URLSearchParams();
Object.entries(query).forEach(([key, value]) => {
queryString.append(key, value);
});
const response = await fetch(`/api/employees?${queryString}`);
return response.json();
},
fetchEmployeesByStatus: async statusFilter => {
let statusQuery;
if (statusFilter === 'active') {
statusQuery = { status__in: EMPLOYEE_STATUSES_CONSIDERED_ACTIVE };
} else if (statusFilter === 'inactive') {
statusQuery = { status__not_in: EMPLOYEE_STATUSES_CONSIDERED_ACTIVE };
} else {
statusQuery = { status: statusFilter };
}
return EmployeeAPI.fetchActiveEmployees(statusQuery);
},
};
React Hook for Status Management
import { useState, useEffect } from 'react';
import { EMPLOYEE_STATUSES_CONSIDERED_ACTIVE } from '@/utils/constants/statuses';
const useEmployeeStatusFilter = employees => {
const [statusFilter, setStatusFilter] = useState('all');
const [filteredEmployees, setFilteredEmployees] = useState(employees);
useEffect(() => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
let filtered = employees;
switch (statusFilter) {
case 'active':
filtered = employees.filter(emp => activeStatuses.includes(emp.status));
break;
case 'inactive':
filtered = employees.filter(
emp => !activeStatuses.includes(emp.status),
);
break;
case 'all':
default:
filtered = employees;
break;
}
setFilteredEmployees(filtered);
}, [employees, statusFilter]);
return {
filteredEmployees,
statusFilter,
setStatusFilter,
activeCount: employees.filter(emp =>
EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',').includes(emp.status),
).length,
inactiveCount: employees.filter(
emp =>
!EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',').includes(emp.status),
).length,
};
};
// Usage in component
const EmployeeList = ({ employees }) => {
const {
filteredEmployees,
statusFilter,
setStatusFilter,
activeCount,
inactiveCount,
} = useEmployeeStatusFilter(employees);
return (
<div>
<div>
<button
onClick={() => setStatusFilter('all')}
className={statusFilter === 'all' ? 'active' : ''}
>
All ({employees.length})
</button>
<button
onClick={() => setStatusFilter('active')}
className={statusFilter === 'active' ? 'active' : ''}
>
Active ({activeCount})
</button>
<button
onClick={() => setStatusFilter('inactive')}
className={statusFilter === 'inactive' ? 'active' : ''}
>
Inactive ({inactiveCount})
</button>
</div>
<div>
{filteredEmployees.map(employee => (
<div key={employee.id}>
{employee.name} - {employee.status}
</div>
))}
</div>
</div>
);
};
Status Management Best Practices
1. Consistent Status Checking
// Always use the constant for active status checking
import { EMPLOYEE_STATUSES_CONSIDERED_ACTIVE } from '@/utils/constants/statuses';
// ✅ Good
const isActiveEmployee = employee => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
return activeStatuses.includes(employee.status);
};
// ❌ Bad - hardcoded values
const isActiveEmployee = employee => {
return ['ACTIVE', 'ON_LEAVE'].includes(employee.status);
};
2. Status Transition Validation
const validateStatusChange = (employee, newStatus, reason) => {
const currentStatus = employee.status;
// Validate the transition is allowed
if (
!EmployeeStatusValidator.validateStatusTransition(currentStatus, newStatus)
) {
throw new Error(
`Invalid status transition from ${currentStatus} to ${newStatus}`,
);
}
// Log the status change
console.log(
`Employee ${employee.id} status changed: ${currentStatus} → ${newStatus}`,
{
reason,
timestamp: new Date().toISOString(),
},
);
return true;
};
3. Status-Dependent Features
const getEmployeePermissions = employee => {
const permissions = {
canAccessPortal: false,
canReceivePayroll: false,
canTakeLeave: false,
canAccessBenefits: false,
};
if (EmployeeStatusValidator.isActiveStatus(employee.status)) {
permissions.canAccessPortal = true;
permissions.canReceivePayroll = true;
permissions.canAccessBenefits = true;
if (employee.status === 'ACTIVE') {
permissions.canTakeLeave = true;
}
}
return permissions;
};
Status Code Extensions
Custom Status Handling
// Extend the active statuses for specific use cases
const getActiveStatusesForContext = context => {
const baseStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
switch (context) {
case 'benefits':
// Benefits might include probation employees
return [...baseStatuses, 'PROBATION'];
case 'training':
// Training might include suspended employees
return [...baseStatuses, 'SUSPENDED'];
case 'payroll':
default:
return baseStatuses;
}
};
Status-Based Styling
const getStatusColor = status => {
const activeStatuses = EMPLOYEE_STATUSES_CONSIDERED_ACTIVE.split(',');
if (activeStatuses.includes(status)) {
return (
{
ACTIVE: '#10B981', // Green
ON_LEAVE: '#F59E0B', // Yellow
ON_NOTICE_OF_EXIT: '#EF4444', // Red
}[status] || '#10B981'
);
}
return '#6B7280'; // Gray for inactive statuses
};
const StatusBadge = ({ status }) => {
const color = getStatusColor(status);
return (
<span
style={{
backgroundColor: color,
color: 'white',
padding: '2px 8px',
borderRadius: '4px',
}}
>
{status.replace(/_/g, ' ')}
</span>
);
};
Related Utilities
- Options - For employee status selection options
- General Helpers - For validation utilities
- Object & Array Utilities - For employee filtering
TypeScript Definitions
type ActiveEmployeeStatus = 'ACTIVE' | 'ON_LEAVE' | 'ON_NOTICE_OF_EXIT';
type InactiveEmployeeStatus =
| 'TERMINATED'
| 'RESIGNED'
| 'SUSPENDED'
| 'PROBATION'
| 'INACTIVE';
type EmployeeStatus = ActiveEmployeeStatus | InactiveEmployeeStatus;
export const EMPLOYEE_STATUSES_CONSIDERED_ACTIVE: string;
interface Employee {
id: number;
name: string;
status: EmployeeStatus;
last_working_day?: string;
leave_type?: 'PAID' | 'UNPAID';
include_in_payroll?: boolean;
}
interface StatusTransition {
from_status: EmployeeStatus;
to_status: EmployeeStatus;
change_date: string;
reason?: string;
}
Migration Notes
Adding New Status Types
When adding new employee statuses:
- Determine if the status is active or inactive
- Update the EMPLOYEE_STATUSES_CONSIDERED_ACTIVE constant if needed
- Add validation rules for status transitions
- Update UI components to handle the new status
- Test payroll and benefits calculations with the new status
Status Consolidation
When consolidating or removing status types:
- Create migration mapping for existing data
- Update the active statuses constant
- Test all status-dependent features
- Update documentation and user interfaces
- Provide transition period for data migration
These status code constants ensure consistent employee lifecycle management across the WorkPayCore frontend application while providing clear business rules for employee classification and processing.