Merge remote-tracking branch 'origin/feature/daily-monitoring-client-portal' into staging
This commit is contained in:
913
Modules/Client/Http/Controllers/Api/DailyMonitoringController.php
Executable file
913
Modules/Client/Http/Controllers/Api/DailyMonitoringController.php
Executable file
@@ -0,0 +1,913 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Client\Http\Controllers\Api;
|
||||||
|
use App\Helpers\Helper;
|
||||||
|
use App\Models\DailyMonitoring;
|
||||||
|
use App\Models\RequestDailyMonitoring;
|
||||||
|
use App\Models\MedicalPlan;
|
||||||
|
use DB;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Routing\Controller;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Support\Facades\File as Files;
|
||||||
|
use Modules\Internal\Transformers\DailyMonitoringResource;
|
||||||
|
use App\Models\File;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bagaskoro BSD 27-10-2023
|
||||||
|
*
|
||||||
|
* Controller untuk daily monitoring
|
||||||
|
*/
|
||||||
|
class DailyMonitoringController extends Controller
|
||||||
|
{
|
||||||
|
protected $path_for_store = 'public/lab_result';
|
||||||
|
protected function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'required' => ':attribute harus diisi',
|
||||||
|
'integer' => ':attribute harus angka',
|
||||||
|
'unique' => ':attribute (:input) sudah ada',
|
||||||
|
'max' => ':attribute maximal :max karakter',
|
||||||
|
'exists' => ':attribute (:input) tidak ditemukan',
|
||||||
|
'numeric' => ':attribute harus angka',
|
||||||
|
'digits_between'=> ':attribute maximal :max digit minimal :min digit'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetMemberList(Request $request)
|
||||||
|
{
|
||||||
|
$startDate = $request->start_date ? Carbon::parse($request->start_date) : Carbon::today();
|
||||||
|
$endDate = $request->end_date ? Carbon::parse($request->end_date)->addDay() : Carbon::today()->addDay();
|
||||||
|
|
||||||
|
$memberList = DB::table('request_log_daily_monitorings')
|
||||||
|
->leftJoin('request_logs', 'request_log_daily_monitorings.request_log_id', '=', 'request_logs.id')
|
||||||
|
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
|
||||||
|
->leftJoin('organizations', 'organizations.id', '=', 'request_logs.organization_id')
|
||||||
|
->select(
|
||||||
|
'members.member_id',
|
||||||
|
'members.name',
|
||||||
|
'members.birth_date',
|
||||||
|
'request_logs.type_of_member as member_type',
|
||||||
|
'members.members_effective_date AS startdate',
|
||||||
|
'members.members_expire_date AS enddate',
|
||||||
|
'request_logs.submission_date as addmision_date',
|
||||||
|
'organizations.name as provider',
|
||||||
|
'request_logs.organization_id',
|
||||||
|
'request_logs.code',
|
||||||
|
// Using a subquery to fetch medical_plan
|
||||||
|
DB::raw('(SELECT plan FROM request_log_medical_plan rdm WHERE rdm.request_log_daily_monitoring_id = request_log_daily_monitorings.id AND type = 1 LIMIT 1) as medical_plan'),
|
||||||
|
DB::raw('(SELECT plan FROM request_log_medical_plan rdm WHERE rdm.request_log_daily_monitoring_id = request_log_daily_monitorings.id AND type = 2 LIMIT 1) as non_medical_plan'),
|
||||||
|
'request_log_daily_monitorings.*'
|
||||||
|
)
|
||||||
|
->whereNull('request_logs.deleted_at') // Use whereNull() for checking NULL
|
||||||
|
->when($request->search, function ($q, $search) {
|
||||||
|
$q->where(function ($subQ) use ($search) {
|
||||||
|
$subQ->where('members.member_id', 'LIKE', "%{$search}%");
|
||||||
|
$subQ->orWhere('members.name', 'LIKE', "%{$search}%");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->when($startDate, function ($q) use ($startDate) {
|
||||||
|
$q->where('request_log_daily_monitorings.submission_date', '>=', $startDate);
|
||||||
|
})
|
||||||
|
->when($endDate, function ($q) use ($endDate) {
|
||||||
|
$q->where('request_log_daily_monitorings.submission_date', '<=', Carbon::parse($endDate)->addDay());
|
||||||
|
})
|
||||||
|
->orderBy('request_logs.created_at', 'desc')
|
||||||
|
->paginate();
|
||||||
|
|
||||||
|
return Helper::paginateResources(DailyMonitoringResource::collection($memberList));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Claim List - by member id
|
||||||
|
*/
|
||||||
|
public function GetClaimList(Request $request, $member_id)
|
||||||
|
{
|
||||||
|
$memberDetail = DB::table('members')
|
||||||
|
->select('id','member_id','name')
|
||||||
|
->where('member_id', $member_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$claimList = DB::table('request_logs')
|
||||||
|
->leftJoin('services', 'services.code', '=', 'request_logs.service_code')
|
||||||
|
->leftJoin('members', 'members.id', '=', 'request_logs.member_id')
|
||||||
|
->select('request_logs.id','request_logs.submission_date AS admission_date','request_logs.discharge_date','request_logs.code','services.name as service_name','request_logs.status','members.name', 'members.member_id')
|
||||||
|
->where('request_logs.service_code', 'IP')
|
||||||
|
->where('request_logs.deleted_at', null)
|
||||||
|
// ->where('request_logs.status_final_log', 'approved')
|
||||||
|
->where("request_logs.member_id", "=", $memberDetail->id)
|
||||||
|
->where("request_logs.organization_id", "=", $request->organization_id)
|
||||||
|
->when($request->search, function ($q, $search) {
|
||||||
|
$q->where('request_logs.code', 'LIKE', "%".$search."%");
|
||||||
|
})
|
||||||
|
->orderBy("request_logs.created_at", "desc")
|
||||||
|
// ->get()
|
||||||
|
->paginate();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => [
|
||||||
|
'member_detail'=> $memberDetail,
|
||||||
|
'claim_list' => $claimList,
|
||||||
|
]
|
||||||
|
],200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detail Monitoring List - by claim_code
|
||||||
|
*/
|
||||||
|
public function GetDetailMonitoringList(Request $request, $request_code)
|
||||||
|
{
|
||||||
|
// get id request log
|
||||||
|
$request_logs = DB::table('request_logs')
|
||||||
|
->select('id','organization_id')
|
||||||
|
->where('code', $request_code)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$detail_list = RequestDailyMonitoring::where('request_log_id', empty($request_logs) == false ? $request_logs->id : '')
|
||||||
|
->orderBy("submission_date", "desc")
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => [
|
||||||
|
'detail_list'=> $detail_list,
|
||||||
|
'organization_id' => $request_logs ? $request_logs->organization_id : 0
|
||||||
|
]
|
||||||
|
],200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetDetailMonitoringListbyID(Request $request, $id)
|
||||||
|
{
|
||||||
|
|
||||||
|
$detail = RequestDailyMonitoring::where('id', $id)
|
||||||
|
->orderBy("created_at", "desc")
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($detail) {
|
||||||
|
// Ubah menjadi array agar bisa dimodifikasi
|
||||||
|
$detailArray = $detail->toArray();
|
||||||
|
|
||||||
|
// Ubah nama key dari request_log_id menjadi log_id
|
||||||
|
$detailArray['log_code'] = $detailArray['request_log_id'];
|
||||||
|
unset($detailArray['request_log_id']);
|
||||||
|
} else {
|
||||||
|
$detailArray = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => $detailArray,
|
||||||
|
], 200);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function UpdateDetailMonitoringbyID(Request $request)
|
||||||
|
{
|
||||||
|
// validation rule
|
||||||
|
$validator = Validator::make($request->all(),[
|
||||||
|
'log_code' => 'required',
|
||||||
|
'reason' => 'required',
|
||||||
|
],$this->messages());
|
||||||
|
|
||||||
|
// validation error
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $validator->getMessageBag()
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// insert claim daily monitoring
|
||||||
|
$db_response = RequestDailyMonitoring::where('id', $request->id)
|
||||||
|
->update([
|
||||||
|
'request_log_id' => $request->log_code,
|
||||||
|
'submission_date' => $request->submission_date,
|
||||||
|
'subject' => $request->subject,
|
||||||
|
'object' => $request->objective,
|
||||||
|
'sistole' => $request->sistole,
|
||||||
|
'diastole' => $request->diastole,
|
||||||
|
'body_temperature' => $request->body_temperature,
|
||||||
|
'respiration_rate' => $request->respiration_rate,
|
||||||
|
'analysis' => $request->analysis,
|
||||||
|
'lab_date' => $request->lab_date,
|
||||||
|
'provider' => $request->provider,
|
||||||
|
'examination' => $request->examination,
|
||||||
|
'doctor_1' => $request->doctor_1,
|
||||||
|
'doctor_2' => $request->doctor_2,
|
||||||
|
'temp_diagnosis' => $request->temp_diagnosis,
|
||||||
|
'final_diagnosis' => $request->final_diagnosis,
|
||||||
|
'approval_pendamping' => $request->approval_pendamping,
|
||||||
|
'description' => $request->keterangan,
|
||||||
|
'note' => $request->catatan,
|
||||||
|
'reason' => $request->reason,
|
||||||
|
'created_by' => auth()->user()->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// cek medical plan
|
||||||
|
$num_medical_plan = 0;
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
if ($row['medical_plan_str']) {
|
||||||
|
$num_medical_plan++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($num_medical_plan == 0) {
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => [
|
||||||
|
'medical_plan' => ['medical plan harus diisi']
|
||||||
|
],
|
||||||
|
'data' => []
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
if ($request->medical_plan){
|
||||||
|
// delete medical plan
|
||||||
|
DB::table('request_log_medical_plan')
|
||||||
|
->where([
|
||||||
|
'request_log_daily_monitoring_id' => $request->id,
|
||||||
|
'type' => 1
|
||||||
|
])
|
||||||
|
->delete();
|
||||||
|
// insert medical plan
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
DB::table('request_log_medical_plan')->insert([
|
||||||
|
'request_log_daily_monitoring_id' => $request->id,
|
||||||
|
'plan' => $row['medical_plan_str'],
|
||||||
|
'type' => 1,
|
||||||
|
'created_at' => date('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->non_medikamentosa_plan){
|
||||||
|
// delete medical plan
|
||||||
|
DB::table('request_log_medical_plan')
|
||||||
|
->where([
|
||||||
|
'request_log_daily_monitoring_id' => $request->id,
|
||||||
|
'type' => 2
|
||||||
|
])
|
||||||
|
->delete();
|
||||||
|
// insert non medical plan
|
||||||
|
foreach ($request->non_medikamentosa_plan as $row) {
|
||||||
|
DB::table('request_log_medical_plan')->insert([
|
||||||
|
'request_log_daily_monitoring_id' => $request->id,
|
||||||
|
'plan' => $row['non_medikamentosa_plan_str'],
|
||||||
|
'type' => 2,
|
||||||
|
'created_at' => date('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert file result
|
||||||
|
if ($request->confirmation_medical_leter){
|
||||||
|
// $fileCurrents = File::where([
|
||||||
|
// 'fileable_id' => $request->id,
|
||||||
|
// 'type' => 'confirmation-medical-letter',
|
||||||
|
// ])->get();
|
||||||
|
// if ($fileCurrents){
|
||||||
|
// foreach($fileCurrents as $fileCurrent){
|
||||||
|
// if (Files::exists($fileCurrent->path)) {
|
||||||
|
// Files::delete();
|
||||||
|
// }
|
||||||
|
// File::find($fileCurrent->id)->delete();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
foreach ($request->confirmation_medical_leter as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $request->id,
|
||||||
|
'type' => 'confirmation-medical-letter',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($request->medical_action_letter){
|
||||||
|
// $fileCurrents = File::where([
|
||||||
|
// 'fileable_id' => $request->id,
|
||||||
|
// 'type' => 'medical-action-letter',
|
||||||
|
// ])->get();
|
||||||
|
// if ($fileCurrents){
|
||||||
|
// foreach($fileCurrents as $fileCurrent){
|
||||||
|
// if (Files::exists($fileCurrent->path)) {
|
||||||
|
// Files::delete();
|
||||||
|
// }
|
||||||
|
// File::find($fileCurrent->id)->delete();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
foreach ($request->medical_action_letter as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $request->id,
|
||||||
|
'type' => 'medical-action-letter',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
// $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($request->result){
|
||||||
|
// $fileCurrents = File::where([
|
||||||
|
// 'fileable_id' => $request->id,
|
||||||
|
// 'type' => 'laboratorium-result',
|
||||||
|
// ])->get();
|
||||||
|
// if ($fileCurrents){
|
||||||
|
// foreach($fileCurrents as $fileCurrent){
|
||||||
|
// if (Files::exists($fileCurrent->path)) {
|
||||||
|
// Files::delete();
|
||||||
|
// }
|
||||||
|
// File::find($fileCurrent->id)->delete();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
foreach ($request->result as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $request->id,
|
||||||
|
'type' => 'laboratorium-result',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => []
|
||||||
|
],200);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'data' => []
|
||||||
|
],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Detail Monitoring List
|
||||||
|
*/
|
||||||
|
public function AddDetailMonitoringList(Request $request, $claim_code)
|
||||||
|
{
|
||||||
|
$request->merge(['claim_code' => $claim_code]);
|
||||||
|
|
||||||
|
// validation rule
|
||||||
|
$validator = Validator::make($request->all(),[
|
||||||
|
'claim_code' => 'required|exists:claim_requests,code',
|
||||||
|
'subject' => 'required',
|
||||||
|
'sistole' => 'required|numeric',
|
||||||
|
'diastole' => 'required|numeric',
|
||||||
|
'body_temperature' => 'required|numeric',
|
||||||
|
'respiration_rate' => 'required|numeric',
|
||||||
|
'analysis' => 'required',
|
||||||
|
'complaints' => 'required',
|
||||||
|
'medical_plan' => 'required',
|
||||||
|
],$this->messages());
|
||||||
|
|
||||||
|
// validation error
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $validator->getMessageBag()
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get claim request
|
||||||
|
$claim_request = DB::table('claim_requests')
|
||||||
|
->select('id')
|
||||||
|
->where('code', $claim_code)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// get claim
|
||||||
|
$claim = DB::table('claims')
|
||||||
|
->select('id')
|
||||||
|
->where('claim_request_id', $claim_request->id)
|
||||||
|
->first();
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
// insert claim daily monitoring
|
||||||
|
$db_response = DailyMonitoring::create([
|
||||||
|
'claim_id' => $claim->id,
|
||||||
|
'subject' => $request->subject,
|
||||||
|
'objective' => $request->objective,
|
||||||
|
'sistole' => $request->sistole,
|
||||||
|
'diastole' => $request->diastole,
|
||||||
|
'body_temperature' => $request->body_temperature,
|
||||||
|
'respiration_rate' => $request->respiration_rate,
|
||||||
|
'analysis' => $request->analysis,
|
||||||
|
'complaints' => $request->complaints,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
// cek medical plan
|
||||||
|
$num_medical_plan = 0;
|
||||||
|
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
if ($row['medical_plan_str']) {
|
||||||
|
$num_medical_plan++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($num_medical_plan == 0) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => [
|
||||||
|
'medical_plan' => ['medical plan harus diisi']
|
||||||
|
],
|
||||||
|
'data' => []
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert medical plan
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
MedicalPlan::create([
|
||||||
|
'claim_daily_monitoring_id' => $db_response->id,
|
||||||
|
'plan' => $row['medical_plan_str'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => []
|
||||||
|
],200);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'data' => []
|
||||||
|
],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Detail Request LOG LIST
|
||||||
|
*/
|
||||||
|
public function AddDetailMonitoringListRequestLog(Request $request, $request_code)
|
||||||
|
{
|
||||||
|
$request->merge(['request_code' => $request_code]);
|
||||||
|
|
||||||
|
// validation rule
|
||||||
|
$validator = Validator::make($request->all(),[
|
||||||
|
'request_code' => 'required|exists:request_logs,code',
|
||||||
|
'subject' => 'required',
|
||||||
|
'submission_date' => 'required',
|
||||||
|
'body_temperature' => 'required',
|
||||||
|
'sistole' => 'required',
|
||||||
|
'diastole' => 'required',
|
||||||
|
'respiration_rate' => 'required',
|
||||||
|
'analysis' => 'required',
|
||||||
|
'medical_plan' => 'required',
|
||||||
|
'non_medikamentosa_plan' => 'required',
|
||||||
|
],$this->messages());
|
||||||
|
|
||||||
|
// validation error
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $validator->getMessageBag()
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get claim request
|
||||||
|
$request_log = DB::table('request_logs')
|
||||||
|
->select('id')
|
||||||
|
->where('code', $request_code)
|
||||||
|
->first();
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
// insert claim daily monitoring
|
||||||
|
$db_response = RequestDailyMonitoring::create([
|
||||||
|
'request_log_id' => $request_log->id,
|
||||||
|
'submission_date' => $request->submission_date,
|
||||||
|
'subject' => $request->subject,
|
||||||
|
'object' => $request->objective,
|
||||||
|
'sistole' => $request->sistole,
|
||||||
|
'diastole' => $request->diastole,
|
||||||
|
'body_temperature' => $request->body_temperature,
|
||||||
|
'respiration_rate' => $request->respiration_rate,
|
||||||
|
'analysis' => $request->analysis,
|
||||||
|
'lab_date' => $request->lab_date,
|
||||||
|
'provider' => $request->provider,
|
||||||
|
'examination' => $request->examination,
|
||||||
|
'created_by' => auth()->user()->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
// cek medical plan
|
||||||
|
$num_medical_plan = 0;
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
if ($row['medical_plan_str']) {
|
||||||
|
$num_medical_plan++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($num_medical_plan == 0) {
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => [
|
||||||
|
'medical_plan' => ['medical plan harus diisi']
|
||||||
|
],
|
||||||
|
'data' => []
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert medical plan
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
DB::table('request_log_medical_plan')->insert([
|
||||||
|
'request_log_daily_monitoring_id' => $db_response->id,
|
||||||
|
'plan' => $row['medical_plan_str'],
|
||||||
|
'type' => 1,
|
||||||
|
'created_at' => date('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert non medical plan
|
||||||
|
foreach ($request->non_medikamentosa_plan as $row) {
|
||||||
|
DB::table('request_log_medical_plan')->insert([
|
||||||
|
'request_log_daily_monitoring_id' => $db_response->id,
|
||||||
|
'plan' => $row['non_medikamentosa_plan_str'],
|
||||||
|
'type' => 2,
|
||||||
|
'created_at' => date('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert file result
|
||||||
|
if ($request->confirmation_medical_leter){
|
||||||
|
foreach ($request->confirmation_medical_leter as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $db_response->id,
|
||||||
|
'type' => 'confirmation-medical-letter',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($request->medical_action_letter){
|
||||||
|
foreach ($request->medical_action_letter as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $db_response->id,
|
||||||
|
'type' => 'medical-action-letter',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($request->result){
|
||||||
|
foreach ($request->result as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $db_response->id,
|
||||||
|
'type' => 'laboratorium-result',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => []
|
||||||
|
],200);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'data' => []
|
||||||
|
],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function AddListRequestLog(Request $request)
|
||||||
|
{
|
||||||
|
// validation rule
|
||||||
|
$validator = Validator::make($request->all(),[
|
||||||
|
'log_code' => 'required|exists:request_logs,id',
|
||||||
|
'subject' => 'required',
|
||||||
|
'submission_date' => 'required',
|
||||||
|
'body_temperature' => 'required',
|
||||||
|
'sistole' => 'required',
|
||||||
|
'diastole' => 'required',
|
||||||
|
'respiration_rate' => 'required',
|
||||||
|
'analysis' => 'required',
|
||||||
|
'medical_plan' => 'required',
|
||||||
|
'non_medikamentosa_plan' => 'required',
|
||||||
|
],$this->messages());
|
||||||
|
|
||||||
|
// validation error
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $validator->getMessageBag()
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get claim request
|
||||||
|
$request_log = DB::table('request_logs')
|
||||||
|
->select('id')
|
||||||
|
->where('id', $request->log_code)
|
||||||
|
->first();
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
// insert claim daily monitoring
|
||||||
|
$db_response = RequestDailyMonitoring::create([
|
||||||
|
'request_log_id' => $request->log_code,
|
||||||
|
'submission_date' => $request->submission_date,
|
||||||
|
'doctor_1' => $request->doctor_1,
|
||||||
|
'doctor_2' => $request->doctor_2,
|
||||||
|
'temp_diagnosis' => $request->temp_diagnosis,
|
||||||
|
'final_diagnosis' => $request->final_diagnosis,
|
||||||
|
'approval_pendamping' => $request->approval_pendamping,
|
||||||
|
'description' => $request->keterangan,
|
||||||
|
'note' => $request->catatan,
|
||||||
|
'subject' => $request->subject,
|
||||||
|
'object' => $request->objective,
|
||||||
|
'sistole' => $request->sistole,
|
||||||
|
'diastole' => $request->diastole,
|
||||||
|
'body_temperature' => $request->body_temperature,
|
||||||
|
'respiration_rate' => $request->respiration_rate,
|
||||||
|
'analysis' => $request->analysis,
|
||||||
|
'lab_date' => $request->lab_date,
|
||||||
|
'provider' => $request->provider,
|
||||||
|
'examination' => $request->examination,
|
||||||
|
'created_by' => auth()->user()->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
// cek medical plan
|
||||||
|
$num_medical_plan = 0;
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
if ($row['medical_plan_str']) {
|
||||||
|
$num_medical_plan++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($num_medical_plan == 0) {
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => [
|
||||||
|
'medical_plan' => ['medical plan harus diisi']
|
||||||
|
],
|
||||||
|
'data' => []
|
||||||
|
],400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert medical plan
|
||||||
|
foreach ($request->medical_plan as $row) {
|
||||||
|
DB::table('request_log_medical_plan')->insert([
|
||||||
|
'request_log_daily_monitoring_id' => $db_response->id,
|
||||||
|
'plan' => $row['medical_plan_str'],
|
||||||
|
'type' => 1,
|
||||||
|
'created_at' => date('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert non medical plan
|
||||||
|
foreach ($request->non_medikamentosa_plan as $row) {
|
||||||
|
DB::table('request_log_medical_plan')->insert([
|
||||||
|
'request_log_daily_monitoring_id' => $db_response->id,
|
||||||
|
'plan' => $row['non_medikamentosa_plan_str'],
|
||||||
|
'type' => 2,
|
||||||
|
'created_at' => date('Y-m-d'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert file result
|
||||||
|
if ($request->confirmation_medical_leter){
|
||||||
|
foreach ($request->confirmation_medical_leter as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $db_response->id,
|
||||||
|
'type' => 'confirmation-medical-letter',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($request->medical_action_letter){
|
||||||
|
foreach ($request->medical_action_letter as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $db_response->id,
|
||||||
|
'type' => 'medical-action-letter',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($request->result){
|
||||||
|
foreach ($request->result as $file) {
|
||||||
|
$name = 'labresult-' . uniqid();
|
||||||
|
$extension= $file->getClientOriginalExtension();
|
||||||
|
$orignalName = $file->getClientOriginalName();
|
||||||
|
$fileName = $name . '.' . $extension;
|
||||||
|
$path = $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
File::create([
|
||||||
|
'fileable_type' => 'App\Models\LaboratoriumResult',
|
||||||
|
'fileable_id' => $db_response->id,
|
||||||
|
'type' => 'laboratorium-result',
|
||||||
|
'name' => $name,
|
||||||
|
'original_name' => $orignalName,
|
||||||
|
'extension' => $extension,
|
||||||
|
'path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// $file->storeAs($this->path_for_store, $fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => []
|
||||||
|
],200);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'data' => []
|
||||||
|
],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Listing Daily Monitoring
|
||||||
|
*/
|
||||||
|
public function deleteDetailMonitoringListRequestLog(Request $request, $id)
|
||||||
|
{
|
||||||
|
$listDailyMonitoring = RequestDailyMonitoring::find($id);
|
||||||
|
$listDailyMonitoring->reason = $request->reason;
|
||||||
|
$listDailyMonitoring->save();
|
||||||
|
|
||||||
|
if (!$listDailyMonitoring) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => "Data not found.",
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$listDailyMonitoring->delete();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "Delete success",
|
||||||
|
'data' => $listDailyMonitoring
|
||||||
|
], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete File Daily Monitoring
|
||||||
|
*/
|
||||||
|
public function deleteFileDetailMonitoringListRequestLog(Request $request, $id){
|
||||||
|
$fileCurrent = File::where([
|
||||||
|
'id' => $id,
|
||||||
|
])->first();
|
||||||
|
if ($fileCurrent){
|
||||||
|
if (Files::exists($fileCurrent->path)) {
|
||||||
|
Files::delete();
|
||||||
|
}
|
||||||
|
$fileCurrent->deleted_at = now();
|
||||||
|
$fileCurrent->reason = $request->reason;
|
||||||
|
$fileCurrent->deleted_by = auth()->user()->id;
|
||||||
|
$fileCurrent->save();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "Delete success",
|
||||||
|
'data' => $fileCurrent
|
||||||
|
], 200);
|
||||||
|
} else {
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => "Data not found.",
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Status Request LOG
|
||||||
|
*/
|
||||||
|
public function UpdateListRequestLog(Request $request, $request_code)
|
||||||
|
{
|
||||||
|
// get claim request
|
||||||
|
$request_log = DB::table('request_logs')
|
||||||
|
->where('code', $request_code)
|
||||||
|
->update([
|
||||||
|
'discharge_date' => now(),
|
||||||
|
'updated_by' => auth()->user()->id,
|
||||||
|
'updated_at' => now()
|
||||||
|
]);
|
||||||
|
if ($request_log) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => "success",
|
||||||
|
'data' => []
|
||||||
|
], 200);
|
||||||
|
} else {
|
||||||
|
return response()->json([
|
||||||
|
'error' => true,
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'data' => []
|
||||||
|
],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,8 @@ use Modules\Internal\Http\Controllers\Api\FormulariumTemplateController;
|
|||||||
use Modules\Internal\Http\Controllers\Api\AuditTrailController;
|
use Modules\Internal\Http\Controllers\Api\AuditTrailController;
|
||||||
use Modules\Internal\Http\Controllers\Api\CorporateController;
|
use Modules\Internal\Http\Controllers\Api\CorporateController;
|
||||||
use Modules\Internal\Http\Controllers\Api\NavigationController;
|
use Modules\Internal\Http\Controllers\Api\NavigationController;
|
||||||
|
use Modules\Client\Http\Controllers\Api\DailyMonitoringController;
|
||||||
|
use Modules\Internal\Http\Controllers\Api\RequestLogController;
|
||||||
|
|
||||||
use Modules\Internal\Http\Controllers\Api\UserManagementController;
|
use Modules\Internal\Http\Controllers\Api\UserManagementController;
|
||||||
|
|
||||||
@@ -35,6 +37,8 @@ use Modules\Internal\Http\Controllers\Api\UserManagementController;
|
|||||||
|
|
||||||
Route::prefix('client')->group(function () {
|
Route::prefix('client')->group(function () {
|
||||||
|
|
||||||
|
Route::get('codeLog', [RequestLogController::class, 'codeLog']);
|
||||||
|
|
||||||
Route::controller(AuthController::class)->group(function () {
|
Route::controller(AuthController::class)->group(function () {
|
||||||
Route::post('login', 'login');
|
Route::post('login', 'login');
|
||||||
Route::post('verify-code', 'validateOtp');
|
Route::post('verify-code', 'validateOtp');
|
||||||
@@ -80,6 +84,15 @@ Route::prefix('client')->group(function () {
|
|||||||
Route::get('download-ecard/{member_id}', [CorporateMemberController::class, 'downloadEcard']);
|
Route::get('download-ecard/{member_id}', [CorporateMemberController::class, 'downloadEcard']);
|
||||||
Route::get('view_card/{member_id}', [CorporateMemberController::class, 'viewECard']);
|
Route::get('view_card/{member_id}', [CorporateMemberController::class, 'viewECard']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::get('memberlist', [DailyMonitoringController::class, 'GetMemberList']);
|
||||||
|
|
||||||
|
// Daily Monitoring
|
||||||
|
Route::prefix('daily_monitoring')->group(function () {
|
||||||
|
Route::get('detail/{claim_code}/list', [DailyMonitoringController::class, 'GetDetailMonitoringList']);
|
||||||
|
Route::get('detail/{id}/edit', [DailyMonitoringController::class, 'GetDetailMonitoringListbyID']);
|
||||||
|
});
|
||||||
|
|
||||||
Route::get('claims/{id}', [ClaimController::class, 'show']);
|
Route::get('claims/{id}', [ClaimController::class, 'show']);
|
||||||
|
|
||||||
Route::post('claim-requests', [ClaimRequestController::class, 'store'])->name('claim-requests.store');
|
Route::post('claim-requests', [ClaimRequestController::class, 'store'])->name('claim-requests.store');
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ class NavigationSeeder extends Seeder
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Daily Monitoring',
|
'title' => 'Daily Monitoring',
|
||||||
'path' => '/daily-monitoring',
|
'path' => '/daily_monitoring',
|
||||||
'permission' => 'daily-monitoring-list-client-portal'
|
'permission' => 'daily-monitoring-list-client-portal'
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ class PermissionTableSeeder extends Seeder
|
|||||||
'employee-data-list-client-portal',
|
'employee-data-list-client-portal',
|
||||||
'corporate-client-portal',
|
'corporate-client-portal',
|
||||||
'alarm-center-list-client-portal',
|
'alarm-center-list-client-portal',
|
||||||
|
'daily-monitoring-list-client-portal',
|
||||||
'formularium-list-client-portal',
|
'formularium-list-client-portal',
|
||||||
'case-management-client-portal',
|
'case-management-client-portal',
|
||||||
'service-monitoring-limit-client-portal',
|
'service-monitoring-limit-client-portal',
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ PORT=8083
|
|||||||
REACT_APP_HOST_API_URL="https://aso-api.linksehat.dev/api/client"
|
REACT_APP_HOST_API_URL="https://aso-api.linksehat.dev/api/client"
|
||||||
|
|
||||||
# VITE_API_URL="https://aso-api.linksehat.dev/api/client"
|
# VITE_API_URL="https://aso-api.linksehat.dev/api/client"
|
||||||
VITE_API_URL="https://aso-api.linksehat.dev/api/client"
|
# VITE_API_URL="https://aso-api.linksehat.dev/api/client"
|
||||||
|
|
||||||
|
VITE_API_URL="http://localhost:8000/api/client"
|
||||||
116
frontend/client-portal/src/@types/claims.ts
Executable file
116
frontend/client-portal/src/@types/claims.ts
Executable file
@@ -0,0 +1,116 @@
|
|||||||
|
import { Benefit } from "./corporates";
|
||||||
|
import { Member } from "./member";
|
||||||
|
|
||||||
|
export type ClaimRequest = {
|
||||||
|
id: number;
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
submission_date: string;
|
||||||
|
payment_type: string;
|
||||||
|
service_code: string;
|
||||||
|
claim_method: string;
|
||||||
|
service_type: string;
|
||||||
|
service_name: string;
|
||||||
|
code_provider: string;
|
||||||
|
file_condition: Files;
|
||||||
|
member: Member;
|
||||||
|
claim: {
|
||||||
|
organization: Organizations
|
||||||
|
}
|
||||||
|
provider_code: string,
|
||||||
|
organization: {
|
||||||
|
code: string
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Claims = {
|
||||||
|
id: number;
|
||||||
|
code: string;
|
||||||
|
plan: Plan;
|
||||||
|
payor_id: string;
|
||||||
|
corporate_id: string;
|
||||||
|
policy_number: string;
|
||||||
|
benefit_desc: string;
|
||||||
|
member: Member;
|
||||||
|
benefit: Benefit | boolean;
|
||||||
|
status: string;
|
||||||
|
claim_request: ClaimRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ClaimsEdit = {
|
||||||
|
id: number;
|
||||||
|
plan_id: string;
|
||||||
|
payor_id: string;
|
||||||
|
corporate_id: string;
|
||||||
|
policy_number: string;
|
||||||
|
member_id: string;
|
||||||
|
benefit_code: string;
|
||||||
|
benefit_desc: string;
|
||||||
|
amount_incurred: number;
|
||||||
|
amount_approved: number;
|
||||||
|
amount_not_approved: number;
|
||||||
|
excess_paid: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Files = {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Plan = {
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ClaimHistoryCare = {
|
||||||
|
id: number;
|
||||||
|
claim_id: number;
|
||||||
|
service_code: string;
|
||||||
|
admission_date: string;
|
||||||
|
discharge_date: string;
|
||||||
|
main_diagnosis_id: number;
|
||||||
|
main_diagnosis_name: string;
|
||||||
|
medical_record_number: string;
|
||||||
|
organization_id: number;
|
||||||
|
practitioner_id: number;
|
||||||
|
organization_name: string;
|
||||||
|
practitioner_name: string;
|
||||||
|
secondary_diagnosis_id: number[];
|
||||||
|
sign: string;
|
||||||
|
symptoms: string;
|
||||||
|
name: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Organizations = {
|
||||||
|
id: number;
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
address: string;
|
||||||
|
type: string;
|
||||||
|
lat: string;
|
||||||
|
lng: string;
|
||||||
|
phone: string;
|
||||||
|
timezone: string;
|
||||||
|
active: boolean | number;
|
||||||
|
province_id: number;
|
||||||
|
city_id: number;
|
||||||
|
district_id: number;
|
||||||
|
village_id: number;
|
||||||
|
postal_code: string;
|
||||||
|
description: string;
|
||||||
|
technology: string;
|
||||||
|
support_services: string;
|
||||||
|
merchant_code: string;
|
||||||
|
merchant_key: string;
|
||||||
|
image_url: string;
|
||||||
|
region_groups: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Import = {
|
||||||
|
result_file: {
|
||||||
|
url: string,
|
||||||
|
name: string,
|
||||||
|
total_success_row: number,
|
||||||
|
total_failed_row: number
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,457 @@
|
|||||||
|
/**
|
||||||
|
* Core
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
|
||||||
|
import { Box, Paper, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Stack, TextField, Button, Menu, Typography, ButtonGroup, } from "@mui/material";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types & Functions
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import { getDailyMonitoringList } from "../Model/Functions";
|
||||||
|
import { DailyMonitoringListType } from "../Model/Types";
|
||||||
|
import DailyMonitoringListRow from "./DailyMonitoringListRow";
|
||||||
|
import { LaravelPaginatedData, LaravelPaginatedDataDefault } from "../../../@types/paginated-data";
|
||||||
|
import { Grid } from "@mui/material";
|
||||||
|
import DataTable from '../../../components/LaravelTable';
|
||||||
|
import DownloadIcon from '@mui/icons-material/Download';
|
||||||
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
import UploadIcon from '@mui/icons-material/Upload';
|
||||||
|
import { MenuItem } from "@mui/material";
|
||||||
|
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||||
|
import axios from "../../../utils/axios";
|
||||||
|
import { DesktopDatePicker, LocalizationProvider } from "@mui/x-date-pickers";
|
||||||
|
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
|
||||||
|
import { fDate } from "../../../utils/formatTime";
|
||||||
|
import { LoadingButton } from "@mui/lab";
|
||||||
|
import { Import } from "../../../@types/claims";
|
||||||
|
import { HeadCell, Order } from '../../../@types/table';
|
||||||
|
import { fDateOnly } from "../../../utils/formatTime";
|
||||||
|
|
||||||
|
export default function DailyMonitoringList() {
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
// State
|
||||||
|
// --------------------
|
||||||
|
const [dataTableIsLoading, setDataTableLoading] = useState<boolean>(true);
|
||||||
|
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>(
|
||||||
|
LaravelPaginatedDataDefault
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tabel Style
|
||||||
|
// --------------------
|
||||||
|
const TableHeadStyle = {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
};
|
||||||
|
|
||||||
|
const [importResult, setImportResult] = useState<Import>(null);
|
||||||
|
// Load Data
|
||||||
|
// -------------------
|
||||||
|
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||||
|
setDataTableLoading(true);
|
||||||
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||||
|
|
||||||
|
const response = await axios.get('/memberlist', {params: filter})
|
||||||
|
setDataTableLoading(false);
|
||||||
|
setDataTableData(response.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyFilter = async (searchFilter: { search: string }) => {
|
||||||
|
await loadDataTableData(searchFilter);
|
||||||
|
setSearchParams(searchFilter);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = (event: ChangeEvent, value: number): void => {
|
||||||
|
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
setSearchParams(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------ handle params ----------------------------- */
|
||||||
|
const [appliedParams, setAppliedParams] = useState({});
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
searchParams: searchParams,
|
||||||
|
setSearchParams: setSearchParams,
|
||||||
|
appliedParams: appliedParams,
|
||||||
|
setAppliedParams: setAppliedParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------ handle order ------------------------------ */
|
||||||
|
const [order, setOrder] = useState<Order>('desc');
|
||||||
|
const [orderBy, setOrderBy] = useState('submission_date');
|
||||||
|
|
||||||
|
const orders = {
|
||||||
|
order: order,
|
||||||
|
setOrder: setOrder,
|
||||||
|
orderBy: orderBy,
|
||||||
|
setOrderBy: setOrderBy,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------- handle sort ------------------------------ */
|
||||||
|
const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => {
|
||||||
|
const isAsc = orders?.orderBy === property && orders?.order === 'asc';
|
||||||
|
|
||||||
|
orders?.setOrder(isAsc ? 'desc' : 'asc');
|
||||||
|
orders?.setOrderBy(property);
|
||||||
|
const parameters = Object.fromEntries([
|
||||||
|
...(params?.searchParams.entries() as IterableIterator<[string, string]>),
|
||||||
|
['order', isAsc ? 'desc' : 'asc'],
|
||||||
|
['orderBy', property],
|
||||||
|
]);
|
||||||
|
params?.setAppliedParams(parameters);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadDataTableData();
|
||||||
|
}, [appliedParams, searchParams, order, orderBy, setSearchParams])
|
||||||
|
|
||||||
|
function SearchInput(props: any) {
|
||||||
|
// SEARCH
|
||||||
|
const searchInput = useRef<HTMLInputElement>(null);
|
||||||
|
const [searchText, setSearchText] = useState('');
|
||||||
|
// Start Date
|
||||||
|
// con
|
||||||
|
|
||||||
|
const handleSearchChange = (event: any) => {
|
||||||
|
const newSearchText = event.target.value ?? '';
|
||||||
|
setSearchText(newSearchText);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const today = new Date(); // Default ke hari ini
|
||||||
|
|
||||||
|
const [startDate, setStartDate] = useState<Date | null>(today);
|
||||||
|
const [endDate, setEndDate] = useState<Date | null>(today);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Set nilai default saat pertama kali load jika searchParams kosong
|
||||||
|
const paramStartDate = searchParams.get('start_date');
|
||||||
|
const paramEndDate = searchParams.get('end_date');
|
||||||
|
|
||||||
|
if (paramStartDate) {
|
||||||
|
setStartDate(new Date(paramStartDate));
|
||||||
|
}
|
||||||
|
if (paramEndDate) {
|
||||||
|
setEndDate(new Date(paramEndDate));
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Trigger First Search
|
||||||
|
setSearchText(searchParams.get('search') ?? '');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form style={{ width: '100%' }}>
|
||||||
|
<Grid container spacing={2} >
|
||||||
|
<Grid item md={8}>
|
||||||
|
<TextField
|
||||||
|
id="search-input"
|
||||||
|
ref={searchInput}
|
||||||
|
label="Search"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
// handleSearchSubmit(event);
|
||||||
|
|
||||||
|
const filter = Object.fromEntries([
|
||||||
|
...searchParams.entries(),
|
||||||
|
['search', searchText],
|
||||||
|
]);
|
||||||
|
setSearchParams(filter);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
value={searchText}
|
||||||
|
placeholder='Search Code or Name...'
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
{/* Start Date */}
|
||||||
|
<Grid item md={2}>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DesktopDatePicker
|
||||||
|
label="Start Date"
|
||||||
|
inputFormat="dd/MM/yyyy"
|
||||||
|
value={startDate}
|
||||||
|
onChange={(value) => {
|
||||||
|
if (value) {
|
||||||
|
setStartDate(value);
|
||||||
|
const dateStr = fDateOnly(value);
|
||||||
|
const filter = Object.fromEntries([...searchParams.entries(), ['start_date', dateStr]]);
|
||||||
|
setSearchParams(filter);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
renderInput={(params) => <TextField {...params} variant="outlined" />}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* End Date */}
|
||||||
|
<Grid item md={2}>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DesktopDatePicker
|
||||||
|
label="End Date"
|
||||||
|
inputFormat="dd/MM/yyyy"
|
||||||
|
value={endDate}
|
||||||
|
onChange={(value) => {
|
||||||
|
if (value) {
|
||||||
|
setEndDate(value);
|
||||||
|
const dateStr = fDateOnly(value);
|
||||||
|
const filter = Object.fromEntries([...searchParams.entries(), ['end_date', dateStr]]);
|
||||||
|
setSearchParams(filter);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
renderInput={(params) => <TextField {...params} variant="outlined" />}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ImportForm(props: any) {
|
||||||
|
// IMPORT
|
||||||
|
// Create Button Menu
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
|
const createMenu = Boolean(anchorEl);
|
||||||
|
const importForm = useRef<HTMLInputElement>(null);
|
||||||
|
const [currentImportFileName, setCurrentImportFileName] = useState(null);
|
||||||
|
const [importLoading, setImportLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImportButton = () => {
|
||||||
|
if (importForm?.current) {
|
||||||
|
handleClose();
|
||||||
|
importForm.current ? importForm.current.click() : console.log('No File selected');
|
||||||
|
} else {
|
||||||
|
alert('No file selected');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancelImportButton = () => {
|
||||||
|
importForm.current.value = '';
|
||||||
|
importForm.current.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleImportChange = (event: any) => {
|
||||||
|
if (event.target.files[0]) {
|
||||||
|
setCurrentImportFileName(event.target.files[0].name);
|
||||||
|
} else {
|
||||||
|
setCurrentImportFileName(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpload = () => {
|
||||||
|
if (importForm.current?.files.length) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', importForm.current?.files[0]);
|
||||||
|
|
||||||
|
setImportLoading(true);
|
||||||
|
axios
|
||||||
|
.post(`customer-service/request/import`, formData)
|
||||||
|
.then((response) => {
|
||||||
|
handleCancelImportButton();
|
||||||
|
loadDataTableData();
|
||||||
|
setImportResult(response.data);
|
||||||
|
// alert('Succesfully read '+ response.data.total_successed_row + ' with ' + response.data.total_failed_row + ' failed rows');
|
||||||
|
setImportLoading(false);
|
||||||
|
})
|
||||||
|
.catch((response) => {
|
||||||
|
enqueueSnackbar(
|
||||||
|
'Looks like something went wrong. Please check your data and try again. ' +
|
||||||
|
response.message,
|
||||||
|
{ variant: 'error' }
|
||||||
|
);
|
||||||
|
setImportLoading(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar('No File Selected', { variant: 'warning' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleGetTemplate = (type :string) => {
|
||||||
|
axios.get('corporates/import-document-example/' + type)
|
||||||
|
.then((response) => {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = response.data.data.file_url;
|
||||||
|
link.setAttribute('download', response.data.data.file_name);
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
handleClose();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleGetData = (type :string) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id="file"
|
||||||
|
ref={importForm}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
onChange={handleImportChange}
|
||||||
|
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain"
|
||||||
|
/>
|
||||||
|
{!currentImportFileName && (
|
||||||
|
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
|
||||||
|
<SearchInput onSearch={applyFilter} />
|
||||||
|
<Menu
|
||||||
|
id="import-button"
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
open={createMenu}
|
||||||
|
onClose={handleClose}
|
||||||
|
MenuListProps={{
|
||||||
|
'aria-labelledby': 'basic-button',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MenuItem onClick={handleImportButton}>
|
||||||
|
<Typography variant='body2'>Import</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleGetTemplate('member');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant='body2'> Download Template</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem onClick={() => navigate(`/daily_monitoring/add_monitoring`)}>
|
||||||
|
<Typography variant='body2'>Tambah</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currentImportFileName && (
|
||||||
|
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
|
||||||
|
<ButtonGroup variant="outlined" aria-label="outlined button group" fullWidth>
|
||||||
|
<Button onClick={handleImportButton} fullWidth>
|
||||||
|
{currentImportFileName ?? 'No File Selected'}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleCancelImportButton}
|
||||||
|
size="small"
|
||||||
|
fullWidth={false}
|
||||||
|
sx={{ p: 1.8 }}
|
||||||
|
>
|
||||||
|
<CancelIcon color="error" />
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
|
||||||
|
<LoadingButton
|
||||||
|
id="upload-button"
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<UploadIcon />}
|
||||||
|
sx={{ p: 1.8 }}
|
||||||
|
onClick={handleUpload}
|
||||||
|
loading={importLoading}
|
||||||
|
>
|
||||||
|
Upload
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{importResult && (
|
||||||
|
<Stack direction={'row'} sx={{ px: 2, pb: 2 }}>
|
||||||
|
<Box sx={{ color: 'text.secondary' }}>
|
||||||
|
Last Import Result :{' '}
|
||||||
|
<Box sx={{ color: 'success.main', display: 'inline' }}>
|
||||||
|
{importResult.total_success_row ?? 0}
|
||||||
|
</Box>{' '}
|
||||||
|
Row Processed,{' '}
|
||||||
|
<Box sx={{ color: 'error.main', display: 'inline' }}>
|
||||||
|
{importResult.total_failed_row}
|
||||||
|
</Box>{' '}
|
||||||
|
Failed, Report :{' '}
|
||||||
|
<a href={importResult.result_file?.url ?? '#'}>
|
||||||
|
{importResult.result_file?.name ?? '-'}
|
||||||
|
</a>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TableContent(){
|
||||||
|
return (
|
||||||
|
<Table sx={{ minWidth: 250 }} size='medium' aria-label="collapsible table">
|
||||||
|
{/* Head Table */}
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={50} />
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Code</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Admission Date</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={150}>Member ID</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={'*'}>Name</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Tanggal Lahir</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Member Type</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Medical Plan</TableCell>
|
||||||
|
<TableCell style={TableHeadStyle} align="left" width={160}>Non Medical Plan</TableCell>
|
||||||
|
<TableCell align="left" width={"10"} />
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
|
||||||
|
{/* Body Table */}
|
||||||
|
{dataTableIsLoading ? (
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={7} align="center">Loading</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
) : dataTableData.data.length == 0 ? (
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={7} align="center">No Data</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
) : dataTableData.data && dataTableData.data.length > 0 ? (
|
||||||
|
<TableBody>
|
||||||
|
{dataTableData.data.map((row: DailyMonitoringListType, index) => (
|
||||||
|
<DailyMonitoringListRow key={index} number={index+1} row={row} />
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
</Table>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid container>
|
||||||
|
<Grid item sm={12}>
|
||||||
|
<ImportForm />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item sm={12} marginTop={2}>
|
||||||
|
<DataTable
|
||||||
|
isLoading={dataTableIsLoading}
|
||||||
|
lastRequest={0}
|
||||||
|
data={dataTableData}
|
||||||
|
handlePageChange={handlePageChange}
|
||||||
|
TableContent={<TableContent />}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Core
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router";
|
||||||
|
import { Box, Collapse, MenuItem, TableCell, TableRow, Stack } from "@mui/material";
|
||||||
|
import Visibility from '@mui/icons-material/Visibility';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
// - Global -
|
||||||
|
import Label from "../../../components/Label";
|
||||||
|
import TableMoreMenu from '../../../components/table/TableMoreMenu';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utils, Types, Functions
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import { fDate } from "../../../utils/formatTime";
|
||||||
|
import { DailyMonitoringListType } from "../Model/Types";
|
||||||
|
import { Edit } from "@mui/icons-material";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
row: DailyMonitoringListType,
|
||||||
|
number: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DailyMonitoringListRow ({ ...props }: Props) {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
|
||||||
|
<TableRow hover sx={{ '& > td': { borderBottom: '1' } }}>
|
||||||
|
<TableCell align="left" />
|
||||||
|
<TableCell align="left">{props.row.code}</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Label
|
||||||
|
variant="ghost"
|
||||||
|
color="default"
|
||||||
|
>
|
||||||
|
{props.row.addmision_date ? fDate(props.row.addmision_date) : '-'}
|
||||||
|
</Label>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{props.row.member_id}</TableCell>
|
||||||
|
<TableCell align="left">{props.row.name}</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
<Label
|
||||||
|
variant="ghost"
|
||||||
|
color="default"
|
||||||
|
>
|
||||||
|
{props.row.birth_date ? fDate(props.row.birth_date) : '-'}
|
||||||
|
</Label>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{props.row.member_type}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{props.row.medical_plan}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
|
{props.row.non_medical_plan}
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
|
<TableCell align="right" onClick={(e) => e.stopPropagation()}>
|
||||||
|
<Stack direction="row" justifyContent="flex-end" spacing={1}>
|
||||||
|
<TableMoreMenu actions={
|
||||||
|
<>
|
||||||
|
<MenuItem onClick={() => navigate(`/daily_monitoring/${props.row.member_id}/claims/${props.row.code}/list_monitoring`)}>
|
||||||
|
<Visibility />
|
||||||
|
View
|
||||||
|
</MenuItem>
|
||||||
|
</>
|
||||||
|
} />
|
||||||
|
</Stack>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,526 @@
|
|||||||
|
/**
|
||||||
|
* Core
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { useFieldArray, useForm } from 'react-hook-form';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { Box, IconButton, Typography, Grid, Card, List, ListItem, Stack, Autocomplete, TextField, Button } from '@mui/material';
|
||||||
|
import { LoadingButton } from "@mui/lab";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
// - Global -
|
||||||
|
import Page from '../../../components/Page';
|
||||||
|
import Label from "../../../components/Label";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icon
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import ArrowBackIosNew from '@mui/icons-material/ArrowBackIosNew';
|
||||||
|
import FiberManualRecord from '@mui/icons-material/FiberManualRecord';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utils, Types, Functions
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import { fDate, fDateOnly } from '../../../utils/formatTime';
|
||||||
|
import { getMonitoringDetailList } from '../Model/Functions';
|
||||||
|
import { getOrganizationId } from '../Model/Functions';
|
||||||
|
import { DetailMonitoringListType } from '../Model/Types';
|
||||||
|
import TableMoreMenu from '../../../components/table/TableMoreMenu';
|
||||||
|
import { MenuItem } from '@mui/material';
|
||||||
|
import { Delete, DeleteForever, Edit, LoopOutlined } from '@mui/icons-material';
|
||||||
|
import MuiDialog from '../../../components/MuiDialog';
|
||||||
|
import { DialogActions } from '@mui/material';
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
import { escape } from 'lodash';
|
||||||
|
|
||||||
|
|
||||||
|
export default function DetailMonitoringList() {
|
||||||
|
const { member_id, claim_code } = useParams();
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const pageTitle = claim_code??'_ _ _ _';
|
||||||
|
|
||||||
|
// State
|
||||||
|
// --------------------
|
||||||
|
const [detailMonitoringList, setDetailMonitoringList] = useState<DetailMonitoringListType[]>();
|
||||||
|
const [organizationId, setOrganizationId] = useState<number|undefined>();
|
||||||
|
|
||||||
|
const [openDialog, setOpenDialog] = useState<boolean>(false)
|
||||||
|
|
||||||
|
// Use Effect
|
||||||
|
// --------------------
|
||||||
|
useEffect(() => {
|
||||||
|
loadDataTableData();
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// Dialog
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
const [selectedReason, setSelectedReason] = useState({value:'-', label:''});
|
||||||
|
const reason = [
|
||||||
|
{ value: 'Wrong Setting', label: 'Wrong Setting' },
|
||||||
|
{ value: 'Hospital Request', label: 'Hospital Request' }
|
||||||
|
];
|
||||||
|
const [error, setError] = useState('');
|
||||||
|
const [id, setId] = useState<null|number>(null);
|
||||||
|
const [id_file, setIdFile] = useState<null|number>(null);
|
||||||
|
|
||||||
|
const handleCloseDialog = () => {
|
||||||
|
setOpenDialog(false);
|
||||||
|
}
|
||||||
|
const handleDelete = () => {
|
||||||
|
if(selectedReason.value != '-'){
|
||||||
|
const parameters = {
|
||||||
|
'reason' : selectedReason.value
|
||||||
|
}
|
||||||
|
if (id){
|
||||||
|
const response = axios.get(`case_management/daily_monitoring/detail/${id}/delete`, {
|
||||||
|
params: { ...parameters },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.error){
|
||||||
|
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
|
||||||
|
window.location.reload();
|
||||||
|
setOpenDialog(false)
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar('Claim Request Updated Error!', { variant: 'error' });
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
axios.get(`case_management/daily_monitoring/detail/${id_file}/delete-file`, {
|
||||||
|
params: { ...parameters },
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.error) {
|
||||||
|
enqueueSnackbar('File Successfully deleted!', { variant: 'success' });
|
||||||
|
window.location.reload();
|
||||||
|
setOpenDialog(false);
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar('Deleted File Error!', { variant: 'error' });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setError('Please select a reason')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleEdit = (id:number|undefined) => {
|
||||||
|
navigate(`/case_management/daily_monitoring/${member_id}/claims/${claim_code}/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getContent = () => (
|
||||||
|
<Stack spacing={1} marginTop={2}>
|
||||||
|
<Typography variant="subtitle2">Are you sure to delete this {id_file ? 'File ' : '' } Daily Monitoring ?</Typography>
|
||||||
|
<Grid item xs={12} md={12} marginTop={4}>
|
||||||
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
|
<Typography variant="subtitle1" marginY={2}>Reason for Delete*</Typography>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom2}>
|
||||||
|
<Autocomplete
|
||||||
|
options={reason}
|
||||||
|
getOptionLabel={(option) => option.label}
|
||||||
|
fullWidth
|
||||||
|
value={selectedReason}
|
||||||
|
onChange={(event, newValue) => {
|
||||||
|
setSelectedReason(newValue);
|
||||||
|
// Validasi jika newValue adalah null
|
||||||
|
if (!newValue) {
|
||||||
|
setError('Please select a reason');
|
||||||
|
} else {
|
||||||
|
setError('');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
label="Reason for Delete"
|
||||||
|
variant="outlined"
|
||||||
|
name='reason'
|
||||||
|
error={Boolean(error)} // Menampilkan error jika ada
|
||||||
|
helperText={error} // Menampilkan pesan kesalahan
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
||||||
|
<Button color="primary" variant="contained" onClick={() => handleDelete()}>Delete</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Load Data
|
||||||
|
// -------------------
|
||||||
|
const loadDataTableData = async () => {
|
||||||
|
const response = await getMonitoringDetailList(claim_code??'');
|
||||||
|
const organization_id = await getOrganizationId(claim_code??'');
|
||||||
|
|
||||||
|
setDetailMonitoringList(response);
|
||||||
|
setOrganizationId(organization_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderHTML(data: string) {
|
||||||
|
return (
|
||||||
|
<div style={{ marginLeft: 20 }}
|
||||||
|
dangerouslySetInnerHTML={{ __html: data }} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title={pageTitle} sx={{ px: 2 }}>
|
||||||
|
<Grid container gap={6}>
|
||||||
|
{/* back button */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<IconButton size='large' color='inherit' onClick={() => navigate(`/daily_monitoring`)} >
|
||||||
|
<ArrowBackIosNew/>
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<Typography variant="h5" sx={{ marginLeft: '24px' }}>
|
||||||
|
{pageTitle}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* tabel claims */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container gap={4} sx={{ px: 2 }}>
|
||||||
|
{
|
||||||
|
detailMonitoringList?.map((row, index) => {
|
||||||
|
return (
|
||||||
|
<Grid key={index} item xs={12}>
|
||||||
|
<Card sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '30px', py: '24px'}}>
|
||||||
|
{/* card header */}
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
pb: '20px',
|
||||||
|
mb: '20px',
|
||||||
|
borderBottom: '1px solid rgba(0,0,0,0.125)',
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Label variant="ghost" color="default">
|
||||||
|
{row.submission_date ? fDate(row.submission_date) : '-'}
|
||||||
|
</Label>
|
||||||
|
|
||||||
|
{row.discharge_date ? (
|
||||||
|
<Label
|
||||||
|
variant="ghost"
|
||||||
|
color="success"
|
||||||
|
sx={{ position: 'absolute', top: 0, right: 0 }}
|
||||||
|
>
|
||||||
|
Close Monitoring
|
||||||
|
</Label>
|
||||||
|
) : (
|
||||||
|
<Label
|
||||||
|
variant="ghost"
|
||||||
|
color="warning"
|
||||||
|
sx={{ position: 'absolute', top: 0, right: 0 }}
|
||||||
|
>
|
||||||
|
On Monitoring
|
||||||
|
</Label>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
{/* card body */}
|
||||||
|
<Grid container gap={4}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container gap={1}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Subject :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
{renderHTML(row.subject)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container gap={1}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Object :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} paddingY={2}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
{renderHTML(row.object)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
Body Temperature
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2">
|
||||||
|
{row.body_temperature} Cel
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
Sistole
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2">
|
||||||
|
{row.sistole} mm[Hg]
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
Diastole
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2">
|
||||||
|
{row.diastole} mm[Hg]
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
Respiration Rate
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2">
|
||||||
|
{row.respiration_rate} / min
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container gap={1}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Analysis :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
{renderHTML(row.analysis)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container gap={1}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Medical Plan :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<List sx={{ color: 'GrayText' }}>
|
||||||
|
{
|
||||||
|
row.medical_plan?.map((data, index) => {
|
||||||
|
return (
|
||||||
|
<ListItem key={index}>
|
||||||
|
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} /> {renderHTML(data.medical_plan_str)}
|
||||||
|
</ListItem>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</List>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container gap={1}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Non Medikamentosa Plan :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<List sx={{ color: 'GrayText' }}>
|
||||||
|
{
|
||||||
|
row.non_medikamentosa_plan?.map((data, index) => {
|
||||||
|
return (
|
||||||
|
<ListItem key={index}>
|
||||||
|
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} /> {renderHTML(data.non_medikamentosa_plan_str)}
|
||||||
|
</ListItem>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</List>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container gap={1}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Laboratorium Result :
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Date
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
{ row.lab_date != null ? fDate(row.lab_date) : '-'}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Location
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
{row.provider != null ? row.provider : '-' }
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Examination
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" color={"GrayText"}>
|
||||||
|
{row.examination != null ? renderHTML(row.examination) : '-' }
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Document Confirmation Medical Letter:
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<List>
|
||||||
|
{row.document?.map((data, index) => (
|
||||||
|
data.type === 'confirmation-medical-letter' ? (
|
||||||
|
<ListItem key={index} sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
|
<div sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} />
|
||||||
|
<a
|
||||||
|
href={data.path}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{data.file_name}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</ListItem>
|
||||||
|
) : null
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Document Medical Action Letter:
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<List>
|
||||||
|
{row.document?.map((data, index) => (
|
||||||
|
data.type === 'medical-action-letter' ? (
|
||||||
|
<ListItem key={index} sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
|
<div sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} />
|
||||||
|
<a
|
||||||
|
href={data.path}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{data.file_name}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</ListItem>
|
||||||
|
) : null
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="body1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
Document Examination Result:
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<List>
|
||||||
|
{row.document?.map((data, index) => (
|
||||||
|
data.type === 'laboratorium-result' ? (
|
||||||
|
<ListItem key={index} sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
|
<div sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<FiberManualRecord sx={{ fontSize: '8px', mr: '10px' }} />
|
||||||
|
<a
|
||||||
|
href={data.path}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{data.file_name}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</ListItem>
|
||||||
|
) : null
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Dialog Delete */}
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: id_file ? "Delete File Daily Monitoring" : "Delete Daily Monitoring"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="xs"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
178
frontend/client-portal/src/pages/DailyMonitoring/Model/Functions.ts
Executable file
178
frontend/client-portal/src/pages/DailyMonitoring/Model/Functions.ts
Executable file
@@ -0,0 +1,178 @@
|
|||||||
|
import axios from '../../../utils/axios';
|
||||||
|
import { makeFormData } from '../../../utils/jsonToFormData';
|
||||||
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
import { DailyMonitoringListType, DetailMonitoringListType, ResponseListingClaimType } from "./Types";
|
||||||
|
import { fDate, fDateOnly } from '../../../utils/formatTime';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listing Daily Monitoring
|
||||||
|
*/
|
||||||
|
export const getDailyMonitoringList = async ( param: any) => {
|
||||||
|
const response = await axios.get('/case_management/memberlist', {params: param})
|
||||||
|
.then((res) =>{
|
||||||
|
return res.data;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listing Claim
|
||||||
|
*/
|
||||||
|
export const getClaimList = async ( member_id: string ): Promise<ResponseListingClaimType> => {
|
||||||
|
const response = await axios.get(`/case_management/claimlist/${member_id}`)
|
||||||
|
.then((res) =>{
|
||||||
|
return res.data.data;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Monitoring Detail
|
||||||
|
*/
|
||||||
|
export const AddMonitoringDetail = async ( claim_code: string,data: DetailMonitoringListType ): Promise<boolean> => {
|
||||||
|
data.lab_date = data.lab_date != '' && data.lab_date != null ? fDateOnly(data.lab_date) : '';
|
||||||
|
data.submission_date = data.submission_date != '' && data.submission_date != null ? fDateOnly(data.submission_date) : '';
|
||||||
|
|
||||||
|
const formData = makeFormData({...data});
|
||||||
|
|
||||||
|
const response = await axios.post(`/daily_monitoring/add-request`, formData)
|
||||||
|
.then((res) =>{
|
||||||
|
enqueueSnackbar(res.data.message, {
|
||||||
|
variant: 'success',
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
if (res.response.status == 400) {
|
||||||
|
let arr_message = res.response.data.message;
|
||||||
|
|
||||||
|
for (const key in arr_message) {
|
||||||
|
enqueueSnackbar(arr_message[key][0], {
|
||||||
|
variant: 'warning',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Monitoring Detail List
|
||||||
|
*/
|
||||||
|
export const getMonitoringDetailList = async ( claim_code: string ): Promise<DetailMonitoringListType[]> => {
|
||||||
|
const response = await axios.get(`/daily_monitoring/detail/${claim_code}/list`)
|
||||||
|
.then((res) =>{
|
||||||
|
return res.data.data.detail_list;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Monitoring Detail List
|
||||||
|
*/
|
||||||
|
export const getOrganizationId = async ( claim_code: string ): Promise<number> => {
|
||||||
|
const response = await axios.get(`/daily_monitoring/detail/${claim_code}/list`)
|
||||||
|
.then((res) =>{
|
||||||
|
return res.data.data.organization_id;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get detail monitoring
|
||||||
|
*/
|
||||||
|
export const getMonitoringDetailById = async ( id: string) => {
|
||||||
|
const response = await axios.get(`/daily_monitoring/detail/${id}/edit`)
|
||||||
|
.then((res) =>{
|
||||||
|
return res.data.data;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update detail monitoring
|
||||||
|
*/
|
||||||
|
export const UpdateMonitoringDetail = async (data: DetailMonitoringListType) => {
|
||||||
|
data.lab_date = data.lab_date != '' && data.lab_date != null ? fDateOnly(data.lab_date) : '';
|
||||||
|
data.submission_date = data.submission_date != '' && data.submission_date != null ? fDateOnly(data.submission_date) : '';
|
||||||
|
|
||||||
|
const formData = makeFormData({...data});
|
||||||
|
|
||||||
|
const response = await axios.post(`/daily_monitoring/detail/update-request`, formData)
|
||||||
|
.then((res) =>{
|
||||||
|
enqueueSnackbar(res.data.message, {
|
||||||
|
variant: 'success',
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
if (res.response.status == 400) {
|
||||||
|
let arr_message = res.response.data.message;
|
||||||
|
|
||||||
|
for (const key in arr_message) {
|
||||||
|
enqueueSnackbar(arr_message[key][0], {
|
||||||
|
variant: 'warning',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enqueueSnackbar("server error !", {
|
||||||
|
variant: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
120
frontend/client-portal/src/pages/DailyMonitoring/Model/Types.ts
Executable file
120
frontend/client-portal/src/pages/DailyMonitoring/Model/Types.ts
Executable file
@@ -0,0 +1,120 @@
|
|||||||
|
/**
|
||||||
|
* List Daily Monitoring
|
||||||
|
*/
|
||||||
|
export type DailyMonitoringListType = {
|
||||||
|
member_id : string,
|
||||||
|
member_type : string,
|
||||||
|
birth_date : string,
|
||||||
|
name : string,
|
||||||
|
start_date : string,
|
||||||
|
end_date : string,
|
||||||
|
description : string,
|
||||||
|
doctor_1 : string,
|
||||||
|
doctor_2 : string,
|
||||||
|
temp_diagnosis : string,
|
||||||
|
final_diagnosis : string,
|
||||||
|
approval_pendamping : string,
|
||||||
|
note : string,
|
||||||
|
addmision_date : string,
|
||||||
|
provider : string,
|
||||||
|
organization_id : number,
|
||||||
|
medical_plan : string,
|
||||||
|
non_medical_plan : string,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response Listing Claim
|
||||||
|
*/
|
||||||
|
export type ResponseListingClaimType = {
|
||||||
|
member_detail : MemberDetailType,
|
||||||
|
claim_list : ClaimListType[],
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Member Detail
|
||||||
|
*/
|
||||||
|
export type MemberDetailType = {
|
||||||
|
id : string,
|
||||||
|
member_id : string,
|
||||||
|
name : string,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Claim
|
||||||
|
*/
|
||||||
|
export type ClaimListType = {
|
||||||
|
claim_id : number,
|
||||||
|
admission_date : string,
|
||||||
|
discharge_date : string,
|
||||||
|
claim_code : string,
|
||||||
|
name : string,
|
||||||
|
code : string,
|
||||||
|
service_name : string,
|
||||||
|
claim_status : string,
|
||||||
|
service_type : string,
|
||||||
|
member_id : string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detail Monitoring List
|
||||||
|
*/
|
||||||
|
export type DetailMonitoringListType = {
|
||||||
|
id : number|null,
|
||||||
|
claim_id : string|null,
|
||||||
|
log_code : string|null,
|
||||||
|
request_log_id : string|null,
|
||||||
|
claim_code : string|undefined,
|
||||||
|
doctor_1 : string|undefined,
|
||||||
|
doctor_2 : string|undefined,
|
||||||
|
temp_diagnosis : string|undefined,
|
||||||
|
final_diagnosis : string|undefined,
|
||||||
|
approval_pendamping : string|undefined,
|
||||||
|
keterangan : string|undefined,
|
||||||
|
catatan : string|undefined,
|
||||||
|
description : string|undefined,
|
||||||
|
note : string|undefined,
|
||||||
|
subject : string|undefined,
|
||||||
|
object : string|undefined,
|
||||||
|
objective : string|undefined,
|
||||||
|
body_temperature: string|undefined,
|
||||||
|
respiration_rate: string|undefined,
|
||||||
|
sistole : string|undefined,
|
||||||
|
diastole : string|undefined
|
||||||
|
analysis : string|undefined,
|
||||||
|
complaints : string|undefined,
|
||||||
|
submission_date : string|undefined,
|
||||||
|
discharge_date : string|undefined,
|
||||||
|
lab_date : string|undefined,
|
||||||
|
provider : string|undefined,
|
||||||
|
examination : string|undefined,
|
||||||
|
reason : string|undefined,
|
||||||
|
medical_plan : MedicalPlanStrType[],
|
||||||
|
non_medikamentosa_plan : NonMedikamentosaPlanType[],
|
||||||
|
confirmation_medical_leter : files[],
|
||||||
|
medical_action_letter : files[],
|
||||||
|
result : files[],
|
||||||
|
document : document[],
|
||||||
|
created_at : string|null
|
||||||
|
data : {
|
||||||
|
organization_id : number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MedicalPlanStrType = {
|
||||||
|
medical_plan_str: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NonMedikamentosaPlanType = {
|
||||||
|
non_medikamentosa_plan_str: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type files = {
|
||||||
|
file: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type document = {
|
||||||
|
id: number
|
||||||
|
file_name: string,
|
||||||
|
path: string,
|
||||||
|
type: string
|
||||||
|
}
|
||||||
48
frontend/client-portal/src/pages/DailyMonitoring/index.tsx
Executable file
48
frontend/client-portal/src/pages/DailyMonitoring/index.tsx
Executable file
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Core
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
import { Box, Grid } from '@mui/material';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components
|
||||||
|
* ============================================
|
||||||
|
*/
|
||||||
|
// - Global -
|
||||||
|
import Page from '../../components/Page';
|
||||||
|
import HeaderBreadcrumbs from "../../components/HeaderBreadcrumbs";
|
||||||
|
// - Local -
|
||||||
|
import DailyMonitoringList from './Components/DailyMonitoringList';
|
||||||
|
|
||||||
|
export default function DailyMonitoring() {
|
||||||
|
const pageTitle = "Daily Monitoring";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title={ pageTitle } sx={{ px: 2 }}>
|
||||||
|
<Grid container>
|
||||||
|
{/* page header */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={ pageTitle }
|
||||||
|
sx={{ px: 1 }}
|
||||||
|
links={[
|
||||||
|
{
|
||||||
|
name: 'Dashboard',
|
||||||
|
href: '/dashboard',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: pageTitle,
|
||||||
|
href: '/daily_monitoring',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* tabel daily monitoring */}
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<DailyMonitoringList />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -117,7 +117,26 @@ export default function Router() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/daily_monitoring',
|
||||||
|
element: (
|
||||||
|
<AuthProvider>
|
||||||
|
<AuthGuard>
|
||||||
|
<DashboardLayout />
|
||||||
|
</AuthGuard>
|
||||||
|
</AuthProvider>
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
element: <DailyMonitoring />,
|
||||||
|
index: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':member_id/claims/:claim_code/list_monitoring',
|
||||||
|
element: <DetailMonitoringList />
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/claim-submit',
|
path: '/claim-submit',
|
||||||
element: (
|
element: (
|
||||||
@@ -463,3 +482,7 @@ const UserRole = Loadable(lazy(() => import('../pages/UserManagement/UserRole/In
|
|||||||
const UserRoleCreate = Loadable(lazy(() => import('../pages/UserManagement/UserRole/CreateUpdate')));
|
const UserRoleCreate = Loadable(lazy(() => import('../pages/UserManagement/UserRole/CreateUpdate')));
|
||||||
const UserAccess = Loadable(lazy(() => import('../pages/UserManagement/UserAccess/Index')));
|
const UserAccess = Loadable(lazy(() => import('../pages/UserManagement/UserAccess/Index')));
|
||||||
const UserAccessCreate = Loadable(lazy(() => import('../pages/UserManagement/UserAccess/CreateUpdate')));
|
const UserAccessCreate = Loadable(lazy(() => import('../pages/UserManagement/UserAccess/CreateUpdate')));
|
||||||
|
|
||||||
|
// Daily Monitoring
|
||||||
|
const DailyMonitoring = Loadable(lazy(() => import('../pages/DailyMonitoring/index')))
|
||||||
|
const DetailMonitoringList = Loadable(lazy(() => import('../pages/DailyMonitoring/Components/DetailMonitoringList')))
|
||||||
@@ -37,6 +37,10 @@ export function fPostFormat(date: Date | string | number, dateFormat = 'yyyy-MM-
|
|||||||
return format(new Date(date), dateFormat);
|
return format(new Date(date), dateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fDateOnly(date: Date | string | number) {
|
||||||
|
return format(new Date(date), 'yyyy-MM-dd');
|
||||||
|
}
|
||||||
|
|
||||||
// export function fDateString(date) {
|
// export function fDateString(date) {
|
||||||
// const dateObj = parseISO(date);
|
// const dateObj = parseISO(date);
|
||||||
// const formattedDate = format(dateObj, 'dd MMMM yyyy');
|
// const formattedDate = format(dateObj, 'dd MMMM yyyy');
|
||||||
|
|||||||
Reference in New Issue
Block a user