fix: align test members payload with top-level API contract

This commit is contained in:
mahdahar 2026-04-02 04:52:50 +07:00
parent 399f4d615b
commit eeaed768c9
5 changed files with 142 additions and 160 deletions

View File

@ -92,9 +92,9 @@ class TestsController extends BaseController
if ($typeCode === 'CALC') { if ($typeCode === 'CALC') {
$row['testdefcal'] = $this->modelCal->getByTestSiteID($id); $row['testdefcal'] = $this->modelCal->getByTestSiteID($id);
$row['testdefgrp'] = $this->modelGrp->getGroupMembers($id); $row['members'] = $this->modelGrp->getGroupMembers($id);
} elseif ($typeCode === 'GROUP') { } elseif ($typeCode === 'GROUP') {
$row['testdefgrp'] = $this->modelGrp->getGroupMembers($id); $row['members'] = $this->modelGrp->getGroupMembers($id);
} elseif ($typeCode !== 'TITLE') { } elseif ($typeCode !== 'TITLE') {
$refType = $row['RefType'] ?? ''; $refType = $row['RefType'] ?? '';
$resultType = $row['ResultType'] ?? ''; $resultType = $row['ResultType'] ?? '';
@ -491,7 +491,7 @@ class TestsController extends BaseController
$this->modelGrp->disableByTestSiteID($testSiteID); $this->modelGrp->disableByTestSiteID($testSiteID);
} }
$memberIDs = $this->resolveCalcMemberIDs($data, $input); $memberIDs = $this->resolveMemberIDs($input);
// Validate member IDs before insertion // Validate member IDs before insertion
$validation = $this->validateMemberIDs($memberIDs); $validation = $this->validateMemberIDs($memberIDs);
@ -507,15 +507,14 @@ class TestsController extends BaseController
} }
} }
private function resolveCalcMemberIDs(array $data, array $input): array private function resolveMemberIDs(array $input): array
{ {
$memberIDs = []; $memberIDs = [];
$rawMembers = $data['members'] ?? ($input['members'] ?? []); $rawMembers = $input['members'] ?? [];
if (is_array($rawMembers)) { if (is_array($rawMembers)) {
foreach ($rawMembers as $member) { foreach ($rawMembers as $member) {
if (is_array($member)) { if (is_array($member)) {
// Only accept TestSiteID, not Member (which might be SeqScr)
$rawID = $member['TestSiteID'] ?? null; $rawID = $member['TestSiteID'] ?? null;
} else { } else {
$rawID = is_numeric($member) ? $member : null; $rawID = is_numeric($member) ? $member : null;
@ -563,20 +562,7 @@ class TestsController extends BaseController
$this->modelGrp->disableByTestSiteID($testSiteID); $this->modelGrp->disableByTestSiteID($testSiteID);
} }
$members = $data['members'] ?? ($input['Members'] ?? []); $memberIDs = $this->resolveMemberIDs($input);
$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)));
// Validate member IDs before insertion // Validate member IDs before insertion
$validation = $this->validateMemberIDs($memberIDs); $validation = $this->validateMemberIDs($memberIDs);

View File

@ -4671,10 +4671,6 @@ paths:
FormulaCode: FormulaCode:
type: string type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
testdefgrp:
type: object
description: Group member payload stored in the `testdefgrp` table.
properties:
members: members:
type: array type: array
description: Array of member TestSiteIDs for CALC/GROUP definitions. description: Array of member TestSiteIDs for CALC/GROUP definitions.
@ -5100,7 +5096,6 @@ paths:
DepartmentID: 2 DepartmentID: 2
testdefcal: testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER) FormulaCode: CKD_EPI(CREA,AGE,GENDER)
testdefgrp:
members: members:
- TestSiteID: 21 - TestSiteID: 21
- TestSiteID: 22 - TestSiteID: 22
@ -5142,7 +5137,6 @@ paths:
DepartmentID: 2 DepartmentID: 2
testdefcal: testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER) FormulaCode: CKD_EPI(CREA,AGE,GENDER)
testdefgrp:
members: members:
- TestSiteID: 21 - TestSiteID: 21
- TestSiteID: 22 - TestSiteID: 22
@ -5169,7 +5163,6 @@ paths:
ConDefID: 1 ConDefID: 1
ClientTestCode: LIPID_C ClientTestCode: LIPID_C
ClientTestName: Lipid Client ClientTestName: Lipid Client
testdefgrp:
members: members:
- TestSiteID: 169 - TestSiteID: 169
- TestSiteID: 170 - TestSiteID: 170
@ -5334,10 +5327,6 @@ paths:
FormulaCode: FormulaCode:
type: string type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
testdefgrp:
type: object
description: Group member payload stored in the `testdefgrp` table.
properties:
members: members:
type: array type: array
description: Array of member TestSiteIDs for CALC/GROUP definitions. description: Array of member TestSiteIDs for CALC/GROUP definitions.
@ -7061,12 +7050,12 @@ components:
description: Calculated test details (only for CALC type) description: Calculated test details (only for CALC type)
items: items:
type: object type: object
testdefgrp: members:
type: array type: array
description: | description: |
Group members (for GROUP and CALC types). Group members (for GROUP and CALC types).
When creating or updating, provide members in details.members array with TestSiteID field. When creating or updating, provide members in members array with TestSiteID field.
Do NOT use Member or SeqScr fields when creating/updating. Do NOT use Member, SeqScr, or Members fields when creating/updating.
items: items:
type: object type: object
properties: properties:
@ -7080,7 +7069,7 @@ components:
type: integer type: integer
description: | description: |
Member TestSiteID (foreign key to testdefsite). 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: TestSiteCode:
type: string type: string
description: Member test code description: Member test code
@ -7349,7 +7338,7 @@ components:
FormulaCode: CKD_EPI(CREA,AGE,GENDER) FormulaCode: CKD_EPI(CREA,AGE,GENDER)
Unit1: mL/min/1.73m2 Unit1: mL/min/1.73m2
Decimal: 0 Decimal: 0
testdefgrp: members:
- TestSiteID: 21 - TestSiteID: 21
TestSiteCode: CREA TestSiteCode: CREA
TestSiteName: Creatinine TestSiteName: Creatinine
@ -7391,7 +7380,7 @@ components:
isVisibleScr: 1 isVisibleScr: 1
isVisibleRpt: 1 isVisibleRpt: 1
isCountStat: 1 isCountStat: 1
testdefgrp: members:
- TestGrpID: 1 - TestGrpID: 1
TestSiteID: 6 TestSiteID: 6
Member: 100 Member: 100

View File

@ -183,12 +183,12 @@ TestDefinition:
description: Calculated test details (only for CALC type) description: Calculated test details (only for CALC type)
items: items:
type: object type: object
testdefgrp: members:
type: array type: array
description: | description: |
Group members (for GROUP and CALC types). Group members (for GROUP and CALC types).
When creating or updating, provide members in details.members array with TestSiteID field. When creating or updating, provide members in members array with TestSiteID field.
Do NOT use Member or SeqScr fields when creating/updating. Do NOT use Member, SeqScr, or Members fields when creating/updating.
items: items:
type: object type: object
properties: properties:
@ -202,7 +202,7 @@ TestDefinition:
type: integer type: integer
description: | description: |
Member TestSiteID (foreign key to testdefsite). 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: TestSiteCode:
type: string type: string
description: Member test code description: Member test code
@ -467,7 +467,7 @@ TestDefinition:
FormulaCode: CKD_EPI(CREA,AGE,GENDER) FormulaCode: CKD_EPI(CREA,AGE,GENDER)
Unit1: mL/min/1.73m2 Unit1: mL/min/1.73m2
Decimal: 0 Decimal: 0
testdefgrp: members:
- TestSiteID: 21 - TestSiteID: 21
TestSiteCode: CREA TestSiteCode: CREA
TestSiteName: Creatinine TestSiteName: Creatinine
@ -509,7 +509,7 @@ TestDefinition:
isVisibleScr: 1 isVisibleScr: 1
isVisibleRpt: 1 isVisibleRpt: 1
isCountStat: 1 isCountStat: 1
testdefgrp: members:
- TestGrpID: 1 - TestGrpID: 1
TestSiteID: 6 TestSiteID: 6
Member: 100 Member: 100

View File

@ -185,10 +185,6 @@
FormulaCode: FormulaCode:
type: string type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
testdefgrp:
type: object
description: Group member payload stored in the `testdefgrp` table.
properties:
members: members:
type: array type: array
description: Array of member TestSiteIDs for CALC/GROUP definitions. description: Array of member TestSiteIDs for CALC/GROUP definitions.
@ -614,7 +610,6 @@
DepartmentID: 2 DepartmentID: 2
testdefcal: testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER) FormulaCode: CKD_EPI(CREA,AGE,GENDER)
testdefgrp:
members: members:
- TestSiteID: 21 - TestSiteID: 21
- TestSiteID: 22 - TestSiteID: 22
@ -656,7 +651,6 @@
DepartmentID: 2 DepartmentID: 2
testdefcal: testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER) FormulaCode: CKD_EPI(CREA,AGE,GENDER)
testdefgrp:
members: members:
- TestSiteID: 21 - TestSiteID: 21
- TestSiteID: 22 - TestSiteID: 22
@ -683,7 +677,6 @@
ConDefID: 1 ConDefID: 1
ClientTestCode: LIPID_C ClientTestCode: LIPID_C
ClientTestName: Lipid Client ClientTestName: Lipid Client
testdefgrp:
members: members:
- TestSiteID: 169 - TestSiteID: 169
- TestSiteID: 170 - TestSiteID: 170
@ -834,10 +827,6 @@
FormulaCode: FormulaCode:
type: string type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}") description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
testdefgrp:
type: object
description: Group member payload stored in the `testdefgrp` table.
properties:
members: members:
type: array type: array
description: Array of member TestSiteIDs for CALC/GROUP definitions. description: Array of member TestSiteIDs for CALC/GROUP definitions.

View File

@ -359,6 +359,17 @@ class TestCreateVariantsTest extends CIUnitTestCase
$this->assertArrayHasKey('data', $json); $this->assertArrayHasKey('data', $json);
$this->assertArrayHasKey('TestSiteId', $json['data']); $this->assertArrayHasKey('TestSiteId', $json['data']);
$this->assertIsInt($json['data']['TestSiteId']); $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( private function assertTechnicalCreated(
@ -390,6 +401,7 @@ class TestCreateVariantsTest extends CIUnitTestCase
$this->assertArrayHasKey('data', $json); $this->assertArrayHasKey('data', $json);
$this->assertArrayHasKey('TestSiteId', $json['data']); $this->assertArrayHasKey('TestSiteId', $json['data']);
$this->assertIsInt($json['data']['TestSiteId']); $this->assertIsInt($json['data']['TestSiteId']);
} }
private function assertCalculatedCreated( private function assertCalculatedCreated(
@ -418,6 +430,14 @@ class TestCreateVariantsTest extends CIUnitTestCase
$this->assertArrayHasKey('data', $json); $this->assertArrayHasKey('data', $json);
$this->assertArrayHasKey('TestSiteId', $json['data']); $this->assertArrayHasKey('TestSiteId', $json['data']);
$this->assertIsInt($json['data']['TestSiteId']); $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 private function buildTechnicalPayload(string $testType, array $details = []): array
@ -451,11 +471,11 @@ class TestCreateVariantsTest extends CIUnitTestCase
'isVisibleScr' => 1, 'isVisibleScr' => 1,
'isVisibleRpt' => 1, 'isVisibleRpt' => 1,
'isCountStat' => 0, 'isCountStat' => 0,
'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members),
'details' => [ 'details' => [
'DisciplineID' => 2, 'DisciplineID' => 2,
'DepartmentID' => 2, 'DepartmentID' => 2,
'FormulaCode' => '{GLU} + {CREA}', 'FormulaCode' => '{GLU} + {CREA}',
'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members),
], ],
]; ];
@ -474,9 +494,7 @@ class TestCreateVariantsTest extends CIUnitTestCase
'isVisibleScr' => 1, 'isVisibleScr' => 1,
'isVisibleRpt' => 1, 'isVisibleRpt' => 1,
'isCountStat' => 1, 'isCountStat' => 1,
'details' => [
'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members), 'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members),
],
'testmap' => $testmap, 'testmap' => $testmap,
]; ];
} }
@ -491,7 +509,7 @@ class TestCreateVariantsTest extends CIUnitTestCase
'Decimal' => array_key_exists('Decimal', $details) ? $details['Decimal'] : 0, '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)) { if (array_key_exists($key, $details)) {
$normalized[$key] = $details[$key]; $normalized[$key] = $details[$key];
} }