[WIP] Claim Encounters
This commit is contained in:
@@ -77,7 +77,7 @@ class ClaimController extends Controller
|
||||
'claimRequest',
|
||||
'claimRequest.files',
|
||||
'items',
|
||||
'items.claim_itemable'
|
||||
'items.claim_itemable',
|
||||
])
|
||||
->findOrFail($id);
|
||||
|
||||
|
||||
@@ -107,7 +107,12 @@ class ClaimController extends Controller
|
||||
'claimRequest',
|
||||
'claimRequest.files',
|
||||
'items',
|
||||
'items.claim_itemable'
|
||||
'items.claim_itemable',
|
||||
'encounters',
|
||||
'encounters.doctors',
|
||||
'encounters.primaryDiagnoses',
|
||||
'encounters.primaryDiagnoses.diagnosis',
|
||||
'encounters.healthcare'
|
||||
])
|
||||
->findOrFail($id);
|
||||
|
||||
@@ -150,6 +155,19 @@ class ClaimController extends Controller
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateDetails(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'healthcare_id' => 'required',
|
||||
'doctor_id' => 'required',
|
||||
'start' => 'required',
|
||||
'end' => 'required'
|
||||
]);
|
||||
|
||||
$claim = Claim::findOrFail($id);
|
||||
|
||||
return $claim;
|
||||
}
|
||||
|
||||
public function updateItems(Request $request, $id)
|
||||
{
|
||||
@@ -242,8 +260,7 @@ class ClaimController extends Controller
|
||||
{
|
||||
$claim = Claim::findOrFail($id);
|
||||
|
||||
// TODO Fix this tipu tipu
|
||||
$hospital = Organization::where('code', 'ORG000D')->first();
|
||||
$hospital = $claim->finalEncounter->healthcare ?? null;
|
||||
|
||||
// TODO Fix this tipu tipu
|
||||
$inpationBenefit = $claim->member->currentPlan->benefits()->first();
|
||||
@@ -251,17 +268,17 @@ class ClaimController extends Controller
|
||||
$pdf = PDF::loadView('pdf.final_log', [
|
||||
'claim' => $claim,
|
||||
'member' => $claim->member,
|
||||
'dateOfAdmission' => now(),
|
||||
'dateOfAdmission' => $claim->start,
|
||||
'hospital' => $hospital,
|
||||
'inpationBenefit' => $inpationBenefit
|
||||
]);
|
||||
|
||||
return $pdf->download('invoice.pdf');
|
||||
return $pdf->download('Final LOG '.$claim->code.'.pdf');
|
||||
|
||||
$view = view('pdf.final_log', [
|
||||
'claim' => $claim,
|
||||
'member' => $claim->member,
|
||||
'dateOfAdmission' => now(),
|
||||
'dateOfAdmission' => $claim->start,
|
||||
'hospital' => $hospital,
|
||||
'inpationBenefit' => $inpationBenefit
|
||||
]);
|
||||
|
||||
281
Modules/Internal/Http/Controllers/ClaimEncounterController.php
Normal file
281
Modules/Internal/Http/Controllers/ClaimEncounterController.php
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Internal\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Claim;
|
||||
use App\Models\Encounter;
|
||||
use App\Models\Practitioner;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Internal\Transformers\EncounterResource;
|
||||
|
||||
class ClaimEncounterController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
* @return Renderable
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('internal::index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
* @return Renderable
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('internal::create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
* @param Request $request
|
||||
* @return Renderable
|
||||
*/
|
||||
public function store(Request $request, $claim_id)
|
||||
{
|
||||
$request->validate([
|
||||
'service_code' => 'required',
|
||||
'tanggal_masuk' => 'required',
|
||||
'tanggal_keluar' => 'required'
|
||||
]);
|
||||
$claim = Claim::findOrFail($claim_id);
|
||||
|
||||
// return ($request->primary_diagnosis['id']);
|
||||
// die;
|
||||
// return $request->toArray();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$newEncounterData = [
|
||||
'status' => 'completed',
|
||||
'class' => $request->service_code,
|
||||
'type' => 'Consultation',
|
||||
'patient_id' => $claim->member->person_id,
|
||||
'start' => $request->tanggal_masuk,
|
||||
'end' => $request->tanggal_keluar,
|
||||
'number_of_bed' => $request->number_of_bed,
|
||||
'duration_day' => $request->duration_day
|
||||
];
|
||||
|
||||
if ($request->has('healthcare')) {
|
||||
$newEncounterData['healthcare_id'] = $request->healthcare['id'];
|
||||
}
|
||||
|
||||
// Create New Encounter
|
||||
$newEncounter = $claim->encounters()->create($newEncounterData);
|
||||
|
||||
|
||||
// --------------------------------------------
|
||||
// Meta
|
||||
// TODO Handle if healthcare not primaya
|
||||
$newEncounter->metas()->updateOrCreate([
|
||||
'type' => 'MEDRECID',
|
||||
'system' => 'primaya-his'
|
||||
], [
|
||||
'type' => 'MEDRECID',
|
||||
'system' => 'primaya-his',
|
||||
'value' => $request->medical_record_number
|
||||
]);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Handle Diagnosis
|
||||
if ($request->has('primary_diagnosis') && $request->primary_diagnosis) {
|
||||
$newEncounter->diagnoses()->create([
|
||||
'diagnosis_id' => $request->primary_diagnosis['id'],
|
||||
'type' => 'primary',
|
||||
'use' => 'discharge',
|
||||
'source' => 'primecenter',
|
||||
'description' => 'Batching',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($request->has('secondary_diagnoses')) {
|
||||
foreach ($request->secondary_diagnoses as $diagnosis) {
|
||||
if (!isset($diagnosis['id'])) { // Handle Null Values
|
||||
continue;
|
||||
}
|
||||
$newEncounter->diagnoses()->create([
|
||||
'diagnosis_id' => $diagnosis['id'],
|
||||
'type' => 'secondary',
|
||||
'use' => 'discharge',
|
||||
'source' => 'primecenter',
|
||||
'description' => 'Batching',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
// Handle Doctors as primary Doctor
|
||||
if ($request->has('doctor')) {
|
||||
$newEncounter->participants()->create([
|
||||
'type' => 'Doctor',
|
||||
'participantable_type' => Practitioner::class,
|
||||
'participantable_id' => $request->doctor['id'],
|
||||
]);
|
||||
}
|
||||
DB::commit();
|
||||
|
||||
$newEncounter->load(['diagnoses', 'doctors', 'healthcare']);
|
||||
|
||||
return Helper::responseJson(data: EncounterResource::make($newEncounter), message: 'Encounter berhasil ditambahkan');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the specified resource.
|
||||
* @param int $id
|
||||
* @return Renderable
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
return view('internal::show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
* @param int $id
|
||||
* @return Renderable
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
return view('internal::edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return Renderable
|
||||
*/
|
||||
public function update(Request $request, $claim_id, $encounter_id)
|
||||
{
|
||||
$request->validate([
|
||||
'service_code' => 'required',
|
||||
'tanggal_masuk' => 'required',
|
||||
'tanggal_keluar' => 'required'
|
||||
]);
|
||||
// $claim = Claim::findOrFail($claim_id);
|
||||
|
||||
// return ($request->primary_diagnosis['id']);
|
||||
// die;
|
||||
// return $request->toArray();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$encounter = Encounter::findOrFail($encounter_id);
|
||||
|
||||
$encounterData = [
|
||||
'status' => 'completed',
|
||||
'class' => $request->service_code,
|
||||
'type' => 'Consultation',
|
||||
'start' => $request->tanggal_masuk,
|
||||
'end' => $request->tanggal_keluar,
|
||||
'number_of_bed' => $request->number_of_bed,
|
||||
'duration_day' => $request->duration_day
|
||||
];
|
||||
|
||||
if ($request->has('healthcare')) {
|
||||
$encounterData['healthcare_id'] = $request->healthcare['id'];
|
||||
}
|
||||
|
||||
// Update The Encounter
|
||||
$encounter->fill($encounterData);
|
||||
$encounter->save();
|
||||
|
||||
|
||||
// --------------------------------------------
|
||||
// Meta
|
||||
// TODO Handle if healthcare not primaya
|
||||
$encounter->metas()->updateOrCreate([
|
||||
'type' => 'MEDRECID',
|
||||
'system' => 'primaya-his'
|
||||
], [
|
||||
'type' => 'MEDRECID',
|
||||
'system' => 'primaya-his',
|
||||
'value' => $request->medical_record_number
|
||||
]);
|
||||
|
||||
// ---------------------------------------------
|
||||
// Handle Diagnosis
|
||||
if ($request->has('primary_diagnosis')) {
|
||||
$encounter->diagnoses()->where('type', 'primary')->delete();
|
||||
$encounter->diagnoses()->create([
|
||||
'diagnosis_id' => $request->primary_diagnosis['id'],
|
||||
'type' => 'primary',
|
||||
'use' => 'discharge',
|
||||
'source' => 'primecenter',
|
||||
'description' => 'Batching',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($request->has('secondary_diagnoses')) {
|
||||
$encounter->diagnoses()->where('type', 'secondary')->delete();
|
||||
foreach ($request->secondary_diagnoses as $diagnosis) {
|
||||
if (!isset($diagnosis['id'])) { // Handle Null Values
|
||||
continue;
|
||||
}
|
||||
$encounter->diagnoses()->create([
|
||||
'diagnosis_id' => $diagnosis['id'],
|
||||
'type' => 'secondary',
|
||||
'use' => 'discharge',
|
||||
'source' => 'primecenter',
|
||||
'description' => 'Batching',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
// Handle Doctors as primary Doctor
|
||||
// if ($request->has('doctor')) {
|
||||
// $encounter->participants()->create([
|
||||
// 'type' => 'Doctor',
|
||||
// 'participantable_type' => Practitioner::class,
|
||||
// 'participantable_id' => $request->doctor['id'],
|
||||
// ]);
|
||||
// }
|
||||
DB::commit();
|
||||
|
||||
$encounter->load(['diagnoses', 'doctors', 'healthcare']);
|
||||
|
||||
return Helper::responseJson(data: EncounterResource::make($encounter), message: 'Encounter berhasil ditambahkan');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
* @param int $id
|
||||
* @return Renderable
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function setFinalEncounter(Request $request, $claim_id)
|
||||
{
|
||||
$request->validate([
|
||||
'encounter_id' => 'required'
|
||||
]);
|
||||
|
||||
$claim = Claim::findOrFail($claim_id);
|
||||
|
||||
$claim->final_encounter_id = $request->encounter_id;
|
||||
$claim->save();
|
||||
|
||||
return Helper::responseJson(data: $claim, message: "Success Update Final Encounter");
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ use Modules\Internal\Http\Controllers\Api\PlanController;
|
||||
use Modules\Internal\Http\Controllers\Api\ProvinceController;
|
||||
use Modules\Internal\Http\Controllers\Api\SpecialityController;
|
||||
use Modules\Internal\Http\Controllers\Api\VillageController;
|
||||
use Modules\Internal\Http\Controllers\ClaimEncounterController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -119,6 +120,10 @@ Route::prefix('internal')->group(function () {
|
||||
Route::get('members', [MemberController::class, 'index']);
|
||||
Route::get('members/{member_id}/benefits', [MemberController::class, 'benefits']);
|
||||
|
||||
Route::post('claims/{claim_id}/encounters', [ClaimEncounterController::class, 'store']);
|
||||
Route::post('claims/{claim_id}/encounters/{encounter_id}/update', [ClaimEncounterController::class, 'update']);
|
||||
Route::post('claims/{claim_id}/set-final-encounter', [ClaimEncounterController::class, 'setFinalEncounter']);
|
||||
|
||||
Route::get('claims', [ClaimController::class, 'index']);
|
||||
Route::post('claims/{id}/update-items', [ClaimController::class, 'updateItems'])->name('claim.update-items');
|
||||
Route::post('claims/{id}/update-diagnosis', [ClaimController::class, 'updateDiagnosis'])->name('claim.update-diagnosis');
|
||||
|
||||
@@ -37,6 +37,10 @@ class ClaimShowResource extends JsonResource
|
||||
$data['primary_diagnosis'] = $this->diagnoses->filter(function($diagnosis){ return $diagnosis->type == 'primary';})->values();
|
||||
$data['secondary_diagnosis'] = $this->diagnoses->filter(function($diagnosis){ return $diagnosis->type == 'secondary';})->values();
|
||||
|
||||
$data['encounters'] = $this->encounters->map(function($encounter) {
|
||||
$encounterData = EncounterResource::make($encounter);
|
||||
return $encounterData;
|
||||
});
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
31
Modules/Internal/Transformers/EncounterResource.php
Normal file
31
Modules/Internal/Transformers/EncounterResource.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Internal\Transformers;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class EncounterResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$encounter = parent::toArray($request);
|
||||
|
||||
$encounter['class_name'] = $this->service->name;
|
||||
$encounter['primary_diagnosis'] = $this->primaryDiagnoses->first();
|
||||
$encounter['primary_doctor'] = $this->doctors->first()
|
||||
? array_merge(
|
||||
$this->doctors->first()->person->toArray(),
|
||||
$this->doctors->first()->toArray()
|
||||
)
|
||||
: null;
|
||||
$encounter['medical_record_number'] = @$this->meta->MEDRECID ?? null;
|
||||
|
||||
return $encounter;
|
||||
}
|
||||
}
|
||||
@@ -149,6 +149,16 @@ class Claim extends Model
|
||||
return $this->belongsTo(Member::class, 'member_id');
|
||||
}
|
||||
|
||||
public function encounters()
|
||||
{
|
||||
return $this->belongsToMany(Encounter::class, 'claim_encounter');
|
||||
}
|
||||
|
||||
public function finalEncounter()
|
||||
{
|
||||
return $this->belongsTo(Encounter::class, 'final_encounter_id');
|
||||
}
|
||||
|
||||
public function diagnoses()
|
||||
{
|
||||
return $this->hasMany(ClaimDiagnosis::class, 'claim_id');
|
||||
@@ -185,5 +195,10 @@ class Claim extends Model
|
||||
->whereIn('status', ['approved', 'paid']);
|
||||
// ->whereBetween('requested_at', [$startDate, $endDate]);
|
||||
}
|
||||
|
||||
public function getTotalTagihanAttribute()
|
||||
{
|
||||
return $this->items->sum('nominal_ditagihkan');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,11 @@ class ClaimDiagnosis extends Model
|
||||
'deleted_by',
|
||||
];
|
||||
|
||||
public $type_enums = [
|
||||
'primary' => 'Primary',
|
||||
'secondary' => 'Secondary'
|
||||
];
|
||||
|
||||
public function icd()
|
||||
{
|
||||
return $this->belongsTo(Icd::class, 'diagnosis_id', 'id');
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
|
||||
class Encounter extends Model
|
||||
{
|
||||
@@ -15,8 +16,37 @@ class Encounter extends Model
|
||||
'class',
|
||||
'type',
|
||||
'patient_id',
|
||||
'healthcare_id',
|
||||
'start',
|
||||
'end',
|
||||
'number_of_bed',
|
||||
'duration_day'
|
||||
];
|
||||
|
||||
public $casts = [
|
||||
'start' => 'datetime',
|
||||
'end' => 'datetime'
|
||||
];
|
||||
|
||||
public static $status_enums = [
|
||||
'completed' => 'Completed',
|
||||
'planned' => 'Planned',
|
||||
'in-progress' => 'In Progress',
|
||||
'on-hold' => 'On Hold',
|
||||
'discharged' => 'Discharged',
|
||||
'completed' => 'Completed',
|
||||
'cancelled' => 'Cancelled',
|
||||
'discontinued' => 'Discontinued',
|
||||
'entered-in-error' => 'Entered in Error',
|
||||
'unknown' => 'Unknown',
|
||||
];
|
||||
|
||||
public $with = [
|
||||
'metas'
|
||||
];
|
||||
|
||||
public $append = [
|
||||
'meta'
|
||||
];
|
||||
|
||||
public function participants()
|
||||
@@ -24,8 +54,55 @@ class Encounter extends Model
|
||||
return $this->hasMany(EncounterParticipant::class, 'encounter_id');
|
||||
}
|
||||
|
||||
public function doctors()
|
||||
{
|
||||
|
||||
// return $this->hasManyThrough(CorporateService::class, Service::class, 'corporate_id', 'service_code', 'id', 'service_code');
|
||||
|
||||
return $this->hasManyThrough(Practitioner::class, EncounterParticipant::class, 'encounter_id', 'id', 'id', 'participantable_id')
|
||||
->where(
|
||||
'participantable_type',
|
||||
array_search(static::class, Relation::morphMap()) ?: Practitioner::class
|
||||
);
|
||||
}
|
||||
|
||||
public function diagnoses()
|
||||
{
|
||||
return $this->hasMany(EncounterDiagnosis::class, 'encounter_id');
|
||||
}
|
||||
|
||||
public function healthcare()
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'healthcare_id');
|
||||
}
|
||||
|
||||
public function metas()
|
||||
{
|
||||
return $this->morphMany(Meta::class, 'metaable');
|
||||
}
|
||||
|
||||
public function primaryDiagnoses()
|
||||
{
|
||||
return $this->diagnoses()->where('type', 'primary');
|
||||
}
|
||||
|
||||
public function secondaryDiagnoses()
|
||||
{
|
||||
return $this->diagnoses()->wher('type', 'primary');
|
||||
}
|
||||
|
||||
public function service()
|
||||
{
|
||||
return $this->belongsTo(Service::class, 'class', 'code');
|
||||
}
|
||||
|
||||
public function getMetaAttribute()
|
||||
{
|
||||
$orgMeta = [];
|
||||
foreach ($this->metas as $meta) {
|
||||
$orgMeta[$meta->type] = $meta->value;
|
||||
}
|
||||
|
||||
return (object) $orgMeta;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ class EncounterDiagnosis extends Model
|
||||
public $fillable = [
|
||||
'encounter_id',
|
||||
'diagnosis_id',
|
||||
'type',
|
||||
'use',
|
||||
'source',
|
||||
'description',
|
||||
@@ -22,8 +23,18 @@ class EncounterDiagnosis extends Model
|
||||
'final' => 'Final'
|
||||
];
|
||||
|
||||
public static $type_enums = [
|
||||
'primary' => 'Primary',
|
||||
'secondary' => 'Secondary'
|
||||
];
|
||||
|
||||
public function encounter()
|
||||
{
|
||||
return $this->belongsTo(Encounter::class, 'encounter_id');
|
||||
}
|
||||
|
||||
public function diagnosis()
|
||||
{
|
||||
return $this->belongsTo(Icd::class, 'diagnosis_id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ class EncounterParticipant extends Model
|
||||
public $fillable = [
|
||||
'encounter_id',
|
||||
'type',
|
||||
'participantable_type',
|
||||
'participantable_id'
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -15,13 +15,16 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('encounters', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('part_of')->comment('encounter_id');
|
||||
$table->foreignId('part_of')->nullable()->comment('encounter_id')->index();
|
||||
$table->string('status');
|
||||
$table->string('class')->nullable();
|
||||
$table->string('type')->nullable();
|
||||
$table->foreignId('patient_id')->nullable();
|
||||
$table->foreignId('patient_id')->nullable()->index();
|
||||
$table->foreignId('healthcare_id')->nullable()->index();
|
||||
$table->dateTime('start')->nullable();
|
||||
$table->dateTime('end')->nullable();
|
||||
$table->integer('number_of_bed')->nullable();
|
||||
$table->integer('duration_day')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
@@ -17,6 +17,7 @@ return new class extends Migration
|
||||
$table->id();
|
||||
$table->foreignId('encounter_id');
|
||||
$table->foreignId('diagnosis_id');
|
||||
$table->string('type')->nullable();
|
||||
$table->string('use')->nullable();
|
||||
$table->text('source')->nullable();
|
||||
$table->text('description')->nullable();
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('claim_encounter', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('claim_id');
|
||||
$table->foreignId('encounter_id');
|
||||
|
||||
$table->index(['claim_id', 'encounter_id'], 'claim_encounter_index');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('claim_encounter');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('claims', function (Blueprint $table) {
|
||||
$table->foreignId('final_encounter_id')->nullable()->after('benefit_id')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('claims', function (Blueprint $table) {
|
||||
$table->dropColumn('final_encounter_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -17,6 +17,7 @@ export default function AutocompleteDoctor({
|
||||
currentValue,
|
||||
textLabel,
|
||||
currentOptions = [],
|
||||
...other
|
||||
}: autocompleteDoctorType) {
|
||||
const [options, setOptions] = useState<IcdType>(currentOptions);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -56,7 +57,7 @@ export default function AutocompleteDoctor({
|
||||
}}
|
||||
loading={loading}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label={textLabel} variant="outlined" fullWidth onChange={(event) => {getOptions(event.target.value)}}/>
|
||||
<TextField {...params} {...other} label={textLabel} variant="outlined" fullWidth onChange={(event) => {getOptions(event.target.value)}}/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ export default function AutocompleteHealthcare({
|
||||
currentValue,
|
||||
textLabel,
|
||||
currentOptions = [],
|
||||
...other
|
||||
}: autocompleteHealthcareType) {
|
||||
const [options, setOptions] = useState<IcdType>(currentOptions);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -56,7 +57,7 @@ export default function AutocompleteHealthcare({
|
||||
}}
|
||||
loading={loading}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label={textLabel} variant="outlined" fullWidth onChange={(event) => {getOptions(event.target.value)}}/>
|
||||
<TextField {...params} {...other} label={textLabel} variant="outlined" fullWidth onChange={(event) => {getOptions(event.target.value)}}/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -49,13 +49,30 @@ export default function RHFDatepicker({ name, ...other }: IProps & TextFieldProp
|
||||
/>
|
||||
)}
|
||||
/> */}
|
||||
<DesktopDatePicker
|
||||
{/* <DesktopDatePicker
|
||||
value={field.value}
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
field.onChange(value)
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} fullWidth />}
|
||||
/> */}
|
||||
|
||||
<DesktopDatePicker
|
||||
value={field.value}
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
field.onChange(value);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
fullWidth
|
||||
error={!!error}
|
||||
helperText={error?.message}
|
||||
{...other}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
)}
|
||||
|
||||
@@ -19,30 +19,25 @@ import {
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
|
||||
import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from '../../components/hook-form';
|
||||
import Page from '../../components/Page';
|
||||
import useSettings from '../../hooks/useSettings';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { styled } from '@mui/system';
|
||||
import axios from '../../utils/axios';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { fCurrency } from '../../utils/formatNumber';
|
||||
import { fDate } from '@/utils/formatTime';
|
||||
import Iconify from '../../components/Iconify';
|
||||
import Form from './Form';
|
||||
import Documents from './components/Documents';
|
||||
import DiagnosisHistory from './components/DiagnosisHistory';
|
||||
import ClaimItems from './components/ClaimItems';
|
||||
import DialogMemberBenefit from './components/DialogMemberBenefit';
|
||||
import AutocompleteDiagnosis from '@/components/autocomplete/AutocompleteDiagnosis';
|
||||
import AutocompleteDiagnosisControlled from '@/components/autocomplete/AutocompleteDiagnosisControlled';
|
||||
import { Icd, IcdType } from '@/@types/diagnosis';
|
||||
import { OrganizationType, PractitionerType } from '@/@types/doctor';
|
||||
import ClaimDetail from './components/ClaimDetail';
|
||||
import DialogHistoryPerawatan from './components/DialogHistoryPerawatan';
|
||||
import { IconButton } from '@mui/material';
|
||||
import { Tooltip } from '@mui/material';
|
||||
|
||||
export default function ClaimsCreateUpdate() {
|
||||
const { themeStretch } = useSettings();
|
||||
@@ -198,8 +193,9 @@ export default function ClaimsCreateUpdate() {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// History Perawatan
|
||||
const [openDialogHistoryPerawatan, setOpenDialogHistoryPerawatan] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
axios.get('/claims/' + id).then(({ data }) => {
|
||||
@@ -212,6 +208,33 @@ export default function ClaimsCreateUpdate() {
|
||||
});
|
||||
}, [id]);
|
||||
|
||||
const handleSetFinalEncounter = (encounter) => {
|
||||
const tempLastFinalEncounterId = currentClaim.final_encounter_id
|
||||
axios.post(`/claims/${id}/set-final-encounter`, {
|
||||
encounter_id: encounter.id
|
||||
})
|
||||
.then((res) => {
|
||||
setCurrentClaim({...currentClaim, ...{final_encounter_id: encounter.id}})
|
||||
enqueueSnackbar(res.data.message, {variant: 'success'})
|
||||
})
|
||||
.catch((err) => {
|
||||
setCurrentClaim({...currentClaim, ...{final_encounter_id: tempLastFinalEncounterId}})
|
||||
enqueueSnackbar(err.message, {variant: 'error'})
|
||||
})
|
||||
setCurrentClaim({...currentClaim, ...{final_encounter_id: encounter.id}})
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Edit History Perawatan
|
||||
|
||||
const [openDialogEditHistoryPerawatan, setOpenDialogEditHistoryPerawatan] = useState(false)
|
||||
const [editedEncounter, setEditedEncounter] = useState(null)
|
||||
|
||||
const showEditEncounter = (encounter) => {
|
||||
setEditedEncounter(encounter)
|
||||
setOpenDialogEditHistoryPerawatan(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<Page title={`Claim : ${currentClaim?.code}`}>
|
||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||
@@ -359,9 +382,86 @@ export default function ClaimsCreateUpdate() {
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={7}>
|
||||
{/* Diagnosis */}
|
||||
{/* Claim Detail */}
|
||||
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2 }}>
|
||||
<ClaimDetail claim={currentClaim} />
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
sx={{ marginBottom: 2 }}
|
||||
>
|
||||
<Stack direction="row" alignItems="center" spacing={1}>
|
||||
<Iconify icon="eva:bell-fill" />
|
||||
<Typography variant="body2" fontWeight={600}>
|
||||
History Perawatan
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography
|
||||
onClick={() => {
|
||||
setOpenDialogHistoryPerawatan(true);
|
||||
}}
|
||||
>
|
||||
+ Tambah History Perawatan
|
||||
</Typography>
|
||||
</Stack>
|
||||
|
||||
{/* For Creation History Perawatan / Encounter */}
|
||||
<DialogHistoryPerawatan
|
||||
openDialog={openDialogHistoryPerawatan}
|
||||
setOpenDialog={setOpenDialogHistoryPerawatan}
|
||||
onChange={() => {}}
|
||||
claim={currentClaim}
|
||||
></DialogHistoryPerawatan>
|
||||
|
||||
<Paper sx={{ background: 'white', marginY: 2, p: 2 }}>
|
||||
<Stack sx={{ maxHeight: '250px', overflowY: 'scroll' }}>
|
||||
{currentClaim?.encounters && currentClaim?.encounters.map((encounter, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
sx={{ marginY: 1 }}
|
||||
>
|
||||
<Stack>
|
||||
<Typography fontWeight={'bold'} onClick={() => {showEditEncounter(encounter)}}><a href="#">{ encounter.class_name }</a></Typography>
|
||||
<Typography sx={{ color: '#777', fontSize: '10px' }}>
|
||||
({ fDate(encounter.start) } - { fDate(encounter.end) })
|
||||
</Typography>
|
||||
<Typography variant="body2">Diagnosis: { encounter.primary_diagnosis ? (`(${encounter.primary_diagnosis.diagnosis?.code}) ${encounter.primary_diagnosis.diagnosis?.name}`) : '-'}</Typography>
|
||||
<Typography variant="body2">Dokter: { encounter.primary_doctor ? (`${encounter.primary_doctor.name}`) : '-'}</Typography>
|
||||
</Stack>
|
||||
<Tooltip title="Diagnosa Final">
|
||||
<IconButton onClick={() => {handleSetFinalEncounter(encounter)}}>
|
||||
<Iconify
|
||||
icon="eva:checkmark-circle-2-fill"
|
||||
color={currentClaim.final_encounter_id == encounter.id ? "green" : "gray"}
|
||||
sx={{ margin: 2 }}
|
||||
></Iconify>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
</Stack>
|
||||
<Divider />
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
{(!currentClaim?.encounters || currentClaim?.encounters.length == 0) && (
|
||||
<Typography>Belum ada History Perawatan</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
{/* For Editing History Perawatan / Encounter */}
|
||||
<DialogHistoryPerawatan
|
||||
openDialog={openDialogEditHistoryPerawatan}
|
||||
setOpenDialog={setOpenDialogEditHistoryPerawatan}
|
||||
onChange={() => {}}
|
||||
claim={currentClaim}
|
||||
encounter={editedEncounter}
|
||||
></DialogHistoryPerawatan>
|
||||
|
||||
{/* <ClaimDetail claim={currentClaim} /> */}
|
||||
</Paper>
|
||||
|
||||
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginTop: 2 }}>
|
||||
|
||||
@@ -21,19 +21,19 @@ export default function DiagnosisHistory({ diagnosis }) {
|
||||
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginTop: 2 }}>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||
<Stack direction="row" alignItems="center" spacing={1}>
|
||||
<Iconify icon="eva:bell-fill" />
|
||||
<Iconify icon="eva:clock-outline" />
|
||||
<Typography variant="body2" fontWeight={600}>
|
||||
Riwayat Diagnosa
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography
|
||||
{/* <Typography
|
||||
variant="body2"
|
||||
onClick={() => {
|
||||
setOpenDialogRequestDocument(true);
|
||||
}}
|
||||
>
|
||||
View All
|
||||
</Typography>
|
||||
</Typography> */}
|
||||
</Stack>
|
||||
|
||||
<Paper sx={{ background: 'white', marginTop: 2 }}>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import MuiDialog from '@/components/MuiDialog';
|
||||
import axios from '@/utils/axios';
|
||||
import { Button, Checkbox, Typography } from '@mui/material';
|
||||
import { Paper } from '@mui/material';
|
||||
import { Stack } from '@mui/material';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { useState } from 'react';
|
||||
import FormHistoryPerawatan from './FormHistoryPerawatan';
|
||||
|
||||
type DialogHistoryPerawatanType = {
|
||||
openDialog: boolean;
|
||||
setOpenDialog: void;
|
||||
onSubmit?: void;
|
||||
claim: any; // TODO create ClaimType
|
||||
encounter?: any;
|
||||
}
|
||||
|
||||
export default function DialogHistoryPerawatan({ openDialog, setOpenDialog, onSubmit, claim, encounter } : DialogHistoryPerawatanType) {
|
||||
|
||||
const isEdit = encounter?.id != null
|
||||
// const benefits = member?.current_plan?.benefits ?? [];
|
||||
// const [selectedBenefits, setSelectedBenefits] = useState([]);
|
||||
|
||||
// const toggleBenefit = (benefit) => {
|
||||
// if (selectedBenefits.includes(benefit)) {
|
||||
// console.log('removing', benefit)
|
||||
// setSelectedBenefits(selectedBenefits.filter((throughBenefit) => benefit.id != throughBenefit.id))
|
||||
// } else {
|
||||
// console.log('adding', benefit)
|
||||
// setSelectedBenefits([...selectedBenefits, benefit])
|
||||
// }
|
||||
// }
|
||||
|
||||
const handleSubmit = (data) => {
|
||||
|
||||
if (!isEdit) {
|
||||
axios.post(`claims/${claim.id}/encounters`, data)
|
||||
.then((res) => {
|
||||
enqueueSnackbar(res.data.message, {variant: 'success'})
|
||||
setOpenDialog(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
enqueueSnackbar(err.message, {variant: 'error'})
|
||||
})
|
||||
} else {
|
||||
axios.post(`claims/${claim.id}/encounters/${data.id}/update`, data)
|
||||
.then((res) => {
|
||||
enqueueSnackbar(res.data.message, {variant: 'success'})
|
||||
setOpenDialog(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
enqueueSnackbar(err.message, {variant: 'error'})
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const getContent = () => (
|
||||
<Stack spacing={1} marginTop={2}>
|
||||
<FormHistoryPerawatan claim={claim} onSubmit={handleSubmit} encounter={encounter}></FormHistoryPerawatan>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
return (
|
||||
<MuiDialog
|
||||
title={{ name: !isEdit ? 'Tambah History Perawatan' : 'Edit History Perawatan' }}
|
||||
openDialog={openDialog}
|
||||
setOpenDialog={setOpenDialog}
|
||||
content={getContent()}
|
||||
maxWidth="xl"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
import * as Yup from 'yup';
|
||||
import { IcdType } from '@/@types/diagnosis';
|
||||
import { OrganizationType, PractitionerType } from '@/@types/doctor';
|
||||
import AutocompleteDiagnosisControlled from '@/components/autocomplete/AutocompleteDiagnosisControlled';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { Paper, Stack, TextField } from '@mui/material';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import axios from '@/utils/axios';
|
||||
import { FormProvider, RHFDatepicker, RHFTextField, RHFSelect } from '@/components/hook-form';
|
||||
import AutocompleteDoctor from '@/components/autocomplete/AutocompleteDoctor';
|
||||
import AutocompleteHealthcare from '@/components/autocomplete/AutocompleteHealthcare';
|
||||
import { Typography } from '@mui/material';
|
||||
import Iconify from '@/components/Iconify';
|
||||
import { Divider } from '@mui/material';
|
||||
|
||||
type FormHistoryPerawatanProps = {
|
||||
claim: any;
|
||||
onSubmit: void;
|
||||
encounter?: any; // TODO EncounterType
|
||||
};
|
||||
|
||||
export default function FormHistoryPerawatan({
|
||||
claim,
|
||||
onSubmit,
|
||||
encounter,
|
||||
}: FormHistoryPerawatanProps) {
|
||||
const isEdit = encounter?.id != null;
|
||||
// --------------------------------------------------------------
|
||||
// Diagnosis
|
||||
const [primaryDiagnosis, setPrimaryDiagnosis] = useState(null);
|
||||
const [secondaryDiagnosis, setSecondaryDiagnosis] = useState(null);
|
||||
const [loadingDiagnosis, setLoadingDiagnosis] = useState(false);
|
||||
const [primaryDiagnosisOptions, setPrimaryDiagnosisOptions] = useState([]);
|
||||
const [secondaryDiagnosisOptions, setSecondaryDiagnosisOptions] = useState([]);
|
||||
const [doctorOptions, setDoctorOptions] = useState([]);
|
||||
const [healthcareOptions, setHealthcareOptions] = useState([]);
|
||||
|
||||
const ClaimDetailSchema = Yup.object().shape({
|
||||
primary_diagnosis: Yup.object().required('Diagnosis Utama Wajib dipilih'),
|
||||
// secondary_diagnosis: Yup.object().required('Diagnosis Utama Wajib dipilih'),
|
||||
doctor: Yup.object().required('Dokter Harus dipilih'),
|
||||
healthcare: Yup.object().required('Healthcare Harus dipilih'),
|
||||
});
|
||||
|
||||
interface FormValuesProps extends Partial<any> {
|
||||
service_code: String;
|
||||
primary_diagnosis: IcdType;
|
||||
secondary_diagnosis: IcdType;
|
||||
doctor: PractitionerType;
|
||||
healthcare: OrganizationType;
|
||||
secondary_diagnoses: IcdType[];
|
||||
}
|
||||
|
||||
const defaultValues = useMemo(
|
||||
() => ({
|
||||
service_code: 'OP',
|
||||
tanggal_masuk: null,
|
||||
tanggal_keluar: null,
|
||||
primary_diagnosis: null,
|
||||
doctor: null,
|
||||
healthcare: null,
|
||||
no_medrec: '',
|
||||
bed: '',
|
||||
duration: '',
|
||||
secondary_diagnoses: [],
|
||||
}),
|
||||
[claim]
|
||||
);
|
||||
|
||||
const methods = useForm<FormValuesProps>({
|
||||
resolver: yupResolver(ClaimDetailSchema),
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
const {
|
||||
reset,
|
||||
watch,
|
||||
control,
|
||||
setValue,
|
||||
getValues,
|
||||
setError,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
} = methods;
|
||||
|
||||
const values = watch();
|
||||
|
||||
const handleSaveDiagnosis = () => {
|
||||
setLoadingDiagnosis(true);
|
||||
|
||||
axios
|
||||
.post(`claims/${claim.id}/update-diagnosis`, {
|
||||
primary: [getValues('primary_diagnosis')?.id],
|
||||
secondary: [getValues('secondary_diagnosis')?.id],
|
||||
})
|
||||
.then((res) => {
|
||||
enqueueSnackbar(res.data.message, { variant: 'success' });
|
||||
})
|
||||
.catch((err) => {
|
||||
setLoadingDiagnosis(false);
|
||||
enqueueSnackbar(err.response?.data?.message ?? err?.message, { variant: 'error' });
|
||||
})
|
||||
.then(() => {
|
||||
setLoadingDiagnosis(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (claim) {
|
||||
// SET Default Primary Diagnosis
|
||||
// if (claim.primary_diagnosis.length && claim.primary_diagnosis[0].icd) {
|
||||
// setPrimaryDiagnosisOptions(
|
||||
// claim.primary_diagnosis.map((diagnosis) => {
|
||||
// if (diagnosis.icd) {
|
||||
// return diagnosis.icd;
|
||||
// }
|
||||
// })
|
||||
// );
|
||||
// setValue('primary_diagnosis', claim.primary_diagnosis[0].icd);
|
||||
// }
|
||||
// SET Default Secondary Diagnosis
|
||||
// if (claim.secondary_diagnosis.length && claim.secondary_diagnosis[0].icd) {
|
||||
// setSecondaryDiagnosisOptions(
|
||||
// claim.secondary_diagnosis.map((diagnosis) => {
|
||||
// if (diagnosis.icd) {
|
||||
// return diagnosis.icd;
|
||||
// }
|
||||
// })
|
||||
// );
|
||||
// setValue('secondary_diagnosis', claim.secondary_diagnosis[0].icd);
|
||||
// }
|
||||
}
|
||||
}, [claim]);
|
||||
|
||||
useEffect(() => {
|
||||
if (encounter?.id) {
|
||||
// Primary Diagnosis
|
||||
if (encounter.primary_diagnosis && encounter.primary_diagnosis?.diagnosis) {
|
||||
setPrimaryDiagnosisOptions([encounter.primary_diagnosis.diagnosis]);
|
||||
setValue('primary_diagnosis', encounter.primary_diagnosis.diagnosis);
|
||||
}
|
||||
|
||||
// Sondary Diagnoses
|
||||
if (encounter.secondary_diagnoses && encounter.secondary_diagnoses.length) {
|
||||
encounter.secondary_diagnoses.map();
|
||||
setPrimaryDiagnosisOptions([encounter.primary_diagnosis.diagnosis]);
|
||||
setValue('primary_diagnosis', encounter.primary_diagnosis.diagnosis);
|
||||
}
|
||||
|
||||
if (encounter.primary_doctor) {
|
||||
// TODO Clear Up Data to used by autocomplete
|
||||
setDoctorOptions([encounter.primary_doctor]);
|
||||
setValue('doctor', encounter.primary_doctor);
|
||||
}
|
||||
|
||||
if (encounter.healthcare) {
|
||||
// TODO Clear Up Data to used by autocomplete
|
||||
setDoctorOptions([encounter.healthcare]);
|
||||
setValue('healthcare', encounter.healthcare);
|
||||
}
|
||||
|
||||
setValue('service_code', encounter.class);
|
||||
setValue('tanggal_masuk', encounter.start);
|
||||
setValue('tanggal_keluar', encounter.end);
|
||||
setValue('medical_record_number', encounter.medical_record_number);
|
||||
setValue('number_of_bed', encounter.number_of_bed);
|
||||
setValue('duration_day', encounter.duration_day);
|
||||
setValue('secondary_diagnoses', encounter.secondary_diagnosis);
|
||||
setValue('id', encounter.id);
|
||||
}
|
||||
}, [encounter]);
|
||||
|
||||
function handleAddSecondaryDiagnosis() {
|
||||
setValue('secondary_diagnoses', [...getValues('secondary_diagnoses'), null]);
|
||||
}
|
||||
|
||||
function handleRemoveSecondaryDiagnosis(diagnosis) {
|
||||
// TODO Fix Bug
|
||||
const newDiagnoses = getValues('secondary_diagnoses').filter((val) => {
|
||||
return diagnosis !== val;
|
||||
});
|
||||
setValue('secondary_diagnoses', newDiagnoses);
|
||||
}
|
||||
|
||||
const services = [
|
||||
{
|
||||
code: 'OP',
|
||||
name: 'Rawat Jalan',
|
||||
},
|
||||
{
|
||||
code: 'IP',
|
||||
name: 'Rawat Inap',
|
||||
},
|
||||
];
|
||||
|
||||
const submitting = () => {
|
||||
onSubmit(getValues());
|
||||
};
|
||||
|
||||
return (
|
||||
<FormProvider methods={methods} onSubmit={handleSubmit(submitting)}>
|
||||
<Stack spacing={2}>
|
||||
<Stack spacing={2} sx={{ background: 'white', p: 2 }}>
|
||||
<RHFSelect name="service_code" label="Layanan" placeholder="Layanan">
|
||||
{/* <option value="" /> */}
|
||||
{services.map((option, index) => (
|
||||
<option key={index} value={option.code}>
|
||||
{option.name}
|
||||
</option>
|
||||
))}
|
||||
</RHFSelect>
|
||||
|
||||
<RHFDatepicker
|
||||
name="tanggal_masuk"
|
||||
placeholder="DD/MM/YYYY"
|
||||
label="Tanggal Masuk"
|
||||
></RHFDatepicker>
|
||||
|
||||
<RHFDatepicker
|
||||
name="tanggal_keluar"
|
||||
placeholder="DD/MM/YYYY"
|
||||
label="Tanggal Keluar"
|
||||
></RHFDatepicker>
|
||||
|
||||
<Controller
|
||||
name="healthcare"
|
||||
control={control}
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<AutocompleteHealthcare
|
||||
onChange={onChange}
|
||||
currentOptions={healthcareOptions}
|
||||
currentValue={value}
|
||||
textLabel="Tempat Dirawat"
|
||||
placeholder="Ketik nama fasilitas kesehatan"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="doctor"
|
||||
control={control}
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<AutocompleteDoctor
|
||||
onChange={onChange}
|
||||
currentOptions={doctorOptions}
|
||||
currentValue={value}
|
||||
textLabel="Dokter yang merawat"
|
||||
placeholder="Ketik nama dokter"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<RHFTextField
|
||||
name="medical_record_number"
|
||||
placeholder='"No. Rekam Medis" di fasilitas kesehatan'
|
||||
label="No. Rekam Medis"
|
||||
></RHFTextField>
|
||||
|
||||
<RHFTextField name="number_of_bed" label="Jumlah Tempat Tidur"></RHFTextField>
|
||||
|
||||
<RHFTextField name="duration_day" label="Lama Perawatan (hari)"></RHFTextField>
|
||||
</Stack>
|
||||
|
||||
<Paper variant="outlined" sx={{ background: 'white', p: 2 }}>
|
||||
<Stack spacing={2}>
|
||||
{/* {JSON.stringify(getValues('primary_diagnosis'))} */}
|
||||
<Controller
|
||||
name="primary_diagnosis"
|
||||
control={control}
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<AutocompleteDiagnosisControlled
|
||||
onChange={onChange}
|
||||
currentOptions={primaryDiagnosisOptions}
|
||||
currentValue={value}
|
||||
textLabel="Diagnosis Utama (ICD-X)"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* SECONDARY DIAGNOSES */}
|
||||
|
||||
<Stack direction="row" justifyContent="end">
|
||||
<Typography
|
||||
onClick={() => {
|
||||
handleAddSecondaryDiagnosis();
|
||||
}}
|
||||
>
|
||||
+ Secondary Diagnosis
|
||||
</Typography>
|
||||
</Stack>
|
||||
|
||||
{getValues('secondary_diagnoses') &&
|
||||
getValues('secondary_diagnoses').map(function (diagnosis, index) {
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
{/* <Stack direction="row" sx={{ width: '100%'}}> */}
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
divider={<Divider orientation="horizontal" flexItem />}
|
||||
>
|
||||
<Typography>
|
||||
<strong>#{index + 1}</strong>
|
||||
</Typography>
|
||||
<Iconify
|
||||
icon="eva-trash-outline"
|
||||
color="red"
|
||||
onClick={() => {
|
||||
handleRemoveSecondaryDiagnosis(diagnosis);
|
||||
}}
|
||||
></Iconify>
|
||||
</Stack>
|
||||
<Controller
|
||||
name={`secondary_diagnoses[${index}]`}
|
||||
control={control}
|
||||
sx={{ width: '100%' }}
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<AutocompleteDiagnosisControlled
|
||||
onChange={onChange}
|
||||
currentOptions={[diagnosis]}
|
||||
currentValue={value}
|
||||
textLabel="Diagnosis Tambahan (ICD-X)"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* </Stack> */}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
{(claim?.status == 'requested' || claim?.status == 'received') && (
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
sx={{ marginTop: 2 }}
|
||||
loading={loadingDiagnosis}
|
||||
onClick={() => {
|
||||
submitting();
|
||||
}}
|
||||
>
|
||||
Simpan Detail
|
||||
</LoadingButton>
|
||||
)}
|
||||
</Stack>
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
||||
@@ -184,35 +184,35 @@ use App\Helpers\Helper;
|
||||
<tr><td colspan="99" style="background: red; padding-left: 30px; color: white">B. Informasi Perawatan</td></tr>
|
||||
<tr>
|
||||
<td style="width: 25%">1. Tanggal Masuk</td>
|
||||
<td style="width: 25%">: {{ '' }}</td>
|
||||
<td style="width: 25%">: {{ $claim->finalEncounter->start ?? "" }}</td>
|
||||
|
||||
<td style="width: 25%">7. Lama Perawatan</td>
|
||||
<td style="width: 25%">: {{ '' }}</td>
|
||||
<td style="width: 25%">: {{ $claim->finalEncounter->duration_day ?? "" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2. Tanggal Keluar</td>
|
||||
<td>: {{ '' }}</td>
|
||||
<td>: {{ $claim->finalEncounter->end }}</td>
|
||||
|
||||
<td>8. Kamar Perawatan</td>
|
||||
<td>: </td>
|
||||
<td>: {{ "" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3. Nama Rumah Sakit</td>
|
||||
<td>: {{ $hospital->name }}</td>
|
||||
|
||||
<td>9. Jumlah Tempat Tidur</td>
|
||||
<td>: {{ '' }}</td>
|
||||
<td>: {{ $claim->finalEncounter->number_of_bed }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4. Dokter yang Merawat</td>
|
||||
<td>: {{ '' }}</td>
|
||||
<td>: {{ $claim->finalEncounter->doctors->first()->person->name ?? '' }}</td>
|
||||
|
||||
<td>10. Estimasi Biaya Rawat Inap</td>
|
||||
<td>: {{ '' }}</td>
|
||||
<td>: {{ $claim->total_tagihan ? Helper::currencyIdrFormat($claim->total_tagihan) : "" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5. No. Rekam Medis</td>
|
||||
<td>: {{ '' }}</td>
|
||||
<td>: {{ $claim->finalEncounter->meta->MEDRECID }}</td>
|
||||
|
||||
<td>11. Diagnosa</td>
|
||||
<td>: {{ $claim->diagnosis?->icd?->code ?? '' }}/{{ $claim->diagnosis?->icd?->name ?? '' }}</td>
|
||||
|
||||
Reference in New Issue
Block a user