fix: support partial PATCH updates across controllers and PatVisit
Allow update endpoints to validate only provided fields, avoid overwriting unchanged data, and preserve existing PatDiag when omitted from PatVisit PATCH payloads.
This commit is contained in:
parent
e99a60fe93
commit
c5c958b58e
@ -12,11 +12,13 @@ class ContactController extends BaseController {
|
|||||||
protected $db;
|
protected $db;
|
||||||
protected $model;
|
protected $model;
|
||||||
protected $rules;
|
protected $rules;
|
||||||
|
protected $patchRules;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->db = \Config\Database::connect();
|
$this->db = \Config\Database::connect();
|
||||||
$this->model = new ContactModel();
|
$this->model = new ContactModel();
|
||||||
$this->rules = [ 'NameFirst' => 'required' ];
|
$this->rules = [ 'NameFirst' => 'required' ];
|
||||||
|
$this->patchRules = [ 'NameFirst' => 'permit_empty' ];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
@ -84,8 +86,16 @@ class ContactController extends BaseController {
|
|||||||
'data' => []
|
'data' => []
|
||||||
], 400);
|
], 400);
|
||||||
}
|
}
|
||||||
|
if (empty($input) || !is_array($input)) {
|
||||||
|
return $this->failValidationErrors('No data provided for update.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$validationInput = array_intersect_key($input, $this->patchRules);
|
||||||
|
if (!empty($validationInput) && !$this->validateData($validationInput, $this->patchRules)) {
|
||||||
|
return $this->failValidationErrors($this->validator->getErrors());
|
||||||
|
}
|
||||||
|
|
||||||
$input['ContactID'] = (int) $ContactID;
|
$input['ContactID'] = (int) $ContactID;
|
||||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
|
|
||||||
try {
|
try {
|
||||||
$this->model->saveContact($input);
|
$this->model->saveContact($input);
|
||||||
$id = $input['ContactID'];
|
$id = $input['ContactID'];
|
||||||
|
|||||||
@ -10,6 +10,7 @@ class LocationController extends BaseController {
|
|||||||
|
|
||||||
protected $model;
|
protected $model;
|
||||||
protected $rules;
|
protected $rules;
|
||||||
|
protected $patchRules;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->model = new LocationModel();
|
$this->model = new LocationModel();
|
||||||
@ -17,6 +18,10 @@ class LocationController extends BaseController {
|
|||||||
'LocCode' => 'required|max_length[6]',
|
'LocCode' => 'required|max_length[6]',
|
||||||
'LocFull' => 'required',
|
'LocFull' => 'required',
|
||||||
];
|
];
|
||||||
|
$this->patchRules = [
|
||||||
|
'LocCode' => 'permit_empty|max_length[6]',
|
||||||
|
'LocFull' => 'permit_empty',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
@ -59,9 +64,17 @@ class LocationController extends BaseController {
|
|||||||
'data' => []
|
'data' => []
|
||||||
], 400);
|
], 400);
|
||||||
}
|
}
|
||||||
|
if (empty($input) || !is_array($input)) {
|
||||||
|
return $this->failValidationErrors('No data provided for update.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$validationInput = array_intersect_key($input, $this->patchRules);
|
||||||
|
if (!empty($validationInput) && !$this->validateData($validationInput, $this->patchRules)) {
|
||||||
|
return $this->failValidationErrors($this->validator->getErrors());
|
||||||
|
}
|
||||||
|
|
||||||
$input['LocationID'] = (int) $LocationID;
|
$input['LocationID'] = (int) $LocationID;
|
||||||
try {
|
try {
|
||||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors( $this->validator->getErrors()); }
|
|
||||||
$result = $this->model->saveLocation($input, true);
|
$result = $this->model->saveLocation($input, true);
|
||||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'data updated successfully', 'data' => $result ], 201);
|
return $this->respondCreated([ 'status' => 'success', 'message' => 'data updated successfully', 'data' => $result ], 201);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ class ContainerDefController extends BaseController {
|
|||||||
protected $db;
|
protected $db;
|
||||||
protected $model;
|
protected $model;
|
||||||
protected $rules;
|
protected $rules;
|
||||||
|
protected $patchRules;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->db = \Config\Database::connect();
|
$this->db = \Config\Database::connect();
|
||||||
@ -21,6 +22,10 @@ class ContainerDefController extends BaseController {
|
|||||||
'ConCode' => 'required|max_length[50]',
|
'ConCode' => 'required|max_length[50]',
|
||||||
'ConName' => 'required|max_length[50]'
|
'ConName' => 'required|max_length[50]'
|
||||||
];
|
];
|
||||||
|
$this->patchRules = [
|
||||||
|
'ConCode' => 'permit_empty|max_length[50]',
|
||||||
|
'ConName' => 'permit_empty|max_length[50]'
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
@ -78,8 +83,17 @@ class ContainerDefController extends BaseController {
|
|||||||
if (!$ConDefID || !ctype_digit((string) $ConDefID)) {
|
if (!$ConDefID || !ctype_digit((string) $ConDefID)) {
|
||||||
return $this->failValidationErrors('ConDefID is required.');
|
return $this->failValidationErrors('ConDefID is required.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($input) || !is_array($input)) {
|
||||||
|
return $this->failValidationErrors('No data provided for update.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$validationInput = array_intersect_key($input, $this->patchRules);
|
||||||
|
if (!empty($validationInput) && !$this->validateData($validationInput, $this->patchRules)) {
|
||||||
|
return $this->failValidationErrors($this->validator->getErrors());
|
||||||
|
}
|
||||||
|
|
||||||
$input['ConDefID'] = (int) $ConDefID;
|
$input['ConDefID'] = (int) $ConDefID;
|
||||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
|
|
||||||
try {
|
try {
|
||||||
$ConDefID = $this->model->update($input['ConDefID'], $input);
|
$ConDefID = $this->model->update($input['ConDefID'], $input);
|
||||||
return $this->respondCreated([ 'status' => 'success', 'message' => "data $ConDefID updated successfully" ]);
|
return $this->respondCreated([ 'status' => 'success', 'message' => "data $ConDefID updated successfully" ]);
|
||||||
|
|||||||
@ -12,6 +12,7 @@ class TestMapController extends BaseController {
|
|||||||
|
|
||||||
protected $db;
|
protected $db;
|
||||||
protected $rules;
|
protected $rules;
|
||||||
|
protected $patchRules;
|
||||||
protected $model;
|
protected $model;
|
||||||
protected $modelDetail;
|
protected $modelDetail;
|
||||||
|
|
||||||
@ -23,6 +24,10 @@ class TestMapController extends BaseController {
|
|||||||
'HostID' => 'required|integer',
|
'HostID' => 'required|integer',
|
||||||
'ClientID' => 'required|integer',
|
'ClientID' => 'required|integer',
|
||||||
];
|
];
|
||||||
|
$this->patchRules = [
|
||||||
|
'HostID' => 'permit_empty|integer',
|
||||||
|
'ClientID' => 'permit_empty|integer',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
@ -70,12 +75,20 @@ class TestMapController extends BaseController {
|
|||||||
public function update($TestMapID = null) {
|
public function update($TestMapID = null) {
|
||||||
$input = $this->request->getJSON(true);
|
$input = $this->request->getJSON(true);
|
||||||
if (!$TestMapID || !ctype_digit((string) $TestMapID)) { return $this->failValidationErrors('TestMapID is required.'); }
|
if (!$TestMapID || !ctype_digit((string) $TestMapID)) { return $this->failValidationErrors('TestMapID is required.'); }
|
||||||
|
if (empty($input) || !is_array($input)) {
|
||||||
|
return $this->failValidationErrors('No data provided for update.');
|
||||||
|
}
|
||||||
$id = (int) $TestMapID;
|
$id = (int) $TestMapID;
|
||||||
if (isset($input['TestMapID']) && (string) $input['TestMapID'] !== (string) $id) {
|
if (isset($input['TestMapID']) && (string) $input['TestMapID'] !== (string) $id) {
|
||||||
return $this->failValidationErrors('TestMapID in URL does not match body.');
|
return $this->failValidationErrors('TestMapID in URL does not match body.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$validationInput = array_intersect_key($input, $this->patchRules);
|
||||||
|
if (!empty($validationInput) && !$this->validateData($validationInput, $this->patchRules)) {
|
||||||
|
return $this->failValidationErrors($this->validator->getErrors());
|
||||||
|
}
|
||||||
|
|
||||||
$input['TestMapID'] = $id;
|
$input['TestMapID'] = $id;
|
||||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors( $this->validator->getErrors() ); }
|
|
||||||
try {
|
try {
|
||||||
$this->model->update($id,$input);
|
$this->model->update($id,$input);
|
||||||
return $this->respondCreated([ 'status' => 'success', 'message' => "data updated successfully", 'data' => $id ]);
|
return $this->respondCreated([ 'status' => 'success', 'message' => "data updated successfully", 'data' => $id ]);
|
||||||
|
|||||||
@ -11,6 +11,7 @@ class TestMapDetailController extends BaseController {
|
|||||||
|
|
||||||
protected $db;
|
protected $db;
|
||||||
protected $rules;
|
protected $rules;
|
||||||
|
protected $patchRules;
|
||||||
protected $model;
|
protected $model;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
@ -24,6 +25,14 @@ class TestMapDetailController extends BaseController {
|
|||||||
'ClientTestCode' => 'permit_empty|max_length[10]',
|
'ClientTestCode' => 'permit_empty|max_length[10]',
|
||||||
'ClientTestName' => 'permit_empty|max_length[100]',
|
'ClientTestName' => 'permit_empty|max_length[100]',
|
||||||
];
|
];
|
||||||
|
$this->patchRules = [
|
||||||
|
'TestMapID' => 'permit_empty|integer',
|
||||||
|
'HostTestCode' => 'permit_empty|max_length[10]',
|
||||||
|
'HostTestName' => 'permit_empty|max_length[100]',
|
||||||
|
'ConDefID' => 'permit_empty|integer',
|
||||||
|
'ClientTestCode' => 'permit_empty|max_length[10]',
|
||||||
|
'ClientTestName' => 'permit_empty|max_length[100]',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
@ -94,13 +103,17 @@ class TestMapDetailController extends BaseController {
|
|||||||
if (!$TestMapDetailID || !ctype_digit((string) $TestMapDetailID)) {
|
if (!$TestMapDetailID || !ctype_digit((string) $TestMapDetailID)) {
|
||||||
return $this->failValidationErrors('TestMapDetailID is required.');
|
return $this->failValidationErrors('TestMapDetailID is required.');
|
||||||
}
|
}
|
||||||
|
if (empty($input) || !is_array($input)) {
|
||||||
|
return $this->failValidationErrors('No data provided for update.');
|
||||||
|
}
|
||||||
$id = (int) $TestMapDetailID;
|
$id = (int) $TestMapDetailID;
|
||||||
if (isset($input['TestMapDetailID']) && (string) $input['TestMapDetailID'] !== (string) $id) {
|
if (isset($input['TestMapDetailID']) && (string) $input['TestMapDetailID'] !== (string) $id) {
|
||||||
return $this->failValidationErrors('TestMapDetailID in URL does not match body.');
|
return $this->failValidationErrors('TestMapDetailID in URL does not match body.');
|
||||||
}
|
}
|
||||||
$input['TestMapDetailID'] = $id;
|
$input['TestMapDetailID'] = $id;
|
||||||
|
|
||||||
if (!$this->validateData($input, $this->rules)) {
|
$validationInput = array_intersect_key($input, $this->patchRules);
|
||||||
|
if (!empty($validationInput) && !$this->validateData($validationInput, $this->patchRules)) {
|
||||||
return $this->failValidationErrors($this->validator->getErrors());
|
return $this->failValidationErrors($this->validator->getErrors());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,13 +210,21 @@ class TestMapDetailController extends BaseController {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->validateData($item, $this->rules)) {
|
$updateData = $item;
|
||||||
|
unset($updateData['TestMapDetailID']);
|
||||||
|
|
||||||
|
if ($updateData === []) {
|
||||||
|
$results['failed'][] = ['index' => $index, 'error' => 'No fields to update'];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->validateData($updateData, $this->patchRules)) {
|
||||||
$results['failed'][] = ['index' => $index, 'errors' => $this->validator->getErrors()];
|
$results['failed'][] = ['index' => $index, 'errors' => $this->validator->getErrors()];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->model->update($id, $item);
|
$this->model->update($id, $updateData);
|
||||||
$results['success'][] = ['index' => $index, 'TestMapDetailID' => $id];
|
$results['success'][] = ['index' => $index, 'TestMapDetailID' => $id];
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$results['failed'][] = ['index' => $index, 'error' => $e->getMessage()];
|
$results['failed'][] = ['index' => $index, 'error' => $e->getMessage()];
|
||||||
|
|||||||
@ -263,7 +263,7 @@ class TestsController extends BaseController
|
|||||||
];
|
];
|
||||||
|
|
||||||
foreach ($allowedUpdateFields as $field) {
|
foreach ($allowedUpdateFields as $field) {
|
||||||
if (isset($input[$field])) {
|
if (array_key_exists($field, $input)) {
|
||||||
$testSiteData[$field] = $input[$field];
|
$testSiteData[$field] = $input[$field];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -421,25 +421,34 @@ class TestsController extends BaseController
|
|||||||
|
|
||||||
private function saveTechDetails($testSiteID, $data, $action, $typeCode)
|
private function saveTechDetails($testSiteID, $data, $action, $typeCode)
|
||||||
{
|
{
|
||||||
$techData = [
|
$allowedFields = [
|
||||||
'DisciplineID' => $data['DisciplineID'] ?? null,
|
'DisciplineID',
|
||||||
'DepartmentID' => $data['DepartmentID'] ?? null,
|
'DepartmentID',
|
||||||
'ResultType' => $data['ResultType'] ?? null,
|
'ResultType',
|
||||||
'RefType' => $data['RefType'] ?? null,
|
'RefType',
|
||||||
'VSet' => $data['VSet'] ?? null,
|
'VSet',
|
||||||
'ReqQty' => $data['ReqQty'] ?? null,
|
'ReqQty',
|
||||||
'ReqQtyUnit' => $data['ReqQtyUnit'] ?? null,
|
'ReqQtyUnit',
|
||||||
'Unit1' => $data['Unit1'] ?? null,
|
'Unit1',
|
||||||
'Factor' => $data['Factor'] ?? null,
|
'Factor',
|
||||||
'Unit2' => $data['Unit2'] ?? null,
|
'Unit2',
|
||||||
'Decimal' => array_key_exists('Decimal', $data) ? $data['Decimal'] : null,
|
'Decimal',
|
||||||
'CollReq' => $data['CollReq'] ?? null,
|
'CollReq',
|
||||||
'Method' => $data['Method'] ?? null,
|
'Method',
|
||||||
'ExpectedTAT' => $data['ExpectedTAT'] ?? null,
|
'ExpectedTAT',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$techData = [];
|
||||||
|
foreach ($allowedFields as $field) {
|
||||||
|
if (array_key_exists($field, $data)) {
|
||||||
|
$techData[$field] = $data[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($techData !== []) {
|
||||||
$this->model->update($testSiteID, $techData);
|
$this->model->update($testSiteID, $techData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function saveRefNumRanges($testSiteID, $ranges, $action, $siteID)
|
private function saveRefNumRanges($testSiteID, $ranges, $action, $siteID)
|
||||||
{
|
{
|
||||||
@ -461,31 +470,71 @@ class TestsController extends BaseController
|
|||||||
|
|
||||||
private function saveCalcDetails($testSiteID, $data, $input, $action)
|
private function saveCalcDetails($testSiteID, $data, $input, $action)
|
||||||
{
|
{
|
||||||
$calcData = [
|
$calcData = [];
|
||||||
'TestSiteID' => $testSiteID,
|
$fieldMap = [
|
||||||
'DisciplineID' => $data['DisciplineID'] ?? null,
|
'DisciplineID' => 'DisciplineID',
|
||||||
'DepartmentID' => $data['DepartmentID'] ?? null,
|
'DepartmentID' => 'DepartmentID',
|
||||||
'FormulaCode' => $data['FormulaCode'] ?? $data['Formula'] ?? null,
|
'Factor' => 'Factor',
|
||||||
'ResultType' => 'NMRIC',
|
'Unit2' => 'Unit2',
|
||||||
'RefType' => $data['RefType'] ?? 'RANGE',
|
'Decimal' => 'Decimal',
|
||||||
'Unit1' => $data['Unit1'] ?? $data['ResultUnit'] ?? null,
|
'Method' => 'Method',
|
||||||
'Factor' => $data['Factor'] ?? null,
|
|
||||||
'Unit2' => $data['Unit2'] ?? null,
|
|
||||||
'Decimal' => array_key_exists('Decimal', $data) ? $data['Decimal'] : null,
|
|
||||||
'Method' => $data['Method'] ?? null,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
foreach ($fieldMap as $source => $target) {
|
||||||
|
if (array_key_exists($source, $data)) {
|
||||||
|
$calcData[$target] = $data[$source];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('FormulaCode', $data) || array_key_exists('Formula', $data)) {
|
||||||
|
$calcData['FormulaCode'] = $data['FormulaCode'] ?? $data['Formula'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('RefType', $data)) {
|
||||||
|
$calcData['RefType'] = $data['RefType'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('Unit1', $data) || array_key_exists('ResultUnit', $data)) {
|
||||||
|
$calcData['Unit1'] = $data['Unit1'] ?? $data['ResultUnit'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasMemberPayload = isset($input['testdefgrp'])
|
||||||
|
&& is_array($input['testdefgrp'])
|
||||||
|
&& array_key_exists('members', $input['testdefgrp']);
|
||||||
|
|
||||||
|
if ($action === 'insert' && !array_key_exists('ResultType', $calcData)) {
|
||||||
|
$calcData['ResultType'] = 'NMRIC';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'insert' && !array_key_exists('RefType', $calcData)) {
|
||||||
|
$calcData['RefType'] = 'RANGE';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($calcData !== []) {
|
||||||
|
$calcData['TestSiteID'] = $testSiteID;
|
||||||
if ($action === 'update') {
|
if ($action === 'update') {
|
||||||
$exists = $this->modelCal->existsByTestSiteID($testSiteID);
|
$exists = $this->modelCal->existsByTestSiteID($testSiteID);
|
||||||
|
|
||||||
if ($exists) {
|
if ($exists) {
|
||||||
|
unset($calcData['TestSiteID']);
|
||||||
$this->modelCal->update($exists['TestCalID'], $calcData);
|
$this->modelCal->update($exists['TestCalID'], $calcData);
|
||||||
} else {
|
} else {
|
||||||
|
if (!array_key_exists('ResultType', $calcData)) {
|
||||||
|
$calcData['ResultType'] = 'NMRIC';
|
||||||
|
}
|
||||||
|
if (!array_key_exists('RefType', $calcData)) {
|
||||||
|
$calcData['RefType'] = 'RANGE';
|
||||||
|
}
|
||||||
$this->modelCal->insert($calcData);
|
$this->modelCal->insert($calcData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->modelCal->insert($calcData);
|
$this->modelCal->insert($calcData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'update' && !$hasMemberPayload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ($action === 'update') {
|
if ($action === 'update') {
|
||||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||||
@ -493,7 +542,6 @@ class TestsController extends BaseController
|
|||||||
|
|
||||||
$memberIDs = $this->resolveMemberIDs($input);
|
$memberIDs = $this->resolveMemberIDs($input);
|
||||||
|
|
||||||
// Validate member IDs before insertion
|
|
||||||
$validation = $this->validateMemberIDs($memberIDs);
|
$validation = $this->validateMemberIDs($memberIDs);
|
||||||
if (!$validation['valid']) {
|
if (!$validation['valid']) {
|
||||||
throw new \Exception('Invalid member TestSiteID(s): ' . implode(', ', $validation['invalid']) . '. Make sure to use TestSiteID, not SeqScr or other values.');
|
throw new \Exception('Invalid member TestSiteID(s): ' . implode(', ', $validation['invalid']) . '. Make sure to use TestSiteID, not SeqScr or other values.');
|
||||||
@ -558,6 +606,14 @@ class TestsController extends BaseController
|
|||||||
|
|
||||||
private function saveGroupDetails($testSiteID, $data, $input, $action)
|
private function saveGroupDetails($testSiteID, $data, $input, $action)
|
||||||
{
|
{
|
||||||
|
$hasMemberPayload = isset($input['testdefgrp'])
|
||||||
|
&& is_array($input['testdefgrp'])
|
||||||
|
&& array_key_exists('members', $input['testdefgrp']);
|
||||||
|
|
||||||
|
if ($action === 'update' && !$hasMemberPayload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ($action === 'update') {
|
if ($action === 'update') {
|
||||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,20 +107,27 @@ class PatVisitModel extends BaseModel {
|
|||||||
throw new \Exception("Visit not found or has been deleted.");
|
throw new \Exception("Visit not found or has been deleted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->where('InternalPVID',$InternalPVID)->set($input)->update();
|
$visitData = array_intersect_key($input, array_flip($this->allowedFields));
|
||||||
|
if (!empty($visitData)) {
|
||||||
|
$this->where('InternalPVID', $InternalPVID)->set($visitData)->update();
|
||||||
|
}
|
||||||
|
|
||||||
// patdiag
|
// patdiag
|
||||||
$exist = $modelPD->where('InternalPVID',$InternalPVID)->find();
|
if (array_key_exists('PatDiag', $input)) {
|
||||||
if($exist) {
|
$exist = $modelPD->where('InternalPVID', $InternalPVID)->find();
|
||||||
if( !empty($input['PatDiag']) && ( !empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']) ) ) {
|
if ($exist) {
|
||||||
$tmp = $modelPD->where('InternalPVID',$InternalPVID)->set($input['PatDiag'])->update();
|
if (!empty($input['PatDiag']) && (!empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']))) {
|
||||||
} else { $tmp = $modelPD->delete($InternalPVID); }
|
$tmp = $modelPD->where('InternalPVID', $InternalPVID)->set($input['PatDiag'])->update();
|
||||||
} else {
|
} else {
|
||||||
if( !empty($input['PatDiag']) && ( !empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']) ) ) {
|
$tmp = $modelPD->delete($InternalPVID);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!empty($input['PatDiag']) && (!empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']))) {
|
||||||
$input['PatDiag']['InternalPVID'] = $InternalPVID;
|
$input['PatDiag']['InternalPVID'] = $InternalPVID;
|
||||||
$tmp = $modelPD->insert($input['PatDiag']);
|
$tmp = $modelPD->insert($input['PatDiag']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (isset($tmp) && $tmp === false) {
|
if (isset($tmp) && $tmp === false) {
|
||||||
$error = $db->error();
|
$error = $db->error();
|
||||||
throw new \Exception("Failed to update PatDiag record. ". $error['message']);
|
throw new \Exception("Failed to update PatDiag record. ". $error['message']);
|
||||||
@ -141,7 +148,7 @@ class PatVisitModel extends BaseModel {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
$db->transCommit();
|
$db->transCommit();
|
||||||
$data = [ "PVID" => $input['PVID'], "InternalPVID" => $InternalPVID ];
|
$data = [ "PVID" => $input['PVID'] ?? $visit['PVID'], "InternalPVID" => $InternalPVID ];
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -153,4 +153,38 @@ class PatVisitUpdateTest extends CIUnitTestCase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPatchWithoutPatDiagKeepsExistingPatDiag(): void
|
||||||
|
{
|
||||||
|
$createPayload = [
|
||||||
|
'InternalPID' => $this->createTestPatient(),
|
||||||
|
'EpisodeID' => 'KEEP-DIAG',
|
||||||
|
'PatDiag' => [
|
||||||
|
'DiagCode' => 'A02',
|
||||||
|
'DiagName' => 'Original Diagnosis',
|
||||||
|
],
|
||||||
|
'PatVisitADT' => [
|
||||||
|
'ADTCode' => 'A01',
|
||||||
|
'LocationID' => '1',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$createResponse = $this->withBodyFormat('json')->call('post', 'api/patvisit', $createPayload);
|
||||||
|
$createResponse->assertStatus(201);
|
||||||
|
|
||||||
|
$createJson = json_decode($createResponse->getJSON(), true);
|
||||||
|
$internalPVID = $createJson['data']['InternalPVID'];
|
||||||
|
$pvid = $createJson['data']['PVID'];
|
||||||
|
|
||||||
|
$patchResponse = $this->withBodyFormat('json')->call('patch', $this->endpoint . '/' . $internalPVID, [
|
||||||
|
'EpisodeID' => 'KEEP-DIAG-UPDATED',
|
||||||
|
]);
|
||||||
|
$patchResponse->assertStatus(200);
|
||||||
|
|
||||||
|
$showResponse = $this->call('get', $this->endpoint . '/' . $pvid);
|
||||||
|
$showResponse->assertStatus(200);
|
||||||
|
|
||||||
|
$showJson = json_decode($showResponse->getJSON(), true);
|
||||||
|
$this->assertEquals('A02', $showJson['data']['DiagCode'] ?? null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user