Add AttDocFirstName, AttDocLastName, and AttDocContactCode to showByPatient via joins to contact and site-scoped contactdetail. Keep existing AttDoc ID field unchanged for backward compatibility. Update PatientVisit OpenAPI schema, regenerate bundled docs, and extend PatVisitByPatientTest assertions for new fields.
163 lines
5.9 KiB
PHP
Executable File
163 lines
5.9 KiB
PHP
Executable File
<?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, attDoc.NameFirst as AttDocFirstName, attDoc.NameLast as AttDocLastName, attDocDetail.ContactCode as AttDocContactCode")
|
|
->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')
|
|
->join('contact attDoc', 'attDoc.ContactID = patvisitadt.AttDoc', 'left')
|
|
->join('contactdetail attDocDetail', 'attDocDetail.ContactID = attDoc.ContactID AND attDocDetail.SiteID = patvisit.SiteID', '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;
|
|
}
|
|
}
|
|
}
|