56 lines
3.6 KiB
PHP
56 lines
3.6 KiB
PHP
<?php
|
|||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
require_once __DIR__ . '/../app/Domain/Reporting/ReportFilters.php';
|
||
|
|
require_once __DIR__ . '/../app/Domain/Reporting/ReportDataMapper.php';
|
||
|
|
require_once __DIR__ . '/../app/Domain/Reporting/ClientJobcardReport.php';
|
||
|
|
require_once __DIR__ . '/../app/Domain/Reporting/ClientHistoryReport.php';
|
||
|
|
require_once __DIR__ . '/../app/Domain/Reporting/TechnicianActivityReport.php';
|
||
|
|
require_once __DIR__ . '/../app/Domain/Reporting/PrintReportRenderer.php';
|
||
|
|
|
||
|
|
$filters = ReportFilters::fromArray([
|
||
|
|
'client_id' => 7,
|
||
|
|
'date_from' => '2026-09-01',
|
||
|
|
'date_to' => '2026-09-30',
|
||
|
|
'technician_id' => 4,
|
||
|
|
'status' => 'open',
|
||
|
|
'priority' => 'high',
|
||
|
|
'sla' => 'at_risk',
|
||
|
|
]);
|
||
|
|
if (!$filters->matches(['client_id' => 7, 'created_at' => '2026-09-10', 'technician_id' => 4, 'status' => 'open', 'priority' => 'high', 'sla_status' => 'at_risk'])) {
|
||
|
|
throw new RuntimeException('Expected report filters to match all selected criteria.');
|
||
|
|
}
|
||
|
|
if ($filters->matches(['client_id' => 7, 'created_at' => '2026-10-01', 'technician_id' => 4, 'status' => 'open', 'priority' => 'high', 'sla_status' => 'at_risk'])) {
|
||
|
|
throw new RuntimeException('Expected date range to exclude rows outside the range.');
|
||
|
|
}
|
||
|
|
|
||
|
|
$jobcards = (new ClientJobcardReport($filters))->build([
|
||
|
|
['id' => 2, 'client_id' => 7, 'client_name' => 'Acme', 'reference_no' => 'JC-2', 'status' => 'open', 'priority' => 'high', 'created_at' => '2026-09-10', 'technician_id' => 4, 'technician_name' => 'Tess', 'sla_status' => 'at_risk', 'internal_notes' => 'secret', 'credentials' => 'omit'],
|
||
|
|
['id' => 1, 'client_id' => 8, 'client_name' => 'Beta', 'reference_no' => 'JC-1', 'status' => 'closed', 'priority' => 'low', 'created_at' => '2026-09-01', 'internal_notes' => 'secret'],
|
||
|
|
], 'client');
|
||
|
|
if ($jobcards !== [['client_id' => 7, 'client_name' => 'Acme', 'reference_no' => 'JC-2', 'status' => 'open', 'priority' => 'high', 'created_at' => '2026-09-10']]) {
|
||
|
|
throw new RuntimeException('Client jobcard report must filter, sort and allow-list deterministically.');
|
||
|
|
}
|
||
|
|
|
||
|
|
$history = (new ClientHistoryReport())->build([
|
||
|
|
['jobcard_id' => 3, 'client_id' => 7, 'reference_no' => 'JC-3', 'from_status' => 'new', 'to_status' => 'open', 'changed_at' => '2026-09-03', 'changed_by_name' => 'Tess', 'internal_notes' => 'secret'],
|
||
|
|
], 'client');
|
||
|
|
if ($history[0] !== ['client_id' => 7, 'reference_no' => 'JC-3', 'from_status' => 'new', 'to_status' => 'open', 'changed_at' => '2026-09-03']) {
|
||
|
|
throw new RuntimeException('Client history report must exclude internal actor/details.');
|
||
|
|
}
|
||
|
|
|
||
|
|
$activity = (new TechnicianActivityReport())->build([
|
||
|
|
['technician_id' => 4, 'technician_name' => 'Tess', 'client_id' => 7, 'client_name' => 'Acme', 'work_date' => '2026-09-02', 'hours' => 1.25, 'counts_toward_sla' => true, 'internal_notes' => 'secret'],
|
||
|
|
['technician_id' => 4, 'technician_name' => 'Tess', 'client_id' => 7, 'client_name' => 'Acme', 'work_date' => '2026-09-03', 'hours' => 2.75, 'counts_toward_sla' => false],
|
||
|
|
], 'internal');
|
||
|
|
if ($activity !== [['technician_id' => 4, 'technician_name' => 'Tess', 'client_id' => 7, 'client_name' => 'Acme', 'hours' => 4.0, 'sla_hours' => 1.25]]) {
|
||
|
|
throw new RuntimeException('Technician activity must aggregate hours deterministically.');
|
||
|
|
}
|
||
|
|
|
||
|
|
$html = (new PrintReportRenderer())->render('Client Jobcards', ['Reference', 'Status'], [['JC-2', 'open']]);
|
||
|
|
if (!str_contains($html, '@media print') || !str_contains($html, '<th>Reference</th>') || !str_contains($html, 'JC-2') || str_contains($html, '<script>')) {
|
||
|
|
throw new RuntimeException('Print report renderer must emit escaped, print-friendly HTML.');
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("Report workflow tests: 5 passed\n");
|