Files
ladill-care/app/Services/Care/NursingDocumentationService.php
isaaccladandCursor f1bb432324
Deploy Ladill Care / deploy (push) Successful in 2m12s
Include checked-in clinic visits on outpatient nursing boards.
OPD/service units list open department appointments without manual place; nursing actions soft-place the visit onto the unit. Inpatient wards stay placement-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 17:05:13 +00:00

161 lines
5.2 KiB
PHP

<?php
namespace App\Services\Care;
use App\Models\CareUnit;
use App\Models\NursingNote;
use App\Models\Visit;
use App\Models\WardHandover;
use Illuminate\Support\Collection;
class NursingDocumentationService
{
public function addNote(
Visit $visit,
string $ownerRef,
?string $actorRef,
string $body,
string $noteType = 'progress',
?string $shiftCode = null,
?int $careUnitId = null,
): NursingNote {
$note = NursingNote::create([
'owner_ref' => $ownerRef,
'organization_id' => $visit->organization_id,
'visit_id' => $visit->id,
'patient_id' => $visit->patient_id,
'care_unit_id' => $careUnitId ?? $visit->care_unit_id,
'note_type' => $noteType,
'shift_code' => $shiftCode,
'body' => $body,
'recorded_by' => $actorRef,
'recorded_at' => now(),
]);
AuditLogger::record(
$ownerRef,
'nursing_note.created',
$visit->organization_id,
$actorRef,
NursingNote::class,
$note->id,
);
return $note;
}
/**
* @return Collection<int, NursingNote>
*/
public function notesForUnit(CareUnit $unit, string $ownerRef, int $limit = 50): Collection
{
return NursingNote::owned($ownerRef)
->where('care_unit_id', $unit->id)
->with(['patient', 'visit'])
->orderByDesc('recorded_at')
->limit($limit)
->get();
}
/**
* @return Collection<int, NursingNote>
*/
public function notesForVisit(Visit $visit, string $ownerRef, int $limit = 50): Collection
{
return NursingNote::owned($ownerRef)
->where('visit_id', $visit->id)
->orderByDesc('recorded_at')
->limit($limit)
->get();
}
/**
* @param array<string, mixed> $data
*/
public function createHandover(
CareUnit $unit,
string $ownerRef,
?string $actorRef,
array $data,
bool $complete = false,
): WardHandover {
$handover = WardHandover::create([
'owner_ref' => $ownerRef,
'organization_id' => $unit->organization_id,
'care_unit_id' => $unit->id,
'from_shift' => $data['from_shift'] ?? null,
'to_shift' => $data['to_shift'] ?? null,
'handed_over_at' => $complete ? now() : ($data['handed_over_at'] ?? null),
'handed_over_by' => $actorRef,
'received_by' => $data['received_by'] ?? null,
'situation' => $data['situation'] ?? null,
'background' => $data['background'] ?? null,
'assessment' => $data['assessment'] ?? null,
'recommendation' => $data['recommendation'] ?? null,
'patient_summaries' => $data['patient_summaries'] ?? $this->defaultPatientSummaries($unit, $ownerRef),
'status' => $complete ? WardHandover::STATUS_COMPLETED : WardHandover::STATUS_DRAFT,
]);
AuditLogger::record(
$ownerRef,
$complete ? 'ward_handover.completed' : 'ward_handover.created',
$unit->organization_id,
$actorRef,
WardHandover::class,
$handover->id,
);
return $handover;
}
/**
* @param array<string, mixed> $data
*/
public function completeHandover(
WardHandover $handover,
string $ownerRef,
?string $actorRef,
array $data = [],
): WardHandover {
$handover->update([
'from_shift' => $data['from_shift'] ?? $handover->from_shift,
'to_shift' => $data['to_shift'] ?? $handover->to_shift,
'received_by' => $data['received_by'] ?? $handover->received_by,
'situation' => $data['situation'] ?? $handover->situation,
'background' => $data['background'] ?? $handover->background,
'assessment' => $data['assessment'] ?? $handover->assessment,
'recommendation' => $data['recommendation'] ?? $handover->recommendation,
'patient_summaries' => $data['patient_summaries'] ?? $handover->patient_summaries,
'handed_over_at' => now(),
'handed_over_by' => $actorRef ?? $handover->handed_over_by,
'status' => WardHandover::STATUS_COMPLETED,
]);
AuditLogger::record(
$ownerRef,
'ward_handover.completed',
$handover->organization_id,
$actorRef,
WardHandover::class,
$handover->id,
);
return $handover->fresh();
}
/**
* @return list<array{visit_id: int, patient_name: string, bed: ?string, note: string}>
*/
public function defaultPatientSummaries(CareUnit $unit, string $ownerRef): array
{
$visits = app(CareUnitCensusService::class)->visitsForUnit($unit, $ownerRef);
return $visits->map(fn (Visit $visit) => [
'visit_id' => $visit->id,
'patient_name' => $visit->patient?->fullName() ?? 'Unknown',
'bed' => $visit->bed?->label,
'note' => '',
])->all();
}
}