fix(testmap): align detail patch operation keys with API docs
This commit is contained in:
parent
7e38622070
commit
c743049ed1
@ -95,8 +95,8 @@ class TestMapController extends BaseController {
|
|||||||
try {
|
try {
|
||||||
$id = $this->model->insert($headerInput);
|
$id = $this->model->insert($headerInput);
|
||||||
|
|
||||||
if ($detailsPayload !== null && !empty($detailsPayload['new'])) {
|
if ($detailsPayload !== null && !empty($detailsPayload['created'])) {
|
||||||
if (!$this->insertDetailRows($id, $detailsPayload['new'])) {
|
if (!$this->insertDetailRows($id, $detailsPayload['created'])) {
|
||||||
$this->db->transRollback();
|
$this->db->transRollback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -235,35 +235,35 @@ class TestMapController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isDetailOpsPayload($detailsPayload)) {
|
if ($this->isDetailOpsPayload($detailsPayload)) {
|
||||||
$newItems = $this->normalizeDetailList($detailsPayload['new'] ?? [], 'details.new');
|
$createdItems = $this->normalizeDetailList($detailsPayload['created'] ?? [], 'details.created');
|
||||||
if ($newItems === null) { return null; }
|
if ($createdItems === null) { return null; }
|
||||||
$editItems = $this->normalizeDetailList($detailsPayload['edit'] ?? [], 'details.edit');
|
$editedItems = $this->normalizeDetailList($detailsPayload['edited'] ?? [], 'details.edited');
|
||||||
if ($editItems === null) { return null; }
|
if ($editedItems === null) { return null; }
|
||||||
$deletedIds = $this->normalizeDetailIds($detailsPayload['deleted'] ?? []);
|
$deletedIds = $this->normalizeDetailIds($detailsPayload['deleted'] ?? []);
|
||||||
if ($deletedIds === null) { return null; }
|
if ($deletedIds === null) { return null; }
|
||||||
|
|
||||||
return ['new' => $newItems, 'edit' => $editItems, 'deleted' => $deletedIds];
|
return ['created' => $createdItems, 'edited' => $editedItems, 'deleted' => $deletedIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isListPayload($detailsPayload)) {
|
if ($this->isListPayload($detailsPayload)) {
|
||||||
$items = $this->normalizeDetailList($detailsPayload, 'details');
|
$items = $this->normalizeDetailList($detailsPayload, 'details');
|
||||||
if ($items === null) { return null; }
|
if ($items === null) { return null; }
|
||||||
return ['new' => $items, 'edit' => [], 'deleted' => []];
|
return ['created' => $items, 'edited' => [], 'deleted' => []];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isAssocArray($detailsPayload)) {
|
if ($this->isAssocArray($detailsPayload)) {
|
||||||
$items = $this->normalizeDetailList([$detailsPayload], 'details');
|
$items = $this->normalizeDetailList([$detailsPayload], 'details');
|
||||||
if ($items === null) { return null; }
|
if ($items === null) { return null; }
|
||||||
return ['new' => $items, 'edit' => [], 'deleted' => []];
|
return ['created' => $items, 'edited' => [], 'deleted' => []];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->failValidationErrors('details must be an array of objects or contain new/edit/deleted arrays.');
|
$this->failValidationErrors('details must be an array of objects or contain created/edited/deleted arrays.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function applyDetailOperations(int $testMapID, array $operations): bool
|
private function applyDetailOperations(int $testMapID, array $operations): bool
|
||||||
{
|
{
|
||||||
if (!empty($operations['edit']) && !$this->updateDetails($testMapID, $operations['edit'])) {
|
if (!empty($operations['edited']) && !$this->updateDetails($testMapID, $operations['edited'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ class TestMapController extends BaseController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($operations['new']) && !$this->insertDetailRows($testMapID, $operations['new'])) {
|
if (!empty($operations['created']) && !$this->insertDetailRows($testMapID, $operations['created'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ class TestMapController extends BaseController {
|
|||||||
$prepared = [];
|
$prepared = [];
|
||||||
foreach ($items as $index => $item) {
|
foreach ($items as $index => $item) {
|
||||||
if (!$this->validateData($item, $this->detailRules)) {
|
if (!$this->validateData($item, $this->detailRules)) {
|
||||||
$this->failValidationErrors(['details.new' => $this->validator->getErrors()]);
|
$this->failValidationErrors(['details.created' => $this->validator->getErrors()]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$prepared[] = array_merge(['TestMapID' => $testMapID], $item);
|
$prepared[] = array_merge(['TestMapID' => $testMapID], $item);
|
||||||
@ -302,12 +302,12 @@ class TestMapController extends BaseController {
|
|||||||
foreach ($items as $index => $detail) {
|
foreach ($items as $index => $detail) {
|
||||||
$detailID = $detail['TestMapDetailID'] ?? null;
|
$detailID = $detail['TestMapDetailID'] ?? null;
|
||||||
if (!$detailID || !ctype_digit((string) $detailID)) {
|
if (!$detailID || !ctype_digit((string) $detailID)) {
|
||||||
$this->failValidationErrors("details.edit[{$index}].TestMapDetailID is required and must be an integer.");
|
$this->failValidationErrors("details.edited[{$index}].TestMapDetailID is required and must be an integer.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('TestMapID', $detail) && (int) $detail['TestMapID'] !== $testMapID) {
|
if (array_key_exists('TestMapID', $detail) && (int) $detail['TestMapID'] !== $testMapID) {
|
||||||
$this->failValidationErrors("details.edit[{$index}] must belong to TestMap {$testMapID}.");
|
$this->failValidationErrors("details.edited[{$index}] must belong to TestMap {$testMapID}.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ class TestMapController extends BaseController {
|
|||||||
|
|
||||||
private function isDetailOpsPayload(array $payload): bool
|
private function isDetailOpsPayload(array $payload): bool
|
||||||
{
|
{
|
||||||
return (bool) array_intersect(array_keys($payload), ['new', 'edit', 'deleted']);
|
return (bool) array_intersect(array_keys($payload), ['created', 'edited', 'deleted']);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isListPayload(array $payload): bool
|
private function isListPayload(array $payload): bool
|
||||||
|
|||||||
@ -4216,11 +4216,11 @@ paths:
|
|||||||
details:
|
details:
|
||||||
description: |
|
description: |
|
||||||
Detail payload supports either a flat array/object (treated as new rows)
|
Detail payload supports either a flat array/object (treated as new rows)
|
||||||
or an operations object with `new`, `edit`, and `deleted` arrays.
|
or an operations object with `created`, `edited`, and `deleted` arrays.
|
||||||
oneOf:
|
oneOf:
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
new:
|
created:
|
||||||
type: array
|
type: array
|
||||||
description: New detail records to insert
|
description: New detail records to insert
|
||||||
items:
|
items:
|
||||||
@ -4236,7 +4236,7 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
ClientTestName:
|
ClientTestName:
|
||||||
type: string
|
type: string
|
||||||
edit:
|
edited:
|
||||||
type: array
|
type: array
|
||||||
description: Existing detail records to update
|
description: Existing detail records to update
|
||||||
items:
|
items:
|
||||||
|
|||||||
@ -191,11 +191,11 @@
|
|||||||
details:
|
details:
|
||||||
description: |
|
description: |
|
||||||
Detail payload supports either a flat array/object (treated as new rows)
|
Detail payload supports either a flat array/object (treated as new rows)
|
||||||
or an operations object with `new`, `edit`, and `deleted` arrays.
|
or an operations object with `created`, `edited`, and `deleted` arrays.
|
||||||
oneOf:
|
oneOf:
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
new:
|
created:
|
||||||
type: array
|
type: array
|
||||||
description: New detail records to insert
|
description: New detail records to insert
|
||||||
items:
|
items:
|
||||||
@ -211,7 +211,7 @@
|
|||||||
type: string
|
type: string
|
||||||
ClientTestName:
|
ClientTestName:
|
||||||
type: string
|
type: string
|
||||||
edit:
|
edited:
|
||||||
type: array
|
type: array
|
||||||
description: Existing detail records to update
|
description: Existing detail records to update
|
||||||
items:
|
items:
|
||||||
|
|||||||
@ -188,13 +188,13 @@ class TestMapPatchTest extends CIUnitTestCase
|
|||||||
->call('patch', "{$this->endpoint}/{$testMap['TestMapID']}", [
|
->call('patch', "{$this->endpoint}/{$testMap['TestMapID']}", [
|
||||||
'ClientType' => 'WST',
|
'ClientType' => 'WST',
|
||||||
'details' => [
|
'details' => [
|
||||||
'edit' => [
|
'edited' => [
|
||||||
[
|
[
|
||||||
'TestMapDetailID' => $editDetail['TestMapDetailID'],
|
'TestMapDetailID' => $editDetail['TestMapDetailID'],
|
||||||
'ClientTestName' => 'Hemoglobin Updated',
|
'ClientTestName' => 'Hemoglobin Updated',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'new' => [
|
'created' => [
|
||||||
[
|
[
|
||||||
'HostTestCode' => 'MCV',
|
'HostTestCode' => 'MCV',
|
||||||
'HostTestName' => 'MCV',
|
'HostTestName' => 'MCV',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user