|
Server : LiteSpeed System : Linux terra.hostitbro.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64 User : outerorb ( 1091) PHP Version : 8.1.34 Disable Function : mail Directory : /home2/outerorb/emp.outerorbittech.in/admin/ | |
|
Path: /home2/outerorb/emp.outerorbittech.in/admin/payslip.php
Size: 9.67 KB
Permissions: 0666
<?php
/**
* admin/payslip.php
* View a single payslip. Called from payroll.php finalized run.
* ?emp=<employee_id>&run=<payroll_run_id>
*/
require __DIR__ . '/../includes/helpers.php';
require_admin();
ensure_payroll_tables();
ensure_employees_table();
$pdo = db();
$empId = (int)($_GET['emp'] ?? 0);
$runId = (int)($_GET['run'] ?? 0);
if (!$empId || !$runId) {
redirect_with_message('payroll.php', 'Invalid payslip request.', 'error');
}
// Load entry
$entryStmt = $pdo->prepare(
'SELECT pe.*, e.first_name, e.last_name, e.department, e.designation, e.employee_id AS emp_code,
e.date_of_joining, e.pan_number,
pr.year, pr.month, pr.finalized_at
FROM payroll_entries pe
JOIN employees e ON e.id = pe.employee_id
JOIN payroll_runs pr ON pr.id = pe.payroll_run_id
WHERE pe.payroll_run_id = ? AND pe.employee_id = ?
LIMIT 1'
);
$entryStmt->execute([$runId, $empId]);
$entry = $entryStmt->fetch();
if (!$entry) {
redirect_with_message('payroll.php', 'Payslip not found.', 'error');
}
$monthLabel = date('F Y', mktime(0,0,0,(int)$entry['month'],1,(int)$entry['year']));
// Earnings rows
$earnings = [
['Basic Salary', $entry['basic']],
['HRA', $entry['hra']],
['DA', $entry['da']],
['Conveyance', $entry['conveyance']],
['Special Allowance',$entry['special_allowance']],
['Other Allowance', $entry['other_allowance']],
];
// Deduction rows
$deductions = [
['PF (Employee)', $entry['pf_deduction']],
['ESI', $entry['esi_deduction']],
['Professional Tax', $entry['pt_deduction']],
['TDS', $entry['tds_deduction']],
['Advance Recovery', $entry['advance_deduction']],
['Other Deductions', $entry['other_deduction']],
];
function fmt(float $v): string { return number_format($v, 2); }
function e(string $v): string { return htmlspecialchars($v, ENT_QUOTES, 'UTF-8'); }
// Words
function rupees_in_words(float $amount): string {
$amount = (int)round($amount);
$ones = ['','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten',
'Eleven','Twelve','Thirteen','Fourteen','Fifteen','Sixteen','Seventeen','Eighteen','Nineteen'];
$tens = ['','','Twenty','Thirty','Forty','Fifty','Sixty','Seventy','Eighty','Ninety'];
if ($amount === 0) return 'Zero';
$parts = [];
if (($cr = intdiv($amount, 10000000)) > 0) { $parts[] = rupees_in_words($cr) . ' Crore'; $amount %= 10000000; }
if (($lac = intdiv($amount, 100000)) > 0) { $parts[] = rupees_in_words($lac) . ' Lakh'; $amount %= 100000; }
if (($th = intdiv($amount, 1000)) > 0) { $parts[] = rupees_in_words($th) . ' Thousand'; $amount %= 1000; }
if (($h = intdiv($amount, 100)) > 0) { $parts[] = $ones[$h] . ' Hundred'; $amount %= 100; }
if ($amount > 0) {
if ($amount < 20) { $parts[] = $ones[$amount]; }
else { $parts[] = $tens[intdiv($amount,10)] . ($amount%10 ? ' '.$ones[$amount%10] : ''); }
}
return implode(' ', $parts);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Payslip — <?php echo e($entry['first_name'].' '.$entry['last_name']); ?> — <?php echo $monthLabel; ?></title>
<style>
*, *::before, *::after { box-sizing:border-box; margin:0; padding:0; }
body { font-family: Arial, Helvetica, sans-serif; font-size:13px; color:#111; background:#f9fafb; }
.page { width:800px; margin:24px auto; background:#fff; border:1px solid #e5e7eb; padding:32px; }
.header-row { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:18px; }
.company-name { font-size:1.3rem; font-weight:800; color:#1e40af; }
.company-sub { font-size:.78rem; color:#6b7280; margin-top:3px; }
.slip-title { font-size:1.1rem; font-weight:700; text-align:right; }
.slip-sub { font-size:.78rem; color:#4b5563; text-align:right; }
.divider { border:none; border-top:2px solid #2563eb; margin:14px 0; }
.info-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:8px 16px; margin-bottom:18px; }
.info-item label { display:block; font-size:.7rem; color:#6b7280; text-transform:uppercase; margin-bottom:2px; }
.info-item span { display:block; font-weight:700; font-size:.82rem; }
.pay-row { display:grid; grid-template-columns:1fr 1fr; gap:0; border:1px solid #e5e7eb; }
.pay-col { flex:1; }
.pay-col-head { background:#1e40af; color:#fff; font-weight:700; padding:7px 12px; font-size:.78rem; }
.pay-item { display:flex; justify-content:space-between; padding:6px 12px; border-bottom:1px solid #f3f4f6; font-size:.8rem; }
.pay-item:last-child { border-bottom:none; }
.pay-total { display:flex; justify-content:space-between; padding:8px 12px; font-weight:800; background:#f1f5f9; font-size:.85rem; border-top:1px solid #e5e7eb; }
.net-box { background:#f0fdf4; border:1px solid #bbf7d0; border-radius:8px; padding:14px 18px; margin:18px 0; display:flex; justify-content:space-between; align-items:center; }
.net-amount { font-size:1.4rem; font-weight:900; color:#16a34a; }
.words { font-size:.75rem; color:#6b7280; margin-top:4px; }
.print-btn { display:block; text-align:center; margin:8px 0 20px; }
@media print {
body { background:#fff; }
.page { width:100%; border:none; padding:20px; margin:0; }
.print-btn, .back-link { display:none; }
}
</style>
</head>
<body>
<div class="print-btn">
<button onclick="window.print()" style="background:#1e40af; color:#fff; border:none; padding:8px 22px; border-radius:6px; cursor:pointer; font-size:.9rem;">
Print / Save PDF
</button>
<a class="back-link" href="payroll.php?year=<?php echo (int)$entry['year']; ?>&month=<?php echo (int)$entry['month']; ?>"
style="font-size:.85rem; color:#2563eb;">← Back to Payroll</a>
</div>
<div class="page">
<div class="header-row">
<div>
<div class="company-name">Outer Orbit Technologies</div>
<div class="company-sub">Human Resource Management System</div>
</div>
<div>
<div class="slip-title">Payslip</div>
<div class="slip-sub"><?php echo $monthLabel; ?></div>
</div>
</div>
<hr class="divider" />
<div class="info-grid">
<div class="info-item">
<label>Employee Name</label>
<span><?php echo e($entry['first_name'].' '.$entry['last_name']); ?></span>
</div>
<div class="info-item">
<label>Employee ID</label>
<span><?php echo e($entry['emp_code'] ?? '—'); ?></span>
</div>
<div class="info-item">
<label>Department</label>
<span><?php echo e($entry['department']); ?></span>
</div>
<div class="info-item">
<label>Designation</label>
<span><?php echo e($entry['designation'] ?? '—'); ?></span>
</div>
<div class="info-item">
<label>Date of Joining</label>
<span><?php echo $entry['date_of_joining'] ? date('d/m/Y', strtotime($entry['date_of_joining'])) : '—'; ?></span>
</div>
<div class="info-item">
<label>PAN</label>
<span><?php echo e($entry['pan_number'] ?? '—'); ?></span>
</div>
<div class="info-item">
<label>Pay Period</label>
<span><?php echo $monthLabel; ?></span>
</div>
<div class="info-item">
<label>Working Days</label>
<span><?php echo $entry['days_worked']; ?> / <?php echo $entry['days_in_month']; ?></span>
</div>
</div>
<div class="pay-row">
<div class="pay-col" style="border-right:1px solid #e5e7eb;">
<div class="pay-col-head">Earnings</div>
<?php foreach ($earnings as [$label, $val]): if (!$val) continue; ?>
<div class="pay-item"><span><?php echo $label; ?></span><span>₹<?php echo fmt((float)$val); ?></span></div>
<?php endforeach; ?>
<div class="pay-total"><span>Gross Earnings</span><span>₹<?php echo fmt((float)$entry['gross']); ?></span></div>
</div>
<div class="pay-col">
<div class="pay-col-head">Deductions</div>
<?php foreach ($deductions as [$label, $val]): if (!$val) continue; ?>
<div class="pay-item"><span><?php echo $label; ?></span><span>₹<?php echo fmt((float)$val); ?></span></div>
<?php endforeach; ?>
<div class="pay-total"><span>Total Deductions</span><span>₹<?php echo fmt((float)$entry['total_deductions']); ?></span></div>
</div>
</div>
<div class="net-box">
<div>
<div style="font-size:.78rem; text-transform:uppercase; color:#166534; margin-bottom:2px;">Net Take-Home Pay</div>
<div class="words">Rupees <?php echo rupees_in_words((float)$entry['net_pay']); ?> Only</div>
</div>
<div class="net-amount">₹<?php echo fmt((float)$entry['net_pay']); ?></div>
</div>
<p style="font-size:.72rem; color:#9ca3af; border-top:1px solid #e5e7eb; padding-top:12px; margin-top:4px;">
This is a computer-generated payslip. No signature is required.
<?php if ($entry['finalized_at']): ?>
Generated on <?php echo date('d M Y', strtotime($entry['finalized_at'])); ?>.
<?php endif; ?>
</p>
</div>
</body>
</html>