complete Complete User Request Submission section RAD-1

This commit is contained in:
2026-01-03 19:14:30 +03:30
commit 7137ec5792
393 changed files with 152602 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
<?php
namespace App\Models;
use App\Enums\DocumentStatusEnum;
use App\Enums\DocumentPriorityEnum;
use App\Observers\DocumentObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
#[ObservedBy(DocumentObserver::class)]
class Document extends Model
{
use HasFactory;
protected $fillable = [
'code',
'modality',
'status',
'priority',
'note',
'submitted_at',
'scan_date',
'processing_deadline',
'finalized_at',
'finalized_by',
'rejection_reason',
'pet_id',
'requester_id',
];
protected $casts = [
'status' => DocumentStatusEnum::class,
'priority' => DocumentPriorityEnum::class,
'submitted_at' => 'datetime',
'scan_date' => 'datetime',
'processing_deadline' => 'datetime',
'finalized_at' => 'datetime',
'finalized_by' => 'integer',
'pet_id' => 'integer',
'requester_id' => 'integer',
];
public function pet()
{
return $this->belongsTo(Pet::class);
}
public function requester()
{
return $this->belongsTo(User::class, 'requester_id');
}
public function finalizedBy()
{
return $this->belongsTo(User::class);
}
public function assignments()
{
return $this->hasMany(DocumentAssignment::class);
}
public function reports()
{
return $this->hasMany(Report::class);
}
public function media()
{
return $this->morphToMany(
\App\Models\Medium::class,
'mediable',
'media_assignments',
'mediable_id',
'media_id'
)->withPivot('collection');
}
public function primaryFiles()
{
return $this->media()->wherePivot('collection', 'primary');
}
public function historyFiles()
{
return $this->media()->wherePivot('collection', 'history');
}
public function users()
{
return $this->belongsToMany(User::class, 'document_assignments')
->withPivot('role')
->withTimestamps();
}
public function mediaAssignments()
{
return $this->morphMany(MediaAssignment::class, 'mediable');
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class DocumentAssignment extends Model
{
use HasFactory;
protected $fillable = [
'document_id',
'user_id',
'role',
];
public function document()
{
return $this->belongsTo(Document::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace App\Models;
use App\Enums\MediaCollectionEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class MediaAssignment extends Model
{
use HasFactory;
protected $fillable = [
'media_id',
'mediable_id',
'mediable_type',
'collection',
];
protected $casts = [
'collection' => MediaCollectionEnum::class,
];
public function media()
{
return $this->belongsTo(Medium::class);
}
public function mediable()
{
return $this->morphTo();
}
}
+113
View File
@@ -0,0 +1,113 @@
<?php
namespace App\Models;
use App\Enums\MediaDiskEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Medium extends Model
{
use HasFactory;
protected $fillable = [
'filename',
'disk',
'path',
'size',
'url',
'mime_type'
];
protected $casts = [
'disk' => MediaDiskEnum::class,
];
public function getFullUrlAttribute()
{
if ($this->disk === MediaDiskEnum::Public) {
return Storage::disk('public')->path($this->path);
}elseif($this->disk === MediaDiskEnum::Private){
return Storage::disk('private')->path($this->path);
}
return $this->url ?? null;
}
public function getStorageDisk()
{
return Storage::disk($this->disk?->value ?? 'public');
}
public function exists()
{
return $this->getStorageDisk()->exists($this->path);
}
public function getContents()
{
return $this->getStorageDisk()->get($this->path);
}
public function deleteFile()
{
if ($this->exists()) {
return $this->getStorageDisk()->delete($this->path);
}
return false;
}
public function getHumanSizeAttribute()
{
$bytes = $this->size;
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, 2) . ' ' . $units[$i];
}
public function isPublic()
{
return $this->disk === MediaDiskEnum::Public;
}
public function isPrivate()
{
return $this->disk === MediaDiskEnum::Private;
}
public function assignments()
{
return $this->hasMany(MediaAssignment::class , 'media_id' , 'id');
}
public function reports()
{
return $this->morphedByMany(
\App\Models\Report::class,
'mediable',
'media_assignments',
'media_id',
'mediable_id'
);
}
public function documents()
{
return $this->morphedByMany(
\App\Models\Document::class,
'mediable',
'media_assignments',
'media_id',
'mediable_id'
);
}
public function users()
{
return $this->hasMany(User::class , 'media_id' , 'id');
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class OtpCode extends Model
{
protected $fillable = [
'phone',
'code',
'expires_at'
];
protected $casts = [
'expires_at' => 'datetime'
];
public function isExpired()
{
return now()->isAfter($this->expires_at);
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Spatie\Permission\Models\Permission as SpatiePermission;
class Permission extends SpatiePermission
{
use HasFactory;
protected $with = ['permissionsParent'];
public function permissionsParent(){
return $this->hasMany(Permission::class , 'parent_id' , 'id');
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
namespace App\Models;
use App\Enums\PetTypeEnum;
use App\Enums\PetGenderEnum;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
class Pet extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = [
'name',
'type',
'gender',
'breed',
'weight',
'sterilized',
'birthday',
'owner_id',
];
protected $casts = [
'type' => PetTypeEnum::class,
'gender' => PetGenderEnum::class,
'weight' => 'integer',
'sterilized' => 'boolean',
'birthday' => 'date',
];
public function owner()
{
return $this->belongsTo(User::class, 'owner_id');
}
public function documents()
{
return $this->hasMany(Document::class);
}
}
+64
View File
@@ -0,0 +1,64 @@
<?php
namespace App\Models;
use App\Enums\ReportStatusEnum;
use App\Enums\MediaCollectionEnum;
use App\Enums\UserEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Report extends Model
{
use HasFactory;
protected $fillable = [
'document_id',
'doctor_id',
'medium_id',
'status',
'body',
'submitted_at',
];
protected $casts = [
'status' => ReportStatusEnum::class,
'submitted_at' => 'datetime',
];
public function document()
{
return $this->belongsTo(Document::class , 'document_id');
}
public function doctor()
{
return $this->belongsTo(User::class, 'doctor_id')->where('level', UserEnum::Doctor->value);
}
public function media()
{
return $this->morphToMany(
\App\Models\Medium::class,
'mediable',
'media_assignments',
'mediable_id',
'media_id'
)->withPivot('collection')->withTimestamps();
}
public function medium()
{
return $this->belongsTo(Medium::class);
}
public function attachments()
{
return $this->media()->wherePivot('collection', MediaCollectionEnum::Attachments->value);
}
public function mediaAssignments()
{
return $this->morphMany(MediaAssignment::class, 'mediable');
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Session extends Model
{
protected $table = 'sessions';
public $timestamps = false;
protected $primaryKey = 'id';
protected $keyType = 'string';
protected $casts = [
'payload' => 'string',
'last_activity' => 'integer',
];
}
+74
View File
@@ -0,0 +1,74 @@
<?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 Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable , HasRoles;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'username',
'fullname',
'national_code',
'level',
'email',
'phone',
'password',
'profile_url',
'clinic_name',
'clinic_phone',
'province',
'city',
'address',
'specialty',
'created_at',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
public function documents()
{
return $this->belongsToMany(Document::class, 'document_assignments')
->withPivot('role')
->withTimestamps();
}
public function pets()
{
return $this->hasMany(Pet::class, 'owner_id');
}
}