Healthcare management app: patients, appointments, consultations, lab, pharmacy inventory, billing, and reports at care.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Appointment extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
public const STATUS_SCHEDULED = 'scheduled';
|
||||
|
||||
public const STATUS_CHECKED_IN = 'checked_in';
|
||||
|
||||
public const STATUS_WAITING = 'waiting';
|
||||
|
||||
public const STATUS_IN_CONSULTATION = 'in_consultation';
|
||||
|
||||
public const STATUS_COMPLETED = 'completed';
|
||||
|
||||
public const STATUS_CANCELLED = 'cancelled';
|
||||
|
||||
public const STATUS_NO_SHOW = 'no_show';
|
||||
|
||||
public const TYPE_SCHEDULED = 'scheduled';
|
||||
|
||||
public const TYPE_WALK_IN = 'walk_in';
|
||||
|
||||
protected $table = 'care_appointments';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'patient_id',
|
||||
'practitioner_id', 'department_id', 'visit_id', 'type', 'status',
|
||||
'scheduled_at', 'checked_in_at', 'waiting_at', 'started_at',
|
||||
'completed_at', 'cancelled_at', 'queue_position', 'reason', 'notes', 'created_by',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'scheduled_at' => 'datetime',
|
||||
'checked_in_at' => 'datetime',
|
||||
'waiting_at' => 'datetime',
|
||||
'started_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
'cancelled_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Appointment $appointment) {
|
||||
if (! $appointment->uuid) {
|
||||
$appointment->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function practitioner(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Practitioner::class, 'practitioner_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function department(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Department::class, 'department_id');
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function visit(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Visit::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function consultation(): HasOne
|
||||
{
|
||||
return $this->hasOne(Consultation::class, 'appointment_id');
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
public static function activeStatuses(): array
|
||||
{
|
||||
return [
|
||||
self::STATUS_SCHEDULED,
|
||||
self::STATUS_CHECKED_IN,
|
||||
self::STATUS_WAITING,
|
||||
self::STATUS_IN_CONSULTATION,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class AuditLog extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_audit_logs';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'actor_ref', 'action',
|
||||
'subject_type', 'subject_id', 'metadata', 'ip_address', 'created_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'metadata' => 'array',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public static function record(
|
||||
string $ownerRef,
|
||||
string $action,
|
||||
?int $organizationId = null,
|
||||
?string $actorRef = null,
|
||||
?string $subjectType = null,
|
||||
?int $subjectId = null,
|
||||
?array $metadata = null,
|
||||
): self {
|
||||
return static::create([
|
||||
'owner_ref' => $ownerRef,
|
||||
'organization_id' => $organizationId,
|
||||
'actor_ref' => $actorRef,
|
||||
'action' => $action,
|
||||
'subject_type' => $subjectType,
|
||||
'subject_id' => $subjectId,
|
||||
'metadata' => $metadata,
|
||||
'ip_address' => request()?->ip(),
|
||||
'created_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Bill extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
|
||||
public const STATUS_OPEN = 'open';
|
||||
|
||||
public const STATUS_PARTIAL = 'partial';
|
||||
|
||||
public const STATUS_PAID = 'paid';
|
||||
|
||||
public const STATUS_VOID = 'void';
|
||||
|
||||
protected $table = 'care_bills';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'visit_id', 'patient_id',
|
||||
'invoice_number', 'status', 'subtotal_minor', 'discount_minor', 'tax_minor',
|
||||
'total_minor', 'amount_paid_minor', 'balance_minor', 'notes', 'created_by', 'finalized_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['finalized_at' => 'datetime'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Bill $bill) {
|
||||
if (! $bill->uuid) {
|
||||
$bill->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function visit(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Visit::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function lineItems(): HasMany
|
||||
{
|
||||
return $this->hasMany(BillLineItem::class, 'bill_id');
|
||||
}
|
||||
|
||||
public function payments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payment::class, 'bill_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class BillLineItem extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_bill_line_items';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'bill_id', 'type', 'description', 'quantity',
|
||||
'unit_price_minor', 'total_minor', 'source_type', 'source_id',
|
||||
];
|
||||
|
||||
public function bill(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Bill::class, 'bill_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Branch extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'care_branches';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'name', 'code', 'address', 'phone', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_active' => 'boolean'];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function departments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Department::class, 'branch_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait BelongsToOwner
|
||||
{
|
||||
public function scopeOwned(Builder $query, string $ownerRef): Builder
|
||||
{
|
||||
return $query->where($this->getTable().'.owner_ref', $ownerRef);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Consultation extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
|
||||
public const STATUS_COMPLETED = 'completed';
|
||||
|
||||
protected $table = 'care_consultations';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'visit_id', 'appointment_id', 'practitioner_id',
|
||||
'patient_id', 'status', 'symptoms', 'clinical_notes',
|
||||
'started_at', 'completed_at', 'completed_by',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'started_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Consultation $consultation) {
|
||||
if (! $consultation->uuid) {
|
||||
$consultation->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function visit(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Visit::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function appointment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Appointment::class, 'appointment_id');
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function practitioner(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Practitioner::class, 'practitioner_id');
|
||||
}
|
||||
|
||||
public function vitalSigns(): HasMany
|
||||
{
|
||||
return $this->hasMany(VitalSign::class, 'consultation_id');
|
||||
}
|
||||
|
||||
public function diagnoses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Diagnosis::class, 'consultation_id');
|
||||
}
|
||||
|
||||
public function documents(): HasMany
|
||||
{
|
||||
return $this->hasMany(ConsultationDocument::class, 'consultation_id');
|
||||
}
|
||||
|
||||
public function investigationRequests(): HasMany
|
||||
{
|
||||
return $this->hasMany(InvestigationRequest::class, 'consultation_id');
|
||||
}
|
||||
|
||||
public function prescriptions(): HasMany
|
||||
{
|
||||
return $this->hasMany(Prescription::class, 'consultation_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ConsultationDocument extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_consultation_documents';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'consultation_id', 'file_path', 'original_name',
|
||||
'mime_type', 'uploaded_by',
|
||||
];
|
||||
|
||||
public function consultation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Consultation::class, 'consultation_id');
|
||||
}
|
||||
|
||||
public function url(): ?string
|
||||
{
|
||||
return $this->file_path && Storage::disk('public')->exists($this->file_path)
|
||||
? Storage::disk('public')->url($this->file_path)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Department extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'care_departments';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'branch_id', 'name', 'type', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_active' => 'boolean'];
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Diagnosis extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_diagnoses';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'consultation_id', 'code', 'description', 'is_primary', 'notes',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_primary' => 'boolean'];
|
||||
}
|
||||
|
||||
public function consultation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Consultation::class, 'consultation_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class DispensingRecord extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_dispensing_records';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'prescription_id', 'prescription_item_id',
|
||||
'drug_batch_id', 'quantity', 'dispensed_by', 'dispensed_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['dispensed_at' => 'datetime'];
|
||||
}
|
||||
|
||||
public function prescription(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Prescription::class, 'prescription_id');
|
||||
}
|
||||
|
||||
public function prescriptionItem(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(PrescriptionItem::class, 'prescription_item_id');
|
||||
}
|
||||
|
||||
public function drugBatch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DrugBatch::class, 'drug_batch_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Drug extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'care_drugs';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'branch_id', 'name', 'generic_name',
|
||||
'sku', 'unit', 'unit_price_minor', 'reorder_level', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_active' => 'boolean'];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function batches(): HasMany
|
||||
{
|
||||
return $this->hasMany(DrugBatch::class, 'drug_id');
|
||||
}
|
||||
|
||||
public function stockOnHand(): int
|
||||
{
|
||||
return (int) $this->batches()->sum('quantity_on_hand');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class DrugBatch extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_drug_batches';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'drug_id', 'batch_number', 'expiry_date',
|
||||
'quantity_on_hand', 'cost_minor', 'received_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'expiry_date' => 'date',
|
||||
'received_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function drug(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Drug::class, 'drug_id');
|
||||
}
|
||||
|
||||
public function dispensingRecords(): HasMany
|
||||
{
|
||||
return $this->hasMany(DispensingRecord::class, 'drug_batch_id');
|
||||
}
|
||||
|
||||
public function isExpired(): bool
|
||||
{
|
||||
return $this->expiry_date !== null && $this->expiry_date->isPast();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class EmergencyContact extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_emergency_contacts';
|
||||
|
||||
protected $fillable = ['owner_ref', 'patient_id', 'name', 'phone', 'relationship', 'is_primary'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_primary' => 'boolean'];
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class InsurancePolicy extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_insurance_policies';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'patient_id', 'provider_name', 'policy_number',
|
||||
'coverage_type', 'expiry_date', 'notes',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['expiry_date' => 'date'];
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class InvestigationAttachment extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_investigation_attachments';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'investigation_result_id', 'file_path', 'original_name',
|
||||
'mime_type', 'uploaded_by',
|
||||
];
|
||||
|
||||
public function result(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(InvestigationResult::class, 'investigation_result_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class InvestigationRequest extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
public const STATUS_PENDING = 'pending';
|
||||
|
||||
public const STATUS_SAMPLE_COLLECTED = 'sample_collected';
|
||||
|
||||
public const STATUS_IN_PROGRESS = 'in_progress';
|
||||
|
||||
public const STATUS_AWAITING_REVIEW = 'awaiting_review';
|
||||
|
||||
public const STATUS_COMPLETED = 'completed';
|
||||
|
||||
public const STATUS_DELIVERED = 'delivered';
|
||||
|
||||
public const STATUS_CANCELLED = 'cancelled';
|
||||
|
||||
protected $table = 'care_investigation_requests';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'visit_id', 'consultation_id',
|
||||
'patient_id', 'investigation_type_id', 'practitioner_id', 'status', 'priority',
|
||||
'clinical_notes', 'requested_by', 'assigned_member_id', 'sample_barcode',
|
||||
'sample_collected_at', 'sample_collected_by', 'completed_at', 'delivered_at',
|
||||
'approved_by', 'approved_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'sample_collected_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
'delivered_at' => 'datetime',
|
||||
'approved_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (InvestigationRequest $request) {
|
||||
if (! $request->uuid) {
|
||||
$request->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function investigationType(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(InvestigationType::class, 'investigation_type_id');
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function visit(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Visit::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function consultation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Consultation::class, 'consultation_id');
|
||||
}
|
||||
|
||||
public function practitioner(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Practitioner::class, 'practitioner_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function assignedMember(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Member::class, 'assigned_member_id');
|
||||
}
|
||||
|
||||
public function result(): HasOne
|
||||
{
|
||||
return $this->hasOne(InvestigationResult::class, 'investigation_request_id');
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
public static function activeStatuses(): array
|
||||
{
|
||||
return [
|
||||
self::STATUS_PENDING,
|
||||
self::STATUS_SAMPLE_COLLECTED,
|
||||
self::STATUS_IN_PROGRESS,
|
||||
self::STATUS_AWAITING_REVIEW,
|
||||
self::STATUS_COMPLETED,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class InvestigationResult extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
|
||||
public const STATUS_APPROVED = 'approved';
|
||||
|
||||
protected $table = 'care_investigation_results';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'investigation_request_id', 'result_summary', 'interpretation',
|
||||
'is_abnormal', 'status', 'entered_by', 'approved_by', 'approved_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'is_abnormal' => 'boolean',
|
||||
'approved_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function request(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(InvestigationRequest::class, 'investigation_request_id');
|
||||
}
|
||||
|
||||
public function values(): HasMany
|
||||
{
|
||||
return $this->hasMany(InvestigationResultValue::class, 'investigation_result_id');
|
||||
}
|
||||
|
||||
public function attachments(): HasMany
|
||||
{
|
||||
return $this->hasMany(InvestigationAttachment::class, 'investigation_result_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class InvestigationResultValue extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_investigation_result_values';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'investigation_result_id', 'parameter', 'value', 'unit',
|
||||
'reference_low', 'reference_high', 'reference_text', 'is_abnormal',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'reference_low' => 'decimal:4',
|
||||
'reference_high' => 'decimal:4',
|
||||
'is_abnormal' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function result(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(InvestigationResult::class, 'investigation_result_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class InvestigationType extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'care_investigation_types';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'name', 'code', 'category', 'description',
|
||||
'unit', 'reference_low', 'reference_high', 'reference_text', 'price_minor', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'reference_low' => 'decimal:4',
|
||||
'reference_high' => 'decimal:4',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function requests(): HasMany
|
||||
{
|
||||
return $this->hasMany(InvestigationRequest::class, 'investigation_type_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Member extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_members';
|
||||
|
||||
protected $fillable = ['owner_ref', 'organization_id', 'user_ref', 'role', 'branch_id'];
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function hasRole(string ...$roles): bool
|
||||
{
|
||||
return in_array($this->role, $roles, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Organization extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'care_organizations';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'name', 'slug', 'logo_path', 'timezone', 'settings',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['settings' => 'array'];
|
||||
}
|
||||
|
||||
public function branches(): HasMany
|
||||
{
|
||||
return $this->hasMany(Branch::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function members(): HasMany
|
||||
{
|
||||
return $this->hasMany(Member::class, 'organization_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Patient extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'care_patients';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'patient_number',
|
||||
'first_name', 'last_name', 'other_names', 'gender', 'date_of_birth',
|
||||
'phone', 'email', 'national_id', 'address', 'city', 'region', 'notes',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['date_of_birth' => 'date'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Patient $patient) {
|
||||
if (! $patient->uuid) {
|
||||
$patient->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function fullName(): string
|
||||
{
|
||||
return trim(implode(' ', array_filter([
|
||||
$this->first_name,
|
||||
$this->other_names,
|
||||
$this->last_name,
|
||||
])));
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function allergies(): HasMany
|
||||
{
|
||||
return $this->hasMany(PatientAllergy::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function conditions(): HasMany
|
||||
{
|
||||
return $this->hasMany(PatientCondition::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function familyHistory(): HasMany
|
||||
{
|
||||
return $this->hasMany(PatientFamilyHistory::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function emergencyContacts(): HasMany
|
||||
{
|
||||
return $this->hasMany(EmergencyContact::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function insurancePolicies(): HasMany
|
||||
{
|
||||
return $this->hasMany(InsurancePolicy::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function attachments(): HasMany
|
||||
{
|
||||
return $this->hasMany(PatientAttachment::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function appointments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Appointment::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function visits(): HasMany
|
||||
{
|
||||
return $this->hasMany(Visit::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function investigationRequests(): HasMany
|
||||
{
|
||||
return $this->hasMany(InvestigationRequest::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function prescriptions(): HasMany
|
||||
{
|
||||
return $this->hasMany(Prescription::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function bills(): HasMany
|
||||
{
|
||||
return $this->hasMany(Bill::class, 'patient_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PatientAllergy extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_patient_allergies';
|
||||
|
||||
protected $fillable = ['owner_ref', 'patient_id', 'allergen', 'severity', 'notes'];
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PatientAttachment extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_patient_attachments';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'patient_id', 'file_path', 'original_name',
|
||||
'mime_type', 'document_type', 'uploaded_by',
|
||||
];
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function url(): ?string
|
||||
{
|
||||
return $this->file_path && Storage::disk('public')->exists($this->file_path)
|
||||
? Storage::disk('public')->url($this->file_path)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PatientCondition extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_patient_conditions';
|
||||
|
||||
protected $fillable = ['owner_ref', 'patient_id', 'condition', 'onset_date', 'is_chronic', 'notes'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'onset_date' => 'date',
|
||||
'is_chronic' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PatientFamilyHistory extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_patient_family_history';
|
||||
|
||||
protected $fillable = ['owner_ref', 'patient_id', 'relation', 'condition', 'notes'];
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Payment extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_payments';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'bill_id', 'amount_minor', 'method',
|
||||
'reference', 'paid_at', 'recorded_by', 'notes',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['paid_at' => 'datetime'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Payment $payment) {
|
||||
if (! $payment->uuid) {
|
||||
$payment->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function bill(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Bill::class, 'bill_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Practitioner extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
protected $table = 'care_practitioners';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'organization_id', 'branch_id', 'department_id', 'member_id',
|
||||
'user_ref', 'name', 'specialty', 'is_active',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_active' => 'boolean'];
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function department(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Department::class, 'department_id');
|
||||
}
|
||||
|
||||
public function member(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Member::class, 'member_id');
|
||||
}
|
||||
|
||||
public function schedules(): HasMany
|
||||
{
|
||||
return $this->hasMany(PractitionerSchedule::class, 'practitioner_id');
|
||||
}
|
||||
|
||||
public function appointments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Appointment::class, 'practitioner_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PractitionerSchedule extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_practitioner_schedules';
|
||||
|
||||
protected $fillable = ['owner_ref', 'practitioner_id', 'day_of_week', 'start_time', 'end_time'];
|
||||
|
||||
public function practitioner(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Practitioner::class, 'practitioner_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Prescription extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
|
||||
public const STATUS_ACTIVE = 'active';
|
||||
|
||||
public const STATUS_DISPENSED = 'dispensed';
|
||||
|
||||
public const STATUS_CANCELLED = 'cancelled';
|
||||
|
||||
protected $table = 'care_prescriptions';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'visit_id', 'consultation_id',
|
||||
'patient_id', 'practitioner_id', 'status', 'notes',
|
||||
'prescribed_by', 'dispensed_by', 'dispensed_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['dispensed_at' => 'datetime'];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Prescription $prescription) {
|
||||
if (! $prescription->uuid) {
|
||||
$prescription->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function visit(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Visit::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function consultation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Consultation::class, 'consultation_id');
|
||||
}
|
||||
|
||||
public function practitioner(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Practitioner::class, 'practitioner_id');
|
||||
}
|
||||
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(PrescriptionItem::class, 'prescription_id')->orderBy('sort_order');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PrescriptionItem extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_prescription_items';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'prescription_id', 'drug_id', 'is_procedure', 'name', 'dosage',
|
||||
'frequency', 'duration', 'route', 'quantity', 'instructions', 'sort_order',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['is_procedure' => 'boolean'];
|
||||
}
|
||||
|
||||
public function prescription(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Prescription::class, 'prescription_id');
|
||||
}
|
||||
|
||||
public function drug(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Drug::class, 'drug_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
/**
|
||||
* Thin local mirror of the platform identity (auth.ladill.com owns users).
|
||||
* Keyed by the OIDC `sub` (public_id); every Care record is scoped to it.
|
||||
*/
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, Notifiable;
|
||||
|
||||
protected $fillable = ['public_id', 'name', 'email', 'avatar_url', 'password', 'last_app_active_at'];
|
||||
|
||||
protected $hidden = ['password', 'remember_token'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_app_active_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
|
||||
public function ownerRef(): string
|
||||
{
|
||||
return (string) $this->public_id;
|
||||
}
|
||||
|
||||
public function avatarUrl(): ?string
|
||||
{
|
||||
$url = trim((string) $this->avatar_url);
|
||||
|
||||
return $url !== '' ? $url : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Visit extends Model
|
||||
{
|
||||
use BelongsToOwner, SoftDeletes;
|
||||
|
||||
public const STATUS_OPEN = 'open';
|
||||
|
||||
public const STATUS_IN_PROGRESS = 'in_progress';
|
||||
|
||||
public const STATUS_COMPLETED = 'completed';
|
||||
|
||||
protected $table = 'care_visits';
|
||||
|
||||
protected $fillable = [
|
||||
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'patient_id',
|
||||
'status', 'checked_in_at', 'completed_at', 'checked_in_by',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'checked_in_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Visit $visit) {
|
||||
if (! $visit->uuid) {
|
||||
$visit->uuid = (string) Str::uuid();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class, 'patient_id');
|
||||
}
|
||||
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class, 'branch_id');
|
||||
}
|
||||
|
||||
public function organization(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function appointment(): HasOne
|
||||
{
|
||||
return $this->hasOne(Appointment::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function consultations(): HasMany
|
||||
{
|
||||
return $this->hasMany(Consultation::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function bill(): HasOne
|
||||
{
|
||||
return $this->hasOne(Bill::class, 'visit_id');
|
||||
}
|
||||
|
||||
public function bills(): HasMany
|
||||
{
|
||||
return $this->hasMany(Bill::class, 'visit_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Concerns\BelongsToOwner;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class VitalSign extends Model
|
||||
{
|
||||
use BelongsToOwner;
|
||||
|
||||
protected $table = 'care_vital_signs';
|
||||
|
||||
protected $fillable = [
|
||||
'owner_ref', 'consultation_id', 'bp_systolic', 'bp_diastolic', 'pulse',
|
||||
'temperature', 'weight_kg', 'height_cm', 'spo2', 'respiratory_rate',
|
||||
'recorded_by', 'recorded_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'temperature' => 'decimal:1',
|
||||
'weight_kg' => 'decimal:2',
|
||||
'height_cm' => 'decimal:1',
|
||||
'recorded_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function consultation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Consultation::class, 'consultation_id');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user