[WIP] Claim Encounters
This commit is contained in:
@@ -77,7 +77,7 @@ class ClaimController extends Controller
|
|||||||
'claimRequest',
|
'claimRequest',
|
||||||
'claimRequest.files',
|
'claimRequest.files',
|
||||||
'items',
|
'items',
|
||||||
'items.claim_itemable'
|
'items.claim_itemable',
|
||||||
])
|
])
|
||||||
->findOrFail($id);
|
->findOrFail($id);
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,12 @@ class ClaimController extends Controller
|
|||||||
'claimRequest',
|
'claimRequest',
|
||||||
'claimRequest.files',
|
'claimRequest.files',
|
||||||
'items',
|
'items',
|
||||||
'items.claim_itemable'
|
'items.claim_itemable',
|
||||||
|
'encounters',
|
||||||
|
'encounters.doctors',
|
||||||
|
'encounters.primaryDiagnoses',
|
||||||
|
'encounters.primaryDiagnoses.diagnosis',
|
||||||
|
'encounters.healthcare'
|
||||||
])
|
])
|
||||||
->findOrFail($id);
|
->findOrFail($id);
|
||||||
|
|
||||||
@@ -150,6 +155,19 @@ class ClaimController extends Controller
|
|||||||
return true;
|
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)
|
public function updateItems(Request $request, $id)
|
||||||
{
|
{
|
||||||
@@ -242,8 +260,7 @@ class ClaimController extends Controller
|
|||||||
{
|
{
|
||||||
$claim = Claim::findOrFail($id);
|
$claim = Claim::findOrFail($id);
|
||||||
|
|
||||||
// TODO Fix this tipu tipu
|
$hospital = $claim->finalEncounter->healthcare ?? null;
|
||||||
$hospital = Organization::where('code', 'ORG000D')->first();
|
|
||||||
|
|
||||||
// TODO Fix this tipu tipu
|
// TODO Fix this tipu tipu
|
||||||
$inpationBenefit = $claim->member->currentPlan->benefits()->first();
|
$inpationBenefit = $claim->member->currentPlan->benefits()->first();
|
||||||
@@ -251,17 +268,17 @@ class ClaimController extends Controller
|
|||||||
$pdf = PDF::loadView('pdf.final_log', [
|
$pdf = PDF::loadView('pdf.final_log', [
|
||||||
'claim' => $claim,
|
'claim' => $claim,
|
||||||
'member' => $claim->member,
|
'member' => $claim->member,
|
||||||
'dateOfAdmission' => now(),
|
'dateOfAdmission' => $claim->start,
|
||||||
'hospital' => $hospital,
|
'hospital' => $hospital,
|
||||||
'inpationBenefit' => $inpationBenefit
|
'inpationBenefit' => $inpationBenefit
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $pdf->download('invoice.pdf');
|
return $pdf->download('Final LOG '.$claim->code.'.pdf');
|
||||||
|
|
||||||
$view = view('pdf.final_log', [
|
$view = view('pdf.final_log', [
|
||||||
'claim' => $claim,
|
'claim' => $claim,
|
||||||
'member' => $claim->member,
|
'member' => $claim->member,
|
||||||
'dateOfAdmission' => now(),
|
'dateOfAdmission' => $claim->start,
|
||||||
'hospital' => $hospital,
|
'hospital' => $hospital,
|
||||||
'inpationBenefit' => $inpationBenefit
|
'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\ProvinceController;
|
||||||
use Modules\Internal\Http\Controllers\Api\SpecialityController;
|
use Modules\Internal\Http\Controllers\Api\SpecialityController;
|
||||||
use Modules\Internal\Http\Controllers\Api\VillageController;
|
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', [MemberController::class, 'index']);
|
||||||
Route::get('members/{member_id}/benefits', [MemberController::class, 'benefits']);
|
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::get('claims', [ClaimController::class, 'index']);
|
||||||
Route::post('claims/{id}/update-items', [ClaimController::class, 'updateItems'])->name('claim.update-items');
|
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');
|
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['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['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;
|
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');
|
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()
|
public function diagnoses()
|
||||||
{
|
{
|
||||||
return $this->hasMany(ClaimDiagnosis::class, 'claim_id');
|
return $this->hasMany(ClaimDiagnosis::class, 'claim_id');
|
||||||
@@ -185,5 +195,10 @@ class Claim extends Model
|
|||||||
->whereIn('status', ['approved', 'paid']);
|
->whereIn('status', ['approved', 'paid']);
|
||||||
// ->whereBetween('requested_at', [$startDate, $endDate]);
|
// ->whereBetween('requested_at', [$startDate, $endDate]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTotalTagihanAttribute()
|
||||||
|
{
|
||||||
|
return $this->items->sum('nominal_ditagihkan');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ class ClaimDiagnosis extends Model
|
|||||||
'deleted_by',
|
'deleted_by',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public $type_enums = [
|
||||||
|
'primary' => 'Primary',
|
||||||
|
'secondary' => 'Secondary'
|
||||||
|
];
|
||||||
|
|
||||||
public function icd()
|
public function icd()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Icd::class, 'diagnosis_id', 'id');
|
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\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||||
|
|
||||||
class Encounter extends Model
|
class Encounter extends Model
|
||||||
{
|
{
|
||||||
@@ -15,8 +16,37 @@ class Encounter extends Model
|
|||||||
'class',
|
'class',
|
||||||
'type',
|
'type',
|
||||||
'patient_id',
|
'patient_id',
|
||||||
|
'healthcare_id',
|
||||||
'start',
|
'start',
|
||||||
'end',
|
'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()
|
public function participants()
|
||||||
@@ -24,8 +54,55 @@ class Encounter extends Model
|
|||||||
return $this->hasMany(EncounterParticipant::class, 'encounter_id');
|
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()
|
public function diagnoses()
|
||||||
{
|
{
|
||||||
return $this->hasMany(EncounterDiagnosis::class, 'encounter_id');
|
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 = [
|
public $fillable = [
|
||||||
'encounter_id',
|
'encounter_id',
|
||||||
'diagnosis_id',
|
'diagnosis_id',
|
||||||
|
'type',
|
||||||
'use',
|
'use',
|
||||||
'source',
|
'source',
|
||||||
'description',
|
'description',
|
||||||
@@ -22,8 +23,18 @@ class EncounterDiagnosis extends Model
|
|||||||
'final' => 'Final'
|
'final' => 'Final'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static $type_enums = [
|
||||||
|
'primary' => 'Primary',
|
||||||
|
'secondary' => 'Secondary'
|
||||||
|
];
|
||||||
|
|
||||||
public function encounter()
|
public function encounter()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Encounter::class, 'encounter_id');
|
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 = [
|
public $fillable = [
|
||||||
'encounter_id',
|
'encounter_id',
|
||||||
'type',
|
'type',
|
||||||
|
'participantable_type',
|
||||||
|
'participantable_id'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ return new class extends Migration
|
|||||||
{
|
{
|
||||||
Schema::create('encounters', function (Blueprint $table) {
|
Schema::create('encounters', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('part_of')->comment('encounter_id');
|
$table->foreignId('part_of')->nullable()->comment('encounter_id')->index();
|
||||||
$table->string('status');
|
$table->string('status');
|
||||||
$table->string('class')->nullable();
|
$table->string('class')->nullable();
|
||||||
$table->string('type')->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('start')->nullable();
|
||||||
$table->dateTime('end')->nullable();
|
$table->dateTime('end')->nullable();
|
||||||
|
$table->integer('number_of_bed')->nullable();
|
||||||
|
$table->integer('duration_day')->nullable();
|
||||||
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->softDeletes();
|
$table->softDeletes();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ return new class extends Migration
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('encounter_id');
|
$table->foreignId('encounter_id');
|
||||||
$table->foreignId('diagnosis_id');
|
$table->foreignId('diagnosis_id');
|
||||||
|
$table->string('type')->nullable();
|
||||||
$table->string('use')->nullable();
|
$table->string('use')->nullable();
|
||||||
$table->text('source')->nullable();
|
$table->text('source')->nullable();
|
||||||
$table->text('description')->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,
|
currentValue,
|
||||||
textLabel,
|
textLabel,
|
||||||
currentOptions = [],
|
currentOptions = [],
|
||||||
|
...other
|
||||||
}: autocompleteDoctorType) {
|
}: autocompleteDoctorType) {
|
||||||
const [options, setOptions] = useState<IcdType>(currentOptions);
|
const [options, setOptions] = useState<IcdType>(currentOptions);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -56,7 +57,7 @@ export default function AutocompleteDoctor({
|
|||||||
}}
|
}}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
renderInput={(params) => (
|
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,
|
currentValue,
|
||||||
textLabel,
|
textLabel,
|
||||||
currentOptions = [],
|
currentOptions = [],
|
||||||
|
...other
|
||||||
}: autocompleteHealthcareType) {
|
}: autocompleteHealthcareType) {
|
||||||
const [options, setOptions] = useState<IcdType>(currentOptions);
|
const [options, setOptions] = useState<IcdType>(currentOptions);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -56,7 +57,7 @@ export default function AutocompleteHealthcare({
|
|||||||
}}
|
}}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
renderInput={(params) => (
|
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}
|
value={field.value}
|
||||||
inputFormat="dd/MM/yyyy"
|
inputFormat="dd/MM/yyyy"
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
field.onChange(value)
|
field.onChange(value)
|
||||||
}}
|
}}
|
||||||
renderInput={(params) => <TextField {...params} fullWidth />}
|
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>
|
</LocalizationProvider>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -19,30 +19,25 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
Typography,
|
Typography,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useParams, useNavigate } from 'react-router-dom';
|
|
||||||
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
|
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
|
||||||
import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from '../../components/hook-form';
|
|
||||||
import Page from '../../components/Page';
|
import Page from '../../components/Page';
|
||||||
import useSettings from '../../hooks/useSettings';
|
import useSettings from '../../hooks/useSettings';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog';
|
|
||||||
import { styled } from '@mui/system';
|
import { styled } from '@mui/system';
|
||||||
import axios from '../../utils/axios';
|
import axios from '../../utils/axios';
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from '@mui/lab';
|
||||||
import { fCurrency } from '../../utils/formatNumber';
|
import { fDate } from '@/utils/formatTime';
|
||||||
import Iconify from '../../components/Iconify';
|
import Iconify from '../../components/Iconify';
|
||||||
import Form from './Form';
|
|
||||||
import Documents from './components/Documents';
|
import Documents from './components/Documents';
|
||||||
import DiagnosisHistory from './components/DiagnosisHistory';
|
import DiagnosisHistory from './components/DiagnosisHistory';
|
||||||
import ClaimItems from './components/ClaimItems';
|
import ClaimItems from './components/ClaimItems';
|
||||||
import DialogMemberBenefit from './components/DialogMemberBenefit';
|
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 ClaimDetail from './components/ClaimDetail';
|
||||||
|
import DialogHistoryPerawatan from './components/DialogHistoryPerawatan';
|
||||||
|
import { IconButton } from '@mui/material';
|
||||||
|
import { Tooltip } from '@mui/material';
|
||||||
|
|
||||||
export default function ClaimsCreateUpdate() {
|
export default function ClaimsCreateUpdate() {
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
@@ -198,8 +193,9 @@ export default function ClaimsCreateUpdate() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
|
// History Perawatan
|
||||||
|
const [openDialogHistoryPerawatan, setOpenDialogHistoryPerawatan] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
axios.get('/claims/' + id).then(({ data }) => {
|
axios.get('/claims/' + id).then(({ data }) => {
|
||||||
@@ -212,6 +208,33 @@ export default function ClaimsCreateUpdate() {
|
|||||||
});
|
});
|
||||||
}, [id]);
|
}, [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 (
|
return (
|
||||||
<Page title={`Claim : ${currentClaim?.code}`}>
|
<Page title={`Claim : ${currentClaim?.code}`}>
|
||||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||||
@@ -359,9 +382,86 @@ export default function ClaimsCreateUpdate() {
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={7}>
|
<Grid item xs={7}>
|
||||||
{/* Diagnosis */}
|
{/* Claim Detail */}
|
||||||
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2 }}>
|
<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>
|
||||||
|
|
||||||
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginTop: 2 }}>
|
<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 }}>
|
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginTop: 2 }}>
|
||||||
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||||
<Stack direction="row" alignItems="center" spacing={1}>
|
<Stack direction="row" alignItems="center" spacing={1}>
|
||||||
<Iconify icon="eva:bell-fill" />
|
<Iconify icon="eva:clock-outline" />
|
||||||
<Typography variant="body2" fontWeight={600}>
|
<Typography variant="body2" fontWeight={600}>
|
||||||
Riwayat Diagnosa
|
Riwayat Diagnosa
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Typography
|
{/* <Typography
|
||||||
variant="body2"
|
variant="body2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenDialogRequestDocument(true);
|
setOpenDialogRequestDocument(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
View All
|
View All
|
||||||
</Typography>
|
</Typography> */}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Paper sx={{ background: 'white', marginTop: 2 }}>
|
<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 colspan="99" style="background: red; padding-left: 30px; color: white">B. Informasi Perawatan</td></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width: 25%">1. Tanggal Masuk</td>
|
<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%">7. Lama Perawatan</td>
|
||||||
<td style="width: 25%">: {{ '' }}</td>
|
<td style="width: 25%">: {{ $claim->finalEncounter->duration_day ?? "" }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>2. Tanggal Keluar</td>
|
<td>2. Tanggal Keluar</td>
|
||||||
<td>: {{ '' }}</td>
|
<td>: {{ $claim->finalEncounter->end }}</td>
|
||||||
|
|
||||||
<td>8. Kamar Perawatan</td>
|
<td>8. Kamar Perawatan</td>
|
||||||
<td>: </td>
|
<td>: {{ "" }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>3. Nama Rumah Sakit</td>
|
<td>3. Nama Rumah Sakit</td>
|
||||||
<td>: {{ $hospital->name }}</td>
|
<td>: {{ $hospital->name }}</td>
|
||||||
|
|
||||||
<td>9. Jumlah Tempat Tidur</td>
|
<td>9. Jumlah Tempat Tidur</td>
|
||||||
<td>: {{ '' }}</td>
|
<td>: {{ $claim->finalEncounter->number_of_bed }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>4. Dokter yang Merawat</td>
|
<td>4. Dokter yang Merawat</td>
|
||||||
<td>: {{ '' }}</td>
|
<td>: {{ $claim->finalEncounter->doctors->first()->person->name ?? '' }}</td>
|
||||||
|
|
||||||
<td>10. Estimasi Biaya Rawat Inap</td>
|
<td>10. Estimasi Biaya Rawat Inap</td>
|
||||||
<td>: {{ '' }}</td>
|
<td>: {{ $claim->total_tagihan ? Helper::currencyIdrFormat($claim->total_tagihan) : "" }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>5. No. Rekam Medis</td>
|
<td>5. No. Rekam Medis</td>
|
||||||
<td>: {{ '' }}</td>
|
<td>: {{ $claim->finalEncounter->meta->MEDRECID }}</td>
|
||||||
|
|
||||||
<td>11. Diagnosa</td>
|
<td>11. Diagnosa</td>
|
||||||
<td>: {{ $claim->diagnosis?->icd?->code ?? '' }}/{{ $claim->diagnosis?->icd?->name ?? '' }}</td>
|
<td>: {{ $claim->diagnosis?->icd?->code ?? '' }}/{{ $claim->diagnosis?->icd?->name ?? '' }}</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user