diff --git a/app/Controllers/Test/TestsController.php b/app/Controllers/Test/TestsController.php index 129c531..ed7ea92 100644 --- a/app/Controllers/Test/TestsController.php +++ b/app/Controllers/Test/TestsController.php @@ -90,11 +90,11 @@ class TestsController extends BaseController $typeCode = $row['TestType'] ?? ''; - if ($typeCode === 'CALC') { - $row['testdefcal'] = $this->modelCal->getByTestSiteID($id); - $row['testdefgrp'] = $this->modelGrp->getGroupMembers($id); - } elseif ($typeCode === 'GROUP') { - $row['testdefgrp'] = $this->modelGrp->getGroupMembers($id); + if ($typeCode === 'CALC') { + $row['testdefcal'] = $this->modelCal->getByTestSiteID($id); + $row['members'] = $this->modelGrp->getGroupMembers($id); + } elseif ($typeCode === 'GROUP') { + $row['members'] = $this->modelGrp->getGroupMembers($id); } elseif ($typeCode !== 'TITLE') { $refType = $row['RefType'] ?? ''; $resultType = $row['ResultType'] ?? ''; @@ -491,7 +491,7 @@ class TestsController extends BaseController $this->modelGrp->disableByTestSiteID($testSiteID); } - $memberIDs = $this->resolveCalcMemberIDs($data, $input); + $memberIDs = $this->resolveMemberIDs($input); // Validate member IDs before insertion $validation = $this->validateMemberIDs($memberIDs); @@ -507,18 +507,17 @@ class TestsController extends BaseController } } - private function resolveCalcMemberIDs(array $data, array $input): array - { - $memberIDs = []; - - $rawMembers = $data['members'] ?? ($input['members'] ?? []); - if (is_array($rawMembers)) { - foreach ($rawMembers as $member) { - if (is_array($member)) { - // Only accept TestSiteID, not Member (which might be SeqScr) - $rawID = $member['TestSiteID'] ?? null; - } else { - $rawID = is_numeric($member) ? $member : null; + private function resolveMemberIDs(array $input): array + { + $memberIDs = []; + + $rawMembers = $input['members'] ?? []; + if (is_array($rawMembers)) { + foreach ($rawMembers as $member) { + if (is_array($member)) { + $rawID = $member['TestSiteID'] ?? null; + } else { + $rawID = is_numeric($member) ? $member : null; } if ($rawID !== null && is_numeric($rawID)) { @@ -557,26 +556,13 @@ class TestsController extends BaseController ]; } - private function saveGroupDetails($testSiteID, $data, $input, $action) - { - if ($action === 'update') { - $this->modelGrp->disableByTestSiteID($testSiteID); - } - - $members = $data['members'] ?? ($input['Members'] ?? []); - $memberIDs = []; - - if (is_array($members)) { - foreach ($members as $m) { - // Only accept TestSiteID, not Member (which might be SeqScr) - $memberID = is_array($m) ? ($m['TestSiteID'] ?? null) : $m; - if ($memberID && is_numeric($memberID)) { - $memberIDs[] = (int) $memberID; - } - } - } - - $memberIDs = array_values(array_unique(array_filter($memberIDs))); + private function saveGroupDetails($testSiteID, $data, $input, $action) + { + if ($action === 'update') { + $this->modelGrp->disableByTestSiteID($testSiteID); + } + + $memberIDs = $this->resolveMemberIDs($input); // Validate member IDs before insertion $validation = $this->validateMemberIDs($memberIDs); diff --git a/public/api-docs.bundled.yaml b/public/api-docs.bundled.yaml index 7b35a7c..0fb47fd 100644 --- a/public/api-docs.bundled.yaml +++ b/public/api-docs.bundled.yaml @@ -4671,21 +4671,17 @@ paths: FormulaCode: type: string description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") - testdefgrp: - type: object - description: Group member payload stored in the `testdefgrp` table. - properties: - members: - type: array - description: Array of member TestSiteIDs for CALC/GROUP definitions. - items: - type: object - properties: - TestSiteID: - type: integer - description: Foreign key referencing the member test's TestSiteID. - required: - - TestSiteID + members: + type: array + description: Array of member TestSiteIDs for CALC/GROUP definitions. + items: + type: object + properties: + TestSiteID: + type: integer + description: Foreign key referencing the member test's TestSiteID. + required: + - TestSiteID refnum: type: array items: @@ -5100,10 +5096,9 @@ paths: DepartmentID: 2 testdefcal: FormulaCode: CKD_EPI(CREA,AGE,GENDER) - testdefgrp: - members: - - TestSiteID: 21 - - TestSiteID: 22 + members: + - TestSiteID: 21 + - TestSiteID: 22 CALC_full: summary: Calculated test with numeric reference ranges and map value: @@ -5142,10 +5137,9 @@ paths: DepartmentID: 2 testdefcal: FormulaCode: CKD_EPI(CREA,AGE,GENDER) - testdefgrp: - members: - - TestSiteID: 21 - - TestSiteID: 22 + members: + - TestSiteID: 21 + - TestSiteID: 22 GROUP_with_members: summary: Group/profile test with members and mapping value: @@ -5169,10 +5163,9 @@ paths: ConDefID: 1 ClientTestCode: LIPID_C ClientTestName: Lipid Client - testdefgrp: - members: - - TestSiteID: 169 - - TestSiteID: 170 + members: + - TestSiteID: 169 + - TestSiteID: 170 responses: '201': description: Test definition created @@ -5334,21 +5327,17 @@ paths: FormulaCode: type: string description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") - testdefgrp: - type: object - description: Group member payload stored in the `testdefgrp` table. - properties: - members: - type: array - description: Array of member TestSiteIDs for CALC/GROUP definitions. - items: - type: object - properties: - TestSiteID: - type: integer - description: Foreign key referencing the member test's TestSiteID. - required: - - TestSiteID + members: + type: array + description: Array of member TestSiteIDs for CALC/GROUP definitions. + items: + type: object + properties: + TestSiteID: + type: integer + description: Foreign key referencing the member test's TestSiteID. + required: + - TestSiteID refnum: type: array items: @@ -7061,12 +7050,12 @@ components: description: Calculated test details (only for CALC type) items: type: object - testdefgrp: + members: type: array description: | Group members (for GROUP and CALC types). - When creating or updating, provide members in details.members array with TestSiteID field. - Do NOT use Member or SeqScr fields when creating/updating. + When creating or updating, provide members in members array with TestSiteID field. + Do NOT use Member, SeqScr, or Members fields when creating/updating. items: type: object properties: @@ -7080,7 +7069,7 @@ components: type: integer description: | Member TestSiteID (foreign key to testdefsite). - **Note**: This field is in the response. When creating/updating, use TestSiteID in details.members array instead. + **Note**: This field is in the response. When creating/updating, use TestSiteID in members array instead. TestSiteCode: type: string description: Member test code @@ -7349,7 +7338,7 @@ components: FormulaCode: CKD_EPI(CREA,AGE,GENDER) Unit1: mL/min/1.73m2 Decimal: 0 - testdefgrp: + members: - TestSiteID: 21 TestSiteCode: CREA TestSiteName: Creatinine @@ -7391,7 +7380,7 @@ components: isVisibleScr: 1 isVisibleRpt: 1 isCountStat: 1 - testdefgrp: + members: - TestGrpID: 1 TestSiteID: 6 Member: 100 diff --git a/public/components/schemas/tests.yaml b/public/components/schemas/tests.yaml index b65fa95..edfdd2c 100644 --- a/public/components/schemas/tests.yaml +++ b/public/components/schemas/tests.yaml @@ -183,26 +183,26 @@ TestDefinition: description: Calculated test details (only for CALC type) items: type: object - testdefgrp: - type: array - description: | - Group members (for GROUP and CALC types). - When creating or updating, provide members in details.members array with TestSiteID field. - Do NOT use Member or SeqScr fields when creating/updating. + members: + type: array + description: | + Group members (for GROUP and CALC types). + When creating or updating, provide members in members array with TestSiteID field. + Do NOT use Member, SeqScr, or Members fields when creating/updating. items: type: object properties: TestGrpID: type: integer description: Group membership record ID - TestSiteID: - type: integer - description: Parent group TestSiteID - Member: - type: integer - description: | - Member TestSiteID (foreign key to testdefsite). - **Note**: This field is in the response. When creating/updating, use TestSiteID in details.members array instead. + TestSiteID: + type: integer + description: Parent group TestSiteID + Member: + type: integer + description: | + Member TestSiteID (foreign key to testdefsite). + **Note**: This field is in the response. When creating/updating, use TestSiteID in members array instead. TestSiteCode: type: string description: Member test code @@ -467,11 +467,11 @@ TestDefinition: FormulaCode: CKD_EPI(CREA,AGE,GENDER) Unit1: mL/min/1.73m2 Decimal: 0 - testdefgrp: - - TestSiteID: 21 - TestSiteCode: CREA - TestSiteName: Creatinine - TestType: TEST + members: + - TestSiteID: 21 + TestSiteCode: CREA + TestSiteName: Creatinine + TestType: TEST - TestSiteID: 51 TestSiteCode: AGE TestSiteName: Age @@ -509,10 +509,10 @@ TestDefinition: isVisibleScr: 1 isVisibleRpt: 1 isCountStat: 1 - testdefgrp: - - TestGrpID: 1 - TestSiteID: 6 - Member: 100 + members: + - TestGrpID: 1 + TestSiteID: 6 + Member: 100 MemberTestSiteID: 100 TestSiteCode: CHOL TestSiteName: Total Cholesterol diff --git a/public/paths/tests.yaml b/public/paths/tests.yaml index d2ba247..dec3f6a 100644 --- a/public/paths/tests.yaml +++ b/public/paths/tests.yaml @@ -185,21 +185,17 @@ FormulaCode: type: string description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") - testdefgrp: - type: object - description: Group member payload stored in the `testdefgrp` table. - properties: - members: - type: array - description: Array of member TestSiteIDs for CALC/GROUP definitions. - items: - type: object - properties: - TestSiteID: - type: integer - description: Foreign key referencing the member test's TestSiteID. - required: - - TestSiteID + members: + type: array + description: Array of member TestSiteIDs for CALC/GROUP definitions. + items: + type: object + properties: + TestSiteID: + type: integer + description: Foreign key referencing the member test's TestSiteID. + required: + - TestSiteID refnum: type: array items: @@ -612,12 +608,11 @@ isCountStat: 0 DisciplineID: 2 DepartmentID: 2 - testdefcal: - FormulaCode: CKD_EPI(CREA,AGE,GENDER) - testdefgrp: - members: - - TestSiteID: 21 - - TestSiteID: 22 + testdefcal: + FormulaCode: CKD_EPI(CREA,AGE,GENDER) + members: + - TestSiteID: 21 + - TestSiteID: 22 CALC_full: summary: Calculated test with numeric reference ranges and map value: @@ -654,12 +649,11 @@ ClientTestName: eGFR Client DisciplineID: 2 DepartmentID: 2 - testdefcal: - FormulaCode: CKD_EPI(CREA,AGE,GENDER) - testdefgrp: - members: - - TestSiteID: 21 - - TestSiteID: 22 + testdefcal: + FormulaCode: CKD_EPI(CREA,AGE,GENDER) + members: + - TestSiteID: 21 + - TestSiteID: 22 GROUP_with_members: summary: Group/profile test with members and mapping value: @@ -683,10 +677,9 @@ ConDefID: 1 ClientTestCode: LIPID_C ClientTestName: Lipid Client - testdefgrp: - members: - - TestSiteID: 169 - - TestSiteID: 170 + members: + - TestSiteID: 169 + - TestSiteID: 170 responses: '201': @@ -834,21 +827,17 @@ FormulaCode: type: string description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") - testdefgrp: - type: object - description: Group member payload stored in the `testdefgrp` table. - properties: - members: - type: array - description: Array of member TestSiteIDs for CALC/GROUP definitions. - items: - type: object - properties: - TestSiteID: - type: integer - description: Foreign key referencing the member test's TestSiteID. - required: - - TestSiteID + members: + type: array + description: Array of member TestSiteIDs for CALC/GROUP definitions. + items: + type: object + properties: + TestSiteID: + type: integer + description: Foreign key referencing the member test's TestSiteID. + required: + - TestSiteID refnum: type: array items: diff --git a/tests/feature/Test/TestCreateVariantsTest.php b/tests/feature/Test/TestCreateVariantsTest.php index ea1c691..9e4086c 100644 --- a/tests/feature/Test/TestCreateVariantsTest.php +++ b/tests/feature/Test/TestCreateVariantsTest.php @@ -359,6 +359,17 @@ class TestCreateVariantsTest extends CIUnitTestCase $this->assertArrayHasKey('data', $json); $this->assertArrayHasKey('TestSiteId', $json['data']); $this->assertIsInt($json['data']['TestSiteId']); + + $show = $this->call('get', $this->endpoint . '/' . $json['data']['TestSiteId']); + $show->assertStatus(200); + + $showData = json_decode($show->getJSON(), true)['data']; + $this->assertArrayHasKey('members', $showData); + $this->assertArrayNotHasKey('testdefgrp', $showData); + + if ($members !== []) { + $this->assertCount(count($members), $showData['members']); + } } private function assertTechnicalCreated( @@ -390,6 +401,7 @@ class TestCreateVariantsTest extends CIUnitTestCase $this->assertArrayHasKey('data', $json); $this->assertArrayHasKey('TestSiteId', $json['data']); $this->assertIsInt($json['data']['TestSiteId']); + } private function assertCalculatedCreated( @@ -418,6 +430,14 @@ class TestCreateVariantsTest extends CIUnitTestCase $this->assertArrayHasKey('data', $json); $this->assertArrayHasKey('TestSiteId', $json['data']); $this->assertIsInt($json['data']['TestSiteId']); + + $show = $this->call('get', $this->endpoint . '/' . $json['data']['TestSiteId']); + $show->assertStatus(200); + + $showData = json_decode($show->getJSON(), true)['data']; + $this->assertArrayHasKey('members', $showData); + $this->assertArrayNotHasKey('testdefgrp', $showData); + $this->assertCount(count($members), $showData['members']); } private function buildTechnicalPayload(string $testType, array $details = []): array @@ -451,11 +471,11 @@ class TestCreateVariantsTest extends CIUnitTestCase 'isVisibleScr' => 1, 'isVisibleRpt' => 1, 'isCountStat' => 0, + 'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members), 'details' => [ 'DisciplineID' => 2, 'DepartmentID' => 2, 'FormulaCode' => '{GLU} + {CREA}', - 'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members), ], ]; @@ -474,9 +494,7 @@ class TestCreateVariantsTest extends CIUnitTestCase 'isVisibleScr' => 1, 'isVisibleRpt' => 1, 'isCountStat' => 1, - 'details' => [ - 'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members), - ], + 'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members), 'testmap' => $testmap, ]; } @@ -491,7 +509,7 @@ class TestCreateVariantsTest extends CIUnitTestCase 'Decimal' => array_key_exists('Decimal', $details) ? $details['Decimal'] : 0, ]; - foreach (['ResultType', 'RefType', 'FormulaCode', 'members', 'ExpectedTAT', 'Factor', 'ReqQty', 'ReqQtyUnit', 'Unit2', 'VSet', 'CollReq'] as $key) { + foreach (['ResultType', 'RefType', 'FormulaCode', 'ExpectedTAT', 'Factor', 'ReqQty', 'ReqQtyUnit', 'Unit2', 'VSet', 'CollReq'] as $key) { if (array_key_exists($key, $details)) { $normalized[$key] = $details[$key]; }