34878-vm/includes/payroll_engine.php
Flatlogic Bot 8d771ec57c V1
2025-10-11 14:09:06 +00:00

83 lines
2.7 KiB
PHP

<?php
function calculate_payroll(float $basic_salary, array $settings): array
{
$result = [
'gross_pay' => $basic_salary,
'items' => [],
'deductions' => [],
'taxes' => [],
'net_pay' => 0,
];
// Add Basic Salary as an earning item
$result['items'][] = ['type' => 'earning', 'description' => 'Basic Salary', 'amount' => $basic_salary];
// --- Deductions ---
// 1. NAPSA Calculation
$napsa_rate = (float)($settings['napsa_rate'] ?? 5) / 100;
$napsa_ceiling = (float)($settings['napsa_ceiling'] ?? 2880);
$assessable_for_napsa = min($basic_salary, $napsa_ceiling);
$napsa_contribution = $assessable_for_napsa * $napsa_rate;
$result['deductions']['napsa'] = $napsa_contribution;
$result['items'][] = ['type' => 'deduction', 'description' => 'NAPSA', 'amount' => $napsa_contribution];
// 2. NHIMA Calculation
$nhima_rate = (float)($settings['nhima_rate'] ?? 1) / 100;
$nhima_contribution = $basic_salary * $nhima_rate;
$result['deductions']['nhima'] = $nhima_contribution;
$result['items'][] = ['type' => 'deduction', 'description' => 'NHIMA', 'amount' => $nhima_contribution];
// --- Taxable Income ---
$taxable_income = $basic_salary - $napsa_contribution;
// --- PAYE Calculation ---
$paye_brackets = json_decode($settings['paye_brackets'] ?? '[]', true);
$paye_tax = 0;
$remaining_income = $taxable_income;
// Sort brackets by 'from' value to ensure correct order
usort($paye_brackets, function($a, $b) {
return $a['from'] <=> $b['from'];
});
$cumulative_tax = 0;
$income_in_previous_bands = 0;
foreach ($paye_brackets as $bracket) {
$from = (float)$bracket['from'];
$to = isset($bracket['to']) ? (float)$bracket['to'] : null;
$rate = (float)$bracket['rate'] / 100;
if ($taxable_income > $from) {
$taxable_in_this_band = 0;
if ($to === null) { // Top bracket
$taxable_in_this_band = $taxable_income - $from;
} else {
$taxable_in_this_band = min($taxable_income, $to) - $from;
}
if ($taxable_in_this_band > 0) {
$cumulative_tax += $taxable_in_this_band * $rate;
}
}
}
$paye_tax = $cumulative_tax;
if ($paye_tax > 0) {
$result['taxes']['paye'] = $paye_tax;
$result['items'][] = ['type' => 'tax', 'description' => 'PAYE', 'amount' => $paye_tax];
}
// --- Final Calculations ---
$total_deductions = array_sum($result['deductions']) + array_sum($result['taxes']);
$net_pay = $basic_salary - $total_deductions;
$result['total_deductions'] = $total_deductions;
$result['net_pay'] = $net_pay;
return $result;
}