Allow update endpoints to validate only provided fields, avoid overwriting unchanged data, and preserve existing PatDiag when omitted from PatVisit PATCH payloads.
161 lines
5.6 KiB
PHP
161 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Models\PatVisit;
|
|
use App\Models\BaseModel;
|
|
use App\Models\CounterModel;
|
|
use App\Models\PatVisit\PatDiagModel;
|
|
use App\Models\PatVisit\PatVisitADTModel;
|
|
|
|
class PatVisitModel extends BaseModel {
|
|
protected $table = 'patvisit';
|
|
protected $primaryKey = 'InternalPVID';
|
|
protected $allowedFields = ['PVID', 'InternalPID', 'EpisodeID', 'LastVisitADT', 'CreateDate', 'EndDate', 'ArchivedDate', 'DelDate'];
|
|
|
|
protected $useTimestamps = true;
|
|
protected $createdField = 'CreateDate';
|
|
protected $updatedField = '';
|
|
protected $useSoftDeletes = true;
|
|
protected $deletedField = 'EndDate';
|
|
|
|
protected $visnum_prefix = "DV";
|
|
|
|
public function show($PVID) {
|
|
$row = $this->select("*, patvisit.InternalPID, patvisit.CreateDate as PVCreateDate, patdiag.CreateDate as PDCreateDate, patvisitadt.CreateDate as PVACreateDate")
|
|
->join('patdiag', 'patdiag.InternalPVID=patvisit.InternalPVID and patdiag.DelDate is null', 'left')
|
|
->join('patvisitadt', 'patvisitadt.InternalPVID=patvisit.InternalPVID', 'left')
|
|
->where('patvisit.PVID',$PVID)
|
|
->where('patvisit.EndDate IS NULL') // Exclude soft deleted
|
|
->first();
|
|
return $row;
|
|
}
|
|
|
|
public function showByPatient($InternalPID) {
|
|
$rows = $this->select("*, patvisit.InternalPID, patvisit.CreateDate as PVCreateDate, patdiag.CreateDate as PDCreateDate, patvisitadt.CreateDate as PVACreateDate")
|
|
->join('patdiag', 'patdiag.InternalPVID=patvisit.InternalPVID and patdiag.DelDate is null', 'left')
|
|
->join('(SELECT a1.*
|
|
FROM patvisitadt a1
|
|
INNER JOIN (
|
|
SELECT InternalPVID, MAX(PVADTID) AS MaxID
|
|
FROM patvisitadt
|
|
GROUP BY InternalPVID
|
|
) a2 ON a1.InternalPVID = a2.InternalPVID AND a1.PVADTID = a2.MaxID
|
|
) AS patvisitadt',
|
|
'patvisitadt.InternalPVID = patvisit.InternalPVID',
|
|
'left')
|
|
->join('location', 'location.LocationID=patvisitadt.LocationID', 'left')
|
|
->where('patvisit.InternalPID',$InternalPID)
|
|
->where('patvisit.EndDate IS NULL') // Exclude soft deleted
|
|
->findAll();
|
|
return $rows;
|
|
}
|
|
|
|
public function createPatVisit($input) {
|
|
$db = $this->db;
|
|
$modelPD = new PatDiagModel();
|
|
$modelPVA = new PatVisitADTModel();
|
|
$db->transBegin();
|
|
try{
|
|
|
|
if (!isset($input['PVID']) || $input['PVID']=='') {
|
|
$modelCounter = new CounterModel();
|
|
$input['PVID'] = $this->visnum_prefix .$modelCounter->use(2);
|
|
}
|
|
|
|
$InternalPVID = $this->insert($input, true);
|
|
if($InternalPVID === false) { throw new \Exception("Failed to insert main PatVisit record."); }
|
|
if( !empty($input['PatDiag']) && ( !empty($input['PatDiag']['DiagCode']) || !empty($input['PatDiag']['Diagnosis']) ) ) {
|
|
$input['PatDiag']['InternalPVID'] = $InternalPVID;
|
|
$tmp = $modelPD->insert($input['PatDiag']);
|
|
if ($tmp === false) { throw new \Exception("Failed to insert PatDiag record."); }
|
|
}
|
|
if( !empty($input['PatVisitADT']) ) {
|
|
$input['PatVisitADT']['InternalPVID'] = $InternalPVID;
|
|
$tmp = $modelPVA->insert($input['PatVisitADT']);
|
|
if ($tmp === false) {
|
|
throw new \Exception("Failed to insert PatVisitADT record.");
|
|
}
|
|
}
|
|
|
|
if ($db->transStatus() === FALSE) {
|
|
$db->transRollback();
|
|
return false;
|
|
} else {
|
|
$db->transCommit();
|
|
$data = [ "PVID" => $input['PVID'], "InternalPVID" => $InternalPVID ];
|
|
return $data;
|
|
}
|
|
} catch (\Exception $e) {
|
|
$db->transRollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function updatePatVisit($input) {
|
|
$InternalPVID = $input['InternalPVID'];
|
|
$modelPD = new PatDiagModel();
|
|
$modelPVA = new PatVisitADTModel();
|
|
|
|
$db = $this->db;
|
|
$db->transBegin();
|
|
try{
|
|
// Check if visit is not soft deleted before updating
|
|
$visit = $this->where('InternalPVID', $InternalPVID)
|
|
->where('EndDate IS NULL')
|
|
->first();
|
|
|
|
if (!$visit) {
|
|
throw new \Exception("Visit not found or has been deleted.");
|
|
}
|
|
|
|
$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']);
|
|
}
|
|
|
|
if(!empty($input['PatVisitADT'])) {
|
|
$adt = $input['PatVisitADT'];
|
|
$adt['InternalPVID'] = $InternalPVID;
|
|
$tmp = $modelPVA->insert($adt);
|
|
if ($tmp === false) {
|
|
$error = $db->error();
|
|
throw new \Exception("Failed to update PatVisitADT record. ". $error['message']);
|
|
}
|
|
}
|
|
|
|
if ($db->transStatus() === FALSE) {
|
|
$db->transRollback();
|
|
return false;
|
|
} else {
|
|
$db->transCommit();
|
|
$data = [ "PVID" => $input['PVID'] ?? $visit['PVID'], "InternalPVID" => $InternalPVID ];
|
|
return $data;
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
$this->db->transRollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
}
|