mahdahar 31acb6bf33 feat: Implement comprehensive report generation system with role-based access control
Add native CodeIgniter 4 report generation functionality replacing legacy spooler_db system.
Provides centralized report generation with audit logging and multi-language support.

New Features:
- Report generation with Indonesian and English language support
- Role-based access control (Lab, Admin, Superuser: generate; CS: print only)
- Preview mode for validation workflow
- Print audit logging to AUDIT_REQUESTS table
- Multi-page report support with proper pagination
- Dual unit system (Conventional and International units)

Controllers:
- ReportController: Main controller for report generation, preview, and print
  - generate(): Full report with audit logging
  - preview(): Preview mode without audit logging
  - print(): Print-only access for CS role
- Home::printReport(): Route handler redirecting based on user role

Libraries:
- ReportHelper: Comprehensive report data retrieval
  - Patient information (name, MR number, demographics, referral)
  - Test results with reference ranges and unit conversions
  - Collection and reception data with timestamps
  - Validation status and validator information
  - Special handling for pending samples and Chinese translations

Routes:
- /report/(:num) - Generate report (Lab, Admin, Superuser)
- /report/(:num)/preview - Preview without audit logging
- /report/(:num)/eng - English language report
- /report/print/(:num) - Print-only access (CS role)
- /print/(:num) - Redirect based on role (all roles)

Views:
- report/template.php: Professional lab report template with Gleneagles branding
  - Header and footer images
  - Patient information table
  - Test results with dual unit columns
  - Collection and reception timestamps
  - Authorization signature area
  - Preview watermark

Role Index Views:
- Removed dialog_preview.php inclusion from all role dashboards
- Consolidated print button directly linking to new report routes

Assets:
- Report-specific CSS files (normalize.min.css, style.css, pdf.css, style_qr.css)
- Gleneagles header and footer images
- Legacy spooler_db files preserved in public/spooler_db/ for reference

Tests:
- ReportTest.php: Unit tests for report generation functionality

Database:
- Uses existing tables: REQUESTS, TESTS, DICT_TESTS, SP_REQUESTS, PATIENTS
- Inserts print audit records into AUDIT_REQUESTS table

Security:
- Parameterized queries throughout (SQL injection prevention)
- Role-based access control enforced at route level
- Proper output escaping with esc() in views
2026-02-02 16:54:22 +07:00

96 lines
3.9 KiB
PHP

<?php
function nullAph($string) {
if($string=='') { $string='null'; }
else {$string= "'$string'";}
return $string;
}
$ACCESSNUMBER=$_GET['acc'];
include('config.php');
$connFB = odbc_connect('GLENEAGLES','','');
$sql = "select * from GDC_CMOD.dbo.v_lab_result where ACCESSNUMBER='$ACCESSNUMBER'";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); }
while ($row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC)) {
$CIDBILLING = $row['CIDBILLING'];
$CIDBILLINGDT = $row['CIDBILLINGDT'];
$CIDPRODUCT = $row['CIDPRODUCT'];
$ODR_CNOLAB = $row['ODR_CNOLAB'];
$RSLT_NCOMPARISON = $row['RSLT_NCOMPARISON'];
$NSEX = $row['NSEX'];
$UOM_ID = $row['UOM_ID'];
$RSLT_VALUEN = $row['RSLT_VALUEN'];
$RSLT_VALUET = $row['RSLT_VALUET'];
//$RSLT_VALUEB = $row['RSLT_VALUEB'];
$RSLT_VALUEB = 'null';
$RSLT_NORMAL = $row['RSLT_NORMAL'];
$RSLT_COMMENT = $row['RSLT_COMMENT'];
$INTER_UOM_ID = $row['INTER_UOM_ID'];
$RSLT_INTERVALUEN = $row['RSLT_INTERVALUEN'];
$RSLT_INTERVALUET = $row['RSLT_INTERVALUET'];
//$RSLT_INTERVALUEB = $row['RSLT_INTERVALUEB'];
$RSLT_INTERVALUEB = 'null';
$RSLT_INTERNORMAL = $row['RSLT_INTERNORMAL'];
$RSLT_INTERCOMMENT = $row['RSLT_INTERCOMMENT'];
$RSLT_NORMALTEXT = $row['FTEXT'];
$MACH_ID = $row['MACH_ID'];
$RSLT_CREATEDBY = $row['RSLT_CREATEDBY'];
$RSLT_NCONVERSION = $row['RSLT_NCONVERSION'];
$CIDBILLING = nullAph($CIDBILLING);
$CIDBILLINGDT = nullAph($CIDBILLINGDT);
$CIDPRODUCT = nullAph($CIDPRODUCT);
//$ODR_CNOLAB = nullAph($ODR_CNOLAB);
$RSLT_NCOMPARISON = nullAph($RSLT_NCOMPARISON);
$NSEX = nullAph($NSEX);
$UOM_ID = nullAph($UOM_ID);
$RSLT_VALUEN = nullAph($RSLT_VALUEN);
$RSLT_VALUET = nullAph($RSLT_VALUET);
$RSLT_NORMAL = nullAph($RSLT_NORMAL);
$RSLT_COMMENT = nullAph($RSLT_COMMENT);
$INTER_UOM_ID = nullAph($INTER_UOM_ID);
$RSLT_INTERVALUEN = nullAph($RSLT_INTERVALUEN);
$RSLT_INTERVALUET = nullAph($RSLT_INTERVALUET);
$RSLT_INTERNORMAL = nullAph($RSLT_INTERNORMAL);
$RSLT_INTERCOMMENT = nullAph($RSLT_INTERCOMMENT);
$RSLT_NORMALTEXT = nullAph($RSLT_NORMALTEXT);
$MACH_ID = nullAph($MACH_ID);
$RSLT_CREATEDBY = nullAph($RSLT_CREATEDBY);
$RSLT_NCONVERSION = nullAph($RSLT_NCONVERSION);
//var sqlFB = "EXECUTE procedure TDL_FILL_LABRESULT ( "+CIDBILLING+", "+CIDBILLINGDT+", "+CIDPRODUCT+", "+RSLT_NCOMPARISON+", "+NSEX+", "+UOM_ID+",
// "+RSLT_VALUEN+", "+RSLT_VALUET+", "+RSLT_VALUEB+", "+RSLT_NORMAL+", "+RSLT_COMMENT+", "+INTER_UOM_ID+", "+RSLT_INTERVALUEN+",
// "+RSLT_INTERVALUET+", "+RSLT_INTERVALUEB+", "+RSLT_INTERNORMAL+", "+RSLT_INTERCOMMENT+","+RSLT_NORMALTEXT+", "+MACH_ID+",
// "+RSLT_CREATEDBY+", "+RSLT_NCONVERSION+")";
if($CIDBILLINGDT !='') {
//echo "<pre>"; print_r($row); echo"</pre>";
$sqlFB = "EXECUTE procedure TDL_FILL_LABRESULT ( $CIDBILLING, $CIDBILLINGDT, $CIDPRODUCT, $RSLT_NCOMPARISON, $NSEX, $UOM_ID,
$RSLT_VALUEN, $RSLT_VALUET, $RSLT_VALUEB, $RSLT_NORMAL, $RSLT_COMMENT, $INTER_UOM_ID, $RSLT_INTERVALUEN,
$RSLT_INTERVALUET, $RSLT_INTERVALUEB, $RSLT_INTERNORMAL, $RSLT_INTERCOMMENT,$RSLT_NORMALTEXT, $MACH_ID, $RSLT_CREATEDBY,
$RSLT_NCONVERSION)";
//echo $sqlFB."<br/>";
//$resultsc = odbc_exec($connFB, $sqlFB) or die("$sqlFB<br/> ".odbc_errormsg());
}
}
// update tdl_order status
$resdt = date('Y-m-d H:i');
$sql = "select status = case
when exists (
select 1 from glendb.dbo.TESTS t
left join glendb.dbo.REQUESTS r on r.REQUESTID=t.REQUESTID
where r.ACCESSNUMBER='$ACCESSNUMBER' and
( t.RESTYPE=0 OR t.RESSTATUS=0 OR Left(t.RESVALUE,7)='Pending' )
and t.NOTPRINTABLE is null
) then 'PENDING'
else 'FINAL'
end";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt == false) { die( print_r( sqlsrv_errors(), true) ); }
$row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC);
if($row[0]!='PENDING') {
$status=1;
$sqlFB = "UPDATE TDL_ORDER SET ODR_NRESULT='$status', ODR_DTRESULT='$resdt' WHERE ODR_CNOLAB='$ODR_CNOLAB'";
//echo $sqlFB."<br/>";
$resultsc = odbc_exec($connFB, $sqlFB) or die(odbc_errormsg());
}
odbc_close($connFB);
?>