prepare("SELECT setting_key, setting_value FROM settings WHERE company_id = ?"); $stmt->execute([$company_id]); $settings_raw = $stmt->fetchAll(); $settings = []; foreach ($settings_raw as $row) { $settings[$row['setting_key']] = $row['setting_value']; } // 2. Fetch employees $stmt = $pdo->prepare("SELECT * FROM employees WHERE company_id = ?"); $stmt->execute([$company_id]); $employees = $stmt->fetchAll(); if (empty($employees)) { throw new Exception("No employees found for this company."); } // 3. Calculate payroll for each employee foreach ($employees as $employee) { $payroll_data = calculate_payroll((float)$employee['basic_salary'], $settings); $payroll_results[] = [ 'employee' => $employee, 'payroll' => $payroll_data, ]; } $success_message = "Payroll calculated for " . count($employees) . " employees."; } catch (Exception $e) { $error_message = "Error calculating payroll: " . $e->getMessage(); } } // Handle Save Payroll if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_payroll'])) { $results_json = $_POST['payroll_results_json'] ?? '[]'; $results_to_save = json_decode($results_json, true); if (empty($results_to_save)) { $error_message = "No payroll data to save."; } else { try { $pdo = db(); $pdo->beginTransaction(); // 1. Create payroll run record $stmt = $pdo->prepare("INSERT INTO payroll_runs (company_id, pay_period_month, pay_period_year, status) VALUES (?, ?, ?, 'completed') ON DUPLICATE KEY UPDATE status='completed'"); $stmt->execute([$company_id, $pay_period_month, $pay_period_year]); $run_id = $pdo->lastInsertId(); // If the run already existed, get its ID if ($run_id == 0) { $stmt = $pdo->prepare("SELECT id FROM payroll_runs WHERE company_id = ? AND pay_period_year = ? AND pay_period_month = ?"); $stmt->execute([$company_id, $pay_period_year, $pay_period_month]); $run_id = $stmt->fetchColumn(); } // 2. Save each payslip foreach ($results_to_save as $result) { $employee_id = $result['employee']['id']; $payroll = $result['payroll']; $stmt = $pdo->prepare("INSERT INTO payslips (payroll_run_id, employee_id, gross_pay, total_deductions, net_pay) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$run_id, $employee_id, $payroll['gross_pay'], $payroll['total_deductions'], $payroll['net_pay']]); $payslip_id = $pdo->lastInsertId(); // 3. Save payslip items foreach ($payroll['items'] as $item) { $stmt = $pdo->prepare("INSERT INTO payslip_items (payslip_id, type, description, amount) VALUES (?, ?, ?, ?)"); $stmt->execute([$payslip_id, $item['type'], $item['description'], $item['amount']]); } } $pdo->commit(); $success_message = "Payroll run for {$pay_period_month}/{$pay_period_year} has been saved successfully!"; $payroll_results = []; // Clear results from view after saving } catch (Exception $e) { if ($pdo->inTransaction()) $pdo->rollBack(); $error_message = "Failed to save payroll run: " . $e->getMessage(); } } } ?>
| Employee | Gross Pay | NAPSA | NHIMA | PAYE | Total Deductions | Net Pay |
|---|---|---|---|---|---|---|
| = htmlspecialchars($result['employee']['first_name'] . ' ' . $result['employee']['last_name']) ?> | ZMW = number_format($result['payroll']['gross_pay'], 2) ?> | ZMW = number_format($result['payroll']['deductions']['napsa'] ?? 0, 2) ?> | ZMW = number_format($result['payroll']['deductions']['nhima'] ?? 0, 2) ?> | ZMW = number_format($result['payroll']['taxes']['paye'] ?? 0, 2) ?> | ZMW = number_format($result['payroll']['total_deductions'], 2) ?> | ZMW = number_format($result['payroll']['net_pay'], 2) ?> |