init project

This commit is contained in:
2026-05-25 11:08:52 +07:00
parent a388c619b5
commit 895fdd9b83
1437 changed files with 384844 additions and 27 deletions

29
app/Models/Antibiotic.php Normal file
View File

@@ -0,0 +1,29 @@
<?php
namespace App\Models;
use App\Traits\AuditLogTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Antibiotic extends BaseModel
{
public $timestamps = false;
use HasFactory, AuditLogTrait;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['name_en','weight', 'lab_id'];
protected $hidden = ['created_at', 'created_by', 'updated_at', 'updated_by', 'record_status_id'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use App\Traits\AuditLogTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class AntibioticResult extends BaseModel
{
protected $table = "antibiogram_results";
public $timestamps = false;
use HasFactory, AuditLogTrait;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['organism_result_id','antibiotic_id','disk_diffusion','mic','sensitive','is_hide','created_at','created_by','updated_at','updated_by','record_status_id'];
public static function boot()
{
parent::boot();
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use MongoDB\Driver\Session;
use App\Traits\AuditLogTrait;
class Appointment extends BaseModel
{
protected $table = "appointments";
public $timestamps = false;
use HasFactory;
use AuditLogTrait;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['patient_id','appointment_date','appointment_type','doctor_id','description','lab_id','created_at','created_by','updated_at','updated_by','record_status_id'];
public static function boot()
{
parent::boot();
}
public function patient(){
return $this->belongsTo(Patient::class, 'patient_id', 'id');
}
public function doctor(){
return $this->belongsTo(Physician::class, 'doctor_id','id');
}
}

69
app/Models/BaseModel.php Normal file
View File

@@ -0,0 +1,69 @@
<?php
/**
* Created by PhpStorm.
* User: mruongyutthy
* Date: 1/4/20
* Time: 21:20
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class BaseModel extends Model
{
use HasFactory;
const RECORD_STATUS_FIELD = 'record_status_id';
const RECORD_STATUS_ACTIVE = 1;
const RECORD_STATUS_DELETE = 0;
const CREATED_AT_FIELD = 'created_at';
const CREATED_BY_FIELD = 'created_by';
const UPDATED_AT_FIELD = 'updated_at';
const UPDATED_BY_FIELD = 'updated_by';
protected static function boot(){
parent::boot();
static::creating(function ($model){
$model->created_at = date('Y-m-d H:i:s');
$model->created_by = Auth::id() ?? 1;
});
static::updating(function ($model){
$model->updated_at = date('Y-m-d H:i:s');
$model->updated_by = Auth::id() ?? 1;
});
}
public static function getTableNameByScheme()
{
$__table = (new static())->table;
$__database = (new static())->getConnection()->getDatabaseName();
return $__database.'.'.$__table;
}
public static function getTableNameByConnection()
{
$__table = (new static())->table;
$__database = (new static())->getConnection()->getName();
return $__database.'.'.$__table;
}
public function createdByUser()
{
return $this->belongsTo(User::class, self::CREATED_BY_FIELD, 'id')->withDefault(function(){
return new User();
});
}
public function updatedByUser()
{
return $this->belongsTo(User::class, self::UPDATED_BY_FIELD, 'id')->withDefault(function(){
return new User();
});;
}
}

26
app/Models/Comment.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Comment extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['comment_desc','sample_type_id','lab_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
public function sample_type(){
return $this->belongsTo('App\Models\SampleType','sample_type_id', 'id');
}
}

22
app/Models/Commune.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use App\Models\Traits\HasLocalizedName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Commune extends Model
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
use HasLocalizedName;
protected $appends = ['name'];
}

43
app/Models/Department.php Normal file
View File

@@ -0,0 +1,43 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use App\Models\Traits\HasLocalizedName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Session;
class Department extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
use HasLocalizedName;
protected $table='departments';
protected $fillable = ['name_en', 'weight', 'lab_id'];
protected $appends = ['name'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
public function samples(){
return $this->hasMany(SampleType::class, 'department_id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE)->where('lab_id', Session::get('base_lab_id'))
->orderBy('weight');
}
}

21
app/Models/District.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use App\Models\Traits\HasLocalizedName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class District extends Model
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
use HasLocalizedName;
protected $appends = ['name'];
}

57
app/Models/Invoice.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Invoice extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'invoices';
protected $fillable = ['invoice_code', 'sample_id', 'total', 'discount','discount_type', 'gross_total', 'deposit', 'bank_deposit', 'balance',
'pay_type', 'invoice_date', 'invoice_note', 'bank_name', 'transaction_ref', 'lab_id', 'is_hide_discount', 'first_paid_date','exchange_rate', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD,
BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD
];
protected $hidden = [BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo(Laboratory::class, 'lab_id','id');
}
public function sample(){
return $this->belongsTo(Sample::class, 'sample_id','id');
}
public function invoiceDetail(){
return $this->hasMany(InvoiceDetail::class, 'invoice_id', 'id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE);
}
public function repayments(){
return $this->hasMany(Repayment::class, 'invoice_id', 'id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE);
}
public function creator()
{
return $this->belongsTo(User::class, 'created_by');
}
public function modifier()
{
return $this->belongsTo(User::class, 'updated_by');
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class InvoiceDetail extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'invoice_details';
protected $fillable = ['invoice_id', 'test_sample_id', 'test_name', 'weight', 'qty', 'unit_price', 'discount_type', 'discount', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD,
BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD
];
protected $hidden = [BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
public function testSample(){
return $this->belongsTo(TestSample::class, 'test_sample_id', 'id');
}
}

50
app/Models/Laboratory.php Normal file
View File

@@ -0,0 +1,50 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use App\Models\Traits\HasLocalizedName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Session;
use App\Traits\AuditLogTrait;
class Laboratory extends BaseModel
{
public $timestamps = false;
use HasFactory;
use HasLocalizedName;
use AuditLogTrait;
/**
* The table associated with the model.
*
* @var string
*/
protected $appends = ['name'];
protected $primaryKey = 'id';
protected $fillable = [
'name_en', 'name_kh', 'short_name', 'address_en', 'address_kh', 'sample_number', 'patient_code', 'is_hide_inv_discount',
'verify_label', 'technician_label', 'logo', 'discount_type','currency', BaseModel::CREATED_AT_FIELD, 'start_date', 'end_date',
'phone_number', 'email', 'shareable_lab_result','allow_external_request','telegrambot','exchange_rate','result_header_id','show_result_footer',
'abnormal_result_font_weight','abnormal_text_color','is_hide_comission_percentage','invoice_template_id','alternative_logo','alter_verify_sign','alter_labtech_sign',
'alternative_footer', 'footer', 'is_auto_make_invoice',
BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD
];
public static function boot()
{
parent::boot();
}
public function userLabCovers(){
return $this->hasMany('App\Models\UserLabCover', 'lab_id','id')->where('record_status_id', RecordStatusEnum::ACTIVE);
}
public function labUsers(){
return $this->hasMany('App\Models\UserLabCover', 'lab_id','id')->where('record_status_id', RecordStatusEnum::ACTIVE)->where('lab_id', Session::get('base_lab_id'));
}
}

19
app/Models/Module.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Module extends Model
{
protected $table = 'sys_module';
protected $primaryKey='module_id';
protected $hidden=['created_at','status','group_module'];
public static function boot()
{
parent::boot();
}
}

27
app/Models/Organism.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Organism extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['name_en', 'weight', 'is_bold', 'lab_id'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class OrganismResult extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['organism_id','test_result_id','quantity_id','contaminant','lab_id','created_at','created_by','updated_at','updated_by','record_status_id'];
public static function boot()
{
parent::boot();
}
}

74
app/Models/Patient.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use DateTime;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
use App\Traits\AuditLogTrait;
class Patient extends BaseModel
{
public $timestamps = false;
use HasFactory;
use AuditLogTrait;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable =
[
'name_en',
'dob',
'patient_uuid',
'gender',
'marital_status',
'phone_number',
'khid_number',
'house_number',
'street_number',
'province_id',
'district_id',
'commune_id',
'village_id',
'lab_id',
self::CREATED_AT_FIELD,
self::CREATED_BY_FIELD,
self::UPDATED_BY_FIELD,
BaseModel::RECORD_STATUS_FIELD
];
public static function boot()
{
parent::boot();
}
public function province(){
return $this->belongsTo(Province::class,'province_id','id');
}
public function district(){
return $this->belongsTo(District::class,'district_id','id');
}
public function commune(){
return $this->belongsTo(Commune::class,'commune_id','id');
}
public function village(){
return $this->belongsTo(Village::class,'village_id','id');
}
public function samples(){
return $this->hasMany(Sample::class,'patient_id','id')
->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => Session::get('base_lab_id')]);
}
public function telegramChatId(){
return $this->belongsTo(PatientTelegram::class,'id', 'patient_id');
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use DateTime;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
class PatientTelegram extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'patient_telegram';
protected $fillable =
[
'patient_id',
'chat_id',
self::CREATED_AT_FIELD,
self::CREATED_BY_FIELD,
self::UPDATED_BY_FIELD,
BaseModel::RECORD_STATUS_FIELD
];
public static function boot()
{
parent::boot();
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class PatientType extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['name_en', 'range_start', 'range_start_unit','range_en','range_end_unit','lab_id'];
public static function boot()
{
parent::boot();
}
}

28
app/Models/Physician.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Physician extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['name_en', 'name_kh','phone','logo','footer','lab_id','is_default'];
protected $hidden = ['created_at', 'created_by', 'updated_at', 'updated_by','record_status_id'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class PhysicianCommission extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'physician_commisssion';
protected $primaryKey = 'id';
protected $fillable = ['physician_id', 'test_sample_id','commission_rate','partner_price','commission_type', 'lab_id', 'created_at', 'created_by', 'updated_at', 'updated_by','record_status_id'];
protected $hidden = ['created_at', 'created_by', 'updated_at', 'updated_by','record_status_id'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
}

22
app/Models/Province.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use App\Models\Traits\HasLocalizedName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Province extends Model
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
use HasLocalizedName;
protected $appends = ['name'];
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Session;
class Publication extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['title_en','title_kh','start_date','end_date','description', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
function receivers(){
return $this->hasMany(PublicationReceiver::class, 'publication_id', 'id');
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class PublicationReceiver extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'publication_receivers';
protected $primaryKey = 'id';
protected $fillable = ['lab_id','publication_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
}

26
app/Models/Quantity.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Quantity extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['quantity_name','lab_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class RejectComment extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = [
'sample_condition_id',
'reject_comment',
'lab_id',
BaseModel::CREATED_AT_FIELD,
BaseModel::CREATED_BY_FIELD
];
public static function boot()
{
parent::boot();
}
}

59
app/Models/Repayment.php Normal file
View File

@@ -0,0 +1,59 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Repayment extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'repayments';
protected $primaryKey='id';
protected $fillable = [
'invoice_id',
'amount_to_pay',
'discount',
'amount_after_discount',
'discount_type',
'cash_repayment_amount',
'bank_repayment_amount',
'repayment_date',
'payment_method',
'bank_name',
'transaction_ref',
'notes',
'lab_id',
'exchange_rate',
BaseModel::CREATED_AT_FIELD,
BaseModel::CREATED_BY_FIELD,
BaseModel::UPDATED_AT_FIELD,
BaseModel::UPDATED_BY_FIELD,
BaseModel::RECORD_STATUS_FIELD
];
protected $hidden = [
'lab_id',
BaseModel::CREATED_AT_FIELD,
BaseModel::CREATED_BY_FIELD,
BaseModel::UPDATED_AT_FIELD,
BaseModel::UPDATED_BY_FIELD,
BaseModel::RECORD_STATUS_FIELD
];
public static function boot()
{
parent::boot();
}
public function invoice(){
return $this->belongsTo(Invoice::class, 'invoice_id','id');
}
}

27
app/Models/Role.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Role extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
public static function boot()
{
parent::boot();
}
protected $fillable = ['name_en', 'lab_id'];
public function lab(){
return $this->belongsTo(Laboratory::class, 'lab_id');
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class RoleHasPermission extends Model
{
//
protected $table = "sys_role_has_permissions";
protected $fillable = ['permission_id','role_id'];
}

214
app/Models/Sample.php Normal file
View File

@@ -0,0 +1,214 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
class Sample extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'samples';
protected $fillable = ['patient_id','admission_date','sample_number','sample_source_id','physician_id',
'sample_condition','reject_comment_id','collected_date','received_date','diagnosis','is_urgent', 'is_printed', 'printed_by','printed_at',
'approved_by','approved_date', 'requested_date','is_accept_request','lab_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD,
BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD,
'result_template_id'
];
//protected $appendsv = ['state'];
protected $append = ['state','progress'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo(Laboratory::class, 'lab_id','id');
}
public function patient(){
return $this->belongsTo(Patient::class, 'patient_id','id');
}
public function sample_source(){
return $this->belongsTo(SampleSource::class, 'sample_source_id','id');
}
public function sample_details(){
return $this->hasMany(SampleDetail::class, 'sample_id', 'id')
->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => Session::get('base_lab_id')]);
}
public function sample_tests(){
return $this->hasMany(TestResult::class, 'sample_id', 'id')
->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => Session::get('base_lab_id')]);
}
public function entryBy(){
return $this->belongsTo(User::class, 'created_by', 'id');
}
public function modifiedBy(){
return $this->belongsTo(User::class, 'updated_by', 'id');
}
public function physician(){
return $this->belongsTo(Physician::class, 'physician_id', 'id');
}
public function invoice(){
return $this->belongsTo(Invoice::class, 'id', 'sample_id')->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE, 'lab_id' => Session::get('base_lab_id')]);
}
function getStateAttribute(){
$state = '#FF0000';
$sampleCondition = $this->sample_condition;
$samplePrinted = $this->is_printed;
$sampleId = $this->id;
$resultItemsData = DB::select('
SELECT
s.id,
s.`sample_number`,
SUM(IF(ts.`field_type`>0, 1,0)) AS non_heading_tests,
SUM(IF(ts.`field_type` IN(1,4) AND tr.test_result IS NOT NULL, 1, 0)) AS done_numeric_tests,
SUM(IF(ts.`field_type` IN(2,3) AND org_result.total_org_result>0, 1, 0)) AS done_org_test
FROM samples s
LEFT JOIN test_results tr
ON tr.`sample_id` = s.`id`
AND s.`lab_id` = tr.`lab_id`
LEFT JOIN test_samples ts
ON ts.id = tr.`test_sample_id`
AND ts.lab_id = tr.lab_id
LEFT JOIN sample_types st
ON st.id = ts.`sample_type_id`
LEFT JOIN(
SELECT
tr.`id`,
COUNT(*) AS total_org_result
FROM samples s
INNER JOIN test_results tr
ON tr.`sample_id` = s.`id`
AND s.`lab_id` = tr.`lab_id`
INNER JOIN organism_results orgr
ON orgr.`test_result_id` = tr.`id`
WHERE s.id = '.$sampleId.'
AND tr.`record_status_id` = 1
AND orgr.`record_status_id` = 1
group by tr.id
) AS org_result
ON org_result.id = tr.`id`
WHERE s.`id` = '.$sampleId.'
AND (tr.`record_status_id` = 1 OR tr.`record_status_id` IS NULL)
AND (st.`record_status_id` = 1 OR st.`record_status_id` IS NULL)
GROUP BY s.`sample_number`, s.id');
$non_heading_tests = 0;
$done_numeric_tests = 0;
$done_org_test = 0;
foreach ($resultItemsData as $v){
$non_heading_tests = $v->non_heading_tests;
$done_numeric_tests = $v->done_numeric_tests;
$done_org_test = $v->done_org_test;
}
if(!is_null($sampleCondition) && $sampleCondition==0) $state = '#FFA500'; // orange for rejected
elseif(($sampleCondition!=0 || is_null($sampleCondition)) && $samplePrinted) $state = '#3b86d1'; // blue for printed
else {
if($non_heading_tests==0) $state = '#FF0000';
else if($non_heading_tests>0 && $non_heading_tests == ($done_numeric_tests+$done_org_test)){
$state = '#008000'; // Green for fully completed
}
elseif($non_heading_tests>0 && ($done_numeric_tests+$done_org_test)==0){
$state = '#FF0000'; // Red for No result at all
}
elseif(($done_numeric_tests+$done_org_test)>0 && $non_heading_tests >($done_numeric_tests+$done_org_test)){
$state = '#FFFF00'; // Yellow for complete some
}
else $state = '#FF0000'; //Silver for known state
}
return $state;
}
function getProgressAttribute(){
$state = '#FF0000';
$sampleCondition = $this->sample_condition;
$samplePrinted = $this->is_printed;
$sampleId = $this->id;
$resultItemsData = DB::select('
SELECT
s.id,
s.`sample_number`,
SUM(IF(ts.`field_type`>0, 1,0)) AS non_heading_tests,
SUM(IF(ts.`field_type` IN(1,4) AND tr.test_result IS NOT NULL, 1, 0)) AS done_numeric_tests,
SUM(IF(ts.`field_type` IN(2,3) AND org_result.total_org_result>0, 1, 0)) AS done_org_test
FROM samples s
LEFT JOIN test_results tr
ON tr.`sample_id` = s.`id`
AND s.`lab_id` = tr.`lab_id`
LEFT JOIN test_samples ts
ON ts.id = tr.`test_sample_id`
AND ts.lab_id = tr.lab_id
LEFT JOIN sample_types st
ON st.id = ts.`sample_type_id`
LEFT JOIN(
SELECT
tr.`id`,
COUNT(*) AS total_org_result
FROM samples s
INNER JOIN test_results tr
ON tr.`sample_id` = s.`id`
AND s.`lab_id` = tr.`lab_id`
INNER JOIN organism_results orgr
ON orgr.`test_result_id` = tr.`id`
WHERE s.id = '.$sampleId.'
AND tr.`record_status_id` = 1
AND orgr.`record_status_id` = 1
group by tr.id
) AS org_result
ON org_result.id = tr.`id`
WHERE s.`id` = '.$sampleId.'
AND (tr.`record_status_id` = 1 OR tr.`record_status_id` IS NULL)
AND (st.`record_status_id` = 1 OR st.`record_status_id` IS NULL)
GROUP BY s.`sample_number`, s.id');
$non_heading_tests = 0;
$done_numeric_tests = 0;
$done_org_test = 0;
foreach ($resultItemsData as $v){
$non_heading_tests = $v->non_heading_tests;
$done_numeric_tests = $v->done_numeric_tests;
$done_org_test = $v->done_org_test;
}
if(!is_null($sampleCondition) && $sampleCondition==0) $state = __('sample.filter_rejected'); // '#FFA500'; // orange for rejected
elseif(($sampleCondition!=0 || is_null($sampleCondition)) && $samplePrinted) $state = __('sample.filter_printed'); // '#3b86d1'; // blue for printed
else {
if($non_heading_tests==0) $state = __('sample.filter_pending');
else if($non_heading_tests>0 && $non_heading_tests == ($done_numeric_tests+$done_org_test)){
$state = __('sample.filter_completed'); // '#008000'; // Green for fully completed
}
elseif($non_heading_tests>0 && ($done_numeric_tests+$done_org_test)==0){
$state = __('sample.filter_pending'); //'#FF0000'; // Red for No result at all
}
elseif(($done_numeric_tests+$done_org_test)>0 && $non_heading_tests >($done_numeric_tests+$done_org_test)){
$state = __('sample.filter_processing'); // '#FFFF00'; // Yellow for complete some
}
else $state = __('sample.filter_pending'); //Silver for known state
}
return $state;
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class SampleDetail extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = [
'sample_id',
'sample_type_id',
'test_date',
'lab_technician_id',
'sample_comment',
'sample_descr',
'sample_volume_1',
'sample_volume_2',
'printed_date',
'printed_by',
'lab_id'
];
public static function boot()
{
parent::boot();
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class SampleSource extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['name_en', 'name_kh', 'lab_id','is_default'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
public function telegramChatId(){
return $this->belongsTo(SampleSourceTelegram::class,'id', 'sample_source_id');
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use DateTime;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
class SampleSourceTelegram extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'sample_source_telegram';
protected $fillable =
[
'sample_source_id',
'chat_id',
self::CREATED_AT_FIELD,
self::CREATED_BY_FIELD,
self::UPDATED_BY_FIELD,
BaseModel::RECORD_STATUS_FIELD
];
public static function boot()
{
parent::boot();
}
}

38
app/Models/SampleType.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Session;
class SampleType extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table='sample_types';
protected $fillable = ['name_en', 'weight', 'department_id','tube','description','lab_id','bg_color','color', 'enter_form_id', 'preview_form_id'];
public static function boot()
{
parent::boot();
}
public function department(){
return $this->belongsTo(Department::class, 'department_id');
}
public function testSamples(){
return $this->hasMany(TestSample::class, 'sample_type_id')
->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE])
//->where('lab_id', Session::get('base_lab_id'))
->orderBy('weight');
}
}

43
app/Models/Supplier.php Normal file
View File

@@ -0,0 +1,43 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Supplier extends BaseModel
{
public $timestamps = true;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'suppliers';
protected $primaryKey = 'id';
protected $fillable = [
'name_en',
'name_kh',
'contact_name',
'position',
'phone_number',
'email',
'address',
'website',
'vat_number',
'description',
'lab_id',
'created_at',
'created_by',
'updated_at',
'updated_by',
'record_status_id'
];
public static function boot()
{
parent::boot();
}
}

29
app/Models/Test.php Normal file
View File

@@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Test extends BaseModel
{
public $timestamps = true;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'tests';
protected $fillable = ['name_en','lab_id','created_at','created_by','record_status_id'];
public static function boot()
{
parent::boot();
}
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class TestCategory extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table='test_categories';
protected $fillable = ['name_en', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
}

30
app/Models/TestGroup.php Normal file
View File

@@ -0,0 +1,30 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class TestGroup extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table='test_groups';
protected $fillable = ['group_name', 'lab_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
public function testGroupDetails(){
return $this->hasMany(TestGroupDetail::class, 'test_group_id', 'id')->where([BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE]);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class TestGroupDetail extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table='test_group_details';
protected $fillable = ['test_group_id','test_sample_id', 'lab_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD, BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD];
public static function boot()
{
parent::boot();
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class TestNormalValue extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $fillable = ['test_sample_id','patient_type_id','sign','minimum','maximum',
BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD, BaseModel::UPDATED_AT_FIELD,
BaseModel::UPDATED_BY_FIELD, BaseModel::RECORD_STATUS_FIELD
];
public static function boot()
{
parent::boot();
}
}

39
app/Models/TestResult.php Normal file
View File

@@ -0,0 +1,39 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class TestResult extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
//protected $appends = ['usd_price'];
public static function boot()
{
parent::boot();
}
protected $fillable = ['sample_id', 'test_sample_id','test_result', 'is_show', 'test_date', 'performed_by', 'lab_id', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD];
function testSample(){
return $this->belongsTo(TestSample::class,'test_sample_id','id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE);
}
// function organismResults(){
// return $this->hasMany(OrganismResult::class,'test_result_id','id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE);
// }
// function getUsdPriceAttribute(){
// return TestSample::query()->find($this->test_sample_id)->first()->usd_price;
// }
}

63
app/Models/TestSample.php Normal file
View File

@@ -0,0 +1,63 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Session;
class TestSample extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
protected $table='test_samples';
public static function boot()
{
parent::boot();
}
protected $fillable = ['sample_type_id', 'test_id','heading_id', 'group_result','category', 'code',
'unit_sign','usd_price', 'weight', 'lab_id','field_type', 'formula', 'format',
'description','is_bold','autocomplete_bind', BaseModel::CREATED_AT_FIELD, BaseModel::CREATED_BY_FIELD];
public function test(){
return $this->belongsTo(Test::class, 'test_id','id');
}
public function sample(){
return $this->belongsTo(SampleType::class, 'sample_type_id','id');
}
public function lab(){
return $this->belongsTo(Laboratory::class, 'lab_id','id');
}
public function organisms(){
return $this->hasMany(TestSampleOrganism::class, 'test_sample_id', 'id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE);
}
public function tests(){
return $this->hasMany(self::class, 'heading_id','id')->where([
BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE,
'lab_id' => Session::get('base_lab_id')
]);
}
public function childTest(){
return $this->hasMany(self::class, 'heading_id','id')->where([
BaseModel::RECORD_STATUS_FIELD => RecordStatusEnum::ACTIVE,
'lab_id' => Session::get('base_lab_id')
]);
}
public function testValues(){
return $this->hasMany(TestNormalValue::class, 'test_sample_id', 'id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class TestSampleOrganism extends BaseModel
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
public static function boot()
{
parent::boot();
}
protected $fillable = ['test_sample_id','organism_id','is_default', 'lab_id', 'created_at', 'created_by', 'updated_at', 'updated_by', 'record_status_id'];
protected $hidden = ['created_at', 'created_by', 'updated_at', 'updated_by'];
public function organism(){
return $this->belongsTo('App\Models\Organism', 'organism_id', 'id')->where(BaseModel::RECORD_STATUS_FIELD, RecordStatusEnum::ACTIVE);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models\Traits;
trait HasLocalizedName
{
//
public function getNameAttribute()
{
$locale = app()->getLocale(); // e.g. 'en' or 'fr'
// Default fallback language
$column = 'name_en';
if (in_array($locale, ['en', 'kh'])) {
$column = "name_{$locale}";
}
// Return localized name if exists, else fallback
return $this->{$column} ?? $this->name_en;
}
}

54
app/Models/User.php Normal file
View File

@@ -0,0 +1,54 @@
<?php
namespace App\Models;
use App\Enums\RecordStatusEnum;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
use App\Traits\AuditLogTrait;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, AuditLogTrait;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name','role_id', 'sample_source_id', 'email', 'password','created_by','signature'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function role(){
return $this->belongsTo('App\Models\Role', 'role_id','id');
}
public function lab_covers(){
return $this->hasMany('App\Models\UserLabCover', 'user_id','id')->where('record_status_id', RecordStatusEnum::ACTIVE );
}
}

View File

@@ -0,0 +1,20 @@
<?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;
class UserLabCover extends Authenticatable
{
public function lab(){
return $this->belongsTo('App\Models\Laboratory', 'lab_id','id');
}
public function user(){
return $this->belongsTo('App\Models\User', 'user_id', 'id');
}
}

22
app/Models/Village.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use App\Models\Traits\HasLocalizedName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Village extends Model
{
public $timestamps = false;
use HasFactory;
/**
* The table associated with the model.
*
* @var string
*/
use HasLocalizedName;
protected $appends = ['name'];
}