Merge remote-tracking branch 'origin/staging' into origin/production
This commit is contained in:
@@ -380,9 +380,9 @@ class ClaimController extends Controller
|
|||||||
DB::raw('
|
DB::raw('
|
||||||
(Select persons.nik FROM persons WHERE persons.id = members.person_id LIMIT 1) AS nik
|
(Select persons.nik FROM persons WHERE persons.id = members.person_id LIMIT 1) AS nik
|
||||||
'),
|
'),
|
||||||
DB::raw('
|
// DB::raw('
|
||||||
"LinkSehat" AS penjamin
|
// "LinkSehat" AS penjamin
|
||||||
'),
|
// '),
|
||||||
DB::raw('
|
DB::raw('
|
||||||
(Select corporates.name FROM corporates
|
(Select corporates.name FROM corporates
|
||||||
LEFT JOIN corporate_employees ON corporate_employees.corporate_id = corporates.id
|
LEFT JOIN corporate_employees ON corporate_employees.corporate_id = corporates.id
|
||||||
@@ -426,6 +426,18 @@ class ClaimController extends Controller
|
|||||||
)
|
)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
//get penjamin
|
||||||
|
$penjamin = 'LinkSehat';
|
||||||
|
if(!empty($dataRumahSakit->corporate_id_partner))
|
||||||
|
{
|
||||||
|
$corporate_id_partners = explode(',', $dataRumahSakit->corporate_id_partner);
|
||||||
|
$valueToCheck = $dataMember->id_perusahaan;
|
||||||
|
|
||||||
|
if (in_array($valueToCheck, $corporate_id_partners)) {
|
||||||
|
$penjamin = $dataMember->nama_perusahaan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Nama Karyawan
|
//Nama Karyawan
|
||||||
$data['namaKaryawan'] = '';
|
$data['namaKaryawan'] = '';
|
||||||
if($dataMember->principal_id)
|
if($dataMember->principal_id)
|
||||||
@@ -480,7 +492,7 @@ class ClaimController extends Controller
|
|||||||
!empty($dataMember->name) ? $dataMember->name : '',
|
!empty($dataMember->name) ? $dataMember->name : '',
|
||||||
$data['namaKaryawan'],
|
$data['namaKaryawan'],
|
||||||
!empty($dataMember->code_plan) ? $dataMember->code_plan : '',
|
!empty($dataMember->code_plan) ? $dataMember->code_plan : '',
|
||||||
'LinkSehat',
|
$penjamin,
|
||||||
!empty($dataMember->nama_perusahaan) ? $dataMember->nama_perusahaan : '',
|
!empty($dataMember->nama_perusahaan) ? $dataMember->nama_perusahaan : '',
|
||||||
!empty($dataMember->no_polis) ? $dataMember->no_polis : '',
|
!empty($dataMember->no_polis) ? $dataMember->no_polis : '',
|
||||||
($firtIndex == $index ? $item->tot_bill : ''),
|
($firtIndex == $index ? $item->tot_bill : ''),
|
||||||
@@ -513,7 +525,7 @@ class ClaimController extends Controller
|
|||||||
!empty($dataMember->name) ? $dataMember->name : '',
|
!empty($dataMember->name) ? $dataMember->name : '',
|
||||||
$data['namaKaryawan'],
|
$data['namaKaryawan'],
|
||||||
!empty($dataMember->code_plan) ? $dataMember->code_plan : '',
|
!empty($dataMember->code_plan) ? $dataMember->code_plan : '',
|
||||||
'LinkSehat',
|
$penjamin,
|
||||||
!empty($dataMember->nama_perusahaan) ? $dataMember->nama_perusahaan : '',
|
!empty($dataMember->nama_perusahaan) ? $dataMember->nama_perusahaan : '',
|
||||||
!empty($dataMember->no_polis) ? $dataMember->no_polis : '',
|
!empty($dataMember->no_polis) ? $dataMember->no_polis : '',
|
||||||
'',
|
'',
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ use App\Helpers\Helper;
|
|||||||
use App\Models\ClaimRequest;
|
use App\Models\ClaimRequest;
|
||||||
use App\Models\File;
|
use App\Models\File;
|
||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
|
use App\Models\RequestLog;
|
||||||
|
use App\Models\Organization;
|
||||||
|
|
||||||
use App\Services\ClaimRequestService;
|
use App\Services\ClaimRequestService;
|
||||||
use App\Services\ClaimService;
|
use App\Services\ClaimService;
|
||||||
use Exception;
|
use Exception;
|
||||||
@@ -26,7 +29,7 @@ class ClaimRequestController extends Controller
|
|||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
* @return Renderable
|
* @return Renderable
|
||||||
*/
|
*/
|
||||||
private static $code_prefix = 'CRQ-H';
|
private static $code_prefix = 'CLAIM';
|
||||||
public function index(request $request)
|
public function index(request $request)
|
||||||
{
|
{
|
||||||
$claimRequests = ClaimRequest::query()
|
$claimRequests = ClaimRequest::query()
|
||||||
@@ -85,21 +88,26 @@ class ClaimRequestController extends Controller
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$check_claim_requests = DB::table('claim_requests')
|
$check_claim_requests = DB::table('claim_requests')
|
||||||
->where('claim_requests.request_log_id', '=', $request->request_logs_id)
|
->where('claim_requests.request_log_id', '=', $request->request_logs_id)
|
||||||
->first();
|
->first();
|
||||||
if(!$check_claim_requests)
|
if(!$check_claim_requests)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
$code = $this->getNextCode();
|
$code = $this->getNextCode($request->request_logs_id);
|
||||||
$member = Member::find($request->member_id);
|
$member = Member::find($request->member_id);
|
||||||
|
$requestLogData = RequestLog::where('id',$request->request_logs_id)->first();
|
||||||
|
$organization = Organization::where(['id' => $requestLogData->organization_id, 'type' => 'hospital'])->first('code');
|
||||||
|
$provideCode = $organization ? $organization->code : '';
|
||||||
|
|
||||||
$newClaimRequest = ClaimRequestService::storeClaimRequest(
|
$newClaimRequest = ClaimRequestService::storeClaimRequest(
|
||||||
row: [],
|
row: [],
|
||||||
code: $code,
|
code: $code,
|
||||||
member: $member,
|
member: $member,
|
||||||
paymentType: 'reimbursement',
|
paymentType: 'cashless',
|
||||||
serviceCode: $request->service_code,
|
serviceCode: $request->service_code,
|
||||||
requestLogID: $request->request_logs_id,
|
requestLogID: $request->request_logs_id,
|
||||||
|
organization_code: $provideCode,
|
||||||
);
|
);
|
||||||
// Log History
|
// Log History
|
||||||
$newClaimRequest->histories()->create([
|
$newClaimRequest->histories()->create([
|
||||||
@@ -228,21 +236,36 @@ class ClaimRequestController extends Controller
|
|||||||
return $claimRequest;
|
return $claimRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getNextCode()
|
public static function getNextCode($request_log_id = 0)
|
||||||
{
|
{
|
||||||
$last_number = ClaimRequest::withTrashed()->max('code');
|
$last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, ".", -1) AS SIGNED)) as max_numeric_code'))
|
||||||
$last_number_parts = explode('-', $last_number);
|
->whereRaw('SUBSTRING_INDEX(code, ".", -1) REGEXP "^[0-9]+$"')
|
||||||
$next_number = count($last_number_parts) < 3 ? 1 : ((int) $last_number_parts[2] + 1);
|
->value('max_numeric_code');
|
||||||
return self::makeCode($next_number);
|
// $next_number = 1;
|
||||||
|
if ($last_numeric_code) {
|
||||||
|
// // Jika ada kode sebelumnya, pecah kode dan tambahkan 1 ke angka terakhir
|
||||||
|
// $parts = explode('-', $last_code);
|
||||||
|
// $last_number = (int) end($parts);
|
||||||
|
$next_number = $last_numeric_code + 1;
|
||||||
|
} else {
|
||||||
|
$next_number = 1;
|
||||||
|
}
|
||||||
|
return self::makeCode($next_number, $request_log_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function makeCode($next_number)
|
public static function makeCode($next_number, $request_log_id)
|
||||||
{
|
{
|
||||||
// Pastikan $next_number adalah integer positif
|
// Pastikan $next_number adalah integer positif
|
||||||
$next_number = max(1, (int) $next_number);
|
$next_number = max(1, (int) $next_number);
|
||||||
|
$requestLogData = RequestLog::where('id', $request_log_id)->first();
|
||||||
|
$organization = Organization::where(['id' => $requestLogData->organization_id, 'type' => 'hospital'])->first('code');
|
||||||
|
$provideCode = $organization ? $organization->code : '';
|
||||||
|
$member = Member::with('currentCorporate')->where(['id' => $requestLogData->member_id])->first();
|
||||||
|
$sparator = '.';
|
||||||
|
$date = date('ymd');
|
||||||
// Menghasilkan kode dengan format yang diinginkan
|
// Menghasilkan kode dengan format yang diinginkan
|
||||||
return self::$code_prefix . '-' . str_pad($next_number, 5, '0', STR_PAD_LEFT);
|
return self::$code_prefix . $sparator. 'H' . $sparator. $provideCode . $sparator. $date. $sparator . $member->currentPolicy->code . $sparator. $member->member_id . $sparator. str_pad($next_number, 5, '0', STR_PAD_LEFT);
|
||||||
|
return self::$code_prefix . '.' . str_pad($next_number, 6, '0', STR_PAD_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_claim_requests(Request $request)
|
public function get_claim_requests(Request $request)
|
||||||
|
|||||||
@@ -37,9 +37,18 @@ class ClaimRequestController extends Controller
|
|||||||
->when($request->search, function ($q, $search) {
|
->when($request->search, function ($q, $search) {
|
||||||
$q->where('code', 'LIKE', "%".$search."%");
|
$q->where('code', 'LIKE', "%".$search."%");
|
||||||
$q->orWhereHas('member', function ($subQuery) use ($search) {
|
$q->orWhereHas('member', function ($subQuery) use ($search) {
|
||||||
$subQuery->where('name', 'LIKE', "%".$search."");
|
$subQuery->where('name', 'LIKE', "%".$search."%");
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
->when($request->start_date, function ($q, $startDate) {
|
||||||
|
$q->where('submission_date', '>', $startDate);
|
||||||
|
})
|
||||||
|
->when($request->end_date, function ($q, $endDate) {
|
||||||
|
$q->where('submission_date', '<', $endDate);
|
||||||
|
})
|
||||||
|
->when($request->service_code, function ($q, $serviceCode) {
|
||||||
|
$q->whereIn('service_code', $serviceCode);
|
||||||
|
})
|
||||||
->when($request->orderBy, function ($q, $orderBy) use ($request) {
|
->when($request->orderBy, function ($q, $orderBy) use ($request) {
|
||||||
if (in_array($orderBy, ['submission_date', 'code'])) {
|
if (in_array($orderBy, ['submission_date', 'code'])) {
|
||||||
$q->orderBy($orderBy, $request->order);
|
$q->orderBy($orderBy, $request->order);
|
||||||
@@ -262,12 +271,8 @@ class ClaimRequestController extends Controller
|
|||||||
'claim',
|
'claim',
|
||||||
'organization',
|
'organization',
|
||||||
]);
|
]);
|
||||||
$organization = Organization::where('code', $request->provider_code)->first();
|
|
||||||
if (!$organization) {
|
|
||||||
return response()->json(['error' => true, 'message' => 'Data tidak ditemukan'], 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
$updateClaimRequest = ClaimRequestService::updateClaimRequest(organization_id: $organization->id, claim_request_id: $id);
|
$updateClaimRequest = ClaimRequestService::updateClaimRequest(reason: $request->reason, submission_date: $request->date, claim_request_id: $id);
|
||||||
|
|
||||||
ClaimRequested::dispatch($updateClaimRequest);
|
ClaimRequested::dispatch($updateClaimRequest);
|
||||||
// Log History
|
// Log History
|
||||||
@@ -511,89 +516,102 @@ class ClaimRequestController extends Controller
|
|||||||
|
|
||||||
public function claimRequestDetail($claimRequestId)
|
public function claimRequestDetail($claimRequestId)
|
||||||
{
|
{
|
||||||
$status = DB::table('claim_requests')
|
// $status = DB::table('claim_requests')
|
||||||
->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
|
// ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
|
||||||
->leftJoin('members', 'claim_requests.member_id', '=', 'members.id')
|
// ->leftJoin('members', 'claim_requests.member_id', '=', 'members.id')
|
||||||
->leftJoin('corporate_employees', 'members.id', '=', 'corporate_employees.member_id')
|
// ->leftJoin('corporate_employees', 'members.id', '=', 'corporate_employees.member_id')
|
||||||
->leftJoin('corporate_divisions', 'corporate_employees.division_id', '=', 'corporate_divisions.id')
|
// ->leftJoin('corporate_divisions', 'corporate_employees.division_id', '=', 'corporate_divisions.id')
|
||||||
->where('claim_requests.id', '=', $claimRequestId)
|
// ->where('claim_requests.id', '=', $claimRequestId)
|
||||||
->select(
|
// ->select(
|
||||||
'claim_requests.submission_date',
|
// 'claim_requests.submission_date',
|
||||||
'claim_requests.code',
|
// 'claim_requests.code',
|
||||||
DB::raw('
|
// DB::raw('
|
||||||
CASE
|
// CASE
|
||||||
WHEN claim_requests.status = "requested" THEN "requested"
|
// WHEN claim_requests.status = "requested" THEN "requested"
|
||||||
WHEN claim_requests.status = "approved" AND claims.status = "approved" THEN "approved"
|
// WHEN claim_requests.status = "approved" AND claims.status = "approved" THEN "approved"
|
||||||
WHEN claim_requests.status = "approved" AND claims.status = "declined" THEN "declined"
|
// WHEN claim_requests.status = "approved" AND claims.status = "declined" THEN "declined"
|
||||||
WHEN claim_requests.status = "approved" AND claims.status = "disbrusmented" THEN "disbrusmented"
|
// WHEN claim_requests.status = "approved" AND claims.status = "disbrusmented" THEN "disbrusmented"
|
||||||
/*WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "pending"*/
|
// /*WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "pending"*/
|
||||||
WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "reviewed"
|
// WHEN claim_requests.status = "approved" AND claims.status = "received" THEN "reviewed"
|
||||||
ELSE ""
|
// ELSE ""
|
||||||
END AS status
|
// END AS status
|
||||||
')
|
// ')
|
||||||
)
|
// )
|
||||||
->first();
|
// ->first();
|
||||||
$results['status'] = $status;
|
// $results['status'] = $status;
|
||||||
$timeline = DB::table('claim_logs')
|
// $timeline = DB::table('claim_logs')
|
||||||
->where('claim_logs.claim_request_id', '=', $claimRequestId)
|
// ->where('claim_logs.claim_request_id', '=', $claimRequestId)
|
||||||
->select(
|
// ->select(
|
||||||
DB::raw('
|
// DB::raw('
|
||||||
CASE
|
// CASE
|
||||||
WHEN claim_logs.status = "requested" THEN "Request"
|
// WHEN claim_logs.status = "requested" THEN "Request"
|
||||||
WHEN claim_logs.status = "reviewed" THEN "Review"
|
// WHEN claim_logs.status = "reviewed" THEN "Review"
|
||||||
WHEN claim_logs.status = "approved" THEN "Approval"
|
// WHEN claim_logs.status = "approved" THEN "Approval"
|
||||||
WHEN claim_logs.status = "declined" THEN "Decline"
|
// WHEN claim_logs.status = "declined" THEN "Decline"
|
||||||
ELSE "-"
|
// ELSE "-"
|
||||||
END AS txt_status
|
// END AS txt_status
|
||||||
'),
|
// '),
|
||||||
DB::raw('
|
// DB::raw('
|
||||||
CASE
|
// CASE
|
||||||
WHEN claim_logs.status = "requested" THEN "#159C9C"
|
// WHEN claim_logs.status = "requested" THEN "#159C9C"
|
||||||
WHEN claim_logs.status = "reviewed" THEN "#0C53B7"
|
// WHEN claim_logs.status = "reviewed" THEN "#0C53B7"
|
||||||
WHEN claim_logs.status = "approved" THEN "#229A16"
|
// WHEN claim_logs.status = "approved" THEN "#229A16"
|
||||||
WHEN claim_logs.status = "declined" THEN "#FF4842"
|
// WHEN claim_logs.status = "declined" THEN "#FF4842"
|
||||||
ELSE "-"
|
// ELSE "-"
|
||||||
END AS txt_status_color
|
// END AS txt_status_color
|
||||||
'),
|
// '),
|
||||||
DB::raw('
|
// DB::raw('
|
||||||
CASE
|
// CASE
|
||||||
WHEN claim_logs.status = "requested" THEN "#00AB5529"
|
// WHEN claim_logs.status = "requested" THEN "#00AB5529"
|
||||||
WHEN claim_logs.status = "reviewed" THEN "#1890FF29"
|
// WHEN claim_logs.status = "reviewed" THEN "#1890FF29"
|
||||||
WHEN claim_logs.status = "approved" THEN "#54D62C29"
|
// WHEN claim_logs.status = "approved" THEN "#54D62C29"
|
||||||
WHEN claim_logs.status = "declined" THEN "#FF48427A"
|
// WHEN claim_logs.status = "declined" THEN "#FF48427A"
|
||||||
ELSE "-"
|
// ELSE "-"
|
||||||
END AS txt_status_backgroundColor
|
// END AS txt_status_backgroundColor
|
||||||
'),
|
// '),
|
||||||
'claim_logs.date',
|
// 'claim_logs.date',
|
||||||
'claim_logs.description',
|
// 'claim_logs.description',
|
||||||
'claim_logs.status'
|
// 'claim_logs.status'
|
||||||
)
|
// )
|
||||||
->orderBy('claim_logs.id', 'desc')
|
// ->orderBy('claim_logs.id', 'desc')
|
||||||
->get();
|
// ->get();
|
||||||
$results['timeline'] = $timeline;
|
// $results['timeline'] = $timeline;
|
||||||
$request_files = DB::table('claim_request_files')
|
// $request_files = DB::table('claim_request_files')
|
||||||
->where('claim_request_files.claim_request_id', '=', $claimRequestId)
|
// ->where('claim_request_files.claim_request_id', '=', $claimRequestId)
|
||||||
->select(
|
// ->select(
|
||||||
'claim_request_files.*',
|
// 'claim_request_files.*',
|
||||||
DB::raw('(SELECT files.fileable_id FROM files WHERE files.fileable_id = claim_request_files.claim_request_id AND files.type = claim_request_files.type LIMIT 1) AS check_files'),
|
// DB::raw('(SELECT files.fileable_id FROM files WHERE files.fileable_id = claim_request_files.claim_request_id AND files.type = claim_request_files.type LIMIT 1) AS check_files'),
|
||||||
)
|
// )
|
||||||
->get();
|
// ->get();
|
||||||
$results['request_files'] = $request_files;
|
// $results['request_files'] = $request_files;
|
||||||
$documents = DB::table('files')
|
// $documents = DB::table('files')
|
||||||
->where('fileable_type', 'App\Models\ClaimRequest')
|
// ->where('fileable_type', 'App\Models\ClaimRequest')
|
||||||
->where('fileable_id', $claimRequestId)
|
// ->where('fileable_id', $claimRequestId)
|
||||||
->select('original_name', \DB::raw("CONCAT('" . env('APP_URL') . "/storage/', path) as path"), 'type')
|
// ->select('original_name', \DB::raw("CONCAT('" . env('APP_URL') . "/storage/', path) as path"), 'type')
|
||||||
->orderBy('id', 'desc')
|
// ->orderBy('id', 'desc')
|
||||||
->get();
|
// ->get();
|
||||||
$results['documents'] = $documents;
|
// $results['documents'] = $documents;
|
||||||
$dialog_submits = DB::table('claim_requests')
|
// $dialog_submits = DB::table('claim_requests')
|
||||||
->leftJoin('members', 'claim_requests.member_id','=', 'members.id')
|
// ->leftJoin('members', 'claim_requests.member_id','=', 'members.id')
|
||||||
->where('claim_requests.id', $claimRequestId)
|
// ->where('claim_requests.id', $claimRequestId)
|
||||||
->select('claim_requests.code', 'members.name', 'claim_requests.submission_date', 'claim_requests.service_code','claim_requests.status')
|
// ->select('claim_requests.code', 'members.name', 'claim_requests.submission_date', 'claim_requests.service_code','claim_requests.status')
|
||||||
->first();
|
// ->first();
|
||||||
$results['dialog_submits'] = $dialog_submits;
|
// $results['dialog_submits'] = $dialog_submits;
|
||||||
|
|
||||||
return Helper::responseJson($results);
|
// return Helper::responseJson($results);
|
||||||
|
|
||||||
|
$claimRequest = ClaimRequest::findOrFail($claimRequestId);
|
||||||
|
$claimRequest->load([
|
||||||
|
'requestLog',
|
||||||
|
'requestLog.organization',
|
||||||
|
'requestLog.member',
|
||||||
|
'member.currentPlan' => function($memberPlan) {
|
||||||
|
$memberPlan->join('claim_requests', 'claim_requests.service_code', '=', 'plans.service_code');
|
||||||
|
},
|
||||||
|
'requestLog.files',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return Helper::responseJson(data: ClaimRequestShowResource::make($claimRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function invoiceFiles(Request $request, $claim_id)
|
public function invoiceFiles(Request $request, $claim_id)
|
||||||
|
|||||||
@@ -395,6 +395,31 @@ class DailyMonitoringController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Status Request LOG
|
* Update Status Request LOG
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ class ReportLogController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show($id)
|
public function show($id)
|
||||||
{
|
{
|
||||||
$claimRequest = RequestLog::findOrFail($id);
|
$requestLog = RequestLog::findOrFail($id);
|
||||||
$claimRequest->load([
|
$requestLog->load([
|
||||||
'histories' => function ($history) {
|
'histories' => function ($history) {
|
||||||
$history->latest();
|
$history->latest();
|
||||||
},
|
},
|
||||||
@@ -120,7 +120,7 @@ class ReportLogController extends Controller
|
|||||||
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return Helper::responseJson(data: RequestLogShowResource::make($claimRequest));
|
return Helper::responseJson(data: RequestLogShowResource::make($requestLog));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -441,6 +441,7 @@ class RequestLogController extends Controller
|
|||||||
'path' => $pathFile,
|
'path' => $pathFile,
|
||||||
'created_by' => auth()->user()->id,
|
'created_by' => auth()->user()->id,
|
||||||
'updated_by' => auth()->user()->id,
|
'updated_by' => auth()->user()->id,
|
||||||
|
'reason' => $request->reason,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -878,6 +879,7 @@ class RequestLogController extends Controller
|
|||||||
'path' => $pathFile,
|
'path' => $pathFile,
|
||||||
'created_by' => auth()->user()->id,
|
'created_by' => auth()->user()->id,
|
||||||
'updated_by' => auth()->user()->id,
|
'updated_by' => auth()->user()->id,
|
||||||
|
'reason' => $request->reason,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,6 +895,7 @@ class RequestLogController extends Controller
|
|||||||
'path' => $pathFile,
|
'path' => $pathFile,
|
||||||
'created_by' => auth()->user()->id,
|
'created_by' => auth()->user()->id,
|
||||||
'updated_by' => auth()->user()->id,
|
'updated_by' => auth()->user()->id,
|
||||||
|
'reason' => $request->reason,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -908,6 +911,7 @@ class RequestLogController extends Controller
|
|||||||
'path' => $pathFile,
|
'path' => $pathFile,
|
||||||
'created_by' => auth()->user()->id,
|
'created_by' => auth()->user()->id,
|
||||||
'updated_by' => auth()->user()->id,
|
'updated_by' => auth()->user()->id,
|
||||||
|
'reason' => $request->reason,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::post('detail/{claim_code}/add', [DailyMonitoringController::class, 'AddDetailMonitoringList']);
|
Route::post('detail/{claim_code}/add', [DailyMonitoringController::class, 'AddDetailMonitoringList']);
|
||||||
Route::post('detail/{claim_code}/add-request', [DailyMonitoringController::class, 'AddDetailMonitoringListRequestLog']);
|
Route::post('detail/{claim_code}/add-request', [DailyMonitoringController::class, 'AddDetailMonitoringListRequestLog']);
|
||||||
Route::post('detail/{claim_code}/update-status', [DailyMonitoringController::class, 'UpdateListRequestLog']);
|
Route::post('detail/{claim_code}/update-status', [DailyMonitoringController::class, 'UpdateListRequestLog']);
|
||||||
|
Route::get('detail/{id}/delete', [DailyMonitoringController::class, 'deleteDetailMonitoringListRequestLog']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Laboratorium Result
|
// Laboratorium Result
|
||||||
@@ -312,7 +313,7 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve');
|
Route::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve');
|
||||||
Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show');
|
Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show');
|
||||||
Route::post('claim-requests', [ClaimRequestController::class, 'createNew']); // Bagaskoro, BSD 2 November 2023
|
Route::post('claim-requests', [ClaimRequestController::class, 'createNew']); // Bagaskoro, BSD 2 November 2023
|
||||||
Route::put('claim-requests/{id}', [ClaimRequestController::class, 'update'])->name('claim-requests.update');
|
Route::post('claim-requests/{id}/update', [ClaimRequestController::class, 'update']);
|
||||||
Route::post('claim-requests/import', [ClaimRequestController::class, 'importClaim'])->name('claim-requests.importClaim');
|
Route::post('claim-requests/import', [ClaimRequestController::class, 'importClaim'])->name('claim-requests.importClaim');
|
||||||
Route::get('claim-requests/detail/{id}', [ClaimRequestController::class, 'claimRequestDetail']);
|
Route::get('claim-requests/detail/{id}', [ClaimRequestController::class, 'claimRequestDetail']);
|
||||||
Route::post('claim-requests/{id}/invoice-files', [ClaimRequestController::class, 'invoiceFiles']);
|
Route::post('claim-requests/{id}/invoice-files', [ClaimRequestController::class, 'invoiceFiles']);
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ namespace Modules\Internal\Transformers;
|
|||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use App\Models\Service;
|
||||||
|
use App\Models\MemberPlan;
|
||||||
|
use App\Models\Plan;
|
||||||
|
use App\Models\CorporateBenefit;
|
||||||
|
use App\Models\RequestLogBenefit;
|
||||||
|
use App\Models\CorporatePolicy;
|
||||||
|
use App\Models\RequestLogMedicine;
|
||||||
|
use App\Models\Organization;
|
||||||
|
use App\Helpers\Helper;
|
||||||
|
|
||||||
class ClaimRequestShowResource extends JsonResource
|
class ClaimRequestShowResource extends JsonResource
|
||||||
{
|
{
|
||||||
@@ -16,25 +25,57 @@ class ClaimRequestShowResource extends JsonResource
|
|||||||
public function toArray($request)
|
public function toArray($request)
|
||||||
{
|
{
|
||||||
$data = parent::toArray($request);
|
$data = parent::toArray($request);
|
||||||
|
$corporateId = $data['member']['current_plan']['corporate_id'] ?? 0;
|
||||||
|
$planMember = MemberPlan::where('member_id', $data['member_id'])->get('plan_id');
|
||||||
|
|
||||||
// Map Histories to Group by Dates
|
$planId = Plan::whereIn('id', $planMember)->where('service_code', $data['service_code'])->first();
|
||||||
$historiesGroupByDate = $this->histories->mapToGroups(function($history) {
|
$benefit = CorporateBenefit::with('benefit')->where('plan_id', $planId->id)->get()->toArray();
|
||||||
return [$history->created_at->format('Y-m-d') => $history];
|
$benefitDetailLog = RequestLogBenefit::with('benefit')->where('request_log_id', $data['request_log_id'])->get()->toArray();
|
||||||
});
|
$medicineDetailLog = RequestLogMedicine::where('request_log_id', $data['request_log_id'])->get()->toArray();
|
||||||
$data['histories_by_date'] = [];
|
|
||||||
foreach ($historiesGroupByDate as $date => $histories) {
|
$benefitData = [];
|
||||||
$data['histories_by_date'][] = [
|
|
||||||
'date' => $date,
|
if (count($benefit)){
|
||||||
'histories' => $histories
|
foreach($benefit as $row){
|
||||||
];
|
array_push($benefitData, $row['benefit']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map Files by type
|
// Policy Number
|
||||||
$filesGroupByType = $this->files->mapToGroups(function($file) {
|
$policyNumber = CorporatePolicy::query()
|
||||||
return [Str::slug($file->type, '_') => $file];
|
->where('corporate_id', $corporateId)
|
||||||
});
|
->first();
|
||||||
$data['files_by_type'] = $filesGroupByType;
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
|
$response = [
|
||||||
|
'id' => $data['id'],
|
||||||
|
'code' => $data['code'],
|
||||||
|
'request_log_id' => $data['request_log_id'],
|
||||||
|
'provider' => $data['request_log']['organization']['name'],
|
||||||
|
'member_id' => $data['request_log']['member']['member_id'],
|
||||||
|
'policy_number' => $policyNumber->code ? $policyNumber->code : '-',
|
||||||
|
'name' => $data['request_log']['member']['name'],
|
||||||
|
'date_of_birth' => $data['request_log']['member']['birth_date'],
|
||||||
|
'gender' => $data['request_log']['member']['gender'],
|
||||||
|
'marital_status' => $data['request_log']['member']['status_marital'],
|
||||||
|
'member_type' => Helper::memberType($data['request_log']['member']['record_type']),
|
||||||
|
'principal_id' => $data['request_log']['member']['principal_id'] ? $data['request_log']['member']['principal_id'] : '-',
|
||||||
|
'principal_name' => $data['request_log']['member']['principal_id'] ? Helper::principalName($data['request_log']['member']['principal_id']) : '-',
|
||||||
|
'relation_with_principal' => Helper::relationWithPrincipal($data['request_log']['member']['relation_with_principal']),
|
||||||
|
'submission_date' => $data['submission_date'],
|
||||||
|
'no_identitas' => $data['request_log']['member']['nric'],
|
||||||
|
'keterangan' => $data['request_log']['keterangan'],
|
||||||
|
'hak_kamar_pasien' => $data['request_log']['hak_kamar_pasien'],
|
||||||
|
'penempatan_kamar' => $data['request_log']['penempatan_kamar'],
|
||||||
|
'catatan' => $data['request_log']['catatan'],
|
||||||
|
'service_type' => Helper::serviceName( $data['request_log']['service_code']),
|
||||||
|
'claim_method' => $data['request_log']['payment_type'],
|
||||||
|
'files' => $data['request_log']['files'],
|
||||||
|
'benefit' => $benefitData,
|
||||||
|
'benefit_data' => $benefitDetailLog,
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use App\Traits\Blameable;
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Altek\Accountant\Contracts\Recordable;
|
||||||
use Str;
|
use Str;
|
||||||
|
|
||||||
class ClaimRequest extends Model
|
class ClaimRequest extends Model
|
||||||
@@ -28,7 +29,8 @@ class ClaimRequest extends Model
|
|||||||
'claim_id',
|
'claim_id',
|
||||||
'organization_id',
|
'organization_id',
|
||||||
'code',
|
'code',
|
||||||
'request_log_id'
|
'request_log_id',
|
||||||
|
'reason'
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
@@ -207,6 +209,11 @@ class ClaimRequest extends Model
|
|||||||
return $this->hasMany(Claim::class, 'claim_request_id');
|
return $this->hasMany(Claim::class, 'claim_request_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function requestLog()
|
||||||
|
{
|
||||||
|
return $this->hasOne(RequestLog::class, 'id', 'request_log_id');
|
||||||
|
}
|
||||||
|
|
||||||
public function files()
|
public function files()
|
||||||
{
|
{
|
||||||
return $this->morphMany(File::class, 'fileable');
|
return $this->morphMany(File::class, 'fileable');
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use DB;
|
use DB;
|
||||||
|
|
||||||
class RequestDailyMonitoring extends Model
|
class RequestDailyMonitoring extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use SoftDeletes;
|
||||||
protected $table = "request_log_daily_monitorings";
|
protected $table = "request_log_daily_monitorings";
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
@@ -28,6 +30,8 @@ class RequestDailyMonitoring extends Model
|
|||||||
'created_by',
|
'created_by',
|
||||||
'updated_by',
|
'updated_by',
|
||||||
'deleted_by',
|
'deleted_by',
|
||||||
|
'reason',
|
||||||
|
'deleted_at'
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $appends = ['medical_plan', 'non_medikamentosa_plan', 'document', 'discharge_date'];
|
protected $appends = ['medical_plan', 'non_medikamentosa_plan', 'document', 'discharge_date'];
|
||||||
@@ -52,6 +56,18 @@ class RequestDailyMonitoring extends Model
|
|||||||
// return round($this->attributes['respiration_rate'], 0);
|
// return round($this->attributes['respiration_rate'], 0);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
protected static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
// Event handling untuk deleting
|
||||||
|
static::deleting(function ($model) {
|
||||||
|
// Set nilai deleted_by dengan ID pengguna yang melakukan penghapusan (jika ada)
|
||||||
|
$model->deleted_by = Auth::id();
|
||||||
|
$model->save();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function getMedicalPlanAttribute()
|
public function getMedicalPlanAttribute()
|
||||||
{
|
{
|
||||||
$arr_medical_plan = [];
|
$arr_medical_plan = [];
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ class RequestLog extends Model
|
|||||||
|
|
||||||
public function requestLogDailyMonitorings()
|
public function requestLogDailyMonitorings()
|
||||||
{
|
{
|
||||||
return $this->hasMany(RequestLogDailyMonitoring::class, 'request_log_id');
|
return $this->hasMany(RequestLogDailyMonitoring::class, 'request_log_id')->whereNull('deleted_at');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPaymentTypeNameAttribute()
|
public function getPaymentTypeNameAttribute()
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use App\Models\CorporateBenefit;
|
|||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
use App\Models\MemberPlan;
|
use App\Models\MemberPlan;
|
||||||
use App\Models\CorporateHospital;
|
use App\Models\CorporateHospital;
|
||||||
|
use App\Models\ClaimRequest;
|
||||||
use App\Models\ExclusionRules;
|
use App\Models\ExclusionRules;
|
||||||
use App\Models\ExclusionImport;
|
use App\Models\ExclusionImport;
|
||||||
use App\Models\Icd;
|
use App\Models\Icd;
|
||||||
@@ -147,6 +148,15 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
$this->logAuditTrail($model, 'deleted');
|
$this->logAuditTrail($model, 'deleted');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ClaimRequest::updated(function ($model) {
|
||||||
|
|
||||||
|
$this->logAuditTrail($model, 'updated');
|
||||||
|
});
|
||||||
|
|
||||||
|
ClaimRequest::deleted(function ($model) {
|
||||||
|
$this->logAuditTrail($model, 'deleted');
|
||||||
|
});
|
||||||
|
|
||||||
// ICD or exlusion
|
// ICD or exlusion
|
||||||
Icd::updated(function ($model) {
|
Icd::updated(function ($model) {
|
||||||
$this->logAuditTrail($model, 'updated');
|
$this->logAuditTrail($model, 'updated');
|
||||||
|
|||||||
@@ -110,19 +110,23 @@ class ClaimRequestService{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function updateClaimRequest($organization_id, $claim_request_id){
|
public static function updateClaimRequest($reason, $submission_date, $claim_request_id){
|
||||||
try {
|
try {
|
||||||
$data = [
|
$claimRequest = ClaimRequest::find($claim_request_id);
|
||||||
'organization_id' => $organization_id
|
|
||||||
];
|
if (!$claimRequest) {
|
||||||
DB::commit();
|
throw new \Exception("Claim request not found");
|
||||||
$update = ClaimRequest::where('id', $claim_request_id)->update($data);
|
}
|
||||||
return ClaimRequest::find($claim_request_id);
|
|
||||||
|
$claimRequest->submission_date = $submission_date;
|
||||||
|
$claimRequest->reason = $reason;
|
||||||
|
|
||||||
|
$claimRequest->save();
|
||||||
|
|
||||||
|
return $claimRequest;
|
||||||
|
|
||||||
} catch (\Exception $error) {
|
} catch (\Exception $error) {
|
||||||
DB::rollBack();
|
throw new \Exception($error->getMessage());
|
||||||
|
|
||||||
throw new \Exception($error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('claim_requests', function (Blueprint $table) {
|
||||||
|
$table->string('reason')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('claim_requests', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('reason');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('request_log_daily_monitorings', function (Blueprint $table) {
|
||||||
|
$table->string('reason');
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('request_log_daily_monitorings', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('reason');
|
||||||
|
$table->dropSoftDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -10,12 +10,16 @@ export type ClaimRequest = {
|
|||||||
service_code: string;
|
service_code: string;
|
||||||
claim_method: string;
|
claim_method: string;
|
||||||
service_type: string;
|
service_type: string;
|
||||||
|
service_name: string;
|
||||||
code_provider: string;
|
code_provider: string;
|
||||||
file_condition: Files;
|
file_condition: Files;
|
||||||
member: Member;
|
member: Member;
|
||||||
claim: {
|
claim: {
|
||||||
organization: Organizations
|
organization: Organizations
|
||||||
}
|
}
|
||||||
|
organization: {
|
||||||
|
code: string
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Claims = {
|
export type Claims = {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
* Core
|
* Core
|
||||||
* ============================================
|
* ============================================
|
||||||
*/
|
*/
|
||||||
import { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useFieldArray, useForm } from 'react-hook-form';
|
import { useFieldArray, useForm } from 'react-hook-form';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { Box, IconButton, Typography, Grid, Card, List, ListItem } from '@mui/material';
|
import { Box, IconButton, Typography, Grid, Card, List, ListItem, Stack, Autocomplete, TextField, Button } from '@mui/material';
|
||||||
import { LoadingButton } from "@mui/lab";
|
import { LoadingButton } from "@mui/lab";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +31,13 @@ import { fDate, fDateOnly } from '@/utils/formatTime';
|
|||||||
import { getMonitoringDetailList } from '../Model/Functions';
|
import { getMonitoringDetailList } from '../Model/Functions';
|
||||||
import { getOrganizationId } from '../Model/Functions';
|
import { getOrganizationId } from '../Model/Functions';
|
||||||
import { DetailMonitoringListType } from '../Model/Types';
|
import { DetailMonitoringListType } from '../Model/Types';
|
||||||
|
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
||||||
|
import { MenuItem } from '@mui/material';
|
||||||
|
import { Delete } from '@mui/icons-material';
|
||||||
|
import MuiDialog from '@/components/MuiDialog';
|
||||||
|
import { DialogActions } from '@mui/material';
|
||||||
|
import axios from '@/utils/axios';
|
||||||
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
|
||||||
|
|
||||||
export default function DetailMonitoringList() {
|
export default function DetailMonitoringList() {
|
||||||
@@ -42,12 +49,91 @@ export default function DetailMonitoringList() {
|
|||||||
// --------------------
|
// --------------------
|
||||||
const [detailMonitoringList, setDetailMonitoringList] = useState<DetailMonitoringListType[]>();
|
const [detailMonitoringList, setDetailMonitoringList] = useState<DetailMonitoringListType[]>();
|
||||||
const [organizationId, setOrganizationId] = useState<number|undefined>();
|
const [organizationId, setOrganizationId] = useState<number|undefined>();
|
||||||
|
|
||||||
|
const [openDialog, setOpenDialog] = useState<boolean>(false)
|
||||||
|
|
||||||
// Use Effect
|
// Use Effect
|
||||||
// --------------------
|
// --------------------
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadDataTableData();
|
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);
|
||||||
|
const handleCloseDialog = () => {
|
||||||
|
setOpenDialog(false);
|
||||||
|
}
|
||||||
|
const handleDelete = () => {
|
||||||
|
if(selectedReason.value != '-'){
|
||||||
|
const parameters = {
|
||||||
|
'reason' : selectedReason.value
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
setError('Please select a reason')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getContent = () => (
|
||||||
|
<Stack spacing={1} marginTop={2}>
|
||||||
|
<Typography variant="subtitle2">Are you sure to delete this 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
|
// Load Data
|
||||||
// -------------------
|
// -------------------
|
||||||
const loadDataTableData = async () => {
|
const loadDataTableData = async () => {
|
||||||
@@ -81,33 +167,49 @@ export default function DetailMonitoringList() {
|
|||||||
detailMonitoringList?.map((row, index) => {
|
detailMonitoringList?.map((row, index) => {
|
||||||
return (
|
return (
|
||||||
<Grid key={index} item xs={12}>
|
<Grid key={index} item xs={12}>
|
||||||
<Card sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '32px', py: '24px'}}>
|
<Card sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '30px', py: '24px'}}>
|
||||||
{/* card header */}
|
{/* card header */}
|
||||||
<Box sx={{ pb: '20px', mb: '20px', borderBottom: '1px solid rgba(0,0,0,0.125)' }}>
|
<Box
|
||||||
<Label
|
sx={{
|
||||||
variant="ghost"
|
pb: '20px',
|
||||||
color="default"
|
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) : '-'}
|
{row.submission_date ? fDate(row.submission_date) : '-'}
|
||||||
</Label>
|
</Label>
|
||||||
|
|
||||||
{row.discharge_date.discharge_date ?
|
{row.discharge_date ? (
|
||||||
(<Label
|
<Label
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color="success"
|
color="success"
|
||||||
sx={{marginLeft: '85%'}}
|
sx={{ position: 'absolute', top: 0, right: '120px' }} // Atur posisi label "Close Monitoring"
|
||||||
>
|
>
|
||||||
Close Monitoring
|
Close Monitoring
|
||||||
</Label>) : (<Label
|
</Label>
|
||||||
variant="ghost"
|
) : (
|
||||||
color="warning"
|
<Label
|
||||||
sx={{marginLeft: '77%'}}
|
variant="ghost"
|
||||||
>
|
color="warning"
|
||||||
|
sx={{ position: 'absolute', top: 0, right: '120px' }} // Atur posisi label "On Monitoring"
|
||||||
|
>
|
||||||
On Monitoring
|
On Monitoring
|
||||||
</Label>)}
|
</Label>
|
||||||
|
)}
|
||||||
</Box>
|
|
||||||
|
|
||||||
|
<Box sx={{ marginLeft: 'auto' }}> {/* Menempatkan TableMoreMenu di sebelah kanan */}
|
||||||
|
<TableMoreMenu actions={
|
||||||
|
<MenuItem onClick={() => {setOpenDialog(true); setId(row.id)}}>
|
||||||
|
<Delete color='error' />
|
||||||
|
Delete
|
||||||
|
</MenuItem>
|
||||||
|
} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
{/* card body */}
|
{/* card body */}
|
||||||
<Grid container gap={4}>
|
<Grid container gap={4}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
@@ -387,6 +489,15 @@ export default function DetailMonitoringList() {
|
|||||||
}
|
}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Dialog Delete */}
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: "Delete Daily Monitoring"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="xs"
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export type ClaimListType = {
|
|||||||
* Detail Monitoring List
|
* Detail Monitoring List
|
||||||
*/
|
*/
|
||||||
export type DetailMonitoringListType = {
|
export type DetailMonitoringListType = {
|
||||||
id : string|null,
|
id : number|null,
|
||||||
claim_id : string|null,
|
claim_id : string|null,
|
||||||
claim_code : string,
|
claim_code : string,
|
||||||
subject : string,
|
subject : string,
|
||||||
@@ -61,6 +61,7 @@ export type DetailMonitoringListType = {
|
|||||||
analysis : string,
|
analysis : string,
|
||||||
complaints : string,
|
complaints : string,
|
||||||
submission_date : string,
|
submission_date : string,
|
||||||
|
discharge_date : string,
|
||||||
lab_date : string,
|
lab_date : string,
|
||||||
provider : string,
|
provider : string,
|
||||||
examination : string,
|
examination : string,
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
import MuiDialog from "@/components/MuiDialog";
|
||||||
|
import { Autocomplete, Button, Card, Checkbox, DialogActions, Grid, TextField, Typography } from "@mui/material";
|
||||||
|
import { Paper } from "@mui/material";
|
||||||
|
import { Stack } from '@mui/material';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { ClaimRequest, Files } from '@/@types/claims';
|
||||||
|
import { fDateOnly, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
|
import axios from "@/utils/axios";
|
||||||
|
import { enqueueSnackbar, useSnackbar } from "notistack";
|
||||||
|
import { useNavigate } from "react-router";
|
||||||
|
import * as Yup from 'yup';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
|
||||||
|
type DialogConfirmationType = {
|
||||||
|
openDialog: boolean;
|
||||||
|
setOpenDialog: any;
|
||||||
|
onSubmit?: void;
|
||||||
|
approve: string;
|
||||||
|
claimRequest: ClaimRequest|undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DialogConfirmation({claimRequest, setOpenDialog, openDialog, approve, onSubmit} : DialogConfirmationType ) {
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
date: claimRequest?.date,
|
||||||
|
id: claimRequest?.id,
|
||||||
|
reason: claimRequest?.reason
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleChange = (field, value) => {
|
||||||
|
setFormData((prevData) => ({
|
||||||
|
...prevData,
|
||||||
|
[field]: value,
|
||||||
|
}));
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
axios
|
||||||
|
.post(`customer-service/request/final-log`, formData)
|
||||||
|
.then((response) => {
|
||||||
|
enqueueSnackbar('Verification Request LOG Success', { variant: 'success' });
|
||||||
|
setOpenDialog(false);
|
||||||
|
if (requestLog?.service_type == 'Inpatient'){
|
||||||
|
navigate('/case_management/inpatient_monitoring');
|
||||||
|
} else {
|
||||||
|
navigate('/custormer-service/final-log');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const style1 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '30%'
|
||||||
|
}
|
||||||
|
const style2 = {
|
||||||
|
width: '70%'
|
||||||
|
}
|
||||||
|
const marginBottom1 = {
|
||||||
|
marginBottom: 1,
|
||||||
|
}
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
const handleCloseDialog = () => {
|
||||||
|
setOpenDialog(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getContent = () => (
|
||||||
|
<Stack spacing={1} marginTop={2}>
|
||||||
|
<Typography variant="subtitle2">Are you sure to {approve == 'approved' ? 'approve' : 'deciline'} this final log ?</Typography>
|
||||||
|
<Grid item xs={12} md={12} marginTop={4}>
|
||||||
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Member ID</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.member_id}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Policy Number</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.policy_number}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.name}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Submission Date</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.submission_date ? fDateTimesecond(requestLog?.submission_date) : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Claim Method</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.claim_method ? toTitleCase(requestLog?.claim_method) : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Service Type</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.service_type}</Typography>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom2}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Discharge Date</Typography>
|
||||||
|
<TextField
|
||||||
|
label="Discharge Date"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
type="date"
|
||||||
|
value={formData.discharge_date ? fDateOnly(formData.discharge_date) : ''}
|
||||||
|
onChange={(e) => handleChange('discharge_date', e.target.value)}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom2}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Catatan</Typography>
|
||||||
|
<TextField
|
||||||
|
label="Catatan"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={formData.catatan}
|
||||||
|
onChange={(e) => handleChange('catatan', e.target.value)}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom2}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Diagnosis ICD - X</Typography>
|
||||||
|
<Autocomplete
|
||||||
|
multiple
|
||||||
|
options={icdOptions}
|
||||||
|
getOptionLabel={(option) => option.label}
|
||||||
|
fullWidth
|
||||||
|
value={icdOptions.filter((icd) => formData.icdCodes.includes(icd.value))}
|
||||||
|
onChange={(e, newValues) => handleChange('icdCodes', newValues.map((value) => value.value))}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
label="Diagnosis ICD - X"
|
||||||
|
variant="outlined"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
||||||
|
|
||||||
|
{approve == 'approved' ? (
|
||||||
|
<Button color="primary" variant="contained" onClick={() => handleApprove()}>Approve</Button>
|
||||||
|
) : (
|
||||||
|
<Button color="error" variant="contained" onClick={() => handleApprove()}>Decline</Button>
|
||||||
|
) }
|
||||||
|
|
||||||
|
</DialogActions>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: "Confirmation"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="xl"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
import MuiDialog from "@/components/MuiDialog";
|
||||||
|
import { Autocomplete, Button, Card, Checkbox, DialogActions, Grid, Typography } from "@mui/material";
|
||||||
|
import { Paper } from "@mui/material";
|
||||||
|
import { Stack } from '@mui/material';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
|
import axios from "@/utils/axios";
|
||||||
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
import { useNavigate } from "react-router";
|
||||||
|
import { TextField } from "@mui/material";
|
||||||
|
|
||||||
|
|
||||||
|
type DialogDeleteType = {
|
||||||
|
openDialog: boolean;
|
||||||
|
setOpenDialog: any;
|
||||||
|
onSubmit?: void;
|
||||||
|
id: number|undefined;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DialogDeleteFileLog({id, path, setOpenDialog, openDialog,onSubmit} : DialogDeleteType ) {
|
||||||
|
const style1 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '30%'
|
||||||
|
}
|
||||||
|
const style2 = {
|
||||||
|
width: '70%'
|
||||||
|
}
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCloseDialog = () => {
|
||||||
|
setOpenDialog(false);
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
const [isReasonSelected, setIsReasonSelected] = useState(false);
|
||||||
|
|
||||||
|
const reasons = [
|
||||||
|
{ value: 'Wrong Setting', label: 'Wrong Setting' },
|
||||||
|
{ value: 'Hospital Request', label: 'Hospital Request' }
|
||||||
|
];
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
path: path,
|
||||||
|
reason: null
|
||||||
|
});
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
setFormData({
|
||||||
|
reason: null,
|
||||||
|
path: path
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Update formData setiap kali approve berubah
|
||||||
|
setFormData(prevData => ({
|
||||||
|
...prevData,
|
||||||
|
path: path || '',
|
||||||
|
}));
|
||||||
|
}, [path]);
|
||||||
|
|
||||||
|
const handleChange = (field, value) => {
|
||||||
|
setFormData((prevData) => ({
|
||||||
|
...prevData,
|
||||||
|
[field]: value,
|
||||||
|
}));
|
||||||
|
if (field === 'reason') {
|
||||||
|
setIsReasonSelected(!!value);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (isReasonSelected && formData.reason !== '') {
|
||||||
|
console.log(formData)
|
||||||
|
axios
|
||||||
|
.post(`customer-service/request/${id}/delete_file`, formData)
|
||||||
|
.then((response) => {
|
||||||
|
enqueueSnackbar('File LOG has Deleted', { variant: 'success' });
|
||||||
|
setOpenDialog(false);
|
||||||
|
window.location.reload()
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setIsReasonSelected(false);
|
||||||
|
alert('Silakan pilih alasan sebelum menghapus data.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getContent = () => (
|
||||||
|
<Stack spacing={1} marginTop={2}>
|
||||||
|
<Typography variant="subtitle2" marginBottom={4}>Are you sure to delete this file Final LOG ?</Typography>
|
||||||
|
<br/>
|
||||||
|
<Grid item xs={12} md={12} marginTop={2}>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom2}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Reason*</Typography>
|
||||||
|
<Autocomplete
|
||||||
|
options={reasons}
|
||||||
|
getOptionLabel={(option) => option.label}
|
||||||
|
fullWidth
|
||||||
|
value={reasons.find((r) => r.value === formData.reason) || null} // Use find to match the default value
|
||||||
|
onChange={(e, newValue) => handleChange('reason', newValue?.value)}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
label="Reason"
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
error={!isReasonSelected} // Menandai input sebagai salah jika opsi tidak dipilih
|
||||||
|
helperText={!isReasonSelected ? 'Alasan harus dipilih' : ''}
|
||||||
|
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Grid>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
||||||
|
<Button color="error" variant="contained" onClick={handleSubmit}>Delete</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: "Delete File Final LOG"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="xs"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
import Iconify from '@/components/Iconify';
|
||||||
|
import { fCurrency } from '@/utils/formatNumber';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
import { Avatar, Button, Divider, LinearProgress, linearProgressClasses, ButtonBase, Box } from '@mui/material';
|
||||||
|
import { Card, Autocomplete } from '@mui/material';
|
||||||
|
import { Stack, Typography } from '@mui/material';
|
||||||
|
import { fPostFormat } from '@/utils/formatTime';
|
||||||
|
import axios from '@/utils/axios';
|
||||||
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
import { useRef, useState, useContext, useEffect } from 'react';
|
||||||
|
import { makeFormData } from '@/utils/jsonToFormData';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
// import { LanguageContext } from '@/contexts/LanguageContext';
|
||||||
|
import { DatePicker, LocalizationProvider, MobileDatePicker } from '@mui/x-date-pickers';
|
||||||
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||||
|
import TextField from '@mui/material/TextField';
|
||||||
|
import MuiDialog from '@/components/MuiDialog';
|
||||||
|
|
||||||
|
type DialogUploadType = {
|
||||||
|
openDialog: boolean;
|
||||||
|
setOpenDialog: any;
|
||||||
|
onSubmit?: void;
|
||||||
|
id: number|undefined;
|
||||||
|
}
|
||||||
|
export default function DialogUploadFileFinalLog({ id, openDialog, setOpenDialog }: DialogUploadType) {
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Files Diagnosa
|
||||||
|
const fileDiagnosaInput = useRef<HTMLInputElement>(null);
|
||||||
|
const [fileDiagnosas, setFileDiagnosas] = useState<any>([]);
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
const reason = [
|
||||||
|
{ value: 'Wrong Setting', label: 'Wrong Setting' },
|
||||||
|
{ value: 'Hospital Request', label: 'Hospital Request' }
|
||||||
|
];
|
||||||
|
const [selectedReason, setSelectedReason] = useState({value:'-', label:''});
|
||||||
|
const [error, setError] = useState('');
|
||||||
|
const handleDiagnosaInputChange = (event:any) => {
|
||||||
|
if (event.target.files[0]) {
|
||||||
|
setFileDiagnosas([...fileDiagnosas, ...event.target.files]);
|
||||||
|
} else {
|
||||||
|
console.log('NO FILE');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const removeDiagnosaFiles = (filesState:any, index:any) => {
|
||||||
|
setFileDiagnosas(
|
||||||
|
filesState.filter((file:any, fileIndex:any) => {
|
||||||
|
return fileIndex != index;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Files Result Kondisi
|
||||||
|
|
||||||
|
const fileKondisiInput = useRef<HTMLInputElement>(null);
|
||||||
|
const [fileKondisis, setFileKondisis] = useState<any>([]);
|
||||||
|
|
||||||
|
const handleKondisiInputChange = (event:any) => {
|
||||||
|
if (event.target.files[0]) {
|
||||||
|
setFileKondisis([...fileKondisis, ...event.target.files]);
|
||||||
|
} else {
|
||||||
|
console.log('NO FILE');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const removeKondisiFiles = (filesState:any, index:any) => {
|
||||||
|
setFileKondisis(
|
||||||
|
filesState.filter((file:any, fileIndex:any) => {
|
||||||
|
return fileIndex != index;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Files Result Hasil Penunjang
|
||||||
|
|
||||||
|
const fileHasilPenunjangInput = useRef<HTMLInputElement>(null);
|
||||||
|
const [fileHasilPenunjangs, setFileHasilPenunjangs] = useState<any>([]);
|
||||||
|
|
||||||
|
const handleResultInputChange = (event:any) => {
|
||||||
|
if (event.target.files[0]) {
|
||||||
|
setFileHasilPenunjangs([...fileHasilPenunjangs, ...event.target.files]);
|
||||||
|
} else {
|
||||||
|
console.log('NO FILE');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const removeFiles = (filesState:any, index:any) => {
|
||||||
|
setFileHasilPenunjangs(
|
||||||
|
filesState.filter((file:any, fileIndex:any) => {
|
||||||
|
return fileIndex != index;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Submit Form
|
||||||
|
const [submitLoading, setSubmitLoading] = useState(false);
|
||||||
|
function submitRequestFinalLog() {
|
||||||
|
if(selectedReason.value != '-'){
|
||||||
|
setSubmitLoading(true);
|
||||||
|
const formData = makeFormData({
|
||||||
|
request_logs_id: id,
|
||||||
|
result_files: fileHasilPenunjangs,
|
||||||
|
diagnosa_files: fileDiagnosas,
|
||||||
|
kondisi_files: fileKondisis,
|
||||||
|
reason: selectedReason.value
|
||||||
|
});
|
||||||
|
axios
|
||||||
|
.post(`/customer-service/request/${id}/add_file`, formData)
|
||||||
|
.then((response) => {
|
||||||
|
enqueueSnackbar('Berhasil membuat data', { variant: 'success' });
|
||||||
|
setOpenDialog(false);
|
||||||
|
window.location.reload()
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
enqueueSnackbar('Something Went Wrong', { variant: 'error' });
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setSubmitLoading(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setError('Please select a reason')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getContent = () => (
|
||||||
|
<Stack>
|
||||||
|
<Stack
|
||||||
|
divider={<Divider orientation="horizontal" flexItem />}
|
||||||
|
spacing={4}
|
||||||
|
sx={{ marginY: 2, marginBottom: 6 }}
|
||||||
|
>
|
||||||
|
{/* -------------------------------Upload Dokumen Hasil Penunjang------------------------------- */}
|
||||||
|
<Stack sx={{ marginTop: 2 }}>
|
||||||
|
{/* <Typography variant="body2">Hasil Lab, </Typography> */}
|
||||||
|
<Stack
|
||||||
|
divider={<Divider orientation="horizontal" flexItem />}
|
||||||
|
spacing={1}
|
||||||
|
sx={{ marginY: 2 }}
|
||||||
|
>
|
||||||
|
{fileHasilPenunjangs &&
|
||||||
|
fileHasilPenunjangs.map((file:any, index:any) => (
|
||||||
|
<Stack direction="row" justifyContent={'space-between'} key={index}>
|
||||||
|
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
||||||
|
<Iconify
|
||||||
|
icon="eva:trash-2-outline"
|
||||||
|
color={'darkred'}
|
||||||
|
onClick={() => {
|
||||||
|
removeFiles(fileHasilPenunjangs, index);
|
||||||
|
}}
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
></Iconify>
|
||||||
|
</Stack>
|
||||||
|
))}
|
||||||
|
|
||||||
|
</Stack>
|
||||||
|
{/* { JSON.stringify(filesResult) } */}
|
||||||
|
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
||||||
|
bgcolor: '#919EAB52',
|
||||||
|
borderRadius: '8px',
|
||||||
|
width: '100%', height: '60px'}} onClick={() => fileHasilPenunjangInput.current?.click()}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
placeItems: 'center',
|
||||||
|
gap: 1,
|
||||||
|
placeContent: 'center',
|
||||||
|
|
||||||
|
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
||||||
|
<Typography variant="body1" fontWeight="bold">
|
||||||
|
Add Files
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id="file"
|
||||||
|
ref={fileHasilPenunjangInput}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
multiple
|
||||||
|
onChange={handleResultInputChange}
|
||||||
|
accept="application/pdf,image/*"
|
||||||
|
/>
|
||||||
|
</ButtonBase>
|
||||||
|
<Typography variant="subtitle1" marginY={2}>Reason for Update*</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 updates"
|
||||||
|
variant="outlined"
|
||||||
|
name='reason'
|
||||||
|
error={Boolean(error)} // Menampilkan error jika ada
|
||||||
|
helperText={error} // Menampilkan pesan kesalahan
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
</Stack>
|
||||||
|
<LoadingButton
|
||||||
|
variant="contained"
|
||||||
|
sx={{ marginTop: 2, p: 2, backgroundColor: '#19BBBB' }}
|
||||||
|
onClick={() => {
|
||||||
|
submitRequestFinalLog();
|
||||||
|
}}
|
||||||
|
loading={submitLoading}
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: "Add Files"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="md"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import { yupResolver } from '@hookform/resolvers/yup';
|
|||||||
import { Controller, useForm } from 'react-hook-form';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
import React, { useRef, useEffect, useMemo, useState } from 'react';
|
import React, { useRef, useEffect, useMemo, useState } from 'react';
|
||||||
import axios from '../../../utils/axios';
|
import axios from '../../../utils/axios';
|
||||||
import { FormProvider, RHFTextField } from '../../../components/hook-form';
|
import { FormProvider, RHFDatepicker, RHFTextField } from '../../../components/hook-form';
|
||||||
|
|
||||||
import { makeFormData } from '@/utils/jsonToFormData';
|
import { makeFormData } from '@/utils/jsonToFormData';
|
||||||
import {
|
import {
|
||||||
@@ -31,6 +31,7 @@ import {
|
|||||||
Divider,
|
Divider,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
Box,
|
Box,
|
||||||
|
DialogActions,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import Iconify from '../../../components/Iconify';
|
import Iconify from '../../../components/Iconify';
|
||||||
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
||||||
@@ -39,7 +40,10 @@ import { fCurrency } from '../../../utils/formatNumber';
|
|||||||
import MemberSelectDialog from '../../../components/dialogs/MemberSelectDialog';
|
import MemberSelectDialog from '../../../components/dialogs/MemberSelectDialog';
|
||||||
import { Add, ArrowBackIosNew, DeleteOutline } from '@mui/icons-material';
|
import { Add, ArrowBackIosNew, DeleteOutline } from '@mui/icons-material';
|
||||||
import { ClaimRequest, Files } from '@/@types/claims';
|
import { ClaimRequest, Files } from '@/@types/claims';
|
||||||
import { fDateTimesecond } from '@/utils/formatTime';
|
import { fDateOnly, fDateTimesecond, fPostFormat } from '@/utils/formatTime';
|
||||||
|
import RHFDatePicker from '@/components/hook-form/RHFDatePickerV2';
|
||||||
|
import RHFDateTimePicker from '@/components/hook-form/v2/RHFDateTimePicker';
|
||||||
|
import MuiDialog from '@/components/MuiDialog';
|
||||||
|
|
||||||
interface FormValuesProps extends Partial<ClaimRequest> {
|
interface FormValuesProps extends Partial<ClaimRequest> {
|
||||||
taxes: boolean;
|
taxes: boolean;
|
||||||
@@ -57,7 +61,7 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
const { enqueueSnackbar } = useSnackbar();
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
|
||||||
const EditClaimSchema = Yup.object().shape({
|
const EditClaimSchema = Yup.object().shape({
|
||||||
organization_id: Yup.string().required('Code Provider is required'),
|
date: Yup.string().required('Date Submission is required'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultValues = useMemo(
|
const defaultValues = useMemo(
|
||||||
@@ -73,6 +77,16 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
[currentClaim]
|
[currentClaim]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const [date, setDate] = useState(currentClaim?.submission_date)
|
||||||
|
const id = currentClaim?.id
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setDate(currentClaim?.submission_date)
|
||||||
|
}, [currentClaim]);
|
||||||
|
|
||||||
|
console.log(date);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isEdit && currentClaim) {
|
if (isEdit && currentClaim) {
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
@@ -80,9 +94,6 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
if (!isEdit) {
|
if (!isEdit) {
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
}
|
}
|
||||||
// setFileKondisis(currentClaim?.files_by_type?.claim_diagnosis);
|
|
||||||
// setFileDiagnosas(currentClaim?.files_by_type?.claim_diagnosis);
|
|
||||||
setFileHasilPenunjangCurrent(currentClaim?.files_by_type?.claim_result);
|
|
||||||
}, [isEdit, currentClaim]);
|
}, [isEdit, currentClaim]);
|
||||||
|
|
||||||
|
|
||||||
@@ -97,99 +108,25 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
control,
|
control,
|
||||||
setValue,
|
setValue,
|
||||||
getValues,
|
getValues,
|
||||||
setError,
|
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
} = methods;
|
} = methods;
|
||||||
|
|
||||||
const values = watch();
|
|
||||||
|
|
||||||
const [isCheckingLimit, setIsCheckingLimit] = useState(false);
|
|
||||||
const [isEligible, setIsEligible] = useState(false);
|
|
||||||
const [memberBenefits, setMemberBenefits] = useState([]);
|
|
||||||
const [diagnosisOption, setDiagnosisOption] = useState([]);
|
|
||||||
const [isMemberDialogOpen, setIsMemberDialogOpen] = useState(false);
|
|
||||||
const [member, setMember] = useState({})
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
// Files Result Kondisi
|
|
||||||
const fileKondisiInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileKondisis, setFileKondisis] = useState<Files>([]);
|
|
||||||
|
|
||||||
const handleKondisiInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileKondisis([...fileKondisis, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeKondisiFiles = (filesState, index) => {
|
|
||||||
setFileKondisis(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Files Result Diagnosa
|
|
||||||
const fileDiagnosaInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileDiagnosas, setFileDiagnosas] = useState([]);
|
|
||||||
|
|
||||||
const handleDiagnosaInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileDiagnosas([...fileDiagnosas, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeDiagnosaFiles = (filesState, index) => {
|
|
||||||
setFileDiagnosas(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Files Result Hasil Penunjang
|
|
||||||
const fileHasilPenunjangInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileHasilPenunjangs, setFileHasilPenunjangs] = useState([]);
|
|
||||||
const [fileHasilPenunjangsCurrent, setFileHasilPenunjangCurrent] = useState([]);
|
|
||||||
|
|
||||||
const handleResultInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileHasilPenunjangs([...fileHasilPenunjangs, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeFiles = (filesState, index) => {
|
|
||||||
setFileHasilPenunjangs(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const onSubmit = async (data: FormValuesProps) => {
|
const onSubmit = async (data: FormValuesProps) => {
|
||||||
try {
|
try {
|
||||||
// const formData = new FormData();
|
const formData = new FormData();
|
||||||
// formData.append('result_files', fileHasilPenunjangs);
|
// formData.append('result_files', fileHasilPenunjangs);
|
||||||
// formData.append('diagnosa_files', fileDiagnosaInput);
|
// formData.append('diagnosa_files', fileDiagnosaInput);
|
||||||
// formData.append('kondisi_files', fileKondisiInput);
|
// formData.append('kondisi_files', fileKondisiInput);
|
||||||
// formData.append('provider_code', data.organization_id);
|
// formData.append('provider_code', data.organization_id);
|
||||||
// formData.append('_method', 'PUT');
|
// formData.append('_method', 'PUT');
|
||||||
const formData = makeFormData({
|
// formData.append('date', fPostFormat(id));
|
||||||
result_files: fileHasilPenunjangs,
|
|
||||||
diagnosa_files: fileDiagnosas,
|
|
||||||
kondisi_files: fileKondisis,
|
|
||||||
provider_code: data.organization_id,
|
|
||||||
_method: 'PUT'
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = await axios.put(`/claim-requests/${data.id}`, formData);
|
|
||||||
|
|
||||||
|
// const response = await axios.post(`/claim-requests/${data.id}/update`, formData);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
|
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
|
||||||
navigate('/claim-requests');
|
navigate('/claim-requests');
|
||||||
@@ -205,6 +142,118 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleApprove = () => {
|
||||||
|
if(selectedReason.value != '-'){
|
||||||
|
const formData = makeFormData({
|
||||||
|
date: fPostFormat(date),
|
||||||
|
reason: selectedReason.value,
|
||||||
|
});
|
||||||
|
const response = axios.post(`/claim-requests/${id}/update`, formData);
|
||||||
|
|
||||||
|
if (!response.error){
|
||||||
|
reset();
|
||||||
|
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
|
||||||
|
navigate('/claim-requests');
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar('Claim Request Updated Error!', { variant: 'error' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setError('Please select a reason')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const [openDialog, setOpenDialog] = useState(false);
|
||||||
|
const style1 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '30%'
|
||||||
|
}
|
||||||
|
const style2 = {
|
||||||
|
width: '70%'
|
||||||
|
}
|
||||||
|
const marginBottom1 = {
|
||||||
|
marginBottom: 1,
|
||||||
|
}
|
||||||
|
const marginBottom2 = {
|
||||||
|
marginBottom: 2,
|
||||||
|
}
|
||||||
|
const handleCloseDialog = () => {
|
||||||
|
setOpenDialog(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const reason = [
|
||||||
|
{ value: 'Wrong Setting', label: 'Wrong Setting' },
|
||||||
|
{ value: 'Hospital Request', label: 'Hospital Request' }
|
||||||
|
];
|
||||||
|
const [selectedReason, setSelectedReason] = React.useState({value:'-', label:''});
|
||||||
|
const [error, setError] = useState('');
|
||||||
|
|
||||||
|
const getContent = () => (
|
||||||
|
<Stack spacing={1} marginTop={2}>
|
||||||
|
<Typography variant="subtitle2">Are you sure to update this claim ?</Typography>
|
||||||
|
<Grid item xs={12} md={12} marginTop={4}>
|
||||||
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Code</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.code}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.member?.name}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Date of Submission</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{date ? fDateTimesecond(date) : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Claim Method</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.payment_type}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Service Type</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.service_name || '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Code Provider</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{currentClaim?.organization?.code || '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
|
<Typography variant="subtitle1" marginY={2}>Reason for Update*</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 updates"
|
||||||
|
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={() => handleApprove()}>Approve</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
||||||
@@ -254,12 +303,18 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
|
|
||||||
|
|
||||||
<Grid item xs={3}>
|
<Grid item xs={3}>
|
||||||
<RHFTextField InputProps={{endAdornment: (
|
<Controller
|
||||||
<InputAdornment position="end">
|
name="date"
|
||||||
<CalendarTodayIcon />
|
control={control}
|
||||||
</InputAdornment>
|
render={({ field }) => (
|
||||||
), }}
|
<RHFDateTimePicker
|
||||||
name="date" label="Date of Submission" disabled/>
|
{...field}
|
||||||
|
label="Date of Submission"
|
||||||
|
value={field.value || null}
|
||||||
|
onChange={() => setDate(field.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={3}>
|
||||||
<RHFTextField name="claim_method" label="Claim Method" disabled/>
|
<RHFTextField name="claim_method" label="Claim Method" disabled/>
|
||||||
@@ -268,161 +323,8 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
<RHFTextField name="service_type" label="Service Type*" disabled/>
|
<RHFTextField name="service_type" label="Service Type*" disabled/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={3}>
|
||||||
<RHFTextField name="organization_id" label="Code Provider*"/>
|
<RHFTextField name="organization_id" label="Code Provider*" disabled/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
{/* -------------------------------Upload Dokumen Kondisi------------------------------- */}
|
|
||||||
<React.Fragment>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant='h6'> Condition Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
{fileKondisis &&
|
|
||||||
fileKondisis.map((file, index) => (
|
|
||||||
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
||||||
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {
|
|
||||||
removeKondisiFiles(fileKondisis, index);
|
|
||||||
}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileKondisiInput.current?.click()}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
placeItems: 'center',
|
|
||||||
gap: 1,
|
|
||||||
placeContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
Add File
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
id="file"
|
|
||||||
ref={fileKondisiInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={handleKondisiInputChange}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
</Grid>
|
|
||||||
</React.Fragment>
|
|
||||||
{/* -------------------------------Upload Dokumen Diagnosa------------------------------- */}
|
|
||||||
<React.Fragment>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant='h6'> Diagnosis Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
{fileDiagnosas &&
|
|
||||||
fileDiagnosas.map((file, index) => (
|
|
||||||
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
||||||
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {
|
|
||||||
removeDiagnosaFiles(fileDiagnosas, index);
|
|
||||||
}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileDiagnosaInput.current?.click()}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
placeItems: 'center',
|
|
||||||
gap: 1,
|
|
||||||
placeContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
Add Result
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
id="file"
|
|
||||||
ref={fileDiagnosaInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={handleDiagnosaInputChange}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
</Grid>
|
|
||||||
</React.Fragment>
|
|
||||||
{/* -------------------------------Upload Result Hasil Penunjang------------------------------- */}
|
|
||||||
<React.Fragment>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography variant='h6'> Supporting Result Document</Typography>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
{fileHasilPenunjangs &&
|
|
||||||
fileHasilPenunjangs.map((file, index) => (
|
|
||||||
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
||||||
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {
|
|
||||||
removeFiles(fileHasilPenunjangs, index);
|
|
||||||
}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileHasilPenunjangInput.current?.click()}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
placeItems: 'center',
|
|
||||||
gap: 1,
|
|
||||||
placeContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
Add Result
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
id="file"
|
|
||||||
ref={fileHasilPenunjangInput}
|
|
||||||
style={{ display: 'none' }}
|
|
||||||
multiple
|
|
||||||
onChange={handleResultInputChange}
|
|
||||||
accept="application/pdf"
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
</Grid>
|
|
||||||
</React.Fragment>
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Card>
|
</Card>
|
||||||
<Grid container marginTop={3}>
|
<Grid container marginTop={3}>
|
||||||
@@ -440,17 +342,24 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<LoadingButton
|
<Button
|
||||||
type="submit"
|
// type="submit"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
size="large"
|
size="large"
|
||||||
loading={isSubmitting}
|
onClick={() => date ? setOpenDialog(true) : setOpenDialog(false)}
|
||||||
>
|
>
|
||||||
Update
|
Update
|
||||||
</LoadingButton>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<MuiDialog
|
||||||
|
title={{name: "Update Status"}}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
maxWidth="md"
|
||||||
|
/>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ export default function ClaimsCreateUpdate() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
axios.get('/claim-requests/' + id).then((res) => {
|
axios.get('/claim-requests/' + id).then((res) => {
|
||||||
console.log('Yeet', res.data);
|
|
||||||
setCurrentClaim(res.data.data);
|
setCurrentClaim(res.data.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// mui
|
// mui
|
||||||
import { Container, Grid, Stack, Typography, Card, TextField, Divider, ButtonBase, Box, IconButton } from '@mui/material';
|
import { Container, Grid, Stack, Typography, Card, TextField, Divider, ButtonBase, Box, IconButton, MenuItem } from '@mui/material';
|
||||||
// components
|
// components
|
||||||
import Page from '../../components/Page';
|
import Page from '../../components/Page';
|
||||||
// utils
|
// utils
|
||||||
@@ -8,7 +8,7 @@ import useSettings from '../../hooks/useSettings';
|
|||||||
import { useNavigate, useParams, useLocation } from 'react-router-dom';
|
import { useNavigate, useParams, useLocation } from 'react-router-dom';
|
||||||
import { useEffect, useState, useRef } from 'react';
|
import { useEffect, useState, useRef } from 'react';
|
||||||
import axios from '../../utils/axios';
|
import axios from '../../utils/axios';
|
||||||
// pages
|
// pages
|
||||||
import DetailTimeline from '../../pages/ClaimRequests/DetailTimeline';
|
import DetailTimeline from '../../pages/ClaimRequests/DetailTimeline';
|
||||||
import DetailStepper from '../../pages/ClaimRequests/DetailStepper';
|
import DetailStepper from '../../pages/ClaimRequests/DetailStepper';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
@@ -19,7 +19,7 @@ import RemoveIcon from '@mui/icons-material/Remove';
|
|||||||
import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||||
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||||
import Iconify from '@/components/Iconify';
|
import Iconify from '@/components/Iconify';
|
||||||
import { fPostFormat } from '@/utils/formatTime';
|
import { fDate, fPostFormat } from '@/utils/formatTime';
|
||||||
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
|
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
|
||||||
import DownloadIcon from '@mui/icons-material/Download';
|
import DownloadIcon from '@mui/icons-material/Download';
|
||||||
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
|
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
|
||||||
@@ -28,279 +28,509 @@ import { fDateTimesecond } from '@/utils/formatTime';
|
|||||||
import { makeFormData } from '@/utils/jsonToFormData';
|
import { makeFormData } from '@/utils/jsonToFormData';
|
||||||
|
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
import { DetailClaimRequest } from './Model/Types';
|
||||||
|
import { Delete, EditOutlined } from '@mui/icons-material';
|
||||||
|
import { fNumber } from '@/utils/formatNumber';
|
||||||
|
import palette from '@/theme/palette';
|
||||||
|
import MoreMenu from '@/components/MoreMenu';
|
||||||
|
import DialogUploadFileFinalLog from './Components/DialogUploadFileFinalLog';
|
||||||
|
import DialogDeleteFileLog from './Components/DialogDeleteFileLog';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export default function Detail() {
|
export default function Detail() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const queryParams = new URLSearchParams(location.search);
|
const queryParams = new URLSearchParams(location.search);
|
||||||
const code = queryParams.get('code');
|
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
const [data, setData] = useState();
|
const [claimRequests, setClaimRequest] = useState<DetailClaimRequest>();
|
||||||
const [dataDialog, setDataDialog] = useState();
|
|
||||||
const [document, setDocument] = useState(null);
|
|
||||||
|
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
axios
|
axios
|
||||||
.get('/claim-requests/detail/'+id)
|
.get('claim-requests/detail/'+id)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setData(response.data);
|
setClaimRequest(response.data.data)
|
||||||
setDataDialog(response.data.data.dialog_submits);
|
|
||||||
setDocument(response.data.data.documents);
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
|
||||||
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const [isInvoiceVisible, setInvoiceVisibility] = useState(false);
|
|
||||||
|
|
||||||
const handleInvoice = () => {
|
|
||||||
setInvoiceVisibility(!isInvoiceVisible);
|
|
||||||
}
|
|
||||||
const currentDate = new Date();
|
|
||||||
const formattedCurrentDate = format(currentDate, 'dd MMM yyyy');
|
|
||||||
const [dateInvoice, setDateInvoice] = useState(currentDate);
|
|
||||||
|
|
||||||
const fileInvoiceInput = useRef<HTMLInputElement>(null);
|
|
||||||
const [fileInvoices, setFileInvoices] = useState([]);
|
|
||||||
|
|
||||||
const handleInvoiceInputChange = (event) => {
|
|
||||||
if (event.target.files[0]) {
|
|
||||||
setFileInvoices([...fileInvoices, ...event.target.files]);
|
|
||||||
} else {
|
|
||||||
console.log('NO FILE');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const removeInvoiceFiles = (filesState, index) => {
|
|
||||||
setFileInvoices(
|
|
||||||
filesState.filter((file, fileIndex) => {
|
|
||||||
return fileIndex != index;
|
|
||||||
})
|
})
|
||||||
);
|
}, [id]);
|
||||||
};
|
|
||||||
const date = dateInvoice ? fPostFormat(dateInvoice, 'yyyy-MM-dd') : null;
|
function toTitleCase(str: string | null) {
|
||||||
|
return str.replace(/\w\S*/g, function(txt) {
|
||||||
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const style1 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '30%'
|
||||||
|
}
|
||||||
|
const style2 = {
|
||||||
|
width: '70%'
|
||||||
|
}
|
||||||
|
const style3 = {
|
||||||
|
color: '#919EAB',
|
||||||
|
width: '35%'
|
||||||
|
}
|
||||||
|
const marginBottom1 = {
|
||||||
|
marginBottom: 1,
|
||||||
|
}
|
||||||
|
|
||||||
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
||||||
const handleCloseDialogSubmit = () => {
|
const handleCloseDialogSubmit = () => {
|
||||||
setOpenDialogSubmit(false);
|
setOpenDialogSubmit(false);
|
||||||
}
|
}
|
||||||
const handleSubmitData = () => {
|
const [approve, setApprove] = useState('');
|
||||||
// if(fileInvoices.length > 0)
|
|
||||||
// {
|
|
||||||
//submit data
|
|
||||||
axios
|
|
||||||
.post('claim-requests/'+id+'/approve')
|
|
||||||
.then((response) => {
|
|
||||||
enqueueSnackbar('Success Submit Claim Request', { variant: 'success' });
|
|
||||||
setOpenDialogSubmit(false);
|
|
||||||
})
|
|
||||||
.catch(({ response }) => {
|
|
||||||
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
|
||||||
});
|
|
||||||
//Upload file invoices
|
|
||||||
const formData = makeFormData({
|
|
||||||
date:date,
|
|
||||||
invoice_files: fileInvoices,
|
|
||||||
});
|
|
||||||
axios
|
|
||||||
.post('claim-requests/'+id+'/invoice-files', formData)
|
|
||||||
.then((response) => {
|
|
||||||
enqueueSnackbar(response.data.message ?? 'Success upload invoice', { variant: 'success' });
|
|
||||||
})
|
|
||||||
.catch(({ response }) => {
|
|
||||||
enqueueSnackbar(response.data.message ?? 'Something Went Wrong', { variant: 'error' });
|
|
||||||
});
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// enqueueSnackbar('Please upload file invoice, before submit', { variant: 'warning' });
|
|
||||||
// }
|
|
||||||
|
|
||||||
setTimeout(() =>
|
// Handle Delete File LOG
|
||||||
{
|
const [pathFile, setPathFile] = useState('')
|
||||||
window.location.reload();
|
const [dialogDeleteFIleLog, setDialogDeleteFileLog] = useState(false)
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
};
|
// Handle Upload File LOG
|
||||||
|
const [dialogUploadFileLog, setDialogUploadFileLog] = useState(false)
|
||||||
const check_invoice = document?.find((dataInvoice) => dataInvoice.type === 'claim-invoice');
|
|
||||||
|
|
||||||
|
// Buat total data
|
||||||
|
const totalAmountIncurred = (claimRequests?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
|
return accumulator + (item.amount_incurred || 0);
|
||||||
|
}, 0);
|
||||||
|
const totalAmountApprove = (claimRequests?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
|
return accumulator + (item.amount_approved || 0);
|
||||||
|
}, 0);
|
||||||
|
const totalAmountNotApprove = (claimRequests?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
|
return accumulator + (item.amount_not_approved || 0);
|
||||||
|
}, 0);
|
||||||
|
const totalExcessPaid = (claimRequests?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
|
return accumulator + (item.excess_paid || 0);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page title='Detail'>
|
<Page title='Detail'>
|
||||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||||
<Stack direction="row" alignItems="center" sx={{ marginBottom: 3 }}>
|
<Stack direction="row" alignItems="center" sx={{ marginBottom: 3 }}>
|
||||||
<ArrowBackIosIcon onClick={() => navigate(-1)} sx={{cursor:'pointer'}}/>
|
<ArrowBackIosIcon onClick={() => navigate(-1)} sx={{cursor:'pointer'}}/>
|
||||||
<Typography variant="h5" sx={{marginLeft:2}}>{(data && data.data) ? data.data.status.code : ''}</Typography>
|
<Typography variant="h5" sx={{marginLeft:2}}>{(claimRequests && claimRequests.code ? claimRequests.code : '')}</Typography>
|
||||||
{data ? (
|
|
||||||
<Stack direction="row" spacing={2} ml="auto">
|
|
||||||
<Typography variant="body2" sx={{color: '#757575'}}>Submission Date</Typography>
|
|
||||||
<Typography variant="body2" fontWeight="bold">{(data && data.data) ? format(new Date(data.data.status.submission_date), "d MMM yyyy") : ''}</Typography>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
) : ''}
|
|
||||||
</Stack>
|
|
||||||
{data ? (
|
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
|
{/* Detail */}
|
||||||
<Grid item xs={12} md={12}>
|
<Grid item xs={12} md={12}>
|
||||||
<DetailStepper data={data}/>
|
<Card sx={{padding:2}} >
|
||||||
</Grid>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={12} md={12}>
|
<Grid item xs={6}>
|
||||||
<Stack direction="row" alignItems="center">
|
<Typography variant='subtitle1' sx={{ color: '#19BBBB', marginBottom: 4 }} gutterBottom>
|
||||||
<Typography variant="subtitle1">Format Claim</Typography>
|
Details
|
||||||
<Button variant="outlined" color="primary" startIcon={< DownloadIcon/>} sx={{marginLeft: 'auto'}}>
|
|
||||||
<Typography variant="button" display="block">Import</Typography>
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
{check_invoice ? (
|
|
||||||
<Grid item xs={12} md={12}>
|
|
||||||
<Stack direction="row" alignItems="center">
|
|
||||||
<Typography variant="subtitle1">Request Claim</Typography>
|
|
||||||
<Button variant="outlined" color="primary" startIcon={ isInvoiceVisible ? < RemoveIcon/> : < AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => handleInvoice()}>
|
|
||||||
<Typography variant="button" display="block">Invoice</Typography>
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
|
||||||
</Grid>
|
|
||||||
) : ''}
|
|
||||||
<Grid item xs={12} md={12} sx={{display : isInvoiceVisible ? '' : 'none',}}>
|
|
||||||
<Card sx={{padding: 2}}>
|
|
||||||
<Stack direction="column" spacing={2}>
|
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
|
||||||
<DatePicker
|
|
||||||
label="Invoice Date"
|
|
||||||
value={dateInvoice}
|
|
||||||
onChange={(newValue) => {
|
|
||||||
setDateInvoice(newValue);
|
|
||||||
}}
|
|
||||||
inputFormat="dd MMM yyyy"
|
|
||||||
renderInput={(params) => <TextField sx={{width:'40%'}} {...params} defaultValue={formattedCurrentDate} required/>}
|
|
||||||
/>
|
|
||||||
</LocalizationProvider>
|
|
||||||
<Stack
|
|
||||||
divider={<Divider orientation="horizontal" flexItem />}
|
|
||||||
spacing={1}
|
|
||||||
sx={{ marginY: 2 }}
|
|
||||||
>
|
|
||||||
{fileInvoices &&
|
|
||||||
fileInvoices.map((file, index) => (
|
|
||||||
<Stack direction="row" justifyContent={'space-between'} key={index}>
|
|
||||||
<Stack direction="row" spacing={1} sx={{color: '#19BBBB'}}>
|
|
||||||
<InsertDriveFileIcon />
|
|
||||||
<Typography variant="body2" gutterBottom>{file.name ? file.name : '-'}</Typography>
|
|
||||||
</Stack>
|
|
||||||
<Iconify
|
|
||||||
icon="eva:trash-2-outline"
|
|
||||||
color={'darkred'}
|
|
||||||
onClick={() => {
|
|
||||||
removeInvoiceFiles(fileInvoices, index);
|
|
||||||
}}
|
|
||||||
sx={{cursor: 'pointer'}}
|
|
||||||
></Iconify>
|
|
||||||
</Stack>
|
|
||||||
))}
|
|
||||||
</Stack>
|
|
||||||
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
||||||
bgcolor: '#919EAB52',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '100%', height: '60px'}} onClick={() => fileInvoiceInput.current?.click()}>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
placeItems: 'center',
|
|
||||||
gap: 1,
|
|
||||||
placeContent: 'center',
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
Upload Invoice
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Grid>
|
||||||
<input
|
</Grid>
|
||||||
type="file"
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
id="file"
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Provider Name</Typography>
|
||||||
ref={fileInvoiceInput}
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.provider}</Typography>
|
||||||
style={{ display: 'none' }}
|
</Stack>
|
||||||
multiple
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
onChange={handleInvoiceInputChange}
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Member ID</Typography>
|
||||||
accept="application/pdf"
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.member_id}</Typography>
|
||||||
/>
|
</Stack>
|
||||||
</ButtonBase>
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Policy Number</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.policy_number}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.name}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Date Of Birth</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.date_of_birth ? fDate(claimRequests?.date_of_birth) : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Marital Status</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.marital_status}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Submission Date</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.submission_date ? fDateTimesecond(claimRequests?.submission_date) : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>No KTP</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.no_identitas ? claimRequests?.no_identitas : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Keterangan</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.keterangan ? claimRequests?.keterangan : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Hak Kamar Pasien</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.hak_kamar_pasien ? claimRequests?.hak_kamar_pasien : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Penempatan Kamar</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.penempatan_kamar ? claimRequests?.penempatan_kamar : '-'}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style3} gutterBottom>Diagnosis</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>
|
||||||
|
{claimRequests?.diagnosis?.length > 0 ? (
|
||||||
|
<ul>
|
||||||
|
{claimRequests?.diagnosis.map((diagnosisItem, index) => (
|
||||||
|
<li key={index}>{diagnosisItem.code} - {diagnosisItem.name}</li>
|
||||||
|
// Replace 'name' with the property you want to display
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
) : (
|
||||||
|
<p>No diagnosis available.</p>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} md={12}>
|
|
||||||
<DetailTimeline data={data}/>
|
{/* Service */}
|
||||||
|
<Grid item xs={12} md={12} marginTop={2}>
|
||||||
|
<Card sx={{padding:2}} >
|
||||||
|
<Typography variant='subtitle1' sx={{color: '#19BBBB', marginBottom: 4}} gutterBottom>Service</Typography>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Service Type</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.service_type}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Claim Method</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{toTitleCase(claimRequests?.claim_method ?? '-')}</Typography>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
{/* Document */}
|
||||||
<Grid item xs={12} md={12}>
|
<Grid item xs={12} md={12}>
|
||||||
<Stack direction="row" padding={4}>
|
<Card sx={{padding:2}} >
|
||||||
{dataDialog && dataDialog.status === 'requested' ? (
|
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{marginBottom: 4}}>
|
||||||
<>
|
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
||||||
<Button variant="outlined" sx={{color: '#212B36', marginLeft: 'auto', borderColor: '#919EAB52'}} >Cancel</Button>
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Document </Typography>
|
||||||
<Button sx={{backgroundColor: '#19BBBB', marginLeft: 1}} variant="contained" onClick={()=> setOpenDialogSubmit(true)}>Submit</Button>
|
|
||||||
</>
|
|
||||||
) : ''}
|
|
||||||
{/* Dialog Submits */}
|
|
||||||
<Dialog open={openDialogSubmit} onClose={handleCloseDialogSubmit} fullWidth={true}>
|
|
||||||
<DialogTitle sx={{ backgroundColor: '#19BBBB', color: '#FFF', padding: 2 }}>
|
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
||||||
<Stack direction="row" alignItems='center' spacing={1}>
|
|
||||||
<Typography variant="h6">Confirmation</Typography>
|
|
||||||
</Stack>
|
|
||||||
<IconButton sx={{ color: '#FFF' }} onClick={handleCloseDialogSubmit}>
|
|
||||||
<CloseIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</DialogTitle>
|
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
||||||
<DialogContent>
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
{dataDialog ? (
|
setDialogUploadFileLog(true)
|
||||||
<Stack spacing={2} padding={2}>
|
}} >
|
||||||
<Typography variant='body1'>Are you sure to submit this claim ?</Typography>
|
<Typography variant="button" display="block">File</Typography>
|
||||||
<Card sx={{padding:2}} >
|
</Button>
|
||||||
<Stack direction='row' spacing={2}>
|
</Stack>
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Code</Typography>
|
</Stack>
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>{dataDialog.code}</Typography>
|
{claimRequests?.files?.map((documentType, index) => (
|
||||||
</Stack>
|
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{marginBottom: 2}} key={index}>
|
||||||
<Stack direction='row' spacing={2}>
|
<Stack direction="column" spacing={2} >
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Name</Typography>
|
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>{dataDialog.name}</Typography>
|
<a
|
||||||
</Stack>
|
href={documentType.url}
|
||||||
<Stack direction='row' spacing={2}>
|
style={{
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Date Submission</Typography>
|
cursor: 'pointer',
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>{fDateTimesecond(dataDialog.submission_date)}</Typography>
|
textDecoration: 'none',
|
||||||
</Stack>
|
color: '#19BBBB',
|
||||||
<Stack direction='row' spacing={2}>
|
display: 'flex',
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Claim Method</Typography>
|
alignItems: 'center' // Menjadikan konten dalam satu garis vertikal
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>Service Type</Typography>
|
}}
|
||||||
</Stack>
|
target="_blank"
|
||||||
<Stack direction='row' spacing={2}>
|
>
|
||||||
<Typography variant='subtitle2' sx={{color: '#919EAB', width: '30%'}}>Service Type</Typography>
|
<InsertDriveFileIcon style={{ marginRight: '5px' }} />
|
||||||
<Typography variant='subtitle2' sx={{width: '70%'}}>
|
<Typography variant="body1" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
|
||||||
{dataDialog.service_code === 'IP' ? 'Inpatient' : 'Outpatient'}
|
</a>
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
</Card>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
) : ''}
|
<Stack direction="column" spacing={2}>
|
||||||
</DialogContent>
|
<IconButton onClick={() => {
|
||||||
<DialogActions>
|
setDialogDeleteFileLog(true)
|
||||||
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialogSubmit}>Cancel</Button>
|
setPathFile(documentType.path)
|
||||||
<Button sx={{backgroundColor: '#19BBBB'}} onClick={handleSubmitData} variant="contained">Submit</Button>
|
}} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}>
|
||||||
</DialogActions>
|
<Delete color='error' fontSize="small" />
|
||||||
</Dialog>
|
</IconButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<DialogDeleteFileLog
|
||||||
|
id={claimRequests?.request_log_id}
|
||||||
|
path={pathFile}
|
||||||
|
setOpenDialog={setDialogDeleteFileLog}
|
||||||
|
openDialog={dialogDeleteFIleLog}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DialogUploadFileFinalLog
|
||||||
|
id={claimRequests?.request_log_id}
|
||||||
|
setOpenDialog={setDialogUploadFileLog}
|
||||||
|
openDialog={dialogUploadFileLog}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Benefit */}
|
||||||
|
<Grid item xs={12} md={12}>
|
||||||
|
<Card sx={{padding:2}} >
|
||||||
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Benefit</Typography>
|
||||||
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
|
// setDialogBenefit(true);
|
||||||
|
}} >
|
||||||
|
<Typography variant="button" display="block">Benefit</Typography>
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Box sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '24px', py: '20px', marginBottom: '24px', borderRadius: '12px'}}>
|
||||||
|
{claimRequests?.benefit_data?.map((item, index) => (
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container >
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
|
||||||
|
{item.benefit?.description}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
|
||||||
|
<MoreMenu actions={
|
||||||
|
<>
|
||||||
|
<MenuItem onClick={() => {
|
||||||
|
// setDialogEditBenefit(true)
|
||||||
|
// setIdBenefitData(item.id)
|
||||||
|
// setBenefitConfigurationData(item)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<EditOutlined />
|
||||||
|
Edit
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem onClick={() => {
|
||||||
|
// setIdBenefitData(item.id)
|
||||||
|
// setDialogDeleteBenefit(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Delete color='error'/>
|
||||||
|
Delete
|
||||||
|
</MenuItem>
|
||||||
|
</>
|
||||||
|
} />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} py={2}>
|
||||||
|
<Box sx={{ py: '8px', px: '12px', background: palette.light.grey[50012], borderRadius: '6px'}}>
|
||||||
|
<Grid container spacing={1}>
|
||||||
|
|
||||||
|
{/* Amount Incurred */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Incurred
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.amount_incurred)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Amount Approved */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Approved
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.amount_approved)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Amount Not Approved */}
|
||||||
|
<Grid item xs={3}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Not Approved
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.amount_not_approved)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Excess Paid* */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Excess Paid*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(item.excess_paid)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Keterangan* */}
|
||||||
|
<Grid item xs={3}>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Keterangan*
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{item.keterangan}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
<hr />
|
||||||
|
<br />
|
||||||
|
{claimRequests?.benefit_data && claimRequests.benefit_data.length > 0 ? (
|
||||||
|
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
|
||||||
|
Total Benefit
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Box sx={{ py: '8px', px: '12px', background: palette.light.grey[50012], borderRadius: '6px'}}>
|
||||||
|
<Grid container spacing={1}>
|
||||||
|
|
||||||
|
{/* Amount Incurred */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Incurred
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(totalAmountIncurred)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Amount Approved */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Approved
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(totalAmountApprove)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Amount Not Approved */}
|
||||||
|
<Grid item xs={3}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Amount Not Approved
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(totalAmountNotApprove)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Excess Paid* */}
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption">
|
||||||
|
Excess Paid
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{fNumber(totalExcessPaid)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
null
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* PR Buat pindahin ke componen */}
|
||||||
|
{/* <CardBenefit
|
||||||
|
requestLog={requestLog}
|
||||||
|
>
|
||||||
|
|
||||||
|
</CardBenefit> */}
|
||||||
|
{/* <DialogBenefit
|
||||||
|
requestLog={requestLog}
|
||||||
|
openDialog={openDialogBenefit}
|
||||||
|
setOpenDialog={setDialogBenefit}
|
||||||
|
|
||||||
|
/>
|
||||||
|
{/* Dialog Edit */}
|
||||||
|
{/* <DialogEditBenefit
|
||||||
|
id={idBenefitData}
|
||||||
|
data={BenefitConfigurationData}
|
||||||
|
openDialog={openDialogEditBenefit}
|
||||||
|
setOpenDialog={setDialogEditBenefit}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
{/* Dialog Delete */}
|
||||||
|
{/* <DialogDeleteBenfit
|
||||||
|
id={idBenefitData}
|
||||||
|
openDialog={openDialogDeleteBenefit}
|
||||||
|
setOpenDialog={setDialogDeleteBenefit}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
{/* Dialog Edit Detai; */}
|
||||||
|
{/* <DialogEditFinalLOG
|
||||||
|
setOpenDialog={setDialogDEditDetail}
|
||||||
|
requestLog={requestLog}
|
||||||
|
openDialog={openDialogEditDetail}
|
||||||
|
/> */}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
) : ''}
|
|
||||||
</Container>
|
</Container>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
Chip,
|
Chip,
|
||||||
TableHead,
|
TableHead,
|
||||||
Grid,
|
Grid,
|
||||||
|
Autocomplete,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||||
@@ -43,25 +44,59 @@ import { enqueueSnackbar } from 'notistack';
|
|||||||
import { Divider } from '@mui/material';
|
import { Divider } from '@mui/material';
|
||||||
import Iconify from '@/components/Iconify';
|
import Iconify from '@/components/Iconify';
|
||||||
import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim';
|
import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim';
|
||||||
import { fDateTimesecond } from '@/utils/formatTime';
|
import { fDateOnly, fDateTimesecond } from '@/utils/formatTime';
|
||||||
import { capitalizeFirstLetter } from '@/utils/formatString';
|
import { capitalizeFirstLetter } from '@/utils/formatString';
|
||||||
import Label from '@/components/Label';
|
import Label from '@/components/Label';
|
||||||
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
||||||
import { Import } from '@/@types/claims';
|
import { Import } from '@/@types/claims';
|
||||||
|
import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||||
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||||
// import LoadingButton from '@/theme/overrides/LoadingButton';
|
// import LoadingButton from '@/theme/overrides/LoadingButton';
|
||||||
|
|
||||||
export default function List() {
|
export default function List() {
|
||||||
|
type ServiceCode = {
|
||||||
|
value: string,
|
||||||
|
label: string
|
||||||
|
}
|
||||||
const { themeColorPresets } = useSettings();
|
const { themeColorPresets } = useSettings();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const [importResult, setImportResult] = useState<Import>(null);
|
const [importResult, setImportResult] = useState<Import>(null);
|
||||||
|
const [selectedOptions, setSelectedOptions] = useState<ServiceCode|undefined>([]); // State untuk nilai terpilih
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
const defaultValue = [
|
||||||
|
{
|
||||||
|
value: '-',
|
||||||
|
label: '-'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const [serviceCode, setServiceCode] = useState(defaultValue);
|
||||||
|
|
||||||
|
const handleOptionService = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFilter = (event: React.SyntheticEvent<Element, Event>, newValue: { value: string, label: string }[], name:string) => { //
|
||||||
|
const serviceCodeArray :string[] = [];
|
||||||
|
const codeArray :string[] = [];
|
||||||
|
const typeArray :string[] = [];
|
||||||
|
const planArray :string[] = [];
|
||||||
|
if (name == 'service_code'){
|
||||||
|
newValue.map(row => {
|
||||||
|
serviceCodeArray.push(row.value);
|
||||||
|
})
|
||||||
|
setSelectedOptions(newValue)
|
||||||
|
}
|
||||||
|
var entries = [...searchParams.entries(), ['service_code', serviceCodeArray ?? '']];
|
||||||
|
const filter = Object.fromEntries(entries);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
}
|
||||||
|
|
||||||
function SearchInput(props: any) {
|
function SearchInput(props: any) {
|
||||||
// SEARCH
|
// SEARCH
|
||||||
const searchInput = useRef<HTMLInputElement>(null);
|
const searchInput = useRef<HTMLInputElement>(null);
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
|
|
||||||
const handleSearchChange = (event: any) => {
|
const handleSearchChange = (event: any) => {
|
||||||
const newSearchText = event.target.value ?? '';
|
const newSearchText = event.target.value ?? '';
|
||||||
setSearchText(newSearchText);
|
setSearchText(newSearchText);
|
||||||
@@ -79,16 +114,83 @@ export default function List() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSearchSubmit} style={{ width: '100%' }}>
|
<form onSubmit={handleSearchSubmit} style={{ width: '100%' }}>
|
||||||
<TextField
|
<Grid container spacing={2} >
|
||||||
id="search-input"
|
<Grid item md={5}>
|
||||||
ref={searchInput}
|
<TextField
|
||||||
label="Search"
|
id="search-input"
|
||||||
variant="outlined"
|
ref={searchInput}
|
||||||
fullWidth
|
label="Search"
|
||||||
onChange={handleSearchChange}
|
variant="outlined"
|
||||||
value={searchText}
|
fullWidth
|
||||||
placeholder='Search Code or Name...'
|
onChange={handleSearchChange}
|
||||||
/>
|
value={searchText}
|
||||||
|
placeholder='Search Code or Name...'
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item md={2}>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DesktopDatePicker
|
||||||
|
label="Start Date"
|
||||||
|
value={searchParams.get('start_date')}
|
||||||
|
inputFormat="dd/MM/yyyy"
|
||||||
|
onChange={(value) => {
|
||||||
|
try {
|
||||||
|
if (value && !!Date.parse(value)) {
|
||||||
|
const date:string = value ? fDateOnly(value) : '';
|
||||||
|
var entries = [...searchParams.entries(), ['start_date', date ?? '']];
|
||||||
|
const filter = Object.fromEntries(entries);
|
||||||
|
setSearchParams(filter);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}}
|
||||||
|
renderInput={(params) => <TextField {...params} variant="outlined" />}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</Grid>
|
||||||
|
<Grid item md={2}>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DesktopDatePicker
|
||||||
|
label="End Date"
|
||||||
|
inputFormat="MM/dd/yyyy"
|
||||||
|
value={searchParams.get('end_date')}
|
||||||
|
onChange={(value) => {
|
||||||
|
try {
|
||||||
|
if (value && !!Date.parse(value)) {
|
||||||
|
const date = fDateOnly(value);
|
||||||
|
var entries = [...searchParams.entries(), ['end_date', date ?? '']];
|
||||||
|
const filter = Object.fromEntries(entries);
|
||||||
|
setSearchParams(filter);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}}
|
||||||
|
renderInput={(params) => <TextField {...params} variant="outlined" />}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</Grid>
|
||||||
|
<Grid item md={3}>
|
||||||
|
<Autocomplete
|
||||||
|
id="combo-box-demo"
|
||||||
|
options={serviceCode}
|
||||||
|
multiple
|
||||||
|
limitTags={1}
|
||||||
|
value={selectedOptions}
|
||||||
|
onChange={
|
||||||
|
(event, newValue) => handleFilter(event, newValue, 'service_code')
|
||||||
|
}
|
||||||
|
fullWidth
|
||||||
|
disableCloseOnSelect
|
||||||
|
getOptionLabel={(option) => option.label}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField {...params} label="Service" variant="outlined" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -279,11 +381,21 @@ export default function List() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||||
|
|
||||||
|
axios.get('service').then((response) => {
|
||||||
|
const formattedData = response.data.data.map(service => ({
|
||||||
|
value: service.code,
|
||||||
|
label: service.name
|
||||||
|
}));
|
||||||
|
setServiceCode(formattedData);
|
||||||
|
});
|
||||||
|
|
||||||
setDataTableLoading(true);
|
setDataTableLoading(true);
|
||||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||||
const response = await axios.get('/claim-requests', { params: filter });
|
const response = await axios.get('/claim-requests', { params: filter });
|
||||||
// console.log(response.data);
|
console.log(response.data);
|
||||||
setDataTableLoading(false);
|
setDataTableLoading(false);
|
||||||
|
|
||||||
|
|
||||||
setDataTableData(response.data);
|
setDataTableData(response.data);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,3 +23,61 @@ export type ServiceType = {
|
|||||||
code : string
|
code : string
|
||||||
name : string
|
name : string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type DetailClaimRequest = {
|
||||||
|
id : number,
|
||||||
|
code : string,
|
||||||
|
member_id : string,
|
||||||
|
policy_number : string,
|
||||||
|
name : string,
|
||||||
|
date_of_birth : string,
|
||||||
|
gender : string,
|
||||||
|
marital_status : string,
|
||||||
|
submission_date : string,
|
||||||
|
service_type : string,
|
||||||
|
claim_method : string,
|
||||||
|
no_identitas : string,
|
||||||
|
keterangan : string,
|
||||||
|
hak_kamar_pasien : string,
|
||||||
|
penempatan_kamar : string,
|
||||||
|
provider : string,
|
||||||
|
status : string,
|
||||||
|
request_log_id : number,
|
||||||
|
benefit : Benefit[],
|
||||||
|
reason : string,
|
||||||
|
files : file[],
|
||||||
|
benefit_data : BenefitData[],
|
||||||
|
diagnosis : Diagnosis[],
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Benefit = {
|
||||||
|
code: string,
|
||||||
|
description: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BenefitData = {
|
||||||
|
amount_incurred : number,
|
||||||
|
amount_approved : number,
|
||||||
|
amount_not_approved : number,
|
||||||
|
excess_paid : number,
|
||||||
|
keterangan : string,
|
||||||
|
benefit : Benefit,
|
||||||
|
request_log_id : number,
|
||||||
|
benefit_name : string,
|
||||||
|
description : string,
|
||||||
|
id : number,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Diagnosis = {
|
||||||
|
id : number,
|
||||||
|
name : string,
|
||||||
|
code : string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type file = {
|
||||||
|
original_name: string,
|
||||||
|
name: string,
|
||||||
|
path: string,
|
||||||
|
url: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user