gdc_cmod/app/Controllers/SamplesController.php
mahdahar 3cf4cc7f3f feat: Implement audit trail system for dual-level validation workflow
This commit adds comprehensive audit logging for specimen requests and sample collection activities across all roles.
Changes Summary:
New Features:
- Added AUDIT_EVENTS table schema for tracking validation and sample collection events
- Created ApiRequestsAuditController with /api/requests/(:any)/audit endpoint to retrieve audit history
- Added dialog_audit.php view component for displaying audit trails in UI
- Integrated audit logging into validation workflow (VAL1, VAL2, UNVAL events)
Database:
- Created AUDIT_EVENTS table with columns: ACCESSNUMBER, EVENT_TYPE, USERID, EVENT_AT, REASON
- Supports tracking validation events and sample collection actions
Controllers:
- RequestsController: Now inserts audit records for all validation operations
- ApiRequestsAuditController: New API controller returning validation and sample collection history
Routes:
- Added GET /api/requests/(:any)/audit endpoint for retrieving audit trail
- Removed DELETE /api/samples/collect/(:any) endpoint (uncollect functionality)
Views Refactoring:
- Consolidated dashboard layouts into shared components:
  - layout.php (from layout_dashboard.php)
  - script_requests.php (from script_dashboard.php)
  - script_validation.php (from script_validate.php)
  - content_requests.php (from dashboard_table.php)
  - content_validation.php (from dashboard_validate.php)
- Added content_validation_new.php for enhanced validation interface
2026-01-23 16:41:12 +07:00

118 lines
4.9 KiB
PHP

<?php
namespace App\Controllers;
use CodeIgniter\API\ResponseTrait;
use App\Controllers\BaseController;
class SamplesController extends BaseController
{
use ResponseTrait;
public function show($accessnumber)
{
$db = \Config\Database::connect();
$sql = "SELECT right(p.PATNUMBER,16) as [patnumber], ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') as [Name],
case when format(p.BIRTHDATE,'MMdd')=format(spr.COLLECTIONDATE,'MMdd') then DATEDIFF(YEAR,p.BIRTHDATE, spr.COLLECTIONDATE)
else FLOOR(DATEDIFF(DAY, p.BIRTHDATE, spr.COLLECTIONDATE) / 365.25) end ,
[Gender] = case
when p.SEX = 1 then 'M'
when p.SEX = 2 then 'F'
else ''
end, spr.REQDATE, spo.COMMENTTEXT, dmg.DMG_CKTPNO, dmg.DMG_CPLACEOFBIRTH
from SP_REQUESTS spr
left join PATIENTS p on p.PATID=spr.PATID
left join SP_REQUESTS_OCOM spo on spr.SP_ACCESSNUMBER=spo.SP_ACCESSNUMBER
left join GDC_CMOD.dbo.TDL_DEMOGRAPHIC dmg on right(dmg.DMG_CPATNUMBER,15)=right(p.PATNUMBER,15)
where spr.PATID=p.PATID and spr.SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getRowArray();
$data = [
'patnumber' => $results["patnumber"],
'age' => $results[""],
'patname' => $results['Name'] ?? '',
'reqdate' => $results['REQDATE'] ?? '',
'gender' => $results['Gender'] ?? '',
'placeofbirth' => $results['DMG_CPLACEOFBIRTH'] ?? '',
'ktp' => $results['DMG_CKTPNO'] ?? '',
'comment' => $results['COMMENTTEXT'] ?? '',
'accessnumber' => $accessnumber,
];
$samples = [];
$sql = "SELECT req.SAMPTYPEID, req.SAMPCODE, req.SHORTTEXT, tu.STATUS, st.TUBESTATUS
from GDC_CMOD.dbo.v_sp_reqtube req
left join GDC_CMOD.dbo.TUBES tu on req.SP_ACCESSNUMBER=tu.ACCESSNUMBER and req.SAMPCODE=tu.TUBENUMBER
left join glendb.dbo.SP_TUBES st on st.SP_ACCESSNUMBER=req.SP_ACCESSNUMBER and req.SAMPCODE=st.SAMPLETYPE
where req.SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getResultArray();
foreach ($results as $row) {
$samples[] = [
'samptypeid' => $row['SAMPTYPEID'] ?? null,
'sampcode' => $row['SAMPCODE'] ?? null,
'name' => $row['SHORTTEXT'] ?? '',
'colstatus' => $row['STATUS'] ?? '',
'tubestatus' => $row['TUBESTATUS'] ?? '',
];
}
$data['samples'] = $samples;
$resp = ['data' => $data];
return $this->response->setJSON($resp);
}
public function collect($accessnumber)
{
$db = \Config\Database::connect();
$input = $this->request->getJSON(true);
$samplenumber = $input['samplenumber'];
$userid = session('userid');
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='1', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
$db->query($sql);
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
VALUES ('$accessnumber', '$samplenumber', '$userid', '1', getdate())";
$db->query($sql);
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
}
public function unreceive($accessnumber)
{
$db = \Config\Database::connect();
$input = $this->request->getJSON(true);
$samplenumber = $input['samplenumber'];
$sql = "select r.EXTERNALORDERNUMBER, dt.TESTCODE, do.HISCODE from glendb.dbo.TESTS t
left join glendb.dbo.DICT_TESTS dt on dt.TESTID=t.TESTID
left join glendb.dbo.REQUESTS r on r.REQUESTID=t.REQUESTID
left join glendb.dbo.DICT_TEST_SAMPLES dts on dts.TESTID=t.TESTID
left join glendb.dbo.DICT_SAMPLES_TYPES ds on ds.SAMPTYPEID=dts.SAMPTYPEID
left join GDC_CMOD.dbo.DICT_TESTS_ORDER do on do.TESTCODE=dt.TESTCODE
where t.DEPTH=0
and r.ACCESSNUMBER='$accessnumber' and ds.SAMPCODE='$samplenumber'";
$rows = $db->query($sql)->getResultArray();
$his_test = '';
$lis_test = '';
foreach ($rows as $row) {
$hon = $row['EXTERNALORDERNUMBER'];
$testcode = $row['TESTCODE'];
$hiscode = $row['HISCODE'];
$his_test .= "'$hiscode',";
$lis_test .= "'$testcode',";
}
$his_test = rtrim($his_test, ',');
$lis_test = rtrim($lis_test, ',');
$conn = odbc_connect('GLENEAGLES', '', '');
$sql = "UPDATE TDL_ORDERDT SET ODD_NRECEIVED=NULL , ODD_DTRECEIVE=NULL WHERE ODR_CNOLAB='$hon' and ODD_CPRODUCTCODE IN ($his_test)";
$rs = odbc_exec($conn, $sql);
if (!$rs) {
exit("Error in Update FB");
}
$sql = "update SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$accessnumber' and SAMPLETYPE='$samplenumber' ";
$db->query($sql);
$sql = "update SP_TESTS set SP_TESTSTATUS=NULL where SP_ACCESSNUMBER='$accessnumber' and SP_TESTCODE in ($lis_test)";
$db->query($sql);
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
}
}