Initial commit - Physiotherapy Clinic Management System
This commit is contained in:
commit
dbb326f2cc
300 files changed
+144285
No files matched your search
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Appointment extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'patient_id',
|
||||
'user_id',
|
||||
'appointment_date',
|
||||
'duration_minutes',
|
||||
'status',
|
||||
'notes',
|
||||
'cancellation_reason',
|
||||
'cancelled_by',
|
||||
'cancelled_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'appointment_date' => 'datetime',
|
||||
'cancelled_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function cancelledBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'cancelled_by');
|
||||
}
|
||||
|
||||
public function treatments()
|
||||
{
|
||||
return $this->hasMany(Treatment::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ChartOfAccount extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'type',
|
||||
'category',
|
||||
'description',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Currency extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'symbol',
|
||||
'decimal_places',
|
||||
'exchange_rate_to_base',
|
||||
'is_base',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'decimal_places' => 'integer',
|
||||
'exchange_rate_to_base' => 'decimal:6',
|
||||
'is_base' => 'boolean',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Invoice extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'invoice_number',
|
||||
'patient_id',
|
||||
'treatment_id',
|
||||
'invoice_date',
|
||||
'due_date',
|
||||
'subtotal',
|
||||
'tax_amount',
|
||||
'discount_amount',
|
||||
'total_amount',
|
||||
'paid_amount',
|
||||
'status',
|
||||
'currency_id',
|
||||
'notes',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'invoice_date' => 'date',
|
||||
'due_date' => 'date',
|
||||
'subtotal' => 'decimal:2',
|
||||
'tax_amount' => 'decimal:2',
|
||||
'discount_amount' => 'decimal:2',
|
||||
'total_amount' => 'decimal:2',
|
||||
'paid_amount' => 'decimal:2',
|
||||
];
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class);
|
||||
}
|
||||
|
||||
public function treatment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Treatment::class);
|
||||
}
|
||||
|
||||
public function currency(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Currency::class);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function payments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
}
|
||||
|
||||
public function getBalanceAttribute(): float
|
||||
{
|
||||
return $this->total_amount - $this->paid_amount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class LedgerEntry extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'entry_date',
|
||||
'chart_of_account_id',
|
||||
'currency_id',
|
||||
'amount',
|
||||
'description',
|
||||
'source_type',
|
||||
'source_id',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'entry_date' => 'date',
|
||||
'amount' => 'decimal:2',
|
||||
];
|
||||
|
||||
public function chartOfAccount(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ChartOfAccount::class);
|
||||
}
|
||||
|
||||
public function currency(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Currency::class);
|
||||
}
|
||||
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function scopeIncome($query)
|
||||
{
|
||||
return $query->whereHas('chartOfAccount', function ($q) {
|
||||
$q->where('type', 'income');
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeExpense($query)
|
||||
{
|
||||
return $query->whereHas('chartOfAccount', function ($q) {
|
||||
$q->where('type', 'expense');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Package extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'number_of_sessions',
|
||||
'price',
|
||||
'currency_id',
|
||||
'validity_days',
|
||||
'description',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'number_of_sessions' => 'integer',
|
||||
'price' => 'decimal:2',
|
||||
'validity_days' => 'integer',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function currency(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Currency::class);
|
||||
}
|
||||
|
||||
public function patientPackages(): HasMany
|
||||
{
|
||||
return $this->hasMany(PatientPackage::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Patient extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'patient_code',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'phone',
|
||||
'date_of_birth',
|
||||
'gender',
|
||||
'address',
|
||||
'emergency_contact_name',
|
||||
'emergency_contact_phone',
|
||||
'medical_history',
|
||||
'allergies',
|
||||
'notes',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'date_of_birth' => 'date',
|
||||
];
|
||||
|
||||
public function appointments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Appointment::class);
|
||||
}
|
||||
|
||||
public function treatments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Treatment::class);
|
||||
}
|
||||
|
||||
public function invoices(): HasMany
|
||||
{
|
||||
return $this->hasMany(Invoice::class);
|
||||
}
|
||||
|
||||
public function fullName(): string
|
||||
{
|
||||
return "{$this->first_name} {$this->last_name}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PatientPackage extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'patient_id',
|
||||
'package_id',
|
||||
'total_sessions',
|
||||
'remaining_sessions',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'total_sessions' => 'integer',
|
||||
'remaining_sessions' => 'integer',
|
||||
'start_date' => 'date',
|
||||
'end_date' => 'date',
|
||||
];
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class);
|
||||
}
|
||||
|
||||
public function package(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Package::class);
|
||||
}
|
||||
|
||||
public function consumeSession(): bool
|
||||
{
|
||||
if ($this->remaining_sessions > 0 && $this->status === 'active') {
|
||||
$this->remaining_sessions--;
|
||||
if ($this->remaining_sessions === 0) {
|
||||
$this->status = 'completed';
|
||||
}
|
||||
$this->save();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Payment extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'payment_number',
|
||||
'invoice_id',
|
||||
'payment_date',
|
||||
'amount',
|
||||
'payment_method',
|
||||
'reference_number',
|
||||
'notes',
|
||||
'received_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'payment_date' => 'date',
|
||||
'amount' => 'decimal:2',
|
||||
];
|
||||
|
||||
public function invoice(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Invoice::class);
|
||||
}
|
||||
|
||||
public function receivedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'received_by');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Reminder extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'appointment_id',
|
||||
'template_id',
|
||||
'channel',
|
||||
'content',
|
||||
'send_at',
|
||||
'sent_at',
|
||||
'status',
|
||||
'error_message',
|
||||
'response',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'send_at' => 'datetime',
|
||||
'sent_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function appointment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Appointment::class);
|
||||
}
|
||||
|
||||
public function template(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ReminderTemplate::class, 'template_id');
|
||||
}
|
||||
|
||||
public function markAsSent(string $response = null): void
|
||||
{
|
||||
$this->status = 'sent';
|
||||
$this->sent_at = now();
|
||||
$this->response = $response;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function markAsFailed(string $errorMessage): void
|
||||
{
|
||||
$this->status = 'failed';
|
||||
$this->error_message = $errorMessage;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class ReminderTemplate extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'content',
|
||||
'channel',
|
||||
'hours_before',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'hours_before' => 'integer',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function reminders(): HasMany
|
||||
{
|
||||
return $this->hasMany(Reminder::class, 'template_id');
|
||||
}
|
||||
|
||||
public function parseContent(array $placeholders): string
|
||||
{
|
||||
$content = $this->content;
|
||||
foreach ($placeholders as $key => $value) {
|
||||
$content = str_replace('{' . $key . '}', $value, $content);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Treatment extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'patient_id',
|
||||
'appointment_id',
|
||||
'user_id',
|
||||
'treatment_code',
|
||||
'name',
|
||||
'description',
|
||||
'sessions_count',
|
||||
'sessions_completed',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'status',
|
||||
'total_cost',
|
||||
'currency_id',
|
||||
'notes',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'start_date' => 'date',
|
||||
'end_date' => 'date',
|
||||
'sessions_count' => 'integer',
|
||||
'sessions_completed' => 'integer',
|
||||
'total_cost' => 'decimal:2',
|
||||
];
|
||||
|
||||
public function patient(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Patient::class);
|
||||
}
|
||||
|
||||
public function appointment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Appointment::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function currency(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Currency::class);
|
||||
}
|
||||
|
||||
public function invoices(): HasMany
|
||||
{
|
||||
return $this->hasMany(Invoice::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable implements MustVerifyEmail
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'role',
|
||||
'specialization',
|
||||
'hourly_rate',
|
||||
'session_rate',
|
||||
'target_sessions_per_day',
|
||||
'target_sessions_per_month',
|
||||
'working_schedule',
|
||||
'two_factor_secret',
|
||||
'two_factor_recovery_codes',
|
||||
'two_factor_enabled',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
'two_factor_secret',
|
||||
'two_factor_recovery_codes',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'two_factor_enabled' => 'boolean',
|
||||
'two_factor_recovery_codes' => 'array',
|
||||
];
|
||||
|
||||
public function isTwoFactorEnabled(): bool
|
||||
{
|
||||
return $this->two_factor_enabled === true;
|
||||
}
|
||||
|
||||
public function getTwoFactorSecret(): ?string
|
||||
{
|
||||
return $this->two_factor_secret ? decrypt($this->two_factor_secret) : null;
|
||||
}
|
||||
|
||||
public function setTwoFactorSecret(string $secret): void
|
||||
{
|
||||
$this->two_factor_secret = encrypt($secret);
|
||||
}
|
||||
|
||||
public function generateRecoveryCodes(): array
|
||||
{
|
||||
$codes = [];
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$codes[] = bin2hex(random_bytes(4));
|
||||
}
|
||||
return $codes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Wage extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'period_start',
|
||||
'period_end',
|
||||
'sessions_count',
|
||||
'hours_worked',
|
||||
'base_amount',
|
||||
'bonus',
|
||||
'deductions',
|
||||
'total_amount',
|
||||
'currency_id',
|
||||
'status',
|
||||
'notes',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'period_start' => 'date',
|
||||
'period_end' => 'date',
|
||||
'sessions_count' => 'integer',
|
||||
'hours_worked' => 'integer',
|
||||
'base_amount' => 'decimal:2',
|
||||
'bonus' => 'decimal:2',
|
||||
'deductions' => 'decimal:2',
|
||||
'total_amount' => 'decimal:2',
|
||||
];
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function currency(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Currency::class);
|
||||
}
|
||||
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user