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
@ -6,18 +6,20 @@ use App\Controllers\BaseController;
|
||||
use App\Libraries\ValueSet;
|
||||
use App\Models\Contact\ContactModel;
|
||||
|
||||
class ContactController extends BaseController {
|
||||
class ContactController extends BaseController {
|
||||
use ResponseTrait;
|
||||
|
||||
protected $db;
|
||||
protected $model;
|
||||
protected $rules;
|
||||
protected $db;
|
||||
protected $model;
|
||||
protected $rules;
|
||||
protected $patchRules;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = \Config\Database::connect();
|
||||
$this->model = new ContactModel();
|
||||
$this->rules = [ 'NameFirst' => 'required' ];
|
||||
}
|
||||
public function __construct() {
|
||||
$this->db = \Config\Database::connect();
|
||||
$this->model = new ContactModel();
|
||||
$this->rules = [ 'NameFirst' => 'required' ];
|
||||
$this->patchRules = [ 'NameFirst' => 'permit_empty' ];
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$ContactName = $this->request->getVar('ContactName');
|
||||
@ -84,8 +86,16 @@ class ContactController extends BaseController {
|
||||
'data' => []
|
||||
], 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;
|
||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
|
||||
try {
|
||||
$this->model->saveContact($input);
|
||||
$id = $input['ContactID'];
|
||||
|
||||
@ -5,19 +5,24 @@ use App\Traits\ResponseTrait;
|
||||
use App\Controllers\BaseController;
|
||||
use App\Models\Location\LocationModel;
|
||||
|
||||
class LocationController extends BaseController {
|
||||
use ResponseTrait;
|
||||
class LocationController extends BaseController {
|
||||
use ResponseTrait;
|
||||
|
||||
protected $model;
|
||||
protected $rules;
|
||||
protected $patchRules;
|
||||
|
||||
protected $model;
|
||||
protected $rules;
|
||||
|
||||
public function __construct() {
|
||||
$this->model = new LocationModel();
|
||||
$this->rules = [
|
||||
'LocCode' => 'required|max_length[6]',
|
||||
'LocFull' => 'required',
|
||||
];
|
||||
}
|
||||
public function __construct() {
|
||||
$this->model = new LocationModel();
|
||||
$this->rules = [
|
||||
'LocCode' => 'required|max_length[6]',
|
||||
'LocFull' => 'required',
|
||||
];
|
||||
$this->patchRules = [
|
||||
'LocCode' => 'permit_empty|max_length[6]',
|
||||
'LocFull' => 'permit_empty',
|
||||
];
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$LocName = $this->request->getVar('LocName');
|
||||
@ -59,12 +64,20 @@ class LocationController extends BaseController {
|
||||
'data' => []
|
||||
], 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;
|
||||
try {
|
||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors( $this->validator->getErrors()); }
|
||||
$result = $this->model->saveLocation($input, true);
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'data updated successfully', 'data' => $result ], 201);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'data updated successfully', 'data' => $result ], 201);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,21 +7,26 @@ use App\Controllers\BaseController;
|
||||
use App\Libraries\ValueSet;
|
||||
use App\Models\Specimen\ContainerDefModel;
|
||||
|
||||
class ContainerDefController extends BaseController {
|
||||
class ContainerDefController extends BaseController {
|
||||
use ResponseTrait;
|
||||
|
||||
protected $db;
|
||||
protected $model;
|
||||
protected $rules;
|
||||
protected $db;
|
||||
protected $model;
|
||||
protected $rules;
|
||||
protected $patchRules;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = \Config\Database::connect();
|
||||
$this->model = new ContainerDefModel();
|
||||
$this->rules = [
|
||||
'ConCode' => 'required|max_length[50]',
|
||||
'ConName' => 'required|max_length[50]'
|
||||
];
|
||||
}
|
||||
$this->model = new ContainerDefModel();
|
||||
$this->rules = [
|
||||
'ConCode' => '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() {
|
||||
try {
|
||||
@ -78,11 +83,20 @@ class ContainerDefController extends BaseController {
|
||||
if (!$ConDefID || !ctype_digit((string) $ConDefID)) {
|
||||
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;
|
||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
|
||||
try {
|
||||
$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" ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
@ -10,10 +10,11 @@ use App\Models\Test\TestMapDetailModel;
|
||||
class TestMapController extends BaseController {
|
||||
use ResponseTrait;
|
||||
|
||||
protected $db;
|
||||
protected $rules;
|
||||
protected $model;
|
||||
protected $modelDetail;
|
||||
protected $db;
|
||||
protected $rules;
|
||||
protected $patchRules;
|
||||
protected $model;
|
||||
protected $modelDetail;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = \Config\Database::connect();
|
||||
@ -23,7 +24,11 @@ class TestMapController extends BaseController {
|
||||
'HostID' => 'required|integer',
|
||||
'ClientID' => 'required|integer',
|
||||
];
|
||||
}
|
||||
$this->patchRules = [
|
||||
'HostID' => 'permit_empty|integer',
|
||||
'ClientID' => 'permit_empty|integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$rows = $this->model->getUniqueGroupings();
|
||||
@ -70,15 +75,23 @@ class TestMapController extends BaseController {
|
||||
public function update($TestMapID = null) {
|
||||
$input = $this->request->getJSON(true);
|
||||
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;
|
||||
if (isset($input['TestMapID']) && (string) $input['TestMapID'] !== (string) $id) {
|
||||
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;
|
||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors( $this->validator->getErrors() ); }
|
||||
try {
|
||||
$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 ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
@ -9,22 +9,31 @@ use App\Models\Test\TestMapDetailModel;
|
||||
class TestMapDetailController extends BaseController {
|
||||
use ResponseTrait;
|
||||
|
||||
protected $db;
|
||||
protected $rules;
|
||||
protected $model;
|
||||
protected $db;
|
||||
protected $rules;
|
||||
protected $patchRules;
|
||||
protected $model;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = \Config\Database::connect();
|
||||
$this->model = new TestMapDetailModel;
|
||||
$this->rules = [
|
||||
'TestMapID' => 'required|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]',
|
||||
];
|
||||
}
|
||||
$this->rules = [
|
||||
'TestMapID' => 'required|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]',
|
||||
];
|
||||
$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() {
|
||||
$testMapID = $this->request->getGet('TestMapID');
|
||||
@ -94,15 +103,19 @@ class TestMapDetailController extends BaseController {
|
||||
if (!$TestMapDetailID || !ctype_digit((string) $TestMapDetailID)) {
|
||||
return $this->failValidationErrors('TestMapDetailID is required.');
|
||||
}
|
||||
if (empty($input) || !is_array($input)) {
|
||||
return $this->failValidationErrors('No data provided for update.');
|
||||
}
|
||||
$id = (int) $TestMapDetailID;
|
||||
if (isset($input['TestMapDetailID']) && (string) $input['TestMapDetailID'] !== (string) $id) {
|
||||
return $this->failValidationErrors('TestMapDetailID in URL does not match body.');
|
||||
}
|
||||
$input['TestMapDetailID'] = $id;
|
||||
|
||||
if (!$this->validateData($input, $this->rules)) {
|
||||
return $this->failValidationErrors($this->validator->getErrors());
|
||||
}
|
||||
|
||||
$validationInput = array_intersect_key($input, $this->patchRules);
|
||||
if (!empty($validationInput) && !$this->validateData($validationInput, $this->patchRules)) {
|
||||
return $this->failValidationErrors($this->validator->getErrors());
|
||||
}
|
||||
|
||||
try {
|
||||
$this->model->update($id, $input);
|
||||
@ -179,7 +192,7 @@ class TestMapDetailController extends BaseController {
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function batchUpdate() {
|
||||
public function batchUpdate() {
|
||||
$items = $this->request->getJSON(true);
|
||||
|
||||
if (!is_array($items)) {
|
||||
@ -189,24 +202,32 @@ class TestMapDetailController extends BaseController {
|
||||
$results = ['success' => [], 'failed' => []];
|
||||
$this->db->transStart();
|
||||
|
||||
foreach ($items as $index => $item) {
|
||||
$id = $item['TestMapDetailID'] ?? null;
|
||||
foreach ($items as $index => $item) {
|
||||
$id = $item['TestMapDetailID'] ?? null;
|
||||
|
||||
if (!$id) {
|
||||
$results['failed'][] = ['index' => $index, 'error' => 'TestMapDetailID required'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->validateData($item, $this->rules)) {
|
||||
$results['failed'][] = ['index' => $index, 'errors' => $this->validator->getErrors()];
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->model->update($id, $item);
|
||||
$results['success'][] = ['index' => $index, 'TestMapDetailID' => $id];
|
||||
} catch (\Exception $e) {
|
||||
$results['failed'][] = ['index' => $index, 'error' => $e->getMessage()];
|
||||
if (!$id) {
|
||||
$results['failed'][] = ['index' => $index, 'error' => 'TestMapDetailID required'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$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()];
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->model->update($id, $updateData);
|
||||
$results['success'][] = ['index' => $index, 'TestMapDetailID' => $id];
|
||||
} catch (\Exception $e) {
|
||||
$results['failed'][] = ['index' => $index, 'error' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -262,11 +262,11 @@ class TestsController extends BaseController
|
||||
'StartDate',
|
||||
];
|
||||
|
||||
foreach ($allowedUpdateFields as $field) {
|
||||
if (isset($input[$field])) {
|
||||
$testSiteData[$field] = $input[$field];
|
||||
}
|
||||
}
|
||||
foreach ($allowedUpdateFields as $field) {
|
||||
if (array_key_exists($field, $input)) {
|
||||
$testSiteData[$field] = $input[$field];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($testSiteData)) {
|
||||
$this->model->update($id, $testSiteData);
|
||||
@ -421,24 +421,33 @@ class TestsController extends BaseController
|
||||
|
||||
private function saveTechDetails($testSiteID, $data, $action, $typeCode)
|
||||
{
|
||||
$techData = [
|
||||
'DisciplineID' => $data['DisciplineID'] ?? null,
|
||||
'DepartmentID' => $data['DepartmentID'] ?? null,
|
||||
'ResultType' => $data['ResultType'] ?? null,
|
||||
'RefType' => $data['RefType'] ?? null,
|
||||
'VSet' => $data['VSet'] ?? null,
|
||||
'ReqQty' => $data['ReqQty'] ?? null,
|
||||
'ReqQtyUnit' => $data['ReqQtyUnit'] ?? null,
|
||||
'Unit1' => $data['Unit1'] ?? null,
|
||||
'Factor' => $data['Factor'] ?? null,
|
||||
'Unit2' => $data['Unit2'] ?? null,
|
||||
'Decimal' => array_key_exists('Decimal', $data) ? $data['Decimal'] : null,
|
||||
'CollReq' => $data['CollReq'] ?? null,
|
||||
'Method' => $data['Method'] ?? null,
|
||||
'ExpectedTAT' => $data['ExpectedTAT'] ?? null,
|
||||
$allowedFields = [
|
||||
'DisciplineID',
|
||||
'DepartmentID',
|
||||
'ResultType',
|
||||
'RefType',
|
||||
'VSet',
|
||||
'ReqQty',
|
||||
'ReqQtyUnit',
|
||||
'Unit1',
|
||||
'Factor',
|
||||
'Unit2',
|
||||
'Decimal',
|
||||
'CollReq',
|
||||
'Method',
|
||||
'ExpectedTAT',
|
||||
];
|
||||
|
||||
$this->model->update($testSiteID, $techData);
|
||||
$techData = [];
|
||||
foreach ($allowedFields as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$techData[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
|
||||
if ($techData !== []) {
|
||||
$this->model->update($testSiteID, $techData);
|
||||
}
|
||||
}
|
||||
|
||||
private function saveRefNumRanges($testSiteID, $ranges, $action, $siteID)
|
||||
@ -461,50 +470,89 @@ class TestsController extends BaseController
|
||||
|
||||
private function saveCalcDetails($testSiteID, $data, $input, $action)
|
||||
{
|
||||
$calcData = [
|
||||
'TestSiteID' => $testSiteID,
|
||||
'DisciplineID' => $data['DisciplineID'] ?? null,
|
||||
'DepartmentID' => $data['DepartmentID'] ?? null,
|
||||
'FormulaCode' => $data['FormulaCode'] ?? $data['Formula'] ?? null,
|
||||
'ResultType' => 'NMRIC',
|
||||
'RefType' => $data['RefType'] ?? 'RANGE',
|
||||
'Unit1' => $data['Unit1'] ?? $data['ResultUnit'] ?? null,
|
||||
'Factor' => $data['Factor'] ?? null,
|
||||
'Unit2' => $data['Unit2'] ?? null,
|
||||
'Decimal' => array_key_exists('Decimal', $data) ? $data['Decimal'] : null,
|
||||
'Method' => $data['Method'] ?? null,
|
||||
$calcData = [];
|
||||
$fieldMap = [
|
||||
'DisciplineID' => 'DisciplineID',
|
||||
'DepartmentID' => 'DepartmentID',
|
||||
'Factor' => 'Factor',
|
||||
'Unit2' => 'Unit2',
|
||||
'Decimal' => 'Decimal',
|
||||
'Method' => 'Method',
|
||||
];
|
||||
|
||||
if ($action === 'update') {
|
||||
$exists = $this->modelCal->existsByTestSiteID($testSiteID);
|
||||
|
||||
if ($exists) {
|
||||
$this->modelCal->update($exists['TestCalID'], $calcData);
|
||||
} else {
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
} else {
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
|
||||
if ($action === 'update') {
|
||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
|
||||
|
||||
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') {
|
||||
$exists = $this->modelCal->existsByTestSiteID($testSiteID);
|
||||
|
||||
if ($exists) {
|
||||
unset($calcData['TestSiteID']);
|
||||
$this->modelCal->update($exists['TestCalID'], $calcData);
|
||||
} else {
|
||||
if (!array_key_exists('ResultType', $calcData)) {
|
||||
$calcData['ResultType'] = 'NMRIC';
|
||||
}
|
||||
if (!array_key_exists('RefType', $calcData)) {
|
||||
$calcData['RefType'] = 'RANGE';
|
||||
}
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
} else {
|
||||
$this->modelCal->insert($calcData);
|
||||
}
|
||||
}
|
||||
|
||||
if ($action === 'update' && !$hasMemberPayload) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action === 'update') {
|
||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
|
||||
$memberIDs = $this->resolveMemberIDs($input);
|
||||
|
||||
// Validate member IDs before insertion
|
||||
$validation = $this->validateMemberIDs($memberIDs);
|
||||
if (!$validation['valid']) {
|
||||
throw new \Exception('Invalid member TestSiteID(s): ' . implode(', ', $validation['invalid']) . '. Make sure to use TestSiteID, not SeqScr or other values.');
|
||||
}
|
||||
|
||||
foreach ($memberIDs as $memberID) {
|
||||
$this->modelGrp->insert([
|
||||
'TestSiteID' => $testSiteID,
|
||||
'Member' => $memberID,
|
||||
]);
|
||||
}
|
||||
|
||||
$validation = $this->validateMemberIDs($memberIDs);
|
||||
if (!$validation['valid']) {
|
||||
throw new \Exception('Invalid member TestSiteID(s): ' . implode(', ', $validation['invalid']) . '. Make sure to use TestSiteID, not SeqScr or other values.');
|
||||
}
|
||||
|
||||
foreach ($memberIDs as $memberID) {
|
||||
$this->modelGrp->insert([
|
||||
'TestSiteID' => $testSiteID,
|
||||
'Member' => $memberID,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function resolveMemberIDs(array $input): array
|
||||
@ -558,6 +606,14 @@ class TestsController extends BaseController
|
||||
|
||||
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') {
|
||||
$this->modelGrp->disableByTestSiteID($testSiteID);
|
||||
}
|
||||
|
||||
@ -107,20 +107,27 @@ class PatVisitModel extends BaseModel {
|
||||
throw new \Exception("Visit not found or has been deleted.");
|
||||
}
|
||||
|
||||
$this->where('InternalPVID',$InternalPVID)->set($input)->update();
|
||||
|
||||
// patdiag
|
||||
$exist = $modelPD->where('InternalPVID',$InternalPVID)->find();
|
||||
if($exist) {
|
||||
if( !empty($input['PatDiag']) && ( !empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']) ) ) {
|
||||
$tmp = $modelPD->where('InternalPVID',$InternalPVID)->set($input['PatDiag'])->update();
|
||||
} else { $tmp = $modelPD->delete($InternalPVID); }
|
||||
} else {
|
||||
if( !empty($input['PatDiag']) && ( !empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']) ) ) {
|
||||
$input['PatDiag']['InternalPVID'] = $InternalPVID;
|
||||
$tmp = $modelPD->insert($input['PatDiag']);
|
||||
}
|
||||
}
|
||||
$visitData = array_intersect_key($input, array_flip($this->allowedFields));
|
||||
if (!empty($visitData)) {
|
||||
$this->where('InternalPVID', $InternalPVID)->set($visitData)->update();
|
||||
}
|
||||
|
||||
// patdiag
|
||||
if (array_key_exists('PatDiag', $input)) {
|
||||
$exist = $modelPD->where('InternalPVID', $InternalPVID)->find();
|
||||
if ($exist) {
|
||||
if (!empty($input['PatDiag']) && (!empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']))) {
|
||||
$tmp = $modelPD->where('InternalPVID', $InternalPVID)->set($input['PatDiag'])->update();
|
||||
} else {
|
||||
$tmp = $modelPD->delete($InternalPVID);
|
||||
}
|
||||
} else {
|
||||
if (!empty($input['PatDiag']) && (!empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']))) {
|
||||
$input['PatDiag']['InternalPVID'] = $InternalPVID;
|
||||
$tmp = $modelPD->insert($input['PatDiag']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($tmp) && $tmp === false) {
|
||||
$error = $db->error();
|
||||
throw new \Exception("Failed to update PatDiag record. ". $error['message']);
|
||||
@ -141,9 +148,9 @@ class PatVisitModel extends BaseModel {
|
||||
return false;
|
||||
} else {
|
||||
$db->transCommit();
|
||||
$data = [ "PVID" => $input['PVID'], "InternalPVID" => $InternalPVID ];
|
||||
return $data;
|
||||
}
|
||||
$data = [ "PVID" => $input['PVID'] ?? $visit['PVID'], "InternalPVID" => $InternalPVID ];
|
||||
return $data;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->db->transRollback();
|
||||
|
||||
@ -152,5 +152,39 @@ class PatVisitUpdateTest extends CIUnitTestCase
|
||||
'message' => 'Invalid or missing ID'
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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