2026-03-16 07:24:50 +07:00
< ? php
namespace App\Controllers ;
use App\Traits\ResponseTrait ;
use CodeIgniter\Controller ;
use App\Libraries\ValueSet ;
2026-03-03 13:51:27 +07:00
use App\Models\OrderTest\OrderTestModel ;
2026-01-12 16:53:41 +07:00
use App\Models\Patient\PatientModel ;
2026-03-03 13:51:27 +07:00
use App\Models\PatVisit\PatVisitModel ;
2026-03-16 07:24:50 +07:00
class OrderTestController extends Controller {
use ResponseTrait ;
protected $db ;
protected $model ;
protected $patientModel ;
protected $visitModel ;
protected $rules ;
public function __construct () {
$this -> db = \Config\Database :: connect ();
$this -> model = new OrderTestModel ();
$this -> patientModel = new PatientModel ();
$this -> visitModel = new PatVisitModel ();
$this -> rules = [
'InternalPID' => 'required|is_natural'
];
}
public function index () {
$internalPID = $this -> request -> getVar ( 'InternalPID' );
$includeDetails = $this -> request -> getVar ( 'include' ) === 'details' ;
try {
if ( $internalPID ) {
$rows = $this -> model -> getOrdersByPatient ( $internalPID );
} else {
$rows = $this -> db -> table ( 'ordertest' )
-> where ( 'DelDate' , null )
-> orderBy ( 'TrnDate' , 'DESC' )
-> get ()
-> getResultArray ();
}
$rows = ValueSet :: transformLabels ( $rows , [
'Priority' => 'order_priority' ,
'OrderStatus' => 'order_status' ,
]);
if ( $includeDetails && ! empty ( $rows )) {
foreach ( $rows as & $row ) {
$row [ 'Specimens' ] = $this -> getOrderSpecimens ( $row [ 'InternalOID' ]);
$row [ 'Tests' ] = $this -> getOrderTests ( $row [ 'InternalOID' ]);
}
}
return $this -> respond ([
'status' => 'success' ,
'message' => 'Data fetched successfully' ,
'data' => $rows
], 200 );
} catch ( \Exception $e ) {
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
}
public function show ( $orderID = null ) {
try {
$row = $this -> model -> getOrder ( $orderID );
if ( empty ( $row )) {
return $this -> respond ([
'status' => 'success' ,
'message' => 'Data not found.' ,
'data' => null
], 200 );
}
$row = ValueSet :: transformLabels ([ $row ], [
'Priority' => 'order_priority' ,
'OrderStatus' => 'order_status' ,
])[ 0 ];
// Include specimens and tests
$row [ 'Specimens' ] = $this -> getOrderSpecimens ( $row [ 'InternalOID' ]);
$row [ 'Tests' ] = $this -> getOrderTests ( $row [ 'InternalOID' ]);
return $this -> respond ([
'status' => 'success' ,
'message' => 'Data fetched successfully' ,
'data' => $row
], 200 );
} catch ( \Exception $e ) {
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
}
private function getOrderSpecimens ( $internalOID ) {
$specimens = $this -> db -> table ( 'specimen s' )
-> select ( 's.*, cd.ConCode, cd.ConName' )
-> join ( 'containerdef cd' , 'cd.ConDefID = s.ConDefID' , 'left' )
-> where ( 's.OrderID' , $internalOID )
-> where ( 's.EndDate IS NULL' )
-> get ()
-> getResultArray ();
// Get status for each specimen
foreach ( $specimens as & $specimen ) {
$status = $this -> db -> table ( 'specimenstatus' )
-> where ( 'SID' , $specimen [ 'SID' ])
-> where ( 'EndDate IS NULL' )
-> orderBy ( 'CreateDate' , 'DESC' )
-> get ()
-> getRowArray ();
$specimen [ 'Status' ] = $status [ 'SpcStatus' ] ? ? 'PENDING' ;
}
return $specimens ;
}
private function getOrderTests ( $internalOID ) {
$tests = $this -> db -> table ( 'patres pr' )
-> select ( 'pr.*, tds.TestSiteCode, tds.TestSiteName, tds.TestType, tds.SeqScr AS TestSeqScr, tds.SeqRpt AS TestSeqRpt, tds.DisciplineID, d.DisciplineCode, d.DisciplineName, d.SeqScr AS DisciplineSeqScr, d.SeqRpt AS DisciplineSeqRpt' )
-> join ( 'testdefsite tds' , 'tds.TestSiteID = pr.TestSiteID' , 'left' )
-> join ( 'discipline d' , 'd.DisciplineID = tds.DisciplineID' , 'left' )
-> where ( 'pr.OrderID' , $internalOID )
-> where ( 'pr.DelDate IS NULL' )
-> orderBy ( 'COALESCE(d.SeqScr, 999999) ASC' )
-> orderBy ( 'COALESCE(d.SeqRpt, 999999) ASC' )
-> orderBy ( 'COALESCE(tds.SeqScr, 999999) ASC' )
-> orderBy ( 'COALESCE(tds.SeqRpt, 999999) ASC' )
-> orderBy ( 'pr.ResultID ASC' )
-> get ()
-> getResultArray ();
foreach ( $tests as & $test ) {
$discipline = [
'DisciplineID' => $test [ 'DisciplineID' ] ? ? null ,
'DisciplineCode' => $test [ 'DisciplineCode' ] ? ? null ,
'DisciplineName' => $test [ 'DisciplineName' ] ? ? null ,
'SeqScr' => $test [ 'DisciplineSeqScr' ] ? ? null ,
'SeqRpt' => $test [ 'DisciplineSeqRpt' ] ? ? null ,
];
$test [ 'Discipline' ] = $discipline ;
$test [ 'SeqScr' ] = $test [ 'TestSeqScr' ] ? ? null ;
$test [ 'SeqRpt' ] = $test [ 'TestSeqRpt' ] ? ? null ;
$test [ 'DisciplineID' ] = $discipline [ 'DisciplineID' ];
unset ( $test [ 'DisciplineCode' ], $test [ 'DisciplineName' ], $test [ 'DisciplineSeqScr' ], $test [ 'DisciplineSeqRpt' ], $test [ 'TestSeqScr' ], $test [ 'TestSeqRpt' ]);
}
unset ( $test );
return $tests ;
}
public function create () {
$input = $this -> request -> getJSON ( true );
if ( ! $this -> validateData ( $input , $this -> rules )) {
return $this -> failValidationErrors ( $this -> validator -> getErrors ());
}
try {
if ( ! $this -> patientModel -> find ( $input [ 'InternalPID' ])) {
return $this -> failValidationErrors ([ 'InternalPID' => 'Patient not found' ]);
}
if ( ! empty ( $input [ 'PatVisitID' ])) {
$visit = $this -> visitModel -> find ( $input [ 'PatVisitID' ]);
if ( ! $visit ) {
return $this -> failValidationErrors ([ 'PatVisitID' => 'Visit not found' ]);
}
}
$orderID = $this -> model -> createOrder ( $input );
// Fetch complete order details
$order = $this -> model -> getOrder ( $orderID );
$order [ 'Specimens' ] = $this -> getOrderSpecimens ( $order [ 'InternalOID' ]);
$order [ 'Tests' ] = $this -> getOrderTests ( $order [ 'InternalOID' ]);
// Rule engine triggers are fired at the test/result level (test_created, result_updated)
2026-03-12 06:34:56 +07:00
2025-09-19 15:22:25 +07:00
return $this -> respondCreated ([
2026-01-12 16:53:41 +07:00
'status' => 'success' ,
'message' => 'Order created successfully' ,
2026-03-03 13:51:27 +07:00
'data' => $order
2025-09-19 15:22:25 +07:00
], 201 );
2026-03-16 07:24:50 +07:00
} catch ( \Exception $e ) {
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
}
public function update () {
$input = $this -> request -> getJSON ( true );
if ( empty ( $input [ 'OrderID' ])) {
return $this -> failValidationErrors ([ 'OrderID' => 'OrderID is required' ]);
}
try {
$order = $this -> model -> getOrder ( $input [ 'OrderID' ]);
if ( ! $order ) {
return $this -> failNotFound ( 'Order not found' );
}
$updateData = [];
if ( isset ( $input [ 'Priority' ])) $updateData [ 'Priority' ] = $input [ 'Priority' ];
if ( isset ( $input [ 'OrderStatus' ])) $updateData [ 'OrderStatus' ] = $input [ 'OrderStatus' ];
if ( isset ( $input [ 'OrderingProvider' ])) $updateData [ 'OrderingProvider' ] = $input [ 'OrderingProvider' ];
if ( isset ( $input [ 'DepartmentID' ])) $updateData [ 'DepartmentID' ] = $input [ 'DepartmentID' ];
if ( isset ( $input [ 'WorkstationID' ])) $updateData [ 'WorkstationID' ] = $input [ 'WorkstationID' ];
if ( ! empty ( $updateData )) {
$this -> model -> update ( $order [ 'InternalOID' ], $updateData );
}
$updatedOrder = $this -> model -> getOrder ( $input [ 'OrderID' ]);
$updatedOrder [ 'Specimens' ] = $this -> getOrderSpecimens ( $updatedOrder [ 'InternalOID' ]);
$updatedOrder [ 'Tests' ] = $this -> getOrderTests ( $updatedOrder [ 'InternalOID' ]);
return $this -> respond ([
'status' => 'success' ,
'message' => 'Order updated successfully' ,
'data' => $updatedOrder
], 200 );
} catch ( \Exception $e ) {
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
}
public function delete () {
$input = $this -> request -> getJSON ( true );
$orderID = $input [ 'OrderID' ] ? ? null ;
if ( empty ( $orderID )) {
return $this -> failValidationErrors ([ 'OrderID' => 'OrderID is required' ]);
}
try {
$order = $this -> model -> getOrder ( $orderID );
if ( ! $order ) {
return $this -> failNotFound ( 'Order not found' );
}
$this -> model -> softDelete ( $orderID );
return $this -> respondDeleted ([
'status' => 'success' ,
'message' => 'Order deleted successfully'
]);
} catch ( \Exception $e ) {
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
}
public function updateStatus () {
$input = $this -> request -> getJSON ( true );
if ( empty ( $input [ 'OrderID' ]) || empty ( $input [ 'OrderStatus' ])) {
return $this -> failValidationErrors ([ 'error' => 'OrderID and OrderStatus are required' ]);
}
$validStatuses = [ 'ORD' , 'SCH' , 'ANA' , 'VER' , 'REV' , 'REP' ];
if ( ! in_array ( $input [ 'OrderStatus' ], $validStatuses )) {
return $this -> failValidationErrors ([ 'OrderStatus' => 'Invalid status. Valid: ' . implode ( ', ' , $validStatuses )]);
}
try {
$order = $this -> model -> getOrder ( $input [ 'OrderID' ]);
if ( ! $order ) {
return $this -> failNotFound ( 'Order not found' );
}
$this -> model -> updateStatus ( $input [ 'OrderID' ], $input [ 'OrderStatus' ]);
$updatedOrder = $this -> model -> getOrder ( $input [ 'OrderID' ]);
$updatedOrder [ 'Specimens' ] = $this -> getOrderSpecimens ( $updatedOrder [ 'InternalOID' ]);
$updatedOrder [ 'Tests' ] = $this -> getOrderTests ( $updatedOrder [ 'InternalOID' ]);
return $this -> respond ([
'status' => 'success' ,
'message' => 'Order status updated successfully' ,
'data' => $updatedOrder
], 200 );
} catch ( \Exception $e ) {
return $this -> failServerError ( 'Something went wrong: ' . $e -> getMessage ());
}
}
}