511 lines
23 KiB
PHP
511 lines
23 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/db/config.php';
|
|
require_once __DIR__ . '/includes/auth_helper.php';
|
|
Auth::requireLogin();
|
|
|
|
$tenant_id = (int)$_SESSION['tenant_id'];
|
|
$selected_year = (int)($_GET['year'] ?? date('Y'));
|
|
|
|
// 1. Get Company Settings
|
|
$stmt = db()->prepare("SELECT * FROM company_settings WHERE id = 1");
|
|
$stmt->execute();
|
|
$company = $stmt->fetch();
|
|
|
|
// 2. Determine Fiscal Year Range
|
|
$fiscal_end_raw = $company['fiscal_year_end'] ?? '12-31';
|
|
$fiscal_month = (int)date('m', strtotime($fiscal_end_raw));
|
|
$fiscal_day = (int)date('d', strtotime($fiscal_end_raw));
|
|
|
|
// If fiscal end is 2024-03-31, and selected year is 2024:
|
|
// Start: 2023-04-01, End: 2024-03-31
|
|
$end_date = sprintf('%d-%02d-%02d', $selected_year, $fiscal_month, $fiscal_day);
|
|
$start_date = date('Y-m-d', strtotime($end_date . ' -1 year +1 day'));
|
|
|
|
// 3. Fetch Projects active in this period (with labour or expenses)
|
|
$projects_query = "
|
|
SELECT DISTINCT p.*
|
|
FROM projects p
|
|
LEFT JOIN labour_entries le ON p.id = le.project_id AND le.entry_date BETWEEN ? AND ?
|
|
LEFT JOIN expenses e ON p.id = e.project_id AND e.entry_date BETWEEN ? AND ?
|
|
WHERE (le.id IS NOT NULL OR e.id IS NOT NULL)
|
|
ORDER BY p.name ASC
|
|
";
|
|
$stmt = db()->prepare($projects_query);
|
|
$stmt->execute([$start_date, $end_date, $start_date, $end_date]);
|
|
$active_projects = $stmt->fetchAll();
|
|
|
|
// 4. Helper for Labour Data
|
|
function getLabourForProject($projectId, $start, $end) {
|
|
$stmt = db()->prepare("
|
|
SELECT le.*, e.name as employee_name, lt.name as labour_type
|
|
FROM labour_entries le
|
|
JOIN employees e ON le.employee_id = e.id
|
|
LEFT JOIN labour_types lt ON le.labour_type_id = lt.id
|
|
WHERE le.project_id = ? AND le.entry_date BETWEEN ? AND ?
|
|
ORDER BY le.entry_date ASC
|
|
");
|
|
$stmt->execute([$projectId, $start, $end]);
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
// 5. Helper for Expense Data
|
|
function getExpensesForProject($projectId, $start, $end) {
|
|
$stmt = db()->prepare("
|
|
SELECT e.*, s.name as supplier_name, et.name as expense_type
|
|
FROM expenses e
|
|
JOIN suppliers s ON e.supplier_id = s.id
|
|
LEFT JOIN expense_types et ON e.expense_type_id = et.id
|
|
WHERE e.project_id = ? AND e.entry_date BETWEEN ? AND ?
|
|
ORDER BY e.entry_date ASC
|
|
");
|
|
$stmt->execute([$projectId, $start, $end]);
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
// 6. Helper for Summary Calendar (Labour Hours)
|
|
$summary_labour_query = "
|
|
SELECT p.id as project_id, p.name as project_name, DATE_FORMAT(le.entry_date, '%Y-%m') as month, SUM(le.hours) as total_hours, SUM(le.hours * IFNULL(le.hourly_rate, 0)) as total_cost
|
|
FROM labour_entries le
|
|
JOIN projects p ON le.project_id = p.id
|
|
WHERE le.entry_date BETWEEN ? AND ?
|
|
GROUP BY p.id, p.name, month
|
|
";
|
|
$stmt = db()->prepare($summary_labour_query);
|
|
$stmt->execute([$start_date, $end_date]);
|
|
$summary_labour_data = $stmt->fetchAll();
|
|
|
|
// 7. Helper for Summary Calendar (Expenses)
|
|
$summary_expense_query = "
|
|
SELECT p.id as project_id, p.name as project_name, DATE_FORMAT(e.entry_date, '%Y-%m') as month, SUM(e.amount) as total_amount
|
|
FROM expenses e
|
|
JOIN projects p ON e.project_id = p.id
|
|
WHERE e.entry_date BETWEEN ? AND ?
|
|
GROUP BY p.id, p.name, month
|
|
";
|
|
$stmt = db()->prepare($summary_expense_query);
|
|
$stmt->execute([$start_date, $end_date]);
|
|
$summary_expense_data = $stmt->fetchAll();
|
|
|
|
// Organize Summary Data
|
|
$months = [];
|
|
try {
|
|
$current_dt = new DateTime($start_date);
|
|
$current_dt->modify('first day of this month');
|
|
$end_dt = new DateTime($end_date);
|
|
$end_dt->modify('first day of this month');
|
|
|
|
while ($current_dt <= $end_dt) {
|
|
$months[] = $current_dt->format('Y-m');
|
|
$current_dt->modify('+1 month');
|
|
if (count($months) > 13) break; // Safety for roughly 1 year
|
|
}
|
|
} catch (Exception $e) {
|
|
// Fallback if DateTime fails
|
|
$months = [date('Y-m', strtotime($start_date))];
|
|
}
|
|
|
|
$labour_matrix = [];
|
|
$project_names = [];
|
|
foreach ($summary_labour_data as $row) {
|
|
$pid = $row['project_id'];
|
|
$project_names[$pid] = $row['project_name'];
|
|
$labour_matrix[$pid][$row['month']] = ['hours' => $row['total_hours'], 'cost' => $row['total_cost']];
|
|
}
|
|
|
|
$expense_matrix = [];
|
|
foreach ($summary_expense_data as $row) {
|
|
$pid = $row['project_id'];
|
|
$project_names[$pid] = $row['project_name'];
|
|
$expense_matrix[$pid][$row['month']] = $row['total_amount'];
|
|
}
|
|
|
|
$pageTitle = "SRED Claim Report - " . $selected_year;
|
|
?>
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title><?= $pageTitle ?></title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<style>
|
|
@media print {
|
|
.no-print { display: none !important; }
|
|
.page-break { page-break-before: always; }
|
|
body { background: white; }
|
|
.container { width: 100%; max-width: 100%; margin: 0; padding: 0; }
|
|
.card { border: none !important; box-shadow: none !important; }
|
|
}
|
|
body { background: #f8f9fa; font-family: 'Inter', sans-serif; }
|
|
.report-page { background: white; min-height: 297mm; padding: 20mm; margin: 20px auto; box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15); width: 210mm; }
|
|
.title-page { display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; }
|
|
.toc-item { display: flex; justify-content: space-between; border-bottom: 1px dotted #ccc; margin-bottom: 10px; }
|
|
.chart-container { height: 300px; }
|
|
.table-tight th, .table-tight td { padding: 4px 8px; font-size: 0.85rem; }
|
|
.calendar-table th, .calendar-table td { font-size: 0.75rem; text-align: center; vertical-align: middle; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="no-print bg-dark text-white p-3 sticky-top shadow d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<a href="sred_claim_report_selector.php" class="btn btn-sm btn-outline-light me-2"><i class="bi bi-arrow-left"></i> Back</a>
|
|
<strong>SRED Claim Report Generator</strong>
|
|
</div>
|
|
<button onclick="window.print()" class="btn btn-primary btn-sm"><i class="bi bi-printer"></i> Print Report / Save PDF</button>
|
|
</div>
|
|
|
|
<!-- PAGE 1: TITLE PAGE -->
|
|
<div class="report-page title-page">
|
|
<?php if (!empty($company['logo_path'])): ?>
|
|
<img src="<?= htmlspecialchars($company['logo_path']) ?>" alt="Logo" class="mb-5" style="max-height: 150px;">
|
|
<?php endif; ?>
|
|
|
|
<div style="margin-top: auto; margin-bottom: auto;">
|
|
<h1 class="display-3 fw-bold mb-4"><?= htmlspecialchars($company['company_name'] ?? 'Company Name') ?></h1>
|
|
<h2 class="text-primary mb-5">SRED CLAIM REPORT</h2>
|
|
<h4 class="text-muted">Fiscal Year: <?= $selected_year ?></h4>
|
|
<p class="mt-3 text-muted">Range: <?= date('M d, Y', strtotime($start_date)) ?> to <?= date('M d, Y', strtotime($end_date)) ?></p>
|
|
</div>
|
|
|
|
<div class="mt-auto border-top pt-4 w-100">
|
|
<p class="mb-1 fw-bold"><?= htmlspecialchars($company['address_1'] ?? '') ?></p>
|
|
<?php if ($company['address_2']): ?><p class="mb-1"><?= htmlspecialchars($company['address_2']) ?></p><?php endif; ?>
|
|
<p class="mb-1"><?= htmlspecialchars($company['city'] ?? '') ?>, <?= htmlspecialchars($company['province'] ?? '') ?> <?= htmlspecialchars($company['postal_code'] ?? '') ?></p>
|
|
<p class="mb-1">Phone: <?= htmlspecialchars($company['phone'] ?? '') ?> | Email: <?= htmlspecialchars($company['email'] ?? '') ?></p>
|
|
<p class="mb-0">Website: <?= htmlspecialchars($company['website'] ?? '') ?></p>
|
|
<?php if ($company['business_number']): ?>
|
|
<p class="mt-2 fw-bold">Business Number: <?= htmlspecialchars($company['business_number']) ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- PAGE 2: TABLE OF CONTENTS -->
|
|
<div class="report-page page-break">
|
|
<h2 class="mb-5 border-bottom pb-3">Table of Contents</h2>
|
|
<div class="mt-4">
|
|
<div class="toc-item"><span>1. Title Page</span><span>1</span></div>
|
|
<div class="toc-item"><span>2. Table of Contents</span><span>2</span></div>
|
|
<?php
|
|
$page_counter = 3;
|
|
foreach ($active_projects as $p):
|
|
$proj_start_page = $page_counter;
|
|
?>
|
|
<div class="toc-item fw-bold mt-3"><span>Project: <?= htmlspecialchars($p['name']) ?></span><span><?= $page_counter++ ?></span></div>
|
|
<div class="toc-item ps-4 text-muted"><span>Insights & Charts</span><span><?= ($page_counter - 1) ?></span></div>
|
|
<div class="toc-item ps-4 text-muted"><span>Labour Detail Report</span><span><?= $page_counter++ ?></span></div>
|
|
<div class="toc-item ps-4 text-muted"><span>Expense Detail Report</span><span><?= $page_counter++ ?></span></div>
|
|
<?php endforeach; ?>
|
|
<div class="toc-item fw-bold mt-4"><span>Summarized Claim (Calendar Views)</span><span><?= $page_counter++ ?></span></div>
|
|
<div class="toc-item ps-4 text-muted"><span>Labour Summary</span><span><?= ($page_counter - 1) ?></span></div>
|
|
<div class="toc-item ps-4 text-muted"><span>Expense Summary</span><span><?= $page_counter++ ?></span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- PROJECT PAGES -->
|
|
<?php foreach ($active_projects as $idx => $project):
|
|
$labour = getLabourForProject($project['id'], $start_date, $end_date);
|
|
$expenses = getExpensesForProject($project['id'], $start_date, $end_date);
|
|
|
|
// Process Insights
|
|
$employee_hours = [];
|
|
$labour_type_hours = [];
|
|
$total_proj_hours = 0;
|
|
$total_proj_labour_cost = 0;
|
|
foreach ($labour as $l) {
|
|
$employee_hours[$l['employee_name']] = ($employee_hours[$l['employee_name']] ?? 0) + (float)$l['hours'];
|
|
$labour_type_hours[$l['labour_type'] ?? 'Other'] = ($labour_type_hours[$l['labour_type'] ?? 'Other'] ?? 0) + (float)$l['hours'];
|
|
$total_proj_hours += (float)$l['hours'];
|
|
$total_proj_labour_cost += (float)$l['hours'] * (float)($l['hourly_rate'] ?? 0);
|
|
}
|
|
arsort($employee_hours);
|
|
$top_employees = array_slice($employee_hours, 0, 5, true);
|
|
|
|
$total_proj_expenses = 0;
|
|
foreach ($expenses as $e) {
|
|
$total_proj_expenses += (float)$e['amount'];
|
|
}
|
|
?>
|
|
<!-- Project Page 1: Insights -->
|
|
<div class="report-page page-break">
|
|
<div class="d-flex justify-content-between align-items-start mb-4 border-bottom pb-3">
|
|
<div>
|
|
<h6 class="text-uppercase text-primary fw-bold mb-1">Project Analysis</h6>
|
|
<h2 class="mb-0"><?= htmlspecialchars($project['name']) ?></h2>
|
|
</div>
|
|
<div class="text-end">
|
|
<span class="badge bg-light text-dark border">Project ID: <?= htmlspecialchars($project['code'] ?? $project['id']) ?></span>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="lead text-muted mb-4"><?= nl2br(htmlspecialchars($project['description'] ?? 'No project description available.')) ?></p>
|
|
|
|
<div class="row mb-5">
|
|
<div class="col-6">
|
|
<div class="card bg-light border-0">
|
|
<div class="card-body">
|
|
<h6 class="text-muted small text-uppercase">Total Labour Hours</h6>
|
|
<h3 class="mb-0 fw-bold"><?= number_format($total_proj_hours, 1) ?> h</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="card bg-light border-0">
|
|
<div class="card-body">
|
|
<h6 class="text-muted small text-uppercase">Total Estimated Cost</h6>
|
|
<h3 class="mb-0 fw-bold text-success">$<?= number_format($total_proj_labour_cost + $total_proj_expenses, 2) ?></h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-6">
|
|
<h6 class="fw-bold mb-3">Top Employees by Hours</h6>
|
|
<div class="chart-container">
|
|
<canvas id="chart_emp_<?= $project['id'] ?>"></canvas>
|
|
</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<h6 class="fw-bold mb-3">Labour by Category</h6>
|
|
<div class="chart-container">
|
|
<canvas id="chart_type_<?= $project['id'] ?>"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
new Chart(document.getElementById('chart_emp_<?= $project['id'] ?>').getContext('2d'), {
|
|
type: 'bar',
|
|
data: {
|
|
labels: <?= json_encode(array_keys($top_employees)) ?>,
|
|
datasets: [{
|
|
label: 'Hours',
|
|
data: <?= json_encode(array_values($top_employees)) ?>,
|
|
backgroundColor: '#0d6efd'
|
|
}]
|
|
},
|
|
options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } } }
|
|
});
|
|
new Chart(document.getElementById('chart_type_<?= $project['id'] ?>').getContext('2d'), {
|
|
type: 'doughnut',
|
|
data: {
|
|
labels: <?= json_encode(array_keys($labour_type_hours)) ?>,
|
|
datasets: [{
|
|
data: <?= json_encode(array_values($labour_type_hours)) ?>,
|
|
backgroundColor: ['#0d6efd', '#198754', '#ffc107', '#0dcaf0', '#6c757d']
|
|
}]
|
|
},
|
|
options: { responsive: true, maintainAspectRatio: false }
|
|
});
|
|
</script>
|
|
</div>
|
|
|
|
<!-- Project Page 2: Labour Details -->
|
|
<div class="report-page page-break">
|
|
<h4 class="mb-4 border-bottom pb-2">Labour Detail Report: <?= htmlspecialchars($project['name']) ?></h4>
|
|
<table class="table table-bordered table-tight">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Employee</th>
|
|
<th>Activity Type</th>
|
|
<th class="text-end">Hours</th>
|
|
<th class="text-end">Rate</th>
|
|
<th class="text-end">Total Wage</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($labour)): ?>
|
|
<tr><td colspan="6" class="text-center text-muted">No labour entries recorded.</td></tr>
|
|
<?php endif; ?>
|
|
<?php foreach ($labour as $l):
|
|
$cost = (float)$l['hours'] * (float)($l['hourly_rate'] ?? 0);
|
|
?>
|
|
<tr>
|
|
<td><?= $l['entry_date'] ?></td>
|
|
<td><?= htmlspecialchars($l['employee_name']) ?></td>
|
|
<td><?= htmlspecialchars($l['labour_type'] ?? 'N/A') ?></td>
|
|
<td class="text-end"><?= number_format((float)$l['hours'], 2) ?></td>
|
|
<td class="text-end"><?= $l['hourly_rate'] ? '$'.number_format((float)$l['hourly_rate'], 2) : '-' ?></td>
|
|
<td class="text-end fw-bold"><?= $cost > 0 ? '$'.number_format($cost, 2) : '-' ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
<tfoot class="bg-light">
|
|
<tr>
|
|
<td colspan="3" class="text-end fw-bold">Project Totals:</td>
|
|
<td class="text-end fw-bold text-primary"><?= number_format($total_proj_hours, 2) ?> h</td>
|
|
<td></td>
|
|
<td class="text-end fw-bold text-success">$<?= number_format($total_proj_labour_cost, 2) ?></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
<div class="mt-4 extra-small text-muted">
|
|
Note: Hourly rates are recorded at the time of entry to reflect historical wage adjustments accurately.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Project Page 3: Expense Details -->
|
|
<div class="report-page page-break">
|
|
<h4 class="mb-4 border-bottom pb-2">Expense Detail Report: <?= htmlspecialchars($project['name']) ?></h4>
|
|
<table class="table table-bordered table-tight">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Supplier</th>
|
|
<th>Expense Type</th>
|
|
<th>Notes</th>
|
|
<th class="text-end">Allocation</th>
|
|
<th class="text-end">Amount</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($expenses)): ?>
|
|
<tr><td colspan="6" class="text-center text-muted">No expenses recorded.</td></tr>
|
|
<?php endif; ?>
|
|
<?php foreach ($expenses as $e): ?>
|
|
<tr>
|
|
<td><?= $e['entry_date'] ?></td>
|
|
<td><?= htmlspecialchars($e['supplier_name']) ?></td>
|
|
<td><?= htmlspecialchars($e['expense_type'] ?? 'N/A') ?></td>
|
|
<td style="max-width: 200px;" class="text-truncate"><?= htmlspecialchars($e['notes'] ?? '') ?></td>
|
|
<td class="text-end"><?= number_format((float)$e['allocation_percent'], 0) ?>%</td>
|
|
<td class="text-end fw-bold">$<?= number_format((float)$e['amount'], 2) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
<tfoot class="bg-light">
|
|
<tr>
|
|
<td colspan="5" class="text-end fw-bold">Total Expenses:</td>
|
|
<td class="text-end fw-bold text-success">$<?= number_format($total_proj_expenses, 2) ?></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
<!-- SUMMARIZED CLAIM - LABOUR -->
|
|
<div class="report-page page-break">
|
|
<h3 class="mb-4 border-bottom pb-2">Summarized Claim: Monthly Labour Hours</h3>
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered calendar-table">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="text-start">Project Name</th>
|
|
<?php foreach ($months as $m): ?>
|
|
<th><?= date('M y', strtotime($m)) ?></th>
|
|
<?php endforeach; ?>
|
|
<th class="bg-secondary text-white">Total $</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
$grand_total_hours = 0;
|
|
$grand_total_cost = 0;
|
|
foreach ($labour_matrix as $pid => $data):
|
|
$row_cost = 0;
|
|
$pname = $project_names[$pid] ?? 'Unknown Project';
|
|
?>
|
|
<tr>
|
|
<td class="text-start fw-bold"><?= htmlspecialchars($pname) ?></td>
|
|
<?php foreach ($months as $m):
|
|
$h = (float)($data[$m]['hours'] ?? 0);
|
|
$c = (float)($data[$m]['cost'] ?? 0);
|
|
$row_cost += $c;
|
|
$grand_total_hours += $h;
|
|
?>
|
|
<td><?= $h > 0 ? number_format($h, 1) : '-' ?></td>
|
|
<?php endforeach; ?>
|
|
<td class="fw-bold">$<?= number_format($row_cost, 0) ?></td>
|
|
</tr>
|
|
<?php
|
|
$grand_total_cost += $row_cost;
|
|
endforeach; ?>
|
|
</tbody>
|
|
<tfoot class="bg-light fw-bold">
|
|
<tr>
|
|
<td class="text-start">Monthly Totals</td>
|
|
<?php foreach ($months as $m):
|
|
$m_hours = 0;
|
|
foreach($labour_matrix as $pid => $d) $m_hours += (float)($d[$m]['hours'] ?? 0);
|
|
?>
|
|
<td><?= $m_hours > 0 ? number_format($m_hours, 1) : '-' ?></td>
|
|
<?php endforeach; ?>
|
|
<td class="text-success">$<?= number_format($grand_total_cost, 2) ?></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
<p class="small text-muted mt-3">All amounts are calculated using the recorded hourly rate at the time of labour entry.</p>
|
|
</div>
|
|
|
|
<!-- SUMMARIZED CLAIM - EXPENSES -->
|
|
<div class="report-page page-break">
|
|
<h3 class="mb-4 border-bottom pb-2">Summarized Claim: Monthly Expenses</h3>
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered calendar-table">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="text-start">Project Name</th>
|
|
<?php foreach ($months as $m): ?>
|
|
<th><?= date('M y', strtotime($m)) ?></th>
|
|
<?php endforeach; ?>
|
|
<th class="bg-secondary text-white">Total $</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
$grand_total_expense = 0;
|
|
foreach ($expense_matrix as $pid => $data):
|
|
$row_amount = 0;
|
|
$pname = $project_names[$pid] ?? 'Unknown Project';
|
|
?>
|
|
<tr>
|
|
<td class="text-start fw-bold"><?= htmlspecialchars($pname) ?></td>
|
|
<?php foreach ($months as $m):
|
|
$a = (float)($data[$m] ?? 0);
|
|
$row_amount += $a;
|
|
?>
|
|
<td><?= $a > 0 ? '$'.number_format($a, 0) : '-' ?></td>
|
|
<?php endforeach; ?>
|
|
<td class="fw-bold">$<?= number_format($row_amount, 0) ?></td>
|
|
</tr>
|
|
<?php
|
|
$grand_total_expense += $row_amount;
|
|
endforeach; ?>
|
|
</tbody>
|
|
<tfoot class="bg-light fw-bold">
|
|
<tr>
|
|
<td class="text-start">Monthly Totals</td>
|
|
<?php foreach ($months as $m):
|
|
$m_amt = 0;
|
|
foreach($expense_matrix as $pid => $d) $m_amt += (float)($d[$m] ?? 0);
|
|
?>
|
|
<td><?= $m_amt > 0 ? '$'.number_format($m_amt, 0) : '-' ?></td>
|
|
<?php endforeach; ?>
|
|
<td class="text-success">$<?= number_format($grand_total_expense, 2) ?></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mt-5 text-center">
|
|
<div class="border p-4 d-inline-block">
|
|
<h5 class="text-uppercase text-muted small mb-3">Total Captured Wages and Expenses for SR&ED Claim</h5>
|
|
<h1 class="display-4 fw-bold text-primary">$<?= number_format($grand_total_cost + $grand_total_expense, 2) ?></h1>
|
|
<p class="mb-0 text-muted">Includes all Labour Wages and Project Expenses for Fiscal Year <?= $selected_year ?></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="no-print mt-5 text-center p-4 text-muted border-top bg-white">
|
|
SR&ED Manager Claim Report Generator | © <?= date('Y') ?>
|
|
</footer>
|
|
|
|
</body>
|
|
</html>
|