Deploy Ladill Care / deploy (push) Successful in 55s
Seeds NEWS2/Braden/Morse/pain packs with visit vitals and a unit dashboard for MAR, assessments, notes, and handover activity. Co-authored-by: Cursor <cursoragent@cursor.com>
110 lines
3.4 KiB
PHP
110 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Care;
|
|
|
|
use App\Models\Assessment;
|
|
use App\Models\AssessmentTemplate;
|
|
use App\Models\CareUnit;
|
|
use App\Models\Visit;
|
|
use App\Models\VisitVital;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class NursingAssessmentService
|
|
{
|
|
/** @var list<string> */
|
|
public const NURSING_PACK_CODES = ['news2', 'braden', 'morse', 'pain_nrs'];
|
|
|
|
/**
|
|
* @return Collection<int, AssessmentTemplate>
|
|
*/
|
|
public function nursingTemplates(): Collection
|
|
{
|
|
return AssessmentTemplate::query()
|
|
->whereNull('organization_id')
|
|
->where('is_current', true)
|
|
->where('is_active', true)
|
|
->whereIn('code', self::NURSING_PACK_CODES)
|
|
->orderBy('name')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Board rows for placed patients: latest nursing assessments + latest vitals.
|
|
*
|
|
* @return list<array<string, mixed>>
|
|
*/
|
|
public function unitBoard(CareUnit $unit, string $ownerRef): array
|
|
{
|
|
$templates = $this->nursingTemplates();
|
|
$visits = Visit::owned($ownerRef)
|
|
->where('care_unit_id', $unit->id)
|
|
->whereIn('status', [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS])
|
|
->with(['patient', 'bed'])
|
|
->orderBy('placed_at')
|
|
->get();
|
|
|
|
$rows = [];
|
|
foreach ($visits as $visit) {
|
|
$latestByCode = Assessment::owned($ownerRef)
|
|
->where('visit_id', $visit->id)
|
|
->whereIn('status', [Assessment::STATUS_DRAFT, Assessment::STATUS_COMPLETED])
|
|
->whereHas('template', fn ($q) => $q->whereIn('code', $templates->pluck('code')->all()))
|
|
->with(['template', 'score'])
|
|
->orderByDesc('id')
|
|
->get()
|
|
->unique(fn (Assessment $a) => $a->template?->code)
|
|
->keyBy(fn (Assessment $a) => $a->template?->code);
|
|
|
|
$latestVitals = VisitVital::owned($ownerRef)
|
|
->where('visit_id', $visit->id)
|
|
->orderByDesc('recorded_at')
|
|
->first();
|
|
|
|
$rows[] = [
|
|
'visit' => $visit,
|
|
'patient' => $visit->patient,
|
|
'bed' => $visit->bed,
|
|
'assessments' => $latestByCode,
|
|
'vitals' => $latestVitals,
|
|
];
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
public function recordVisitVitals(
|
|
Visit $visit,
|
|
string $ownerRef,
|
|
?string $actorRef,
|
|
array $data,
|
|
): VisitVital {
|
|
$vital = VisitVital::create([
|
|
'owner_ref' => $ownerRef,
|
|
'organization_id' => $visit->organization_id,
|
|
'visit_id' => $visit->id,
|
|
'patient_id' => $visit->patient_id,
|
|
'care_unit_id' => $visit->care_unit_id,
|
|
'bp_systolic' => $data['bp_systolic'] ?? null,
|
|
'bp_diastolic' => $data['bp_diastolic'] ?? null,
|
|
'pulse' => $data['pulse'] ?? null,
|
|
'temperature' => $data['temperature'] ?? null,
|
|
'spo2' => $data['spo2'] ?? null,
|
|
'respiratory_rate' => $data['respiratory_rate'] ?? null,
|
|
'notes' => $data['notes'] ?? null,
|
|
'recorded_by' => $actorRef,
|
|
'recorded_at' => now(),
|
|
]);
|
|
|
|
AuditLogger::record(
|
|
$ownerRef,
|
|
'visit_vitals.recorded',
|
|
$visit->organization_id,
|
|
$actorRef,
|
|
VisitVital::class,
|
|
$vital->id,
|
|
);
|
|
|
|
return $vital;
|
|
}
|
|
}
|