Compact order show response
- Return compact test list from order show endpoint - Add compact order/test OpenAPI schema refs - Add feature test for compact order show payload - Remove tracked composer.phar binary
This commit is contained in:
parent
4f87be295b
commit
e869ec4ac4
@ -88,9 +88,7 @@ class OrderTestController extends Controller {
|
|||||||
'OrderStatus' => 'order_status',
|
'OrderStatus' => 'order_status',
|
||||||
])[0];
|
])[0];
|
||||||
|
|
||||||
// Include specimens and tests
|
$row['Tests'] = $this->getOrderTestsCompact($row['InternalOID']);
|
||||||
$row['Specimens'] = $this->getOrderSpecimens($row['InternalOID']);
|
|
||||||
$row['Tests'] = $this->getOrderTests($row['InternalOID']);
|
|
||||||
|
|
||||||
return $this->respond([
|
return $this->respond([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
@ -125,6 +123,18 @@ class OrderTestController extends Controller {
|
|||||||
return $specimens;
|
return $specimens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getOrderTestsCompact($internalOID) {
|
||||||
|
return $this->db->table('patres pr')
|
||||||
|
->distinct()
|
||||||
|
->select('pr.TestSiteID, tds.TestSiteCode, tds.TestSiteName')
|
||||||
|
->join('testdefsite tds', 'tds.TestSiteID = pr.TestSiteID', 'left')
|
||||||
|
->where('pr.OrderID', $internalOID)
|
||||||
|
->where('pr.DelDate IS NULL')
|
||||||
|
->orderBy('tds.TestSiteCode', 'ASC')
|
||||||
|
->get()
|
||||||
|
->getResultArray();
|
||||||
|
}
|
||||||
|
|
||||||
private function getOrderTests($internalOID) {
|
private function getOrderTests($internalOID) {
|
||||||
$tests = $this->db->table('patres pr')
|
$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')
|
->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')
|
||||||
|
|||||||
BIN
composer.phar
BIN
composer.phar
Binary file not shown.
@ -1437,7 +1437,7 @@ paths:
|
|||||||
tags:
|
tags:
|
||||||
- Order
|
- Order
|
||||||
summary: Get order by ID
|
summary: Get order by ID
|
||||||
description: Returns order details with associated specimens and tests
|
description: Returns compact order details with test list only
|
||||||
security:
|
security:
|
||||||
- bearerAuth: []
|
- bearerAuth: []
|
||||||
parameters:
|
parameters:
|
||||||
@ -1449,7 +1449,7 @@ paths:
|
|||||||
description: Order ID (e.g., 0025030300001)
|
description: Order ID (e.g., 0025030300001)
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Order details with specimens and tests
|
description: Compact order details with tests
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
@ -1460,7 +1460,7 @@ paths:
|
|||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
data:
|
data:
|
||||||
$ref: '#/components/schemas/OrderTest'
|
$ref: '#/components/schemas/OrderTestCompact'
|
||||||
patch:
|
patch:
|
||||||
tags:
|
tags:
|
||||||
- Order
|
- Order
|
||||||
@ -7790,6 +7790,90 @@ components:
|
|||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/OrderTestItem'
|
$ref: '#/components/schemas/OrderTestItem'
|
||||||
description: Test results (patres) for this order
|
description: Test results (patres) for this order
|
||||||
|
OrderTestCompact:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
InternalOID:
|
||||||
|
type: integer
|
||||||
|
description: Internal order ID
|
||||||
|
OrderID:
|
||||||
|
type: string
|
||||||
|
description: Order ID (e.g., 0025030300001)
|
||||||
|
PlacerID:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
InternalPID:
|
||||||
|
type: integer
|
||||||
|
description: Patient internal ID
|
||||||
|
SiteID:
|
||||||
|
type: integer
|
||||||
|
PVADTID:
|
||||||
|
type: integer
|
||||||
|
description: Visit ADT ID
|
||||||
|
ReqApp:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
Priority:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- R
|
||||||
|
- S
|
||||||
|
- U
|
||||||
|
description: |
|
||||||
|
R: Routine
|
||||||
|
S: Stat
|
||||||
|
U: Urgent
|
||||||
|
PriorityLabel:
|
||||||
|
type: string
|
||||||
|
description: Priority display text
|
||||||
|
TrnDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: Transaction/Order date
|
||||||
|
EffDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: Effective date
|
||||||
|
CreateDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
OrderStatus:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- ORD
|
||||||
|
- SCH
|
||||||
|
- ANA
|
||||||
|
- VER
|
||||||
|
- REV
|
||||||
|
- REP
|
||||||
|
description: |
|
||||||
|
ORD: Ordered
|
||||||
|
SCH: Scheduled
|
||||||
|
ANA: Analysis
|
||||||
|
VER: Verified
|
||||||
|
REV: Reviewed
|
||||||
|
REP: Reported
|
||||||
|
OrderStatusLabel:
|
||||||
|
type: string
|
||||||
|
description: Order status display text
|
||||||
|
Tests:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/OrderTestCompactItem'
|
||||||
|
description: Compact test list for this order
|
||||||
|
OrderTestCompactItem:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
TestSiteID:
|
||||||
|
type: integer
|
||||||
|
description: Test definition site ID
|
||||||
|
TestSiteCode:
|
||||||
|
type: string
|
||||||
|
description: Test code
|
||||||
|
TestSiteName:
|
||||||
|
type: string
|
||||||
|
description: Test name
|
||||||
|
nullable: true
|
||||||
OrderItem:
|
OrderItem:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@ -22,45 +22,45 @@ servers:
|
|||||||
- url: https://clqms01-api.services-summit.my.id/
|
- url: https://clqms01-api.services-summit.my.id/
|
||||||
description: Production server
|
description: Production server
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- name: Authentication
|
- name: Authentication
|
||||||
description: User authentication and session management
|
description: User authentication and session management
|
||||||
- name: Patient
|
- name: Patient
|
||||||
description: Patient registration and management
|
description: Patient registration and management
|
||||||
- name: Patient Visit
|
- name: Patient Visit
|
||||||
description: Patient visit/encounter management
|
description: Patient visit/encounter management
|
||||||
- name: Organization
|
- name: Organization
|
||||||
description: Organization structure (accounts, sites, disciplines, departments, workstations)
|
description: Organization structure (accounts, sites, disciplines, departments, workstations)
|
||||||
- name: Location
|
- name: Location
|
||||||
description: Location management (rooms, wards, buildings)
|
description: Location management (rooms, wards, buildings)
|
||||||
- name: Equipment
|
- name: Equipment
|
||||||
description: Laboratory equipment and instrument management
|
description: Laboratory equipment and instrument management
|
||||||
- name: Specimen
|
- name: Specimen
|
||||||
description: Specimen and container management
|
description: Specimen and container management
|
||||||
- name: Test
|
- name: Test
|
||||||
description: Test definitions and test catalog
|
description: Test definitions and test catalog
|
||||||
- name: Rule
|
- name: Rule
|
||||||
description: Rule engine - rules can be linked to multiple tests via testrule mapping table
|
description: Rule engine - rules can be linked to multiple tests via testrule mapping table
|
||||||
- name: Calculation
|
- name: Calculation
|
||||||
description: Lightweight calculator endpoint for retrieving computed values by code or name
|
description: Lightweight calculator endpoint for retrieving computed values by code or name
|
||||||
- name: Order
|
- name: Order
|
||||||
description: Laboratory order management
|
description: Laboratory order management
|
||||||
- name: Result
|
- name: Result
|
||||||
description: Patient results reporting with auto-validation
|
description: Patient results reporting with auto-validation
|
||||||
- name: Report
|
- name: Report
|
||||||
description: Lab report generation (HTML view)
|
description: Lab report generation (HTML view)
|
||||||
- name: Edge API
|
- name: Edge API
|
||||||
description: Instrument integration endpoints
|
description: Instrument integration endpoints
|
||||||
- name: Contact
|
- name: Contact
|
||||||
description: Contact management (doctors, practitioners, etc.)
|
description: Contact management (doctors, practitioners, etc.)
|
||||||
- name: ValueSet
|
- name: ValueSet
|
||||||
description: Value set definitions and items
|
description: Value set definitions and items
|
||||||
- name: User
|
- name: User
|
||||||
description: User management and administration
|
description: User management and administration
|
||||||
- name: Demo
|
- name: Demo
|
||||||
description: Demo/test endpoints (no authentication)
|
description: Demo/test endpoints (no authentication)
|
||||||
- name: Audit
|
- name: Audit
|
||||||
description: Audit log retrieval and filtering
|
description: Audit log retrieval and filtering
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
@ -153,6 +153,10 @@ components:
|
|||||||
$ref: './components/schemas/orders.yaml#/OrderTestList'
|
$ref: './components/schemas/orders.yaml#/OrderTestList'
|
||||||
OrderTest:
|
OrderTest:
|
||||||
$ref: './components/schemas/orders.yaml#/OrderTest'
|
$ref: './components/schemas/orders.yaml#/OrderTest'
|
||||||
|
OrderTestCompact:
|
||||||
|
$ref: './components/schemas/orders.yaml#/OrderTestCompact'
|
||||||
|
OrderTestCompactItem:
|
||||||
|
$ref: './components/schemas/orders.yaml#/OrderTestCompactItem'
|
||||||
OrderItem:
|
OrderItem:
|
||||||
$ref: './components/schemas/orders.yaml#/OrderItem'
|
$ref: './components/schemas/orders.yaml#/OrderItem'
|
||||||
|
|
||||||
@ -190,13 +194,13 @@ components:
|
|||||||
UserListResponse:
|
UserListResponse:
|
||||||
$ref: './components/schemas/user.yaml#/UserListResponse'
|
$ref: './components/schemas/user.yaml#/UserListResponse'
|
||||||
|
|
||||||
# Rules schemas
|
# Rules schemas
|
||||||
RuleDef:
|
RuleDef:
|
||||||
$ref: './components/schemas/rules.yaml#/RuleDef'
|
$ref: './components/schemas/rules.yaml#/RuleDef'
|
||||||
RuleWithDetails:
|
RuleWithDetails:
|
||||||
$ref: './components/schemas/rules.yaml#/RuleWithDetails'
|
$ref: './components/schemas/rules.yaml#/RuleWithDetails'
|
||||||
TestRule:
|
TestRule:
|
||||||
$ref: './components/schemas/rules.yaml#/TestRule' # Mapping table between rules and tests
|
$ref: './components/schemas/rules.yaml#/TestRule' # Mapping table between rules and tests
|
||||||
|
|
||||||
# Paths are in separate files in the paths/ directory
|
# Paths are in separate files in the paths/ directory
|
||||||
# To view the complete API with all paths, use: api-docs.bundled.yaml
|
# To view the complete API with all paths, use: api-docs.bundled.yaml
|
||||||
|
|||||||
@ -124,6 +124,83 @@ OrderTest:
|
|||||||
$ref: '#/OrderTestItem'
|
$ref: '#/OrderTestItem'
|
||||||
description: Test results (patres) for this order
|
description: Test results (patres) for this order
|
||||||
|
|
||||||
|
OrderTestCompact:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
InternalOID:
|
||||||
|
type: integer
|
||||||
|
description: Internal order ID
|
||||||
|
OrderID:
|
||||||
|
type: string
|
||||||
|
description: Order ID (e.g., 0025030300001)
|
||||||
|
PlacerID:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
InternalPID:
|
||||||
|
type: integer
|
||||||
|
description: Patient internal ID
|
||||||
|
SiteID:
|
||||||
|
type: integer
|
||||||
|
PVADTID:
|
||||||
|
type: integer
|
||||||
|
description: Visit ADT ID
|
||||||
|
ReqApp:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
Priority:
|
||||||
|
type: string
|
||||||
|
enum: [R, S, U]
|
||||||
|
description: |
|
||||||
|
R: Routine
|
||||||
|
S: Stat
|
||||||
|
U: Urgent
|
||||||
|
PriorityLabel:
|
||||||
|
type: string
|
||||||
|
description: Priority display text
|
||||||
|
TrnDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: Transaction/Order date
|
||||||
|
EffDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: Effective date
|
||||||
|
CreateDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
OrderStatus:
|
||||||
|
type: string
|
||||||
|
enum: [ORD, SCH, ANA, VER, REV, REP]
|
||||||
|
description: |
|
||||||
|
ORD: Ordered
|
||||||
|
SCH: Scheduled
|
||||||
|
ANA: Analysis
|
||||||
|
VER: Verified
|
||||||
|
REV: Reviewed
|
||||||
|
REP: Reported
|
||||||
|
OrderStatusLabel:
|
||||||
|
type: string
|
||||||
|
description: Order status display text
|
||||||
|
Tests:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/OrderTestCompactItem'
|
||||||
|
description: Compact test list for this order
|
||||||
|
|
||||||
|
OrderTestCompactItem:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
TestSiteID:
|
||||||
|
type: integer
|
||||||
|
description: Test definition site ID
|
||||||
|
TestSiteCode:
|
||||||
|
type: string
|
||||||
|
description: Test code
|
||||||
|
TestSiteName:
|
||||||
|
type: string
|
||||||
|
description: Test name
|
||||||
|
nullable: true
|
||||||
|
|
||||||
OrderSpecimen:
|
OrderSpecimen:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@ -196,7 +196,7 @@
|
|||||||
get:
|
get:
|
||||||
tags: [Order]
|
tags: [Order]
|
||||||
summary: Get order by ID
|
summary: Get order by ID
|
||||||
description: Returns order details with associated specimens and tests
|
description: Returns compact order details with test list only
|
||||||
security:
|
security:
|
||||||
- bearerAuth: []
|
- bearerAuth: []
|
||||||
parameters:
|
parameters:
|
||||||
@ -208,7 +208,7 @@
|
|||||||
description: Order ID (e.g., 0025030300001)
|
description: Order ID (e.g., 0025030300001)
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Order details with specimens and tests
|
description: Compact order details with tests
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
@ -219,7 +219,7 @@
|
|||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
data:
|
data:
|
||||||
$ref: '../components/schemas/orders.yaml#/OrderTest'
|
$ref: '../components/schemas/orders.yaml#/OrderTestCompact'
|
||||||
|
|
||||||
patch:
|
patch:
|
||||||
tags: [Order]
|
tags: [Order]
|
||||||
|
|||||||
118
tests/feature/OrderTest/OrderTestShowCompactTest.php
Normal file
118
tests/feature/OrderTest/OrderTestShowCompactTest.php
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Feature\OrderTest;
|
||||||
|
|
||||||
|
use App\Models\OrderTest\OrderTestModel;
|
||||||
|
use App\Models\Patient\PatientModel;
|
||||||
|
use App\Models\Test\TestDefSiteModel;
|
||||||
|
use CodeIgniter\Test\CIUnitTestCase;
|
||||||
|
use CodeIgniter\Test\FeatureTestTrait;
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
|
||||||
|
class OrderTestShowCompactTest extends CIUnitTestCase
|
||||||
|
{
|
||||||
|
use FeatureTestTrait;
|
||||||
|
|
||||||
|
protected string $token;
|
||||||
|
protected string $endpoint = 'api/ordertest';
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$key = getenv('JWT_SECRET') ?: 'my-secret-key';
|
||||||
|
$payload = [
|
||||||
|
'iss' => 'localhost',
|
||||||
|
'aud' => 'localhost',
|
||||||
|
'iat' => time(),
|
||||||
|
'nbf' => time(),
|
||||||
|
'exp' => time() + 3600,
|
||||||
|
'uid' => 1,
|
||||||
|
'email' => 'admin@admin.com',
|
||||||
|
];
|
||||||
|
$this->token = JWT::encode($payload, $key, 'HS256');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function authHeaders(): array
|
||||||
|
{
|
||||||
|
return ['Cookie' => 'token=' . $this->token];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createOrderWithTest(): array
|
||||||
|
{
|
||||||
|
$patientModel = new PatientModel();
|
||||||
|
$patient = $patientModel->where('DelDate', null)->first();
|
||||||
|
$this->assertNotEmpty($patient, 'No active patient found for order show test.');
|
||||||
|
|
||||||
|
$testModel = new TestDefSiteModel();
|
||||||
|
$test = $testModel->where('EndDate', null)
|
||||||
|
->where('TestType', 'TEST')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$test) {
|
||||||
|
$test = $testModel->where('EndDate', null)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertNotEmpty($test, 'No active test definition found for order show test.');
|
||||||
|
|
||||||
|
$orderModel = new OrderTestModel();
|
||||||
|
$orderID = $orderModel->createOrder([
|
||||||
|
'InternalPID' => (int) $patient['InternalPID'],
|
||||||
|
'SiteID' => (int) ($test['SiteID'] ?? 1),
|
||||||
|
'Tests' => [
|
||||||
|
[
|
||||||
|
'TestSiteID' => (int) $test['TestSiteID'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertNotEmpty($orderID, 'Failed to create order for show test.');
|
||||||
|
|
||||||
|
return [$orderID, $test];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testShowReturnsCompactTestsOnly(): void
|
||||||
|
{
|
||||||
|
[$orderID, $test] = $this->createOrderWithTest();
|
||||||
|
|
||||||
|
$response = $this->withHeaders($this->authHeaders())
|
||||||
|
->call('get', $this->endpoint . '/' . $orderID);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$json = json_decode($response->getJSON(), true);
|
||||||
|
|
||||||
|
$this->assertSame('success', $json['status'] ?? null);
|
||||||
|
$this->assertArrayHasKey('data', $json);
|
||||||
|
$this->assertArrayHasKey('Tests', $json['data']);
|
||||||
|
$this->assertArrayNotHasKey('Specimens', $json['data']);
|
||||||
|
|
||||||
|
$tests = $json['data']['Tests'];
|
||||||
|
$this->assertNotEmpty($tests, 'Compact tests list is empty.');
|
||||||
|
|
||||||
|
$firstTest = $tests[0];
|
||||||
|
$this->assertSame((int) $test['TestSiteID'], (int) $firstTest['TestSiteID']);
|
||||||
|
$this->assertArrayHasKey('TestSiteCode', $firstTest);
|
||||||
|
$this->assertArrayHasKey('TestSiteName', $firstTest);
|
||||||
|
$this->assertArrayNotHasKey('Result', $firstTest);
|
||||||
|
$this->assertArrayNotHasKey('Discipline', $firstTest);
|
||||||
|
$this->assertArrayNotHasKey('OrderID', $firstTest);
|
||||||
|
$this->assertArrayNotHasKey('InternalSID', $firstTest);
|
||||||
|
$this->assertArrayNotHasKey('SID', $firstTest);
|
||||||
|
$this->assertArrayNotHasKey('SampleID', $firstTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testShowNotFound(): void
|
||||||
|
{
|
||||||
|
$response = $this->withHeaders($this->authHeaders())
|
||||||
|
->call('get', $this->endpoint . '/999999999');
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$json = json_decode($response->getJSON(), true);
|
||||||
|
$this->assertSame('success', $json['status'] ?? null);
|
||||||
|
$this->assertNull($json['data'] ?? null);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user