Merge remote-tracking branch 'origin/staging' into origin/production
This commit is contained in:
@@ -316,8 +316,8 @@ class ClaimController extends Controller
|
|||||||
// ->where('request_logs.status_final_log', '=', 'approved')
|
// ->where('request_logs.status_final_log', '=', 'approved')
|
||||||
->where('request_logs.deleted_at', '=', null)
|
->where('request_logs.deleted_at', '=', null)
|
||||||
->when($start != 'all' && $end != 'all', function ($query) use ($start, $end) {
|
->when($start != 'all' && $end != 'all', function ($query) use ($start, $end) {
|
||||||
$query->where('request_logs.submission_date', '>=', $start)
|
$query->where('request_logs.submission_date', '>=',Carbon::parse($start)->subDay())
|
||||||
->where('request_logs.submission_date', '<=', Carbon::parse($end)->addDay());
|
->where('request_logs.submission_date', '<=',Carbon::parse($end)->addDay());
|
||||||
})
|
})
|
||||||
->select(
|
->select(
|
||||||
DB::raw('1 AS no'),
|
DB::raw('1 AS no'),
|
||||||
|
|||||||
@@ -19,7 +19,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 = 'CP';
|
private static $code_prefix = 'CLAIM';
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return view('client::index');
|
return view('client::index');
|
||||||
@@ -224,10 +224,6 @@ class ClaimRequestController extends Controller
|
|||||||
|
|
||||||
public static function getNextCode()
|
public static function getNextCode()
|
||||||
{
|
{
|
||||||
// $last_number = ClaimRequest::max('code');
|
|
||||||
// $next_number = empty($last_number) ? 1 : ((int) explode('-', $last_number)[2] + 1);
|
|
||||||
// return self::makeCode($next_number);
|
|
||||||
|
|
||||||
$last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, "-", -1) AS SIGNED)) as max_numeric_code'))
|
$last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, "-", -1) AS SIGNED)) as max_numeric_code'))
|
||||||
->whereRaw('SUBSTRING_INDEX(code, "-", -1) REGEXP "^[0-9]+$"')
|
->whereRaw('SUBSTRING_INDEX(code, "-", -1) REGEXP "^[0-9]+$"')
|
||||||
->value('max_numeric_code');
|
->value('max_numeric_code');
|
||||||
@@ -247,8 +243,14 @@ class ClaimRequestController extends Controller
|
|||||||
{
|
{
|
||||||
// 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, 6, '0', STR_PAD_LEFT);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ class CorporateMemberController extends Controller
|
|||||||
'service:code,name',
|
'service:code,name',
|
||||||
'files',
|
'files',
|
||||||
])
|
])
|
||||||
->find($request_log_id, ['id', 'submission_date', 'discharge_date', 'member_id', 'service_code', 'organization_id', 'diagnosis']);
|
->find($request_log_id, ['id', 'submission_date', 'discharge_date', 'member_id', 'service_code', 'organization_id', 'diagnosis', 'keterangan', 'catatan']);
|
||||||
|
|
||||||
$dataBenefit = [];
|
$dataBenefit = [];
|
||||||
if (count($data->requestLogBenefits) > 0) {
|
if (count($data->requestLogBenefits) > 0) {
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ class DataServiceMonitoring extends JsonResource
|
|||||||
'name' => $requestLogBenefit->benefit->description,
|
'name' => $requestLogBenefit->benefit->description,
|
||||||
];
|
];
|
||||||
})->all() ?? null,
|
})->all() ?? null,
|
||||||
|
'keterangan' => $this->keterangan ?? null,
|
||||||
|
'catatan' => $this->catatan ?? null,
|
||||||
'benefitTotal' => $this->benefitTotal ?? null,
|
'benefitTotal' => $this->benefitTotal ?? null,
|
||||||
'hospital' => $this->organization->name ?? null,
|
'hospital' => $this->organization->name ?? null,
|
||||||
'admissionDate' => $this->submission_date ?? null,
|
'admissionDate' => $this->submission_date ?? null,
|
||||||
|
|||||||
@@ -133,10 +133,21 @@ class ClaimRequestController extends Controller
|
|||||||
|
|
||||||
if ($request->hasFile('additional_files')) {
|
if ($request->hasFile('additional_files')) {
|
||||||
foreach ($request->additional_files as $file) {
|
foreach ($request->additional_files as $file) {
|
||||||
$pathFile = File::storeFile('additional-files', $newClaimRequest->id, $file);
|
$pathFile = File::storeFile('additional-files', $request->request_logs_id, $file);
|
||||||
$newClaimRequest->files()->updateOrCreate([
|
// $newClaimRequest->files()->updateOrCreate([
|
||||||
|
// 'type' => 'additional-files',
|
||||||
|
// 'name' => File::getFileName('additional-files', $newClaimRequest->id, $file),
|
||||||
|
// 'original_name' => $file->getClientOriginalName(),
|
||||||
|
// 'extension' => $file->getClientOriginalExtension(),
|
||||||
|
// 'path' => $pathFile,
|
||||||
|
// 'created_by' => auth()->user()->id,
|
||||||
|
// 'updated_by' => auth()->user()->id,
|
||||||
|
// ]);
|
||||||
|
File::updateOrCreate([
|
||||||
|
'fileable_type' => 'App\Models\RequestLog',
|
||||||
|
'fileable_id' => $request->request_logs_id,
|
||||||
'type' => 'additional-files',
|
'type' => 'additional-files',
|
||||||
'name' => File::getFileName('additional-files', $newClaimRequest->id, $file),
|
'name' => File::getFileName('additional-files', $request->request_logs_id, $file),
|
||||||
'original_name' => $file->getClientOriginalName(),
|
'original_name' => $file->getClientOriginalName(),
|
||||||
'extension' => $file->getClientOriginalExtension(),
|
'extension' => $file->getClientOriginalExtension(),
|
||||||
'path' => $pathFile,
|
'path' => $pathFile,
|
||||||
@@ -265,7 +276,6 @@ class ClaimRequestController extends Controller
|
|||||||
$date = date('ymd');
|
$date = date('ymd');
|
||||||
// Menghasilkan kode dengan format yang diinginkan
|
// Menghasilkan kode dengan format yang diinginkan
|
||||||
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 . $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)
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ use App\Models\File;
|
|||||||
use Dompdf\Dompdf;
|
use Dompdf\Dompdf;
|
||||||
use Dompdf\Options;
|
use Dompdf\Options;
|
||||||
use Illuminate\Support\Facades\View;
|
use Illuminate\Support\Facades\View;
|
||||||
|
use App\Models\Member;
|
||||||
|
use App\Models\RequestLog;
|
||||||
|
use App\Models\Organization;
|
||||||
|
use App\Services\ClaimRequestService;
|
||||||
|
use App\Models\ClaimRequest;
|
||||||
|
|
||||||
class RequestLogController extends Controller
|
class RequestLogController extends Controller
|
||||||
{
|
{
|
||||||
@@ -20,6 +25,7 @@ class RequestLogController extends Controller
|
|||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
* @return Renderable
|
* @return Renderable
|
||||||
*/
|
*/
|
||||||
|
private static $code_prefix = 'CLAIM';
|
||||||
public function requestLog(Request $request)
|
public function requestLog(Request $request)
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
@@ -244,6 +250,7 @@ class RequestLogController extends Controller
|
|||||||
|
|
||||||
$results = DB::table('request_logs')
|
$results = DB::table('request_logs')
|
||||||
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
|
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
|
||||||
|
->where('request_logs.deleted_at', null)
|
||||||
->when($request->input('search'), function ($query, $search) {
|
->when($request->input('search'), function ($query, $search) {
|
||||||
$query->where(function ($query) use ($search) {
|
$query->where(function ($query) use ($search) {
|
||||||
$query->orWhere('request_logs.code', 'like', "%" . $search . "%")
|
$query->orWhere('request_logs.code', 'like', "%" . $search . "%")
|
||||||
@@ -820,4 +827,110 @@ class RequestLogController extends Controller
|
|||||||
|
|
||||||
return response($pdf->output(), 200, $headers);
|
return response($pdf->output(), 200, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function submitClaims(Request $request)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'selectedRows' => $request->selectedRows,
|
||||||
|
];
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'selectedRows' => 'required'
|
||||||
|
], [
|
||||||
|
'selectedRows.required' => trans('Validation.required',['attribute' => 'Request Logs ID']),
|
||||||
|
]);
|
||||||
|
if ($validator->fails())
|
||||||
|
{
|
||||||
|
return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach ($request->selectedRows as $request_logs_id) {
|
||||||
|
$data_req_logs = DB::table('request_logs')
|
||||||
|
->where('id', '=', $request_logs_id)
|
||||||
|
->select('id', 'member_id', 'service_code')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$check_claim_requests = DB::table('claim_requests')
|
||||||
|
->where('claim_requests.request_log_id', '=', $request_logs_id)
|
||||||
|
->first();
|
||||||
|
if(!$check_claim_requests) {
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
$code = $this->getNextCode($request_logs_id);
|
||||||
|
$member = Member::find($data_req_logs->member_id);
|
||||||
|
$requestLogData = RequestLog::where('id',$request_logs_id)->first();
|
||||||
|
$organization = Organization::where(['id' => $requestLogData->organization_id, 'type' => 'hospital'])->first('code');
|
||||||
|
$provideCode = $organization ? $organization->code : '';
|
||||||
|
|
||||||
|
$newClaimRequest = ClaimRequestService::storeClaimRequest(
|
||||||
|
row: [],
|
||||||
|
code: $code,
|
||||||
|
member: $member,
|
||||||
|
paymentType: 'cashless',
|
||||||
|
serviceCode: $data_req_logs->service_code,
|
||||||
|
requestLogID: $request_logs_id,
|
||||||
|
organization_code: $provideCode,
|
||||||
|
);
|
||||||
|
// Log History
|
||||||
|
$newClaimRequest->histories()->create([
|
||||||
|
'title' => 'New Claim Requested',
|
||||||
|
'description' => "Claim Requested for Member : {$member->member_id} - ({$member->full_name})",
|
||||||
|
'type' => 'info',
|
||||||
|
'system_origin' => 'hospital-portal'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Claim Log
|
||||||
|
DB::table('claim_logs')
|
||||||
|
->insert([
|
||||||
|
'claim_request_id' => $newClaimRequest->id,
|
||||||
|
'status' => 'requested',
|
||||||
|
'date' => date('Y-m-d H:i:s'),
|
||||||
|
'description' => "Claim Requested for Member : {$member->member_id} - ({$member->full_name})",
|
||||||
|
'system_origin' => 'hospital-portal',
|
||||||
|
'created_by' => auth()->user()->id,
|
||||||
|
'created_at' => date('Y-m-d H:i:s'),
|
||||||
|
'updated_at'=> date('Y-m-d H:i:s'),
|
||||||
|
]);
|
||||||
|
DB::commit();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollback();
|
||||||
|
return ApiResponse::apiResponse("Error", $data, $e->getMessage(), 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ApiResponse::apiResponse('Success', $data, trans('Message.success'), 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getNextCode($request_log_id = 0)
|
||||||
|
{
|
||||||
|
$last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, ".", -1) AS SIGNED)) as max_numeric_code'))
|
||||||
|
->whereRaw('SUBSTRING_INDEX(code, ".", -1) REGEXP "^[0-9]+$"')
|
||||||
|
->value('max_numeric_code');
|
||||||
|
// $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, $request_log_id)
|
||||||
|
{
|
||||||
|
// Pastikan $next_number adalah integer positif
|
||||||
|
$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
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ Route::prefix('v1')->group(function() {
|
|||||||
Route::post('request-final-log', 'requestFinalLog');
|
Route::post('request-final-log', 'requestFinalLog');
|
||||||
Route::get('download-log/{request_log_id}', 'downlodLog');
|
Route::get('download-log/{request_log_id}', 'downlodLog');
|
||||||
Route::get('download-final-log/{request_log_id}', 'downlodFinalLog');
|
Route::get('download-final-log/{request_log_id}', 'downlodFinalLog');
|
||||||
|
Route::post('submit-claims', 'submitClaims');
|
||||||
});
|
});
|
||||||
//Notification
|
//Notification
|
||||||
Route::controller(NotificationController::class)->group(function() {
|
Route::controller(NotificationController::class)->group(function() {
|
||||||
|
|||||||
@@ -21,8 +21,18 @@ use Modules\Internal\Transformers\ClaimEditResource;
|
|||||||
use Modules\Internal\Transformers\ClaimHistoryCareResource;
|
use Modules\Internal\Transformers\ClaimHistoryCareResource;
|
||||||
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
|
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
|
||||||
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
|
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
|
||||||
|
use Box\Spout\Common\Entity\Style\CellAlignment;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\View;
|
use Illuminate\Support\Facades\View;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Exports\FailedRowsExport; // Import class export Excel
|
||||||
|
|
||||||
|
use Modules\Internal\Transformers\RequestLogResource;
|
||||||
|
|
||||||
|
use App\Models\RequestLog;
|
||||||
|
|
||||||
use PDF;
|
use PDF;
|
||||||
|
|
||||||
@@ -34,41 +44,436 @@ class ClaimController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
// $serviceCode = 'IP';
|
$limit = $request->has('per_page') ? $request->input('per_page') : 10;
|
||||||
$claims = Claim::with([
|
$results = DB::table('claim_requests')
|
||||||
'member',
|
->leftJoin('request_logs', 'claim_requests.request_log_id','=', 'request_logs.id')
|
||||||
'member.currentCorporate',
|
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
|
||||||
'member.currentCorporate.currentPolicy',
|
// ->leftJoin('member_plans', 'member_plans.member_id', '=', 'members.id')
|
||||||
// 'member.currentPlan' => function($memberPlan) use ($serviceCode) {
|
->when($request->input('search'), function ($query, $search) {
|
||||||
// $memberPlan->where('plans.service_code', $serviceCode);
|
$query->where(function ($query) use ($search) {
|
||||||
// },
|
$query->orWhere('members.name', 'like', "%" . $search . "%");
|
||||||
'member.currentPlan' => function($memberPlan) {
|
$query->orWhere('claim_requests.code', 'like', "%" . $search . "%");
|
||||||
$memberPlan->join('claim_requests', 'claim_requests.service_code', '=', 'plans.service_code');
|
$query->orWhere('members.member_id', 'like', "%" . $search . "%");
|
||||||
},
|
|
||||||
'diagnoses' => function ($diagnosis) {
|
|
||||||
$diagnosis->where('type', 'primary');
|
|
||||||
},
|
|
||||||
'diagnoses.icd',
|
|
||||||
'benefit',
|
|
||||||
'claimRequest',
|
|
||||||
'claimRequest.service',
|
|
||||||
])
|
|
||||||
->when($request->search, function ($q, $search) {
|
|
||||||
$q->where(function ($subQuery) use ($search) {
|
|
||||||
$subQuery->whereHas('claimRequest', function ($claimRequest) use ($search) {
|
|
||||||
$claimRequest->where('code', 'LIKE', "%" . $search . "%");
|
|
||||||
})
|
|
||||||
->orWhereHas('member', function ($member) use ($search) {
|
|
||||||
$member->where('name', 'LIKE', "%" . $search . "%");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
->where('status', '!=', 'requested') // Penjagaan agar approve baru masuk ke claim management
|
->when($request->has('orderBy'), function ($query) use ($request) {
|
||||||
->latest()
|
$orderBy = $request->orderBy;
|
||||||
->paginate(10);
|
$direction = $request->order ?? 'asc';
|
||||||
|
|
||||||
|
$query->orderBy($orderBy, $direction);
|
||||||
|
})
|
||||||
|
->when($request->input('start_date') , function ($query, $start_date) {
|
||||||
|
$query->where(function ($query) use ($start_date) {
|
||||||
|
$query->where('claim_requests.created_at', '>=', $start_date);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->when($request->input('end_date') , function ($query, $end_date) {
|
||||||
|
$query->where(function ($query) use ($end_date) {
|
||||||
|
$query->where('claim_requests.created_at', '<=', $end_date);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->when($request->input('provider') , function ($query, $provider) {
|
||||||
|
$query->where(function ($query) use ($provider) {
|
||||||
|
$query->where('request_logs.organization_id', '=', $provider);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->where('claim_management', '=', 1)
|
||||||
|
->select(
|
||||||
|
'claim_requests.id',
|
||||||
|
'request_logs.id AS id_log',
|
||||||
|
'claim_requests.code as code',
|
||||||
|
'members.name',
|
||||||
|
DB::raw('
|
||||||
|
(SELECT members.member_id FROM members WHERE members.id = claim_requests.member_id LIMIT 1) AS member_id
|
||||||
|
'),
|
||||||
|
'claim_requests.created_at',
|
||||||
|
// DB::raw('
|
||||||
|
// (SELECT plans.code FROM plans WHERE plans.id = member_plans.plan_id LIMIT 1) AS plan_code
|
||||||
|
// '),
|
||||||
|
DB::raw('
|
||||||
|
(SELECT plans.code
|
||||||
|
FROM plans
|
||||||
|
WHERE plans.id IN (
|
||||||
|
SELECT member_plans.plan_id
|
||||||
|
FROM member_plans
|
||||||
|
WHERE member_plans.member_id = claim_requests.member_id
|
||||||
|
)
|
||||||
|
AND plans.service_code = claim_requests.service_code) AS plan_code
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(SELECT services.description FROM services WHERE services.code = claim_requests.service_code LIMIT 1) AS service_code
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(SELECT corporate_policies.code FROM corporate_policies WHERE corporate_policies.id = claim_requests.policy_id LIMIT 1) AS corporate_policies
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(SELECT organizations.name FROM organizations WHERE organizations.id = request_logs.organization_id LIMIT 1) AS provider
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(Select SUM(request_log_benefits.amount_approved) as tot_bill FROM request_log_benefits
|
||||||
|
WHERE request_log_benefits.request_log_id = request_logs.id LIMIT 1) AS tot_bill
|
||||||
|
'),
|
||||||
|
'claim_requests.status_claim_management as status',
|
||||||
|
)
|
||||||
|
->paginate($limit);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return response()->json($claims);
|
return response()->json(Helper::paginateResources($results));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadTemplate()
|
||||||
|
{
|
||||||
|
return Helper::responseJson([
|
||||||
|
'file_name' => "Template - Claim - Management.xlsx",
|
||||||
|
"file_url" => url('files/Template - Claim - Management.xlsx')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->hasFile('file')) {
|
||||||
|
$file = $request->file('file');
|
||||||
|
$data = Excel::toArray([], $file);
|
||||||
|
|
||||||
|
$processedData = $this->processCategoryNames($data);
|
||||||
|
|
||||||
|
$importedRows = 0;
|
||||||
|
$failedRows = [];
|
||||||
|
|
||||||
|
foreach ($processedData as $row) {
|
||||||
|
try {
|
||||||
|
$affectedRows = DB::table('claim_requests')
|
||||||
|
->where('code','=', $row['code'])
|
||||||
|
->where('claim_management','=', 1)
|
||||||
|
->update([
|
||||||
|
'status_claim_management' => $row['qc'] == 'Y' ? 'approved' : 'declined',
|
||||||
|
'reason_decline' => $row['reason'] ? $row['reason'] : null,
|
||||||
|
'approval_by_claim_management' => auth()->user()->id,
|
||||||
|
'approval_date_claim_management' => date('Y-m-d H:i:s'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($affectedRows === 0) {
|
||||||
|
$failedRows[] = $row;
|
||||||
|
} else {
|
||||||
|
$importedRows += $affectedRows;
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$failedRows[] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'message' => 'File uploaded and data saved to database',
|
||||||
|
'data' => [
|
||||||
|
'total_success_row' => $importedRows,
|
||||||
|
'total_failed_row' => count($failedRows),
|
||||||
|
'failed_rows' => $failedRows,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return response()->json($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(['error' => 'No file uploaded.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processCategoryNames($data)
|
||||||
|
{
|
||||||
|
$header = [];
|
||||||
|
$row = [];
|
||||||
|
for ($i = 1; $i < count($data[0]); $i++) {
|
||||||
|
$row[] = $data[0][$i];
|
||||||
|
$header[] = $data[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$filed = [];
|
||||||
|
foreach ($header[0] as $value)
|
||||||
|
{
|
||||||
|
$modelColumn = strtolower(preg_replace('/\s+/', '_', trim($value)));
|
||||||
|
$modelColumn = str_replace(['*', ' '], '', $modelColumn);
|
||||||
|
if($modelColumn)
|
||||||
|
{
|
||||||
|
$filed[] = $modelColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
foreach ($row as $subarray) {
|
||||||
|
$trimmedSubarray = [];
|
||||||
|
for ($i = 0; $i < count($filed); $i++) {
|
||||||
|
$trimmedSubarray[$filed[$i]] = $subarray[$i] ? $subarray[$i] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[] = $trimmedSubarray;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportClaimManagement(Request $request)
|
||||||
|
{
|
||||||
|
$start_date = $request->input('start_date') ? $request->input('start_date') : 'all';
|
||||||
|
$end_date = $request->input('end_date') ? $request->input('end_date') : 'all';
|
||||||
|
$writer = WriterEntityFactory::createXLSXWriter();
|
||||||
|
$writer->openToFile(public_path('files/Report-Data-Claim-Management-'.$start_date.'-'.$end_date.'.xlsx'));
|
||||||
|
$header = [
|
||||||
|
'No',
|
||||||
|
'Code',
|
||||||
|
'Name',
|
||||||
|
'Member ID',
|
||||||
|
'Date Submission',
|
||||||
|
'Plan ID',
|
||||||
|
'Service',
|
||||||
|
'Policy Number',
|
||||||
|
'Provider',
|
||||||
|
'Total Billing',
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$headerRow = WriterEntityFactory::createRowFromArray($header, $style);
|
||||||
|
$writer->addRow($headerRow);
|
||||||
|
// ============================
|
||||||
|
$results = DB::table('claim_requests')
|
||||||
|
->leftJoin('request_logs', 'claim_requests.request_log_id','=', 'request_logs.id')
|
||||||
|
->leftJoin('members', 'request_logs.member_id', '=', 'members.id')
|
||||||
|
// ->leftJoin('member_plans', 'member_plans.member_id', '=', 'members.id')
|
||||||
|
->when($request->input('search'), function ($query, $search) {
|
||||||
|
$query->where(function ($query) use ($search) {
|
||||||
|
$query->orWhere('members.name', 'like', "%" . $search . "%");
|
||||||
|
$query->orWhere('claim_requests.code', 'like', "%" . $search . "%");
|
||||||
|
$query->orWhere('members.member_id', 'like', "%" . $search . "%");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->when($request->has('orderBy'), function ($query) use ($request) {
|
||||||
|
$orderBy = $request->orderBy;
|
||||||
|
$direction = $request->order ?? 'asc';
|
||||||
|
|
||||||
|
$query->orderBy($orderBy, $direction);
|
||||||
|
})
|
||||||
|
->when($request->input('start_date') , function ($query, $start_date) {
|
||||||
|
$query->where(function ($query) use ($start_date) {
|
||||||
|
$query->where('claim_requests.created_at', '>=', $start_date);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->when($request->input('end_date') , function ($query, $end_date) {
|
||||||
|
$query->where(function ($query) use ($end_date) {
|
||||||
|
$query->where('claim_requests.created_at', '<=', $end_date);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->when($request->input('provider') , function ($query, $provider) {
|
||||||
|
$query->where(function ($query) use ($provider) {
|
||||||
|
$query->where('request_logs.organization_id', '=', $provider);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->where('claim_management', '=', 1)
|
||||||
|
->select(
|
||||||
|
'claim_requests.id',
|
||||||
|
'request_logs.id AS id_log',
|
||||||
|
'claim_requests.code as code',
|
||||||
|
'members.name',
|
||||||
|
DB::raw('
|
||||||
|
(SELECT members.member_id FROM members WHERE members.id = claim_requests.member_id LIMIT 1) AS member_id
|
||||||
|
'),
|
||||||
|
'claim_requests.created_at',
|
||||||
|
DB::raw('
|
||||||
|
(SELECT plans.code
|
||||||
|
FROM plans
|
||||||
|
WHERE plans.id IN (
|
||||||
|
SELECT member_plans.plan_id
|
||||||
|
FROM member_plans
|
||||||
|
WHERE member_plans.member_id = claim_requests.member_id
|
||||||
|
)
|
||||||
|
AND plans.service_code = claim_requests.service_code) AS plan_code
|
||||||
|
'),
|
||||||
|
// DB::raw('
|
||||||
|
// (SELECT plans.code FROM plans WHERE plans.id = member_plans.plan_id LIMIT 1) AS plan_code
|
||||||
|
// '),
|
||||||
|
DB::raw('
|
||||||
|
(SELECT services.description FROM services WHERE services.code = claim_requests.service_code LIMIT 1) AS service_code
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(SELECT corporate_policies.code FROM corporate_policies WHERE corporate_policies.id = claim_requests.policy_id LIMIT 1) AS corporate_policies
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(SELECT organizations.name FROM organizations WHERE organizations.id = request_logs.organization_id LIMIT 1) AS provider
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(Select SUM(request_log_benefits.amount_approved) as tot_bill FROM request_log_benefits
|
||||||
|
WHERE request_log_benefits.request_log_id = request_logs.id LIMIT 1) AS tot_bill
|
||||||
|
'),
|
||||||
|
'claim_requests.status_claim_management as status',
|
||||||
|
)
|
||||||
|
->get();
|
||||||
|
$no=0;
|
||||||
|
$gr_total = 0;
|
||||||
|
foreach($results as $item)
|
||||||
|
{
|
||||||
|
$gr_total += $item->tot_bill;
|
||||||
|
$no++;
|
||||||
|
$rowData = [
|
||||||
|
$no,
|
||||||
|
$item->code,
|
||||||
|
$item->name,
|
||||||
|
$item->member_id,
|
||||||
|
$item->created_at,
|
||||||
|
$item->plan_code,
|
||||||
|
$item->service_code,
|
||||||
|
$item->corporate_policies,
|
||||||
|
$item->provider,
|
||||||
|
$item->tot_bill ? $item->tot_bill : 0
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
//->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
$row = WriterEntityFactory::createRowFromArray($rowData, $style);
|
||||||
|
$writer->addRow($row);
|
||||||
|
}
|
||||||
|
$footer = [
|
||||||
|
'Grand Total',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
$gr_total,
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$footerRow = WriterEntityFactory::createRowFromArray($footer, $style);
|
||||||
|
$writer->addRow($footerRow);
|
||||||
|
|
||||||
|
$writer->close();
|
||||||
|
|
||||||
|
return Helper::responseJson([
|
||||||
|
'file_name' => 'Report-Data-Claim-Management-'. $start_date.'-'.$end_date,
|
||||||
|
"file_url" => url('files/Report-Data-Claim-Management-'. $start_date.'-'.$end_date.'.xlsx')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportFiled(Request $request)
|
||||||
|
{
|
||||||
|
$writer = WriterEntityFactory::createXLSXWriter();
|
||||||
|
$writer->openToFile(public_path('files/Report-Data-Filed-Import.xlsx'));
|
||||||
|
$header = [
|
||||||
|
'Code*',
|
||||||
|
'QC*',
|
||||||
|
'Reason'
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$headerRow = WriterEntityFactory::createRowFromArray($header, $style);
|
||||||
|
$writer->addRow($headerRow);
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
foreach($request->params as $item)
|
||||||
|
{
|
||||||
|
|
||||||
|
$rowData = [
|
||||||
|
$item['code'],
|
||||||
|
$item['qc'],
|
||||||
|
$item['reason']
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
//->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
$row = WriterEntityFactory::createRowFromArray($rowData, $style);
|
||||||
|
$writer->addRow($row);
|
||||||
|
}
|
||||||
|
$footer = [
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$footerRow = WriterEntityFactory::createRowFromArray($footer, $style);
|
||||||
|
$writer->addRow($footerRow);
|
||||||
|
|
||||||
|
$writer->close();
|
||||||
|
|
||||||
|
return Helper::responseJson([
|
||||||
|
'file_name' => 'Report-Data-Filed-Import',
|
||||||
|
"file_url" => url('files/Report-Data-Filed-Import.xlsx')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
public function getProvider(Request $request)
|
||||||
|
{
|
||||||
|
$providers = DB::table('organizations')
|
||||||
|
->where('organizations.type', '=', 'hospital')
|
||||||
|
->where('organizations.status', '=', 'active')
|
||||||
|
->select(
|
||||||
|
'organizations.id',
|
||||||
|
'organizations.name'
|
||||||
|
)
|
||||||
|
->orderBy('name', 'asc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return response()->json($providers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cekStatus($id)
|
||||||
|
{
|
||||||
|
$cek = DB::table('claim_requests')
|
||||||
|
->where('claim_requests.id', '=', $id)
|
||||||
|
->select('claim_requests.status_claim_management as status')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$data['cek'] = $cek;
|
||||||
|
|
||||||
|
$member = DB::table('claim_requests')
|
||||||
|
->join('request_logs', 'claim_requests.request_log_id','=', 'request_logs.id')
|
||||||
|
->join('members', 'request_logs.member_id', '=', 'members.id')
|
||||||
|
->where('claim_requests.id', '=', $id)
|
||||||
|
->select('claim_requests.code','members.name','claim_requests.created_at', DB::raw('
|
||||||
|
(SELECT services.name FROM services WHERE services.code = request_logs.service_code LIMIT 1) AS service_type
|
||||||
|
'),)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$data['member'] = $member;
|
||||||
|
|
||||||
|
return response()->json($data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -334,21 +739,18 @@ class ClaimController extends Controller
|
|||||||
return Helper::responseJson([], message: "Diagnosis berhasil di update");
|
return Helper::responseJson([], message: "Diagnosis berhasil di update");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decline($id)
|
public function decline(Request $request, $id)
|
||||||
{
|
{
|
||||||
//Get claim request id
|
|
||||||
$data_claim_requests = DB::table('claim_requests')
|
|
||||||
->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
|
|
||||||
->where('claims.id', $id)
|
|
||||||
->select('claim_requests.id')
|
|
||||||
->first();
|
|
||||||
$id = $data_claim_requests->id;
|
|
||||||
|
|
||||||
DB::table('claims')
|
DB::table('claim_requests')
|
||||||
->where('claim_request_id', $id)
|
->where('claim_requests.id', $id)
|
||||||
->update(
|
->update(
|
||||||
[
|
[
|
||||||
'status' => 'declined'
|
'status' => 'declined',
|
||||||
|
'status_claim_management' => 'declined',
|
||||||
|
'reason_decline' => $request->reasonDecline ? $request->reasonDecline : '',
|
||||||
|
'approval_date_claim_management' => date('Y-m-d H:i:s'),
|
||||||
|
'approval_by_claim_management' => auth()->user()->id
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -370,19 +772,14 @@ class ClaimController extends Controller
|
|||||||
|
|
||||||
public function approve($id)
|
public function approve($id)
|
||||||
{
|
{
|
||||||
//Get claim request id
|
DB::table('claim_requests')
|
||||||
$data_claim_requests = DB::table('claim_requests')
|
->where('claim_requests.id', $id)
|
||||||
->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
|
|
||||||
->where('claims.id', $id)
|
|
||||||
->select('claim_requests.id')
|
|
||||||
->first();
|
|
||||||
$id = $data_claim_requests->id;
|
|
||||||
|
|
||||||
DB::table('claims')
|
|
||||||
->where('claim_request_id', $id)
|
|
||||||
->update(
|
->update(
|
||||||
[
|
[
|
||||||
'status' => 'approved'
|
'status' => 'approved',
|
||||||
|
'status_claim_management' => 'approved',
|
||||||
|
'approval_date_claim_management' => date('Y-m-d H:i:s'),
|
||||||
|
'approval_by_claim_management' => auth()->user()->id
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -17,15 +17,23 @@ use App\Services\ClaimRequestService;
|
|||||||
use App\Exceptions\ImportRowException;
|
use App\Exceptions\ImportRowException;
|
||||||
use App\Events\ClaimRequested;
|
use App\Events\ClaimRequested;
|
||||||
|
|
||||||
|
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
|
||||||
|
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
|
||||||
|
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
|
||||||
|
use Box\Spout\Common\Entity\Style\CellAlignment;
|
||||||
|
|
||||||
use App\Models\File;
|
use App\Models\File;
|
||||||
use App\Models\FilesMcu;
|
use App\Models\FilesMcu;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
|
use App\Models\MemberPlan;
|
||||||
|
use App\Models\Plan;
|
||||||
|
use App\Models\RequestLogBenefit;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
class ClaimRequestController extends Controller
|
class ClaimRequestController extends Controller
|
||||||
{
|
{
|
||||||
private static $code_prefix = 'CRQ-C';
|
private static $code_prefix = 'CLAIM';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
@@ -41,11 +49,17 @@ class ClaimRequestController extends Controller
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
->when($request->start_date, function ($q, $startDate) {
|
->when($request->start_date, function ($q, $startDate) {
|
||||||
$q->where('submission_date', '>', $startDate);
|
$q->where('submission_date', '>', Carbon::parse($startDate)->subDay());
|
||||||
})
|
})
|
||||||
->when($request->end_date, function ($q, $endDate) {
|
->when($request->end_date, function ($q, $endDate) use ($request) {
|
||||||
$q->where('submission_date', '<', $endDate);
|
// Jika tanggal akhir diberikan dan tidak sama dengan tanggal mulai
|
||||||
|
if ($request->start_date != $request->end_date) {
|
||||||
|
$q->where('submission_date', '<', Carbon::parse($endDate)->addDay());
|
||||||
|
} else {
|
||||||
|
$q->where('submission_date', '<', Carbon::parse($endDate)->addDay());
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
->when($request->service_code, function ($q, $serviceCode) {
|
->when($request->service_code, function ($q, $serviceCode) {
|
||||||
$q->whereIn('service_code', $serviceCode);
|
$q->whereIn('service_code', $serviceCode);
|
||||||
})
|
})
|
||||||
@@ -62,7 +76,7 @@ class ClaimRequestController extends Controller
|
|||||||
})
|
})
|
||||||
->with(['member', 'files', 'service', 'member.currentPolicy'])
|
->with(['member', 'files', 'service', 'member.currentPolicy'])
|
||||||
->paginate();
|
->paginate();
|
||||||
|
|
||||||
return Helper::paginateResources(ClaimRequestResource::collection($claimRequests));
|
return Helper::paginateResources(ClaimRequestResource::collection($claimRequests));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,6 +443,7 @@ class ClaimRequestController extends Controller
|
|||||||
$import = new ImportService();
|
$import = new ImportService();
|
||||||
$import->read($fileRead);
|
$import->read($fileRead);
|
||||||
$import->write($fileWrite, 'xsls');
|
$import->write($fileWrite, 'xsls');
|
||||||
|
|
||||||
foreach ($import->sheetsIterator() as $sheetIndex => $sheet) {
|
foreach ($import->sheetsIterator() as $sheetIndex => $sheet) {
|
||||||
if ($sheetIndex == 1) { // Rename First Sheet to Writer
|
if ($sheetIndex == 1) { // Rename First Sheet to Writer
|
||||||
$firstWriterSheet = $import->writer->getCurrentSheet();
|
$firstWriterSheet = $import->writer->getCurrentSheet();
|
||||||
@@ -445,6 +460,9 @@ class ClaimRequestController extends Controller
|
|||||||
$result_headers = array_merge($result_headers, ['Ingest Code', 'Ingest Note']);
|
$result_headers = array_merge($result_headers, ['Ingest Code', 'Ingest Note']);
|
||||||
|
|
||||||
$import->addArrayToRow($result_headers);
|
$import->addArrayToRow($result_headers);
|
||||||
|
$imported_claim_data = 0;
|
||||||
|
$failed_claim_data = [];
|
||||||
|
|
||||||
$doc_headers_indexes = [];
|
$doc_headers_indexes = [];
|
||||||
foreach ($sheet->getRowIterator() as $index => $row) {
|
foreach ($sheet->getRowIterator() as $index => $row) {
|
||||||
if ($index == 1) { // First Row Must be Header
|
if ($index == 1) { // First Row Must be Header
|
||||||
@@ -465,25 +483,28 @@ class ClaimRequestController extends Controller
|
|||||||
}
|
}
|
||||||
try { // Process the Row Data
|
try { // Process the Row Data
|
||||||
$claimRequestService = new ClaimRequestService();
|
$claimRequestService = new ClaimRequestService();
|
||||||
|
|
||||||
$claimRequestService->handleClaimRequestRow($row_data);
|
$claimRequestService->handleClaimRequestRow($row_data);
|
||||||
|
|
||||||
// Write Success Result to File
|
// Write Success Result to File
|
||||||
// $import->read($fileRead);
|
// $import->read($fileRead);
|
||||||
// $import->write($fileWrite, 'xsls');
|
// $import->write($fileWrite, 'xsls');
|
||||||
$result_headers = array_merge($row_data, ['Ingest Code' =>200, 'Ingest Note' => 'Success']);
|
$result_headers = array_merge($row_data, ['Ingest Code' =>200, 'Ingest Note' => 'Success']);
|
||||||
|
// Mengambil tanggal dari objek DateTime
|
||||||
|
$dateSubmission = Helper::dateParser($result_headers['date_submission']); // Format tanggal sesuai kebutuhan
|
||||||
|
// Mengubah nilai date_submission menjadi string tanggal
|
||||||
|
$result_headers['date_submission'] = $dateSubmission;
|
||||||
|
// dd($result_headers);
|
||||||
$import->addArrayToRow($result_headers, $sheet->getName());
|
$import->addArrayToRow($result_headers, $sheet->getName());
|
||||||
|
$imported_claim_data++;
|
||||||
} catch (ImportRowException $e) {
|
} catch (ImportRowException $e) {
|
||||||
// Write Data Validation Error to File
|
// Write Data Validation Error to File
|
||||||
// $import->read($fileRead);
|
// $import->read($fileRead);
|
||||||
// $import->write($fileWrite, 'xsls');
|
// $import->write($fileWrite, 'xsls');
|
||||||
|
$new_claim_data = $import->addArrayToRow(array_merge($row_data, [
|
||||||
$import->addArrayToRow(array_merge($row_data, [
|
|
||||||
'Ingest Code' => $e->getCode(),
|
'Ingest Code' => $e->getCode(),
|
||||||
'Ingest Note' => $e->getMessage(),
|
'Ingest Note' => $e->getMessage(),
|
||||||
]), $sheet->getName());
|
]), $sheet->getName());
|
||||||
|
|
||||||
|
$failed_claim_data[] = ['row_number' => $index, 'error' => $e->getMessage(),'data' => $new_claim_data];
|
||||||
}
|
}
|
||||||
// catch (\Exception $e) {
|
// catch (\Exception $e) {
|
||||||
// // throw new \Exception($e);
|
// // throw new \Exception($e);
|
||||||
@@ -502,104 +523,20 @@ class ClaimRequestController extends Controller
|
|||||||
$import->reader->close();
|
$import->reader->close();
|
||||||
Storage::delete('temp/' . $file_name);
|
Storage::delete('temp/' . $file_name);
|
||||||
$import->writer->close();
|
$import->writer->close();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// 'total_successed_row' => $imported_plan_data,
|
|
||||||
// 'total_failed_row' => count($failed_plan_data),
|
|
||||||
// 'failed_row' => $failed_plan_data,
|
|
||||||
'result_file' => [
|
'result_file' => [
|
||||||
'url' => Storage::disk('public')->url('temp/result-' . $file_name),
|
'url' => Storage::disk('public')->url('temp/result-' . $file_name),
|
||||||
'name' => 'result-' . $file_name,
|
'name' => 'result-' . $file_name,
|
||||||
|
'total_success_row' => $imported_claim_data,
|
||||||
|
'total_failed_row' => count($failed_claim_data),
|
||||||
|
'failed_row' => $failed_claim_data,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function claimRequestDetail($claimRequestId)
|
public function claimRequestDetail($claimRequestId)
|
||||||
{
|
{
|
||||||
// $status = DB::table('claim_requests')
|
|
||||||
// ->leftJoin('claims', 'claim_requests.id', '=', 'claims.claim_request_id')
|
|
||||||
// ->leftJoin('members', 'claim_requests.member_id', '=', 'members.id')
|
|
||||||
// ->leftJoin('corporate_employees', 'members.id', '=', 'corporate_employees.member_id')
|
|
||||||
// ->leftJoin('corporate_divisions', 'corporate_employees.division_id', '=', 'corporate_divisions.id')
|
|
||||||
// ->where('claim_requests.id', '=', $claimRequestId)
|
|
||||||
// ->select(
|
|
||||||
// 'claim_requests.submission_date',
|
|
||||||
// 'claim_requests.code',
|
|
||||||
// DB::raw('
|
|
||||||
// CASE
|
|
||||||
// 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 = "declined" THEN "declined"
|
|
||||||
// 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 "reviewed"
|
|
||||||
// ELSE ""
|
|
||||||
// END AS status
|
|
||||||
// ')
|
|
||||||
// )
|
|
||||||
// ->first();
|
|
||||||
// $results['status'] = $status;
|
|
||||||
// $timeline = DB::table('claim_logs')
|
|
||||||
// ->where('claim_logs.claim_request_id', '=', $claimRequestId)
|
|
||||||
// ->select(
|
|
||||||
// DB::raw('
|
|
||||||
// CASE
|
|
||||||
// WHEN claim_logs.status = "requested" THEN "Request"
|
|
||||||
// WHEN claim_logs.status = "reviewed" THEN "Review"
|
|
||||||
// WHEN claim_logs.status = "approved" THEN "Approval"
|
|
||||||
// WHEN claim_logs.status = "declined" THEN "Decline"
|
|
||||||
// ELSE "-"
|
|
||||||
// END AS txt_status
|
|
||||||
// '),
|
|
||||||
// DB::raw('
|
|
||||||
// CASE
|
|
||||||
// WHEN claim_logs.status = "requested" THEN "#159C9C"
|
|
||||||
// WHEN claim_logs.status = "reviewed" THEN "#0C53B7"
|
|
||||||
// WHEN claim_logs.status = "approved" THEN "#229A16"
|
|
||||||
// WHEN claim_logs.status = "declined" THEN "#FF4842"
|
|
||||||
// ELSE "-"
|
|
||||||
// END AS txt_status_color
|
|
||||||
// '),
|
|
||||||
// DB::raw('
|
|
||||||
// CASE
|
|
||||||
// WHEN claim_logs.status = "requested" THEN "#00AB5529"
|
|
||||||
// WHEN claim_logs.status = "reviewed" THEN "#1890FF29"
|
|
||||||
// WHEN claim_logs.status = "approved" THEN "#54D62C29"
|
|
||||||
// WHEN claim_logs.status = "declined" THEN "#FF48427A"
|
|
||||||
// ELSE "-"
|
|
||||||
// END AS txt_status_backgroundColor
|
|
||||||
// '),
|
|
||||||
// 'claim_logs.date',
|
|
||||||
// 'claim_logs.description',
|
|
||||||
// 'claim_logs.status'
|
|
||||||
// )
|
|
||||||
// ->orderBy('claim_logs.id', 'desc')
|
|
||||||
// ->get();
|
|
||||||
// $results['timeline'] = $timeline;
|
|
||||||
// $request_files = DB::table('claim_request_files')
|
|
||||||
// ->where('claim_request_files.claim_request_id', '=', $claimRequestId)
|
|
||||||
// ->select(
|
|
||||||
// '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'),
|
|
||||||
// )
|
|
||||||
// ->get();
|
|
||||||
// $results['request_files'] = $request_files;
|
|
||||||
// $documents = DB::table('files')
|
|
||||||
// ->where('fileable_type', 'App\Models\ClaimRequest')
|
|
||||||
// ->where('fileable_id', $claimRequestId)
|
|
||||||
// ->select('original_name', \DB::raw("CONCAT('" . env('APP_URL') . "/storage/', path) as path"), 'type')
|
|
||||||
// ->orderBy('id', 'desc')
|
|
||||||
// ->get();
|
|
||||||
// $results['documents'] = $documents;
|
|
||||||
// $dialog_submits = DB::table('claim_requests')
|
|
||||||
// ->leftJoin('members', 'claim_requests.member_id','=', 'members.id')
|
|
||||||
// ->where('claim_requests.id', $claimRequestId)
|
|
||||||
// ->select('claim_requests.code', 'members.name', 'claim_requests.submission_date', 'claim_requests.service_code','claim_requests.status')
|
|
||||||
// ->first();
|
|
||||||
// $results['dialog_submits'] = $dialog_submits;
|
|
||||||
|
|
||||||
// return Helper::responseJson($results);
|
|
||||||
|
|
||||||
$claimRequest = ClaimRequest::findOrFail($claimRequestId);
|
$claimRequest = ClaimRequest::findOrFail($claimRequestId);
|
||||||
$claimRequest->load([
|
$claimRequest->load([
|
||||||
'requestLog',
|
'requestLog',
|
||||||
@@ -704,10 +641,6 @@ class ClaimRequestController extends Controller
|
|||||||
|
|
||||||
public static function getNextCode()
|
public static function getNextCode()
|
||||||
{
|
{
|
||||||
// $last_number = ClaimRequest::max('code');
|
|
||||||
// $next_number = empty($last_number) ? 1 : ((int) explode('-', $last_number)[2] + 1);
|
|
||||||
// return self::makeCode($next_number);
|
|
||||||
|
|
||||||
$last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, "-", -1) AS SIGNED)) as max_numeric_code'))
|
$last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, "-", -1) AS SIGNED)) as max_numeric_code'))
|
||||||
->whereRaw('SUBSTRING_INDEX(code, "-", -1) REGEXP "^[0-9]+$"')
|
->whereRaw('SUBSTRING_INDEX(code, "-", -1) REGEXP "^[0-9]+$"')
|
||||||
->value('max_numeric_code');
|
->value('max_numeric_code');
|
||||||
@@ -725,11 +658,17 @@ class ClaimRequestController extends Controller
|
|||||||
|
|
||||||
public static function makeCode($next_number)
|
public static function makeCode($next_number)
|
||||||
{
|
{
|
||||||
// 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();
|
||||||
// Menghasilkan kode dengan format yang diinginkan
|
$organization = Organization::where(['id' => $requestLogData->organization_id, 'type' => 'hospital'])->first('code');
|
||||||
return self::$code_prefix . '-' . str_pad($next_number, 5, '0', STR_PAD_LEFT);
|
$provideCode = $organization ? $organization->code : '';
|
||||||
|
$member = Member::with('currentCorporate')->where(['id' => $requestLogData->member_id])->first();
|
||||||
|
$sparator = '.';
|
||||||
|
$date = date('ymd');
|
||||||
|
// Menghasilkan kode dengan format yang diinginkan
|
||||||
|
return self::$code_prefix . $sparator. 'H' . $sparator. $provideCode . $sparator. $date. $sparator . $member->currentPolicy->code . $sparator. $member->member_id . $sparator. str_pad($next_number, 6, '0', STR_PAD_LEFT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function requestFiles(Request $request, $claim_id)
|
public function requestFiles(Request $request, $claim_id)
|
||||||
@@ -788,4 +727,309 @@ class ClaimRequestController extends Controller
|
|||||||
|
|
||||||
return Helper::responseJson(data: $request->toArray(), message: 'Invoice Success Uploaded');
|
return Helper::responseJson(data: $request->toArray(), message: 'Invoice Success Uploaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function exportClaimRequest(Request $request)
|
||||||
|
{
|
||||||
|
$claimRequests = ClaimRequest::query()
|
||||||
|
->when($request->search, function ($q, $search) {
|
||||||
|
$q->where('code', 'LIKE', "%".$search."%");
|
||||||
|
$q->orWhereHas('member', function ($subQuery) use ($search) {
|
||||||
|
$subQuery->where('name', 'LIKE', "%".$search."%");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->when($request->start_date, function ($q, $startDate) {
|
||||||
|
$q->where('submission_date', '>', Carbon::parse($startDate)->subDay());
|
||||||
|
})
|
||||||
|
->when($request->end_date, function ($q, $endDate) use ($request) {
|
||||||
|
// Jika tanggal akhir diberikan dan tidak sama dengan tanggal mulai
|
||||||
|
if ($request->start_date != $request->end_date) {
|
||||||
|
$q->where('submission_date', '<', Carbon::parse($endDate)->addDay());
|
||||||
|
} else {
|
||||||
|
$q->where('submission_date', '<=', Carbon::parse($endDate));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->when($request->service_code, function ($q, $serviceCode) {
|
||||||
|
$q->whereIn('service_code', $serviceCode);
|
||||||
|
})
|
||||||
|
->when($request->orderBy, function ($q, $orderBy) use ($request) {
|
||||||
|
if (in_array($orderBy, ['submission_date', 'code'])) {
|
||||||
|
$q->orderBy($orderBy, $request->order);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->when(empty($request->orderBy), function ($q) {
|
||||||
|
$q->orderBy('created_at', 'desc');
|
||||||
|
})
|
||||||
|
->when($request->status, function($q, $status) {
|
||||||
|
$q->where('status', $status);
|
||||||
|
})
|
||||||
|
->with(['member', 'member.currentCorporate', 'files', 'service', 'member.currentPolicy', 'requestLog', 'requestLog.organization',])
|
||||||
|
->addSelect([
|
||||||
|
'tot_billing' => function ($query) {
|
||||||
|
$query->select(DB::raw('SUM(request_log_benefits.amount_approved)'))
|
||||||
|
->from('request_log_benefits')
|
||||||
|
->whereColumn('request_log_benefits.request_log_id', 'claim_requests.request_log_id')
|
||||||
|
->limit(1);
|
||||||
|
}
|
||||||
|
])
|
||||||
|
->get();
|
||||||
|
$writer = WriterEntityFactory::createXLSXWriter();
|
||||||
|
$writer->openToFile(public_path('files/Report-Data-Claim-Request.xlsx'));
|
||||||
|
$header = [
|
||||||
|
'No',
|
||||||
|
'Code Claim',
|
||||||
|
'Date Claim Submission',
|
||||||
|
'Code LOG',
|
||||||
|
'Date Submission',
|
||||||
|
'Date Admission',
|
||||||
|
'Date Discharge',
|
||||||
|
'Provider',
|
||||||
|
'Member ID (BN)',
|
||||||
|
'Member Name',
|
||||||
|
'Member Name Principal',
|
||||||
|
'Plan Code',
|
||||||
|
'Payor ID',
|
||||||
|
'Corporate name',
|
||||||
|
'Policy Number',
|
||||||
|
'Total Billing',
|
||||||
|
'Benefit Code',
|
||||||
|
'Benefit Desc',
|
||||||
|
'Amt Incurred',
|
||||||
|
'Amt Approved',
|
||||||
|
'Amt Not Approved',
|
||||||
|
'Excess Paid',
|
||||||
|
// 'Reason',
|
||||||
|
'Diagnosis',
|
||||||
|
'Keterangan',
|
||||||
|
'Catatan',
|
||||||
|
'Status',
|
||||||
|
'QC'
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$headerRow = WriterEntityFactory::createRowFromArray($header, $style);
|
||||||
|
$writer->addRow($headerRow);
|
||||||
|
|
||||||
|
$results = $claimRequests;
|
||||||
|
$no=0;
|
||||||
|
$gr_total = 0;
|
||||||
|
$rowData=[];
|
||||||
|
foreach($results as $item)
|
||||||
|
{
|
||||||
|
// $gr_total += $item->tot_bill;
|
||||||
|
// $requestLogData = RequestLogBenefit::selectRaw('*,
|
||||||
|
// (SELECT code FROM benefits WHERE benefits.id = request_log_benefits.benefit_id) AS benefit_code,
|
||||||
|
// (SELECT description FROM benefits WHERE benefits.id = request_log_benefits.benefit_id) AS benefit_description,
|
||||||
|
// sum(amount_incurred) AS total_incurred'
|
||||||
|
// )
|
||||||
|
// ->where(['request_log_id' => $item->request_log_id, 'deleted_at' => null])
|
||||||
|
// ->get()->toArray();
|
||||||
|
|
||||||
|
//Data Benefit
|
||||||
|
$requestLogData = DB::table('request_log_benefits')
|
||||||
|
->where('request_log_benefits.request_log_id', '=', $item->request_log_id)
|
||||||
|
->select(
|
||||||
|
'*',
|
||||||
|
// DB::raw('SUM(request_log_benefits.amount_incurred) AS total_incurred'),
|
||||||
|
|
||||||
|
DB::raw('
|
||||||
|
(Select benefits.description FROM benefits
|
||||||
|
WHERE benefits.id = request_log_benefits.benefit_id LIMIT 1) AS benefit_description
|
||||||
|
'),
|
||||||
|
DB::raw('
|
||||||
|
(Select benefits.code FROM benefits
|
||||||
|
WHERE benefits.id = request_log_benefits.benefit_id LIMIT 1) AS benefit_code
|
||||||
|
')
|
||||||
|
)
|
||||||
|
->get();
|
||||||
|
if ($item->member){
|
||||||
|
$member = Member::where('member_id', $item->member->principal_id)->first();
|
||||||
|
$memberPrincipal = $member->name;
|
||||||
|
$memberPlan = MemberPlan::where('member_id', $item->member->id)->get('plan_id')->toArray();
|
||||||
|
$plan= Plan::whereIn('id', $memberPlan)->where('service_code', $item->requestLog->service_code)->first();
|
||||||
|
$planCode = $plan->code;
|
||||||
|
if ($item->member->currentCorporate->id == $item->requestLog->organization->corporate_id_partner){
|
||||||
|
$payor = $item->member->currentCorporate->name;
|
||||||
|
} else {
|
||||||
|
$payor = 'LinkSehat';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$memberPrincipal = '-';
|
||||||
|
$planCode = '-';
|
||||||
|
$payor = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$requestLogData->isEmpty()){
|
||||||
|
foreach($requestLogData as $key => $data){
|
||||||
|
$no++;
|
||||||
|
if ($key == 0){
|
||||||
|
$gr_total += $item->tot_billing;
|
||||||
|
}
|
||||||
|
$rowItem = [
|
||||||
|
$no,
|
||||||
|
$item->code,
|
||||||
|
$item->submission_date ? $item->submission_date : '',
|
||||||
|
$item->requestLog ? $item->requestLog->code : '-',
|
||||||
|
$item->requestLog ? Helper::dateParser($item->requestLog->created_at) : '-', // submission = created_at
|
||||||
|
$item->requestLog ? $item->requestLog->submission_date : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->discharge_date : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->organization->name : '-',
|
||||||
|
$item->member ? $item->member->member_id : '-',
|
||||||
|
$item->member ? $item->member->name : '-',
|
||||||
|
$memberPrincipal,
|
||||||
|
$key == 0 ? $planCode : '',
|
||||||
|
$payor,
|
||||||
|
$item->member ? $item->member->currentCorporate->name : '-',
|
||||||
|
$item->member ? $item->member->currentPolicy->code : '-',
|
||||||
|
$key == 0 ? $item->tot_billing : '',
|
||||||
|
$data->benefit_code,
|
||||||
|
$data->benefit_description,
|
||||||
|
$data->amount_incurred ? $data->amount_incurred : '' ,
|
||||||
|
$data->amount_approved ? $data->amount_approved : '',
|
||||||
|
$data->amount_not_approved ? $data->amount_not_approved : '',
|
||||||
|
$data->excess_paid ? $data->excess_paid : '',
|
||||||
|
// $data->reason ? $data->reason : '',
|
||||||
|
$item->requestLog ? $item->requestLog->diagnosis : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->keterangan : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->catatan : '-',
|
||||||
|
$item->status ? $item->status : '-'
|
||||||
|
];
|
||||||
|
array_push($rowData,$rowItem);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$no++;
|
||||||
|
if ($item->member){
|
||||||
|
$member = Member::where('member_id', $item->member->principal_id)->first();
|
||||||
|
$memberPrincipal = $member->name;
|
||||||
|
$memberPlan = MemberPlan::where('member_id', $item->member->id)->get('plan_id')->toArray();
|
||||||
|
$plan= Plan::whereIn('id', $memberPlan)->where('service_code', $item->requestLog->service_code)->first();
|
||||||
|
$planCode = $plan->code;
|
||||||
|
if ($item->member->currentCorporate->id == $item->requestLog->organization->corporate_id_partner){
|
||||||
|
$payor = $item->member->currentCorporate->name;
|
||||||
|
} else {
|
||||||
|
$payor = 'LinkSehat';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$memberPrincipal = '-';
|
||||||
|
$planCode = '-';
|
||||||
|
$payor = '-';
|
||||||
|
}
|
||||||
|
$rowItem = [
|
||||||
|
$no,
|
||||||
|
$item->code,
|
||||||
|
$item->submission_date ? Helper::dateParser($item->submission_date) : '',
|
||||||
|
$item->requestLog ? $item->requestLog->code : '-',
|
||||||
|
$item->requestLog ? Helper::dateParser($item->requestLog->created_at) : '-', // submission = created_at
|
||||||
|
$item->requestLog ? $item->requestLog->submission_date : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->discharge_date : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->organization->name : '-',
|
||||||
|
$item->member ? $item->member->member_id : '-',
|
||||||
|
$item->member ? $item->member->name : '-',
|
||||||
|
$memberPrincipal,
|
||||||
|
$planCode,
|
||||||
|
$payor,
|
||||||
|
$item->member ? $item->member->currentCorporate->name : '-',
|
||||||
|
$item->member ? $item->member->currentPolicy->code : '-',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
// '',
|
||||||
|
$item->requestLog ? $item->requestLog->diagnosis : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->keterangan : '-',
|
||||||
|
$item->requestLog ? $item->requestLog->catatan : '-',
|
||||||
|
$item->status ? $item->status : '-'
|
||||||
|
];
|
||||||
|
array_push($rowData,$rowItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
//->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
foreach ($rowData as $rowItem) {
|
||||||
|
// if (is_numeric($rowItem[13])) {
|
||||||
|
// // Jumlahkan nilai angka ke total
|
||||||
|
// $grand_total_billing += $rowItem[13];
|
||||||
|
// }
|
||||||
|
$row = WriterEntityFactory::createRowFromArray($rowItem, $style);
|
||||||
|
$writer->addRow($row);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Footer
|
||||||
|
$footer = [
|
||||||
|
'Total',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
$gr_total,
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
''
|
||||||
|
];
|
||||||
|
$style = (new StyleBuilder())
|
||||||
|
->setFontBold()
|
||||||
|
// ->setFontSize(15)
|
||||||
|
// ->setFontColor(Color::BLUE)
|
||||||
|
// ->setShouldWrapText()
|
||||||
|
->setCellAlignment(CellAlignment::LEFT)
|
||||||
|
// ->setBackgroundColor(Color::YELLOW)
|
||||||
|
->build();
|
||||||
|
$grand_total_billing = 0;
|
||||||
|
$footerRow = WriterEntityFactory::createRowFromArray($footer, $style);
|
||||||
|
$writer->addRow($footerRow);
|
||||||
|
|
||||||
|
$writer->close();
|
||||||
|
return Helper::responseJson([
|
||||||
|
'file_name' => 'Report-Data-Claim-Request',
|
||||||
|
"file_url" => url('files/Report-Data-Claim-Request.xlsx')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function submition($id){
|
||||||
|
$claimRequest = ClaimRequest::findOrFail($id);
|
||||||
|
$claimRequest->status = 'submission';
|
||||||
|
$claimRequest->claim_management = 1;
|
||||||
|
$claimRequest->status_claim_management = 'received';
|
||||||
|
$claimRequest->submission_date_claim_management = date('Y-m-d H:i:s');
|
||||||
|
$claimRequest->submission_by_claim_management = auth()->user()->id;
|
||||||
|
|
||||||
|
$claimRequest->save();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => false,
|
||||||
|
'message' => 'Update succses',
|
||||||
|
'data' => $claimRequest],
|
||||||
|
200);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -559,8 +559,8 @@ class CorporateController extends Controller
|
|||||||
break;
|
break;
|
||||||
case 'claim-request':
|
case 'claim-request':
|
||||||
return Helper::responseJson([
|
return Helper::responseJson([
|
||||||
'file_name' => "Template Format Claim.xlsx",
|
'file_name' => "Template Claim Request.xlsx",
|
||||||
"file_url" => url('files/Template Format Claim.xlsx')
|
"file_url" => url('files/Template Claim Request.xlsx')
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
case 'request-log':
|
case 'request-log':
|
||||||
|
|||||||
@@ -235,6 +235,11 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::post('claims/{claim_id}/set-final-encounter', [ClaimEncounterController::class, 'setFinalEncounter']);
|
Route::post('claims/{claim_id}/set-final-encounter', [ClaimEncounterController::class, 'setFinalEncounter']);
|
||||||
|
|
||||||
Route::get('claims', [ClaimController::class, 'index']);
|
Route::get('claims', [ClaimController::class, 'index']);
|
||||||
|
Route::get('claims/download-template', [ClaimController::class, 'downloadTemplate']);
|
||||||
|
Route::post('claims/import', [ClaimController::class, 'import']);
|
||||||
|
Route::post('claims/exportFiled/', [ClaimController::class, 'exportFiled']);
|
||||||
|
Route::get('claims/export-claim-management', [ClaimController::class, 'exportClaimManagement']);
|
||||||
|
Route::get('claims/get-provider', [ClaimController::class, 'getProvider']);
|
||||||
Route::post('claims/{id}/update-items', [ClaimController::class, 'updateItems'])->name('claim.update-items');
|
Route::post('claims/{id}/update-items', [ClaimController::class, 'updateItems'])->name('claim.update-items');
|
||||||
Route::post('claims/{id}/update-diagnosis', [ClaimController::class, 'updateDiagnosis'])->name('claim.update-diagnosis');
|
Route::post('claims/{id}/update-diagnosis', [ClaimController::class, 'updateDiagnosis'])->name('claim.update-diagnosis');
|
||||||
Route::post('claims/{id}/decline', [ClaimController::class, 'decline'])->name('claim.decline');
|
Route::post('claims/{id}/decline', [ClaimController::class, 'decline'])->name('claim.decline');
|
||||||
@@ -248,6 +253,7 @@ Route::prefix('internal')->group(function () {
|
|||||||
|
|
||||||
Route::post('claims', [ClaimController::class, 'store']);
|
Route::post('claims', [ClaimController::class, 'store']);
|
||||||
Route::get('claims/{id}', [ClaimController::class, 'show']);
|
Route::get('claims/{id}', [ClaimController::class, 'show']);
|
||||||
|
Route::get('claims/cek_status/{id}', [ClaimController::class, 'cekStatus']);
|
||||||
Route::put('claims/{id}', [ClaimController::class, 'update']);
|
Route::put('claims/{id}', [ClaimController::class, 'update']);
|
||||||
Route::get('claims/{id}/edit', [ClaimController::class, 'edit']);
|
Route::get('claims/{id}/edit', [ClaimController::class, 'edit']);
|
||||||
Route::post('check-limit', [ClaimController::class, 'checkLimit']);
|
Route::post('check-limit', [ClaimController::class, 'checkLimit']);
|
||||||
@@ -311,13 +317,15 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
|
Route::get('claim-requests', [ClaimRequestController::class, 'index'])->name('claim-requests.index');
|
||||||
Route::get('claim-requests/list-member', [ClaimRequestController::class, 'getClaimMemberInfiniteScroll']); // Bagaskoro, BSD 31 Oktober 2023
|
Route::get('claim-requests/list-member', [ClaimRequestController::class, 'getClaimMemberInfiniteScroll']); // Bagaskoro, BSD 31 Oktober 2023
|
||||||
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::post('claim-requests/{id}/submition', [ClaimRequestController::class, 'submition'])->name('claim-requests.submition');
|
||||||
|
Route::get('claim-requests/{id}/show', [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::post('claim-requests/{id}/update', [ClaimRequestController::class, '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']);
|
||||||
Route::post('claim-requests/{id}/request-files', [ClaimRequestController::class, 'requestFiles']);
|
Route::post('claim-requests/{id}/request-files', [ClaimRequestController::class, 'requestFiles']);
|
||||||
|
Route::get('claim-requests/export', [ClaimRequestController::class, 'exportClaimRequest']);
|
||||||
|
|
||||||
Route::get('claim-requests/service/{id}', [ClaimRequestController::class, 'getServiceMember']);
|
Route::get('claim-requests/service/{id}', [ClaimRequestController::class, 'getServiceMember']);
|
||||||
|
|
||||||
|
|||||||
@@ -71,10 +71,22 @@ class ClaimRequestShowResource extends JsonResource
|
|||||||
'total_excess_paid' => $total_excess_paid,
|
'total_excess_paid' => $total_excess_paid,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$isReversal = false;
|
||||||
|
$isRole = auth()->user()->role_id;
|
||||||
|
if ($data['request_log']['status'] == 'approved' &&
|
||||||
|
$data['request_log']['status_final_log'] == 'approved' &&
|
||||||
|
$data['status'] == 'approved' &&
|
||||||
|
$data['status_claim_management'] == 'approved' &&
|
||||||
|
$isRole != 1 // is admin
|
||||||
|
){
|
||||||
|
$isReversal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$response = [
|
$response = [
|
||||||
'id' => $data['id'],
|
'id' => $data['id'],
|
||||||
'code' => $data['code'],
|
'code' => $data['code'],
|
||||||
|
'status' => $data['status'],
|
||||||
'request_log_id' => $data['request_log_id'],
|
'request_log_id' => $data['request_log_id'],
|
||||||
'request_log' => $requestLogData,
|
'request_log' => $requestLogData,
|
||||||
'provider' => $data['request_log']['organization']['name'],
|
'provider' => $data['request_log']['organization']['name'],
|
||||||
@@ -98,7 +110,9 @@ class ClaimRequestShowResource extends JsonResource
|
|||||||
'service_type' => Helper::serviceName( $data['request_log']['service_code']),
|
'service_type' => Helper::serviceName( $data['request_log']['service_code']),
|
||||||
'claim_method' => $data['request_log']['payment_type'],
|
'claim_method' => $data['request_log']['payment_type'],
|
||||||
'files' => $data['request_log']['files'],
|
'files' => $data['request_log']['files'],
|
||||||
|
'reason_decline' => $data['reason_decline'],
|
||||||
// 'benefit_data' => $benefitDetailLog,
|
// 'benefit_data' => $benefitDetailLog,
|
||||||
|
'is_reversal' => $isReversal, // untuk penjagaan, jika true tidak bisa di edit/hapus lagi
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use App\Models\RequestLogBenefit;
|
|||||||
use App\Models\RequestLogMedicine;
|
use App\Models\RequestLogMedicine;
|
||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
use App\Models\Exclusion;
|
use App\Models\Exclusion;
|
||||||
|
use App\Models\ClaimRequest;
|
||||||
use App\Models\Icd;
|
use App\Models\Icd;
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
use App\Models\CorporatePolicy;
|
use App\Models\CorporatePolicy;
|
||||||
@@ -36,6 +37,23 @@ class RequestLogShowResource extends JsonResource
|
|||||||
$benefitDetailLog = RequestLogBenefit::with('benefit')->where('request_log_id', $requestLog['id'])->get()->toArray();
|
$benefitDetailLog = RequestLogBenefit::with('benefit')->where('request_log_id', $requestLog['id'])->get()->toArray();
|
||||||
$medicineDetailLog = RequestLogMedicine::where('request_log_id', $requestLog['id'])->get()->toArray();
|
$medicineDetailLog = RequestLogMedicine::where('request_log_id', $requestLog['id'])->get()->toArray();
|
||||||
$provider = Organization::where('id', $requestLog['organization_id'])->first();
|
$provider = Organization::where('id', $requestLog['organization_id'])->first();
|
||||||
|
$claimRequest = ClaimRequest::where('request_log_id', $requestLog['id'])->first();
|
||||||
|
if ($claimRequest) {
|
||||||
|
$claimCode = $claimRequest->code;
|
||||||
|
$isReversal = false;
|
||||||
|
$isRole = auth()->user()->role_id;
|
||||||
|
if ($requestLog['status'] == 'approved' &&
|
||||||
|
$requestLog['status_final_log'] == 'approved' &&
|
||||||
|
$claimRequest->status == 'approved' &&
|
||||||
|
$claimRequest->status_claim_management == 'approved' &&
|
||||||
|
$isRole != 1
|
||||||
|
){
|
||||||
|
$isReversal = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$claimCode = '-';
|
||||||
|
$isReversal = false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($provider){
|
if ($provider){
|
||||||
$providerName = $provider->name;
|
$providerName = $provider->name;
|
||||||
@@ -90,11 +108,12 @@ class RequestLogShowResource extends JsonResource
|
|||||||
->whereIn('code', $diagnosis)
|
->whereIn('code', $diagnosis)
|
||||||
->select('code', 'name')
|
->select('code', 'name')
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'id' => $requestLog['id'],
|
'id' => $requestLog['id'],
|
||||||
'code' => $requestLog['code'],
|
'code' => $requestLog['code'],
|
||||||
|
'code_claim' => $claimCode,
|
||||||
'member_id' => $requestLog['member']['member_id'],
|
'member_id' => $requestLog['member']['member_id'],
|
||||||
'corporate_id' => $corporateId,
|
'corporate_id' => $corporateId,
|
||||||
'policy_number' =>$policyNumber->code ? $policyNumber->code : '-',
|
'policy_number' =>$policyNumber->code ? $policyNumber->code : '-',
|
||||||
@@ -128,6 +147,7 @@ class RequestLogShowResource extends JsonResource
|
|||||||
'catatan' => $requestLog['catatan'],
|
'catatan' => $requestLog['catatan'],
|
||||||
'reason' => $requestLog['reason'],
|
'reason' => $requestLog['reason'],
|
||||||
'diagnosis' => $icd,
|
'diagnosis' => $icd,
|
||||||
|
'is_reversal' => $isReversal, // untuk penjagaan, jika true tidak bisa di edit/hapus lagi
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
|
use DateTime;
|
||||||
|
|
||||||
class Helper
|
class Helper
|
||||||
{
|
{
|
||||||
@@ -426,4 +427,20 @@ class Helper
|
|||||||
ini_set('memory_limit', '256M');
|
ini_set('memory_limit', '256M');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function dateParser($date_from_row) {
|
||||||
|
if ($date_from_row instanceof DateTime) {
|
||||||
|
return $date_from_row->format('Y-m-d');
|
||||||
|
} else if ($date_from_row != null) {
|
||||||
|
if (strtotime($date_from_row)){
|
||||||
|
return date('Y-m-d', strtotime($date_from_row));
|
||||||
|
} else {
|
||||||
|
// throw new ImportRowException(__('Format Date Invalid'), 0, null, $date_from_row);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// throw new ImportRowException(__('Format Date Invalid'), 0, null, $date_from_row);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ class ClaimRequest extends Model
|
|||||||
'service_code',
|
'service_code',
|
||||||
'policy_id',
|
'policy_id',
|
||||||
'status',
|
'status',
|
||||||
|
// New field for claim management
|
||||||
|
'claim_management',
|
||||||
|
'status_claim_management',
|
||||||
|
'submission_date_claim_management',
|
||||||
|
'submission_by_claim_management',
|
||||||
|
'approval_date_claim_management',
|
||||||
|
'approval_by_claim_management',
|
||||||
|
'reason_decline',
|
||||||
|
//
|
||||||
'claim_id',
|
'claim_id',
|
||||||
'organization_id',
|
'organization_id',
|
||||||
'code',
|
'code',
|
||||||
@@ -43,69 +52,29 @@ class ClaimRequest extends Model
|
|||||||
];
|
];
|
||||||
|
|
||||||
public static $doc_headers_to_field_map = [
|
public static $doc_headers_to_field_map = [
|
||||||
"PAYOR ID" => "payor_id",
|
"Code LOG" => "code",
|
||||||
"CORPORATE ID" => "corporate_id",
|
"Date Claim Submission" => "date_submission",
|
||||||
"POLICY NUMBER" => "policy_number",
|
"Total Billing" => "total_billing",
|
||||||
"MEMBER ID" => "member_id",
|
"Benefit Code" => "benefit_code",
|
||||||
"MEMBER NAME" => "member_name",
|
"Amt Incurred" => "amount_incurred",
|
||||||
"RECORD TYPE (P/D)" => "record_type",
|
"Amt Approved" => "amount_apporve",
|
||||||
"BENEFIT CODE" => "benefit_code",
|
"Amt Not Approved" => "amount_not_apporve",
|
||||||
"BENEFIT DESC" => "benefit_desc",
|
"Excess Paid" => "excess_paid",
|
||||||
"CLAIM TYPE" => "claim_type",
|
"Reason" => "reason",
|
||||||
"CLAIM PROCESS STATUS" => "status",
|
"QC" => "qc",
|
||||||
"CLIENT CLAIM ID" => "client_claim_id",
|
|
||||||
"REFERENCE NO" => "reference_no",
|
|
||||||
"ADMEDIKA CLAIM ID" => "admika_claim_id",
|
|
||||||
"PROVIDER CODE" => "provider_code",
|
|
||||||
"ADMISSION DATE" => "admission_date",
|
|
||||||
"DISCUTRGE DATE" => "discutrge_date",
|
|
||||||
"DURATION DAYS" => "duration_days",
|
|
||||||
"COVERAGE TYPE" => "coverage_type",
|
|
||||||
"PLAN ID" => "plan_id",
|
|
||||||
"DIAGNOSIS CODE" => "diagnosis_code",
|
|
||||||
"DIAGNOSIS DESC" => "diagnosis_desc",
|
|
||||||
"TOT AMT INCURRED" => "tot_amt_insurred",
|
|
||||||
"TOT AMT APPROVED" => "tot_amt_approved",
|
|
||||||
"TOT AMT NOT APPROVED" => "tot_amt_not_approved",
|
|
||||||
"TOT EXCESS PAID" => "tot_excess_paid",
|
|
||||||
"REMARKS" => "remarks",
|
|
||||||
"SECONDARY DIAGNOSIS CODE" => "secondary_diagnosis",
|
|
||||||
"APPROVED DATE" => "approved_date",
|
|
||||||
"APPROVED BY" => "approved_by",
|
|
||||||
"DATE RECEIVED" => "data_received",
|
|
||||||
"HOSPITAL INVOICE DATE" => "hospital_invoice_date",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public static $listing_doc_headers = [
|
public static $listing_doc_headers = [
|
||||||
"PAYOR ID",
|
"Code LOG",
|
||||||
"CORPORATE ID",
|
"Date Claim Submission",
|
||||||
"POLICY NUMBER",
|
"Total Billing",
|
||||||
"MEMBER ID",
|
"Benefit Code",
|
||||||
"MEMBER NAME",
|
"Amt Incurred",
|
||||||
"RECORD TYPE (P/D)",
|
"Amt Approved",
|
||||||
"CLAIM TYPE",
|
"Amt Not Approved",
|
||||||
"CLAIM PROCESS STATUS",
|
"Excess Paid",
|
||||||
"CLIENT CLAIM ID",
|
// "Reason",
|
||||||
"REFERENCE NO",
|
"QC",
|
||||||
"ADMEDIKA CLAIM ID",
|
|
||||||
"PROVIDER CODE",
|
|
||||||
"ADMISSION DATE",
|
|
||||||
"DISCUTRGE DATE",
|
|
||||||
"DURATION DAYS",
|
|
||||||
"COVERAGE TYPE",
|
|
||||||
"PLAN ID",
|
|
||||||
"DIAGNOSIS CODE",
|
|
||||||
"DIAGNOSIS DESC",
|
|
||||||
"TOT AMT INCURRED",
|
|
||||||
"TOT AMT APPROVED",
|
|
||||||
"TOT AMT NOT APPROVED",
|
|
||||||
"TOT EXCESS PAID",
|
|
||||||
"REMARKS",
|
|
||||||
"SECONDARY DIAGNOSIS CODE",
|
|
||||||
"APPROVED DATE",
|
|
||||||
"APPROVED BY",
|
|
||||||
"DATE RECEIVED",
|
|
||||||
"HOSPITAL INVOICE DATE",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ use App\Events\ClaimApproved;
|
|||||||
use App\Events\ClaimRequested;
|
use App\Events\ClaimRequested;
|
||||||
use App\Models\Claim;
|
use App\Models\Claim;
|
||||||
use App\Models\ClaimRequest;
|
use App\Models\ClaimRequest;
|
||||||
|
use App\Models\RequestLog;
|
||||||
|
use App\Models\Benefit;
|
||||||
|
use App\Models\RequestLogBenefit;
|
||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
use App\Models\Icd;
|
use App\Models\Icd;
|
||||||
@@ -20,6 +23,7 @@ use Str;
|
|||||||
|
|
||||||
class ClaimRequestService{
|
class ClaimRequestService{
|
||||||
|
|
||||||
|
private static $code_prefix = 'CLAIM';
|
||||||
public static function storeClaimRequest($row = null, $code, $member, $paymentType, $serviceCode, $requestLogID = null, $submissionDate = null, $status = 'requested', $organization_code = null)
|
public static function storeClaimRequest($row = null, $code, $member, $paymentType, $serviceCode, $requestLogID = null, $submissionDate = null, $status = 'requested', $organization_code = null)
|
||||||
{
|
{
|
||||||
// try {
|
// try {
|
||||||
@@ -32,24 +36,74 @@ class ClaimRequestService{
|
|||||||
'code' => $row['provider_code']
|
'code' => $row['provider_code']
|
||||||
]), 403, null, $row);
|
]), 403, null, $row);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
$claimRequestData = [
|
if ($status == 'submission'){
|
||||||
'code' => $code,
|
$claimManagement = 1;
|
||||||
'request_log_id' => $requestLogID ?? 0,
|
$submissionDateClaimManagement = $submissionDate;
|
||||||
'member_id' => $member->id,
|
$submissionByClaimManagement = auth()->user()->id;
|
||||||
'submission_date' => $submissionDate ?? now(),
|
$statusClaim = 'received';
|
||||||
'status' => $status,
|
} else {
|
||||||
'payment_type' => $paymentType,
|
$claimManagement = 0;
|
||||||
'service_code' => $serviceCode,
|
$submissionDateClaimManagement = null;
|
||||||
'policy_id' => $member->currentPolicy->id ?? null,
|
$submissionByClaimManagement = null;
|
||||||
'organization_id' => $organization ? $organization->id : 0,
|
$statusClaim = null;
|
||||||
];
|
}
|
||||||
|
if (count($row)>0){
|
||||||
$claimRequest = ClaimRequest::create($claimRequestData);
|
if($row['total_billing']) {
|
||||||
|
$data = [
|
||||||
|
'code' => $code,
|
||||||
|
'request_log_id' => $requestLogID ?? 0,
|
||||||
|
'member_id' => $member->id,
|
||||||
|
'submission_date' => $submissionDate ?? now(),
|
||||||
|
'status' => $status,
|
||||||
|
'claim_management' => $claimManagement,
|
||||||
|
'status_claim_management' => $statusClaim,
|
||||||
|
'submission_date_claim_management' => $submissionDateClaimManagement,
|
||||||
|
'submission_by_claim_management' => $submissionByClaimManagement,
|
||||||
|
'payment_type' => $paymentType,
|
||||||
|
'service_code' => $serviceCode,
|
||||||
|
'policy_id' => $member->currentPolicy->id ?? null,
|
||||||
|
'organization_id' => $organization ? $organization->id : 0,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$data = [];
|
||||||
|
}
|
||||||
|
$claimRequest = ClaimRequest::updateOrCreate(['request_log_id' => $requestLogID],$data);
|
||||||
|
|
||||||
|
$benefitData = Benefit::where('code', $row['benefit_code'])->first();
|
||||||
|
$requestLogData = RequestLogBenefit::updateOrCreate(
|
||||||
|
[
|
||||||
|
'request_log_id' => $requestLogID,
|
||||||
|
'benefit_id' => $benefitData->id,
|
||||||
|
],[
|
||||||
|
'request_log_id' => $requestLogID,
|
||||||
|
'benefit_id' => $benefitData->id,
|
||||||
|
'amount_incurred' => $row['amount_incurred'],
|
||||||
|
'amount_approved' => $row['amount_apporve'],
|
||||||
|
'amount_not_approved' => $row['amount_not_apporve'],
|
||||||
|
'excess_paid' => $row['excess_paid'],
|
||||||
|
]);
|
||||||
|
} else { // input from hospital portal
|
||||||
|
$data = [
|
||||||
|
'code' => $code,
|
||||||
|
'request_log_id' => $requestLogID ?? 0,
|
||||||
|
'member_id' => $member->id,
|
||||||
|
'submission_date' => $submissionDate ?? now(),
|
||||||
|
'status' => $status,
|
||||||
|
'claim_management' => $claimManagement,
|
||||||
|
'status_claim_management' => $statusClaim,
|
||||||
|
'submission_date_claim_management' => $submissionDateClaimManagement,
|
||||||
|
'submission_by_claim_management' => $submissionByClaimManagement,
|
||||||
|
'payment_type' => $paymentType,
|
||||||
|
'service_code' => $serviceCode,
|
||||||
|
'policy_id' => $member->currentPolicy->id ?? null,
|
||||||
|
'organization_id' => $organization ? $organization->id : 0,
|
||||||
|
];
|
||||||
|
$claimRequest = ClaimRequest::updateOrCreate(['request_log_id' => $requestLogID],$data);
|
||||||
|
}
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return $claimRequest;
|
return $claimRequest;
|
||||||
@@ -60,8 +114,6 @@ class ClaimRequestService{
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function storeClaimManagement($row, $member, $claim_request_id){
|
public static function storeClaimManagement($row, $member, $claim_request_id){
|
||||||
try {
|
try {
|
||||||
$organization = 0;
|
$organization = 0;
|
||||||
@@ -130,53 +182,58 @@ class ClaimRequestService{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function validatePlanRow($row)
|
|
||||||
{
|
|
||||||
if (empty($row['member_id'])) {
|
|
||||||
throw new ImportRowException(__('Member ID Required'), 0, null, $row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleClaimRequestRow($row)
|
public function handleClaimRequestRow($row)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$member = Member::where('member_id', $row['member_id'])->with(['currentPlan'])->first();
|
$requestLog = RequestLog::where('code', $row['code'])->first();
|
||||||
if(!$member){
|
if(!$requestLog){
|
||||||
throw new ImportRowException(__('Member Tidak ditemukan'), 0, null, $row);
|
throw new ImportRowException(__('LOG Tidak ditemukan'), 0, null, $row);
|
||||||
};
|
};
|
||||||
$code = $row['client_claim_id'];
|
|
||||||
$organization_id = $row['provider_code'];
|
|
||||||
$submissionDate = Helper::formatDateDB($row['admission_date']);
|
|
||||||
$paymentType = $row['claim_type'];
|
|
||||||
$status = $row['status'];
|
|
||||||
$serviceCode = $row['coverage_type'];
|
|
||||||
|
|
||||||
|
if ($requestLog->status != 'approved' && $requestLog != 'approved'){
|
||||||
|
throw new ImportRowException(__('Request LOG / Final LOG Belum di Approved'), 0, null, $row);
|
||||||
|
}
|
||||||
|
$organization = Organization::where('id', $requestLog->organization_id)->first();
|
||||||
|
|
||||||
|
// Create Code
|
||||||
|
$last_numeric_code = ClaimRequest::select(DB::raw('MAX(CAST(SUBSTRING_INDEX(code, ".", -1) AS SIGNED)) as max_numeric_code'))
|
||||||
|
->whereRaw('SUBSTRING_INDEX(code, ".", -1) REGEXP "^[0-9]+$"')
|
||||||
|
->value('max_numeric_code');
|
||||||
|
// $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;
|
||||||
|
}
|
||||||
|
// make code
|
||||||
|
$member = Member::with('currentCorporate')->where(['id' => $requestLog->member_id])->first();
|
||||||
|
$sparator = '.';
|
||||||
|
$date = date('ymd');
|
||||||
|
// Menghasilkan kode dengan format yang diinginkan
|
||||||
|
$code = 'CLAIM' . $sparator. 'I' . $sparator. $organization->code . $sparator. $date. $sparator . $member->currentPolicy->code . $sparator. $member->member_id . $sparator. str_pad($next_number, 5, '0', STR_PAD_LEFT);
|
||||||
|
$submissionDate = Helper::dateParser($row['date_submission']);
|
||||||
|
$paymentType = $requestLog->payment_type;
|
||||||
|
if ($row['qc'] == 'Y'){
|
||||||
|
$status = 'submission';
|
||||||
|
} else {
|
||||||
|
$status = 'requested';
|
||||||
|
}
|
||||||
|
$serviceCode = $requestLog->service_code;
|
||||||
$newClaimRequest = $this->storeClaimRequest(
|
$newClaimRequest = $this->storeClaimRequest(
|
||||||
row: $row,
|
row: $row,
|
||||||
code: $code,
|
code: $code,
|
||||||
member: $member,
|
member: $member,
|
||||||
paymentType: $paymentType,
|
paymentType: $paymentType,
|
||||||
serviceCode: $serviceCode,
|
serviceCode: $serviceCode,
|
||||||
|
requestLogID: $requestLog->id,
|
||||||
submissionDate: $submissionDate,
|
submissionDate: $submissionDate,
|
||||||
status: $status,
|
status: $status,
|
||||||
organization_code: $organization_id
|
organization_code: $organization->code
|
||||||
);
|
);
|
||||||
|
|
||||||
$newlyCreatedID = $newClaimRequest->id;
|
$newlyCreatedID = $newClaimRequest->id;
|
||||||
|
|
||||||
$newClaimManangement = $this->storeClaimManagement($row, $member, $newlyCreatedID);
|
|
||||||
ClaimRequested::dispatch($newClaimRequest);
|
|
||||||
// Log History
|
|
||||||
$newClaimRequest->histories()->create([
|
|
||||||
'title' => 'New Claim Requested',
|
|
||||||
'description' => "Claim Requested for Member : {$member->member_id} - ({$member->full_name})",
|
|
||||||
'type' => 'info',
|
|
||||||
'system_origin' => 'import-internal-aso'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$claim_request_data = $row;
|
|
||||||
$this->validatePlanRow($claim_request_data);
|
|
||||||
|
|
||||||
return $newClaimRequest;
|
return $newClaimRequest;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw $e;
|
throw $e;
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<?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->integer('claim_management')
|
||||||
|
->default(0)
|
||||||
|
->after('status')
|
||||||
|
->comment('0=claim request, 1=claim management');
|
||||||
|
$table->string('status_claim_management')->after('claim_management')->nullable();
|
||||||
|
$table->dateTime('submission_date_claim_management')->after('status_claim_management')->nullable();
|
||||||
|
$table->string('submission_by_claim_management')->after('submission_date_claim_management')->nullable();
|
||||||
|
$table->dateTime('approval_date_claim_management')->after('submission_by_claim_management')->nullable();
|
||||||
|
$table->string('approval_by_claim_management')->after('approval_date_claim_management')->nullable();
|
||||||
|
$table->string('reason_decline')->after('approval_by_claim_management')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('claim_requests', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('claim_management');
|
||||||
|
$table->dropColumn('status_claim_management');
|
||||||
|
$table->dropColumn('submission_date_claim_management');
|
||||||
|
$table->dropColumn('submission_by_claim_management');
|
||||||
|
$table->dropColumn('approval_date_claim_management');
|
||||||
|
$table->dropColumn('approval_by_claim_management');
|
||||||
|
$table->dropColumn('reason_decline');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -203,6 +203,8 @@ type ServiceMonitoringProps = {
|
|||||||
}[];
|
}[];
|
||||||
}>
|
}>
|
||||||
>;
|
>;
|
||||||
|
keterangan: string;
|
||||||
|
catatan: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ServiceMonitoring() {
|
export default function ServiceMonitoring() {
|
||||||
@@ -591,6 +593,44 @@ export default function ServiceMonitoring() {
|
|||||||
)}
|
)}
|
||||||
</Grid> */}
|
</Grid> */}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
{/* Keterangan */}
|
||||||
|
<Grid item container xs={12} spacing={1.5}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="subtitle2" color={'grey.600'}>
|
||||||
|
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Keterangan'}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="subtitle1" color={'grey.800'}>
|
||||||
|
{loading ? (
|
||||||
|
<Skeleton animation={'wave'} width={300} />
|
||||||
|
) : data && data.keterangan ? (
|
||||||
|
data.keterangan
|
||||||
|
) : (
|
||||||
|
'-'
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
{/* Catatan */}
|
||||||
|
<Grid item container xs={12} spacing={1.5}>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="subtitle2" color={'grey.600'}>
|
||||||
|
{loading ? <Skeleton animation={'wave'} width={200} /> : 'Catatan'}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="subtitle1" color={'grey.800'}>
|
||||||
|
{loading ? (
|
||||||
|
<Skeleton animation={'wave'} width={300} />
|
||||||
|
) : data && data.catatan ? (
|
||||||
|
data.catatan
|
||||||
|
) : (
|
||||||
|
'-'
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,35 +1,30 @@
|
|||||||
import MuiDialog from "@/components/MuiDialog";
|
import MuiDialog from "@/components/MuiDialog";
|
||||||
import { Autocomplete, Button, Card, Checkbox, DialogActions, Grid, TextField, Typography } from "@mui/material";
|
import { Button, Card, Checkbox, DialogActions, Grid, TextField, TextareaAutosize, Typography } from "@mui/material";
|
||||||
import { Paper } from "@mui/material";
|
import { Paper } from "@mui/material";
|
||||||
import { Stack } from '@mui/material';
|
import { Stack } from '@mui/material';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { ClaimRequest, Files } from '@/@types/claims';
|
import { DetailClaimRequest } from "../Model/Types";
|
||||||
import { fDateOnly, fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||||
import axios from "@/utils/axios";
|
import axios from "@/utils/axios";
|
||||||
import { enqueueSnackbar, useSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import * as Yup from 'yup';
|
import { RHFTextField } from "@/components/hook-form";
|
||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
|
||||||
|
|
||||||
type DialogConfirmationType = {
|
type DialogConfirmationType = {
|
||||||
openDialog: boolean;
|
openDialog: boolean;
|
||||||
setOpenDialog: any;
|
setOpenDialog: any;
|
||||||
onSubmit?: void;
|
onSubmit?: void;
|
||||||
approve: string;
|
approve: string;
|
||||||
claimRequest: ClaimRequest|undefined;
|
requestLog: DetailClaimRequest|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DialogConfirmation({claimRequest, setOpenDialog, openDialog, approve, onSubmit} : DialogConfirmationType ) {
|
export default function DialogConfirmation({requestLog, setOpenDialog, openDialog, approve, onSubmit} : DialogConfirmationType ) {
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { enqueueSnackbar } = useSnackbar();
|
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
date: claimRequest?.date,
|
|
||||||
id: claimRequest?.id,
|
|
||||||
reason: claimRequest?.reason
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleChange = (field, value) => {
|
const handleChange = (field, value) => {
|
||||||
setFormData((prevData) => ({
|
setFormData((prevData) => ({
|
||||||
...prevData,
|
...prevData,
|
||||||
@@ -38,24 +33,28 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleApprove = () => {
|
||||||
|
setFormData((prevData) => ({
|
||||||
|
...prevData,
|
||||||
|
status: approve,
|
||||||
|
}));
|
||||||
|
handleSubmit();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
axios
|
axios
|
||||||
.post(`customer-service/request/final-log`, formData)
|
.post(`claim-requests/${requestLog?.id}/submition`, formData)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
enqueueSnackbar('Verification Request LOG Success', { variant: 'success' });
|
enqueueSnackbar('Submition Claim Request Success', { variant: 'success' });
|
||||||
setOpenDialog(false);
|
setOpenDialog(false);
|
||||||
if (requestLog?.service_type == 'Inpatient'){
|
navigate('/claim-requests')
|
||||||
navigate('/case_management/inpatient_monitoring');
|
|
||||||
} else {
|
|
||||||
navigate('/custormer-service/final-log');
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch(({ response }) => {
|
.catch(({ response }) => {
|
||||||
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const style1 = {
|
const style1 = {
|
||||||
color: '#919EAB',
|
color: '#919EAB',
|
||||||
width: '30%'
|
width: '30%'
|
||||||
@@ -66,34 +65,57 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
|
|||||||
const marginBottom1 = {
|
const marginBottom1 = {
|
||||||
marginBottom: 1,
|
marginBottom: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
const marginBottom2 = {
|
const marginBottom2 = {
|
||||||
marginBottom: 2,
|
marginBottom: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
setFormData({
|
||||||
|
status: approve,
|
||||||
|
no_identitas: requestLog?.no_identitas ?? '',
|
||||||
|
keterangan: '',
|
||||||
|
hak_kamar_pasien: '',
|
||||||
|
penempatan_kamar: '',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleCloseDialog = () => {
|
const handleCloseDialog = () => {
|
||||||
setOpenDialog(false);
|
setOpenDialog(false);
|
||||||
|
resetForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleNumericInput = (input: any) => {
|
||||||
|
const numericInput = input.replace(/\D/g, '');
|
||||||
|
return numericInput;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyPress = (e:any) => {
|
||||||
|
if (e.key === 'Enter' && !e.shiftKey) {
|
||||||
|
// Menghentikan default "Enter" (tidak membuat baris baru)
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Menambahkan karakter baris baru
|
||||||
|
handleChange('keterangan', `${formData.keterangan}\n`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(approve, 'test')
|
||||||
const getContent = () => (
|
const getContent = () => (
|
||||||
<Stack spacing={1} marginTop={2}>
|
<Stack spacing={1} marginTop={2}>
|
||||||
<Typography variant="subtitle2">Are you sure to {approve == 'approved' ? 'approve' : 'deciline'} this final log ?</Typography>
|
<Typography variant="subtitle1">Are you sure to submit this claim ?</Typography>
|
||||||
<Grid item xs={12} md={12} marginTop={4}>
|
<Grid item xs={12} md={12} marginTop={4}>
|
||||||
<Card sx={{padding:2, marginTop:2}} >
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Member ID</Typography>
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Code</Typography>
|
||||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.member_id}</Typography>
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.code}</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>
|
||||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Name</Typography>
|
||||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.name}</Typography>
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.name}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Submission Date</Typography>
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Date Submission</Typography>
|
||||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.submission_date ? fDateTimesecond(requestLog?.submission_date) : '-'}</Typography>
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.submission_date ? fDateTimesecond(requestLog?.submission_date) : '-'}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
@@ -105,58 +127,10 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
|
|||||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.service_type}</Typography>
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{requestLog?.service_type}</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</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>
|
</Grid>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialog}>Cancel</Button>
|
||||||
|
<Button color="primary" variant="contained" onClick={() => handleApprove()}>Submit</Button>
|
||||||
{approve == 'approved' ? (
|
|
||||||
<Button color="primary" variant="contained" onClick={() => handleApprove()}>Approve</Button>
|
|
||||||
) : (
|
|
||||||
<Button color="error" variant="contained" onClick={() => handleApprove()}>Decline</Button>
|
|
||||||
) }
|
|
||||||
|
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
@@ -168,7 +142,7 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia
|
|||||||
openDialog={openDialog}
|
openDialog={openDialog}
|
||||||
setOpenDialog={setOpenDialog}
|
setOpenDialog={setOpenDialog}
|
||||||
content={getContent()}
|
content={getContent()}
|
||||||
maxWidth="xl"
|
maxWidth="md"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -78,15 +78,13 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const [date, setDate] = useState(currentClaim?.submission_date)
|
const [date, setDate] = useState(currentClaim?.submission_date ? fDateTimesecond(currentClaim?.submission_date) : null)
|
||||||
const id = currentClaim?.id
|
const id = currentClaim?.id
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDate(currentClaim?.submission_date)
|
setDate(currentClaim?.submission_date)
|
||||||
}, [currentClaim]);
|
}, [currentClaim]);
|
||||||
|
|
||||||
console.log(date);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isEdit && currentClaim) {
|
if (isEdit && currentClaim) {
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
@@ -254,7 +252,6 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Stack direction="row" alignItems="center" sx={{ mb: 5 }}>
|
<Stack direction="row" alignItems="center" sx={{ mb: 5 }}>
|
||||||
@@ -310,10 +307,14 @@ export default function FormEdit({ isEdit, currentClaim }: Props) {
|
|||||||
<RHFDateTimePicker
|
<RHFDateTimePicker
|
||||||
{...field}
|
{...field}
|
||||||
label="Date of Submission"
|
label="Date of Submission"
|
||||||
value={field.value || null}
|
value={field.value}
|
||||||
onChange={() => setDate(field.value)}
|
onChange={() =>
|
||||||
|
setDate(field.value)
|
||||||
|
}
|
||||||
|
dateFormat='dd MMM yyyy HH:mm:ss'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={3}>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export default function ClaimsCreateUpdate() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
axios.get('/claim-requests/' + id).then((res) => {
|
axios.get('/claim-requests/' + id + '/show').then((res) => {
|
||||||
setCurrentClaim(res.data.data);
|
setCurrentClaim(res.data.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ import DialogDeleteFileLog from './Components/DialogDeleteFileLog';
|
|||||||
import DialogBenefit from '../CustomerService/FinalLog/Components/DialogBenefit';
|
import DialogBenefit from '../CustomerService/FinalLog/Components/DialogBenefit';
|
||||||
import DialogDeleteBenefit from '../CustomerService/FinalLog/Components/DialogDeleteBenefit';
|
import DialogDeleteBenefit from '../CustomerService/FinalLog/Components/DialogDeleteBenefit';
|
||||||
import DialogEditBenefit from '../CustomerService/FinalLog/Components/DialogEditBenefit';
|
import DialogEditBenefit from '../CustomerService/FinalLog/Components/DialogEditBenefit';
|
||||||
|
import DialogConfirmation from './Components/DialogConfirmation';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
@@ -49,6 +51,8 @@ export default function Detail() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
const [claimRequests, setClaimRequest] = useState<DetailClaimRequest>();
|
const [claimRequests, setClaimRequest] = useState<DetailClaimRequest>();
|
||||||
|
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
||||||
|
const [isReversal, setIsReversal] = useState(false);
|
||||||
|
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
|
||||||
@@ -57,6 +61,7 @@ export default function Detail() {
|
|||||||
.get('claim-requests/detail/'+id)
|
.get('claim-requests/detail/'+id)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setClaimRequest(response.data.data)
|
setClaimRequest(response.data.data)
|
||||||
|
setIsReversal(response.data.data.is_reversal)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -223,13 +228,18 @@ export default function Detail() {
|
|||||||
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
||||||
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Document </Typography>
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Document </Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
{
|
||||||
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
!isReversal ? (
|
||||||
setDialogUploadFileLog(true)
|
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
||||||
}} >
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
<Typography variant="button" display="block">File</Typography>
|
setDialogUploadFileLog(true)
|
||||||
</Button>
|
}} >
|
||||||
</Stack>
|
<Typography variant="button" display="block">File</Typography>
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
</Stack>
|
</Stack>
|
||||||
{claimRequests?.files?.map((documentType, index) => (
|
{claimRequests?.files?.map((documentType, index) => (
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{marginBottom: 2}} key={index}>
|
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{marginBottom: 2}} key={index}>
|
||||||
@@ -250,14 +260,19 @@ export default function Detail() {
|
|||||||
<Typography variant="body1" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
|
<Typography variant="body1" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
|
||||||
</a>
|
</a>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack direction="column" spacing={2}>
|
{
|
||||||
<IconButton onClick={() => {
|
!isReversal ? (
|
||||||
setDialogDeleteFileLog(true)
|
<Stack direction="column" spacing={2}>
|
||||||
setPathFile(documentType.path)
|
<IconButton onClick={() => {
|
||||||
}} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}>
|
setDialogDeleteFileLog(true)
|
||||||
<Delete color='error' fontSize="small" />
|
setPathFile(documentType.path)
|
||||||
</IconButton>
|
}} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}>
|
||||||
</Stack>
|
<Delete color='error' fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</Stack>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
</Stack>
|
</Stack>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
@@ -281,11 +296,15 @@ export default function Detail() {
|
|||||||
<Card sx={{padding:2}} >
|
<Card sx={{padding:2}} >
|
||||||
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Benefit</Typography>
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Benefit</Typography>
|
||||||
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
{
|
||||||
setDialogBenefit(true);
|
!isReversal ? (
|
||||||
}} >
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
<Typography variant="button" display="block">Benefit</Typography>
|
setDialogBenefit(true);
|
||||||
</Button>
|
}} >
|
||||||
|
<Typography variant="button" display="block">Benefit</Typography>
|
||||||
|
</Button>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Box sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '24px', py: '20px', marginBottom: '24px', borderRadius: '12px'}}>
|
<Box sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '24px', py: '20px', marginBottom: '24px', borderRadius: '12px'}}>
|
||||||
@@ -298,29 +317,34 @@ export default function Detail() {
|
|||||||
{item.benefit?.description}
|
{item.benefit?.description}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
|
{
|
||||||
<MoreMenu actions={
|
!isReversal ? (
|
||||||
<>
|
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
|
||||||
<MenuItem onClick={() => {
|
<MoreMenu actions={
|
||||||
setDialogEditBenefit(true)
|
<>
|
||||||
setIdBenefitData(item.id)
|
<MenuItem onClick={() => {
|
||||||
setBenefitConfigurationData(item)
|
setDialogEditBenefit(true)
|
||||||
}}
|
setIdBenefitData(item.id)
|
||||||
>
|
setBenefitConfigurationData(item)
|
||||||
<EditOutlined />
|
}}
|
||||||
Edit
|
>
|
||||||
</MenuItem>
|
<EditOutlined />
|
||||||
<MenuItem onClick={() => {
|
Edit
|
||||||
setIdBenefitData(item.id)
|
</MenuItem>
|
||||||
setDialogDeleteBenefit(true)
|
<MenuItem onClick={() => {
|
||||||
}}
|
setIdBenefitData(item.id)
|
||||||
>
|
setDialogDeleteBenefit(true)
|
||||||
<Delete color='error'/>
|
}}
|
||||||
Delete
|
>
|
||||||
</MenuItem>
|
<Delete color='error'/>
|
||||||
</>
|
Delete
|
||||||
} />
|
</MenuItem>
|
||||||
</Grid>
|
</>
|
||||||
|
} />
|
||||||
|
</Grid>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} py={2}>
|
<Grid item xs={12} py={2}>
|
||||||
@@ -421,7 +445,7 @@ export default function Detail() {
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
|
<Typography variant="subtitle1" sx={{ fontWeight: 'bold'}}>
|
||||||
Total Benefit
|
Total Benefit
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -436,12 +460,12 @@ export default function Detail() {
|
|||||||
<Grid item xs={2}>
|
<Grid item xs={2}>
|
||||||
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption">
|
<Typography variant="subtitle1">
|
||||||
Amount Incurred
|
Amount Incurred
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
|
||||||
{totalAmountIncurred ? fNumber(totalAmountIncurred) : '0'}
|
{totalAmountIncurred ? fNumber(totalAmountIncurred) : '0'}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -452,12 +476,12 @@ export default function Detail() {
|
|||||||
<Grid item xs={2}>
|
<Grid item xs={2}>
|
||||||
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption">
|
<Typography variant="subtitle1">
|
||||||
Amount Approved
|
Amount Approved
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
|
||||||
{totalAmountApproved ? fNumber(totalAmountApproved) : '0'}
|
{totalAmountApproved ? fNumber(totalAmountApproved) : '0'}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -468,12 +492,12 @@ export default function Detail() {
|
|||||||
<Grid item xs={3}>
|
<Grid item xs={3}>
|
||||||
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption">
|
<Typography variant="subtitle1">
|
||||||
Amount Not Approved
|
Amount Not Approved
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
|
||||||
{totalAmountNotApproved ? fNumber(totalAmountNotApproved) : 0}
|
{totalAmountNotApproved ? fNumber(totalAmountNotApproved) : 0}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -484,12 +508,12 @@ export default function Detail() {
|
|||||||
<Grid item xs={2}>
|
<Grid item xs={2}>
|
||||||
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption">
|
<Typography variant="subtitle1">
|
||||||
Excess Paid
|
Excess Paid
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold' }}>
|
<Typography variant="subtitle2" sx={{ fontWeight: 'bold' }}>
|
||||||
{totalExcessPaid ? fNumber(totalExcessPaid) : 0}
|
{totalExcessPaid ? fNumber(totalExcessPaid) : 0}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -497,6 +521,23 @@ export default function Detail() {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Grid container spacing={1} marginY={2}>
|
||||||
|
<Grid item xs={6}>
|
||||||
|
<Typography variant="subtitle1">
|
||||||
|
Biaya disetujui
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={6} textAlign="right">
|
||||||
|
<Typography variant="subtitle1" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{totalAmountApproved ? fNumber(totalAmountApproved) : '0'}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<Typography variant="subtitle2">
|
||||||
|
Nominal diatas 1 juta akan menunggu persetujuan senior analyst
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -504,9 +545,25 @@ export default function Detail() {
|
|||||||
: (
|
: (
|
||||||
null
|
null
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
{ claimRequests?.status === 'declined' ? (
|
||||||
|
<Card sx={{padding:2, marginTop:2}} >
|
||||||
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Reason</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Box sx={{ border: '1px solid rgba(0,0,0,0.125)', px: '24px', py: '20px', marginBottom: '24px', borderRadius: '12px'}}>
|
||||||
|
<Stack direction='row' spacing={2} sx={marginBottom1}>
|
||||||
|
<Typography variant='subtitle2' sx={style1} gutterBottom>Reason Decline</Typography>
|
||||||
|
<Typography variant='subtitle2' sx={style2} gutterBottom>{claimRequests?.reason_decline}</Typography>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
</Card>
|
||||||
|
) : null }
|
||||||
|
|
||||||
{/* PR Buat pindahin ke componen */}
|
{/* PR Buat pindahin ke componen */}
|
||||||
{/* <CardBenefit
|
{/* <CardBenefit
|
||||||
requestLog={requestLog}
|
requestLog={requestLog}
|
||||||
@@ -542,6 +599,42 @@ export default function Detail() {
|
|||||||
requestLog={requestLog}
|
requestLog={requestLog}
|
||||||
openDialog={openDialogEditDetail}
|
openDialog={openDialogEditDetail}
|
||||||
/> */}
|
/> */}
|
||||||
|
|
||||||
|
{(claimRequests?.status === 'requested') || (claimRequests?.status === 'declined') ? (
|
||||||
|
<Grid item xs={12} md={12}>
|
||||||
|
<Stack direction="row" padding={4} sx={{ justifyContent: 'flex-end' }}>
|
||||||
|
<div style={{ marginRight: '10px' }}> {/* Perubahan sintaksis disini */}
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color='inherit'
|
||||||
|
onClick={() => {
|
||||||
|
navigate('/claim-requests')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => {
|
||||||
|
setOpenDialogSubmit(true);
|
||||||
|
setApprove('approved');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<DialogConfirmation
|
||||||
|
setOpenDialog={setOpenDialogSubmit}
|
||||||
|
requestLog={claimRequests}
|
||||||
|
openDialog={openDialogSubmit}
|
||||||
|
approve={approve}
|
||||||
|
>
|
||||||
|
</DialogConfirmation>
|
||||||
|
</Stack>
|
||||||
|
</Grid>
|
||||||
|
) : null}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,11 @@ export default function List() {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
handleSearchSubmit(event);
|
||||||
|
}
|
||||||
|
}}
|
||||||
value={searchText}
|
value={searchText}
|
||||||
placeholder='Search Code or Name...'
|
placeholder='Search Code or Name...'
|
||||||
/>
|
/>
|
||||||
@@ -152,7 +157,7 @@ export default function List() {
|
|||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
<DesktopDatePicker
|
<DesktopDatePicker
|
||||||
label="End Date"
|
label="End Date"
|
||||||
inputFormat="MM/dd/yyyy"
|
inputFormat="dd/MM/yyyy"
|
||||||
value={searchParams.get('end_date')}
|
value={searchParams.get('end_date')}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
try {
|
try {
|
||||||
@@ -274,7 +279,7 @@ export default function List() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleGetData = (type :string) => {
|
const handleGetData = (type :string) => {
|
||||||
axios.get(`corporates/${corporate_id}/data-plan-benefit`)
|
axios.get(`claim-requests/export`)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = response.data.data.file_url;
|
link.href = response.data.data.file_url;
|
||||||
@@ -361,14 +366,32 @@ export default function List() {
|
|||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
{importResult && (
|
{importResult && (
|
||||||
|
// <Stack direction={'row'} sx={{ px: 2, pb: 2 }}>
|
||||||
|
// <Box sx={{ color: 'text.secondary' }}>
|
||||||
|
// Last Import Result Report :{' '}
|
||||||
|
// <a href={importResult.result_file?.url ?? '#'}>
|
||||||
|
// {importResult.result_file?.name ?? '-'}
|
||||||
|
// </a>
|
||||||
|
// </Box>
|
||||||
|
// </Stack>
|
||||||
|
|
||||||
<Stack direction={'row'} sx={{ px: 2, pb: 2 }}>
|
<Stack direction={'row'} sx={{ px: 2, pb: 2 }}>
|
||||||
<Box sx={{ color: 'text.secondary' }}>
|
<Box sx={{ color: 'text.secondary' }}>
|
||||||
Last Import Result Report :{' '}
|
Last Import Result :{' '}
|
||||||
|
<Box sx={{ color: 'success.main', display: 'inline' }}>
|
||||||
|
{importResult.result_file?.total_success_row ?? 0}
|
||||||
|
</Box>{' '}
|
||||||
|
Row Processed,{' '}
|
||||||
|
<Box sx={{ color: 'error.main', display: 'inline' }}>
|
||||||
|
{importResult.result_file?.total_failed_row}
|
||||||
|
</Box>{' '}
|
||||||
|
Failed, Report :{' '}
|
||||||
<a href={importResult.result_file?.url ?? '#'}>
|
<a href={importResult.result_file?.url ?? '#'}>
|
||||||
{importResult.result_file?.name ?? '-'}
|
{importResult.result_file?.name ?? '-'}
|
||||||
</a>
|
</a>
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -393,7 +416,7 @@ export default function List() {
|
|||||||
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);
|
|
||||||
setDataTableLoading(false);
|
setDataTableLoading(false);
|
||||||
|
|
||||||
|
|
||||||
@@ -468,8 +491,12 @@ export default function List() {
|
|||||||
<TableCell align="left">{row.service_name}</TableCell>
|
<TableCell align="left">{row.service_name}</TableCell>
|
||||||
<TableCell align="left">{row.payment_type_name}</TableCell>
|
<TableCell align="left">{row.payment_type_name}</TableCell>
|
||||||
<TableCell align="left">
|
<TableCell align="left">
|
||||||
{ row.status == "requested" ?
|
{ row.status == "requested" ?
|
||||||
(<Label variant='ghost' color='primary'>{capitalizeFirstLetter(row.status)}</Label>) :
|
(<Label variant='ghost' color='primary'>{capitalizeFirstLetter(row.status)}</Label>) :
|
||||||
|
row.status == "submission" ?
|
||||||
|
(<Label color='info'> {capitalizeFirstLetter(row.status)}</Label>) :
|
||||||
|
row.status == "declined" ?
|
||||||
|
(<Label color='error'> {capitalizeFirstLetter(row.status)}</Label>) :
|
||||||
(<Label color='success'> {capitalizeFirstLetter(row.status)}</Label>)
|
(<Label color='success'> {capitalizeFirstLetter(row.status)}</Label>)
|
||||||
}
|
}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ export type DetailClaimRequest = {
|
|||||||
benefit_data : BenefitData[],
|
benefit_data : BenefitData[],
|
||||||
diagnosis : Diagnosis[],
|
diagnosis : Diagnosis[],
|
||||||
request_log : RequestLogType | undefined,
|
request_log : RequestLogType | undefined,
|
||||||
|
reason_decline : string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RequestLogType = {
|
export type RequestLogType = {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ import List from "./List";
|
|||||||
|
|
||||||
export default function Claims() {
|
export default function Claims() {
|
||||||
|
|
||||||
const pageTitle = 'Claim';
|
const pageTitle = 'Claim Management';
|
||||||
return (
|
return (
|
||||||
<Page title={ pageTitle } sx={{ mx: 2}}>
|
<Page title={ pageTitle } sx={{ mx: 2}}>
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ export default function Claims() {
|
|||||||
links={[
|
links={[
|
||||||
{ name: 'Dashboard', href: '/dashboard' },
|
{ name: 'Dashboard', href: '/dashboard' },
|
||||||
{
|
{
|
||||||
name: 'Claim',
|
name: 'Claim Management',
|
||||||
href: '/claims',
|
href: '/claims',
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// @mui
|
// @mui
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
|
Grid,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
Collapse,
|
Collapse,
|
||||||
@@ -17,12 +18,24 @@ import {
|
|||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TableHead,
|
TableHead,
|
||||||
|
Checkbox,
|
||||||
|
InputAdornment,
|
||||||
|
TableSortLabel,
|
||||||
|
FormControl
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
import { visuallyHidden } from '@mui/utils';
|
||||||
|
|
||||||
|
import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||||
|
import { fDateOnly } from '@/utils/formatTime';
|
||||||
|
|
||||||
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||||
import FindInPageOutlinedIcon from '@mui/icons-material/FindInPageOutlined';
|
import FindInPageOutlinedIcon from '@mui/icons-material/FindInPageOutlined';
|
||||||
import AssessmentIcon from '@mui/icons-material/Assessment';
|
import AssessmentIcon from '@mui/icons-material/Assessment';
|
||||||
// hooks
|
// hooks
|
||||||
import React, { ChangeEvent, useEffect, useRef, useState } from 'react';
|
import React, { ChangeEvent, useEffect, useRef, useState } from 'react';
|
||||||
import { Link, Navigate, useNavigate, useSearchParams } from 'react-router-dom';
|
import { Link, Navigate, useNavigate, useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
// components
|
// components
|
||||||
import axios from '../../utils/axios';
|
import axios from '../../utils/axios';
|
||||||
import { LaravelPaginatedData, LaravelPaginatedDataDefault } from '../../@types/paginated-data';
|
import { LaravelPaginatedData, LaravelPaginatedDataDefault } from '../../@types/paginated-data';
|
||||||
@@ -32,23 +45,146 @@ import EditRoundedIcon from '@mui/icons-material/EditRounded';
|
|||||||
import { Chip } from '@mui/material';
|
import { Chip } from '@mui/material';
|
||||||
import Iconify from '@/components/Iconify';
|
import Iconify from '@/components/Iconify';
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
import { fDate } from '../../utils/formatTime';
|
import { fDate, fDateTime } from '../../utils/formatTime';
|
||||||
import { Claims } from '@/@types/claims';
|
import { Claims } from '@/@types/claims';
|
||||||
import Label from '@/components/Label';
|
import Label from '@/components/Label';
|
||||||
import { capitalizeFirstLetter } from '@/utils/formatString';
|
import { capitalizeFirstLetter } from '@/utils/formatString';
|
||||||
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
||||||
import Edit from '@mui/icons-material/Edit';
|
import Edit from '@mui/icons-material/Edit';
|
||||||
import { Download } from '@mui/icons-material';
|
import { Download } from '@mui/icons-material';
|
||||||
|
import { Add, Search } from '@mui/icons-material';
|
||||||
|
import Autocomplete from '@mui/material/Autocomplete';
|
||||||
|
|
||||||
|
import DownloadIcon from '@mui/icons-material/Download';
|
||||||
|
|
||||||
|
import UploadIcon from '@mui/icons-material/Upload';
|
||||||
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||||
|
|
||||||
|
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
|
||||||
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
|
||||||
|
|
||||||
export default function List() {
|
export default function List() {
|
||||||
|
const [selectAll, setSelectAll] = useState(false);
|
||||||
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
|
const [providers, setProviders] = useState(null);
|
||||||
|
// const [searchText, setSearchText] = useState('');
|
||||||
|
const [order, setOrder] = useState<Order>('desc');
|
||||||
|
const [orderBy, setOrderBy] = useState('created_at');
|
||||||
|
const [perPage, setPerPage] = useState<number>(0);
|
||||||
|
|
||||||
|
const handleChange = (event, newValue) => {
|
||||||
|
// Jika newValue tidak undefined, atur nilai dataProvider
|
||||||
|
if (newValue !== undefined) {
|
||||||
|
setDataProvider(newValue.service_code);
|
||||||
|
} else {
|
||||||
|
// Jika tidak ada yang dipilih, set dataProvider menjadi string kosong
|
||||||
|
setDataProvider(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Dummy data
|
||||||
|
const dummyServices = [
|
||||||
|
{ service_code: '1', name: 'Service 1' },
|
||||||
|
{ service_code: '2', name: 'Service 2' },
|
||||||
|
{ service_code: '3', name: 'Service 3' },
|
||||||
|
// tambahkan data lain sesuai kebutuhan
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleSelectAll = () => {
|
||||||
|
setSelectAll(!selectAll);
|
||||||
|
if (!selectAll) {
|
||||||
|
const requestedIds = dataTableData.data
|
||||||
|
.filter(row => row.status === 'received') // Memfilter baris dengan status 'requested'
|
||||||
|
.map(row => row.id); // Mengambil hanya ID dari baris-baris yang memenuhi kondisi
|
||||||
|
setSelectedRows(requestedIds);
|
||||||
|
} else {
|
||||||
|
setSelectedRows([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRowSelect = (id) => {
|
||||||
|
if (selectedRows.includes(id)) {
|
||||||
|
setSelectedRows(selectedRows.filter(rowId => rowId !== id));
|
||||||
|
} else {
|
||||||
|
setSelectedRows([...selectedRows, id]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const [importResult, setImportResult] = useState(null);
|
const [startDate, setStartDate] = useState(null);
|
||||||
|
const [searchText, setSearchText] = useState('');
|
||||||
|
const [endDate, setEndDate] = useState(null);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [dataProvider, setDataProvider] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (startDate !== null || endDate !== null || dataProvider !== null
|
||||||
|
|| order !== null || orderBy !== null || perPage !== 0) {
|
||||||
|
loadDataTableData();
|
||||||
|
getProvider();
|
||||||
|
}
|
||||||
|
}, [startDate, endDate, dataProvider, order, orderBy, perPage]);
|
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [isLoadingImport, setIsLoadingImport] = useState(false);
|
||||||
|
const handleExportReport = async () => {
|
||||||
|
|
||||||
|
|
||||||
|
const year = startDate?.getFullYear();
|
||||||
|
const month = (startDate?.getMonth() + 1).toString().padStart(2, '0'); // Tambahkan 1 karena bulan dimulai dari 0, dan padStart untuk memastikan 2 digit
|
||||||
|
const day = startDate?.getDate().toString().padStart(2, '0'); // padStart untuk memastikan 2 digit
|
||||||
|
|
||||||
|
const formattedDate = year && month && day ? `${year}-${month}-${day}` : '';
|
||||||
|
|
||||||
|
const year1 = endDate?.getFullYear();
|
||||||
|
const month1 = (endDate?.getMonth() + 1).toString().padStart(2, '0'); // Tambahkan 1 karena bulan dimulai dari 0, dan padStart untuk memastikan 2 digit
|
||||||
|
const day1 = endDate?.getDate().toString().padStart(2, '0'); // padStart untuk memastikan 2 digit
|
||||||
|
|
||||||
|
const formattedDate1 = year1 && month1 && day1 ? `${year1}-${month1}-${day1}` : '';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var filter = Object.fromEntries([...searchParams.entries()]);
|
||||||
|
setIsLoading(true)
|
||||||
|
await axios
|
||||||
|
.get('/claims/export-claim-management',{
|
||||||
|
params: {
|
||||||
|
search: searchText,
|
||||||
|
start_date: formattedDate ? formattedDate : null,
|
||||||
|
end_date:formattedDate1,
|
||||||
|
provider: dataProvider,
|
||||||
|
order: order,
|
||||||
|
orderBy: orderBy,
|
||||||
|
page: perPage,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
enqueueSnackbar('Data berhasil di Export', {
|
||||||
|
variant: 'success',
|
||||||
|
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||||
|
});
|
||||||
|
setIsLoading(false)
|
||||||
|
|
||||||
|
document.location.href = res.data.data.file_url;
|
||||||
|
})
|
||||||
|
.catch((err) =>
|
||||||
|
enqueueSnackbar('Data Gagal di Export', {
|
||||||
|
variant: 'error',
|
||||||
|
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||||
|
})
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
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 handleSearchChange = (event: any) => {
|
const handleSearchChange = (event: any) => {
|
||||||
const newSearchText = event.target.value ?? '';
|
const newSearchText = event.target.value ?? '';
|
||||||
@@ -73,7 +209,7 @@ export default function List() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Trigger First Search
|
// Trigger First Search
|
||||||
setSearchText(searchParams.get('search') ?? '');
|
// setSearchText(searchParams.get('search') ?? '');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -126,41 +262,331 @@ export default function List() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const searchInput = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
|
||||||
|
//handle search
|
||||||
|
const handleSearchChange = (event: any) => {
|
||||||
|
const newSearchText = event.target.value ?? '';
|
||||||
|
setSearchText(newSearchText);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchSubmit = (event: any) => {
|
||||||
|
event.preventDefault();
|
||||||
|
loadDataTableData();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Trigger First Search
|
||||||
|
//setSearchText(searchText);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const item = [
|
||||||
|
{
|
||||||
|
id: '',
|
||||||
|
value: '',
|
||||||
|
name: 'Semua',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// const handleClick = () => {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Dummy Default Data
|
// Dummy Default Data
|
||||||
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
||||||
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>(
|
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>(
|
||||||
LaravelPaginatedDataDefault
|
LaravelPaginatedDataDefault
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||||
setDataTableLoading(true);
|
setDataTableLoading(true);
|
||||||
|
const year = startDate?.getFullYear();
|
||||||
|
const month = (startDate?.getMonth() + 1).toString().padStart(2, '0'); // Tambahkan 1 karena bulan dimulai dari 0, dan padStart untuk memastikan 2 digit
|
||||||
|
const day = startDate?.getDate().toString().padStart(2, '0'); // padStart untuk memastikan 2 digit
|
||||||
|
|
||||||
|
const formattedDate = year && month && day ? `${year}-${month}-${day}` : '';
|
||||||
|
|
||||||
|
const year1 = endDate?.getFullYear();
|
||||||
|
const month1 = (endDate?.getMonth() + 1).toString().padStart(2, '0'); // Tambahkan 1 karena bulan dimulai dari 0, dan padStart untuk memastikan 2 digit
|
||||||
|
const day1 = endDate?.getDate().toString().padStart(2, '0'); // padStart untuk memastikan 2 digit
|
||||||
|
|
||||||
|
const formattedDate1 = year1 && month1 && day1 ? `${year1}-${month1}-${day1}` : '';
|
||||||
|
|
||||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||||
const response = await axios.get('/claims', { params: filter });
|
const response = await axios.get('/claims', {
|
||||||
// console.log(response.data);
|
params: {
|
||||||
|
search: searchText,
|
||||||
|
start_date: formattedDate ? formattedDate : null,
|
||||||
|
end_date:formattedDate1,
|
||||||
|
provider: dataProvider,
|
||||||
|
order: order,
|
||||||
|
orderBy: orderBy,
|
||||||
|
page: perPage,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setDataTableLoading(false);
|
setDataTableLoading(false);
|
||||||
|
|
||||||
setDataTableData(response.data);
|
setDataTableData(response.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getProvider = async () => {
|
||||||
|
const response = await axios.get('/claims/get-provider');
|
||||||
|
setProviders(response.data)
|
||||||
|
}
|
||||||
|
|
||||||
const applyFilter = async (searchFilter: { search: string }) => {
|
const applyFilter = async (searchFilter: { search: string }) => {
|
||||||
await loadDataTableData(searchFilter);
|
await loadDataTableData(searchFilter);
|
||||||
setSearchParams(searchFilter);
|
setSearchParams(searchFilter);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePageChange = (event: ChangeEvent, value: number): void => {
|
const handlePageChange = (event: ChangeEvent, value: number): void => {
|
||||||
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
|
setPerPage(value);
|
||||||
loadDataTableData(filter);
|
|
||||||
setSearchParams(filter);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
||||||
loadDataTableData();
|
const handleCloseDialogSubmit = () => {
|
||||||
}, []);
|
setOpenDialogSubmit(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toTitleCase(str: string | null) {
|
||||||
|
return str.replace(/\w\S*/g, function(txt) {
|
||||||
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const [approve, setApprove] = useState('');
|
||||||
|
|
||||||
|
const [reasonDecline, setReasonDecline] = useState('');
|
||||||
|
|
||||||
|
const handleReasonDeclineChange = (event) => {
|
||||||
|
setReasonDecline(event.target.value);
|
||||||
|
// Tambahkan logika yang diperlukan di sini
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmitData = () => {
|
||||||
|
//approve or decline
|
||||||
|
if (!reasonDecline && approve == 'decline') {
|
||||||
|
enqueueSnackbar('Mohon isi alasan', { variant: 'warning' });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Promise.all(selectedRows.map(send_bulk))
|
||||||
|
.then(() => {
|
||||||
|
enqueueSnackbar('All requests processed successfully', { variant: 'success' });
|
||||||
|
setOpenDialogSubmit(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, 5000); // Reload the page after 5 seconds
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
enqueueSnackbar(error.response?.data?.message ?? 'Something went wrong!', { variant: 'error' });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function send_bulk(id) {
|
||||||
|
return axios.post(`claims/${id}/${approve}`, { reasonDecline: reasonDecline });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
|
const createMenu = Boolean(anchorEl);
|
||||||
|
const importHospital = useRef<HTMLInputElement>(null);
|
||||||
|
const [currentImportFileName, setCurrentImportFileName] = useState(null);
|
||||||
|
const [importLoading, setImportLoading] = useState(false);
|
||||||
|
const [importResult, setImportResult] = useState(null);
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
const handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
const handleImportButton = () => {
|
||||||
|
if (importHospital?.current) {
|
||||||
|
handleClose();
|
||||||
|
importHospital.current ? importHospital.current.click() : console.log('No File selected');
|
||||||
|
} else {
|
||||||
|
alert('No file selected');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCancelImportButton = () => {
|
||||||
|
if(importHospital.current)
|
||||||
|
{
|
||||||
|
importHospital.current.value = '';
|
||||||
|
importHospital.current.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleImportChange = (event: any) => {
|
||||||
|
if (event.target.files[0]) {
|
||||||
|
setCurrentImportFileName(event.target.files[0].name);
|
||||||
|
} else {
|
||||||
|
setCurrentImportFileName(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleUpload = () => {
|
||||||
|
if(importHospital.current && importHospital.current.files)
|
||||||
|
{
|
||||||
|
if (importHospital.current?.files.length) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', importHospital.current?.files[0]);
|
||||||
|
setImportLoading(true);
|
||||||
|
axios
|
||||||
|
.post('claims/import', formData)
|
||||||
|
.then((response) => {
|
||||||
|
handleCancelImportButton();
|
||||||
|
loadDataTableData();
|
||||||
|
setImportResult(response.data);
|
||||||
|
setImportLoading(false);
|
||||||
|
enqueueSnackbar('Success Import Hospitals', { variant: 'success' });
|
||||||
|
})
|
||||||
|
.catch((response) => {
|
||||||
|
enqueueSnackbar(
|
||||||
|
'Looks like something went wrong. Please check your data and try again. ' +
|
||||||
|
response.message,
|
||||||
|
{ variant: 'error' }
|
||||||
|
);
|
||||||
|
setImportLoading(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar('No File Selected', { variant: 'warning' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleGetTemplate = () => {
|
||||||
|
axios.get('claims/download-template').then((response) => {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = response.data.data.file_url;
|
||||||
|
link.setAttribute('download', response.data.data.file_name);
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
handleClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleExportReportFiled = async () => {
|
||||||
|
|
||||||
|
await axios
|
||||||
|
.post('claims/exportFiled', { params: importResult?.data.failed_rows })
|
||||||
|
.then((res) => {
|
||||||
|
enqueueSnackbar('Data berhasil di Export', {
|
||||||
|
variant: 'success',
|
||||||
|
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||||
|
});
|
||||||
|
setIsLoading(false)
|
||||||
|
|
||||||
|
document.location.href = res.data.data.file_url;
|
||||||
|
})
|
||||||
|
.catch((err) =>
|
||||||
|
enqueueSnackbar('Data Gagal di Export', {
|
||||||
|
variant: 'error',
|
||||||
|
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||||
|
})
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// loadDataTableData();
|
||||||
|
// getProvider();
|
||||||
|
// }, []);
|
||||||
|
|
||||||
const headStyle = {
|
const headStyle = {
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
};
|
};
|
||||||
|
const headCells = [
|
||||||
|
{
|
||||||
|
id: 'code',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Code',
|
||||||
|
isSort: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Name',
|
||||||
|
isSort: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: 'member_id',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Member ID',
|
||||||
|
isSort: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'created_at',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Date Submission',
|
||||||
|
isSort: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'plan_code',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Plan ID',
|
||||||
|
isSort: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'service_code',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Service',
|
||||||
|
isSort: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'corporate_policies',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Policy Number',
|
||||||
|
isSort: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'provider',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Provider',
|
||||||
|
isSort: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tot_bill',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Total Billing',
|
||||||
|
isSort: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'status',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Status',
|
||||||
|
isSort: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'action',
|
||||||
|
align: 'left',
|
||||||
|
label: '',
|
||||||
|
isSort: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const orders = {
|
||||||
|
order: order,
|
||||||
|
setOrder: setOrder,
|
||||||
|
orderBy: orderBy,
|
||||||
|
setOrderBy: setOrderBy,
|
||||||
|
};
|
||||||
|
const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => {
|
||||||
|
handleRequestSort(event, property);
|
||||||
|
};
|
||||||
|
const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => {
|
||||||
|
const isAsc = orders?.orderBy === property && orders?.order === 'asc';
|
||||||
|
|
||||||
|
orders?.setOrder(isAsc ? 'desc' : 'asc');
|
||||||
|
orders?.setOrderBy(property);
|
||||||
|
};
|
||||||
// Called on every row to map the data to the columns
|
// Called on every row to map the data to the columns
|
||||||
function createData(data: Claims): Claims {
|
function createData(data: Claims): Claims {
|
||||||
return {
|
return {
|
||||||
@@ -171,10 +597,18 @@ export default function List() {
|
|||||||
{
|
{
|
||||||
/* ------------------ TABLE ROW ------------------ */
|
/* ------------------ TABLE ROW ------------------ */
|
||||||
}
|
}
|
||||||
function Row(props: { row: ReturnType<typeof createData> }) {
|
function Row(props: { row: ReturnType<typeof createData>, isSelected: boolean, onSelect: (id: string) => void }) {
|
||||||
const { row } = props;
|
const { row, isSelected, onSelect } = props;
|
||||||
|
// Memperbaiki destrukturisasi props
|
||||||
|
|
||||||
|
const handleRowCheckboxChange = () => {
|
||||||
|
onSelect(row.id); // Panggil fungsi onSelect dari komponen induk dengan id baris saat checkbox di baris diklik
|
||||||
|
};
|
||||||
|
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
|
const test = 1000;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
|
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
|
||||||
@@ -183,16 +617,22 @@ export default function List() {
|
|||||||
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</TableCell> */}
|
</TableCell> */}
|
||||||
<TableCell align="left">{row.claim_request?.code}</TableCell>
|
<TableCell align="left">
|
||||||
|
{row?.status == 'received' ? (
|
||||||
|
<Checkbox checked={isSelected} onChange={handleRowCheckboxChange} />
|
||||||
|
):''}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{row?.code}</TableCell>
|
||||||
{/* <TableCell align="left">{row.code}</TableCell> */}
|
{/* <TableCell align="left">{row.code}</TableCell> */}
|
||||||
<TableCell align="left">{row.member?.current_plan?.code}</TableCell>
|
<TableCell align="left">{row?.name}</TableCell>
|
||||||
<TableCell align="left">{row.member?.current_corporate?.payor_id}</TableCell>
|
<TableCell align="left">{row?.member_id}</TableCell>
|
||||||
<TableCell align="left">{row.member?.current_corporate?.code}</TableCell>
|
<TableCell align="left">{row?.created_at ? fDateTime(row?.created_at) : ''}</TableCell>
|
||||||
<TableCell align="left">{row.member?.current_corporate?.current_policy?.code}</TableCell>
|
<TableCell align="left">{row?.plan_code}</TableCell>
|
||||||
<TableCell align="left">{row.member?.member_id}</TableCell>
|
<TableCell align="left">{row?.service_code}</TableCell>
|
||||||
<TableCell align="left">{row.benefit_desc}</TableCell>
|
<TableCell align="left">{row?.corporate_policies}</TableCell>
|
||||||
|
<TableCell align="left">{row?.provider}</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="left">Rp. {row?.tot_bill?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")}</TableCell>
|
||||||
|
<TableCell align="left">
|
||||||
{row.status == 'draft' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
{row.status == 'draft' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
||||||
{row.status == 'requested' && (<Label color='primary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
{row.status == 'requested' && (<Label color='primary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
||||||
{row.status == 'received' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
{row.status == 'received' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
||||||
@@ -202,18 +642,17 @@ export default function List() {
|
|||||||
{row.status == 'declined' && (<Label color='error' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
{row.status == 'declined' && (<Label color='error' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableMoreMenu actions={
|
<TableCell align="left">
|
||||||
<>
|
<TableMoreMenu actions={
|
||||||
<MenuItem onClick={() =>navigate(`/claims/edit/${row.id}`) }>
|
<>
|
||||||
<Edit />
|
<MenuItem onClick={() => navigate('/claims/detail/'+row.id_log+'/'+row.id+'') }>
|
||||||
Edit
|
<FindInPageOutlinedIcon />
|
||||||
</MenuItem>
|
Detail
|
||||||
<MenuItem onClick={() => navigate('/claims/detail/'+row.id+'') }>
|
</MenuItem>
|
||||||
<FindInPageOutlinedIcon />
|
</>
|
||||||
Detail
|
} />
|
||||||
</MenuItem>
|
</TableCell>
|
||||||
</>
|
|
||||||
} />
|
|
||||||
|
|
||||||
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@@ -236,40 +675,77 @@ export default function List() {
|
|||||||
/* ------------------ END TABLE ROW ------------------ */
|
/* ------------------ END TABLE ROW ------------------ */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function TableContent() {
|
function TableContent() {
|
||||||
return (
|
return (
|
||||||
<Table aria-label="collapsible table">
|
<Table aria-label="collapsible table">
|
||||||
{/* ------------------ TABLE HEADER ------------------ */}
|
{/* ------------------ TABLE HEADER ------------------ */}
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{/* <TableCell style={headStyle} align="left" /> */}
|
{selectedRows.length > 0 ? (
|
||||||
<TableCell style={headStyle} align="left">
|
<>
|
||||||
Code
|
<TableCell style={{ backgroundColor: '#D1F1F1' }} align="left" colSpan={2}>
|
||||||
</TableCell>
|
<Stack direction="row">
|
||||||
<TableCell style={headStyle} align="left">
|
<Checkbox checked={selectAll} onChange={handleSelectAll} />
|
||||||
Plan ID
|
{selectedRows.length > 0 ? selectedRows.length : '0'} <Typography variant='subtitle2'>Selected</Typography>
|
||||||
</TableCell>
|
</Stack>
|
||||||
<TableCell style={headStyle} align="left">
|
</TableCell>
|
||||||
Payor ID
|
<TableCell style={{ backgroundColor: '#D1F1F1' }} align="left" colSpan={6}>
|
||||||
</TableCell>
|
|
||||||
<TableCell style={headStyle} align="left">
|
</TableCell>
|
||||||
Corporate ID
|
<TableCell style={{ backgroundColor: '#D1F1F1' }} align="right" colSpan={2}>
|
||||||
</TableCell>
|
<Button variant="text" color="error" startIcon={<CancelIcon />} onClick={() => {setOpenDialogSubmit(true);
|
||||||
<TableCell style={headStyle} align="left">
|
setApprove('decline');}}>
|
||||||
Policy Number
|
<Typography variant='subtitle2'>Decline</Typography>
|
||||||
</TableCell>
|
</Button>
|
||||||
<TableCell style={headStyle} align="left">
|
</TableCell>
|
||||||
Member ID
|
<TableCell style={{ backgroundColor: '#D1F1F1' }} align="left" colSpan={2}>
|
||||||
</TableCell>
|
<Button variant="text" color="primary" startIcon={<CheckCircleIcon />} onClick={() => {setOpenDialogSubmit(true);
|
||||||
<TableCell style={headStyle} align="left">
|
setApprove('approve');}}>
|
||||||
Benefit Desc
|
<Typography variant='subtitle2'>Approve</Typography>
|
||||||
</TableCell>
|
</Button>
|
||||||
<TableCell style={headStyle} align="left">
|
</TableCell>
|
||||||
Status
|
|
||||||
</TableCell>
|
</>
|
||||||
<TableCell style={headStyle} align="left">
|
) : (
|
||||||
|
<>
|
||||||
</TableCell>
|
<TableCell style={headStyle} align="left">
|
||||||
|
<Checkbox checked={selectAll} onChange={handleSelectAll} />
|
||||||
|
</TableCell>
|
||||||
|
{headCells &&
|
||||||
|
headCells.map((headCell, index) => (
|
||||||
|
<TableCell
|
||||||
|
key={index}
|
||||||
|
sortDirection={orders?.orderBy === headCell.id ? orders.order : false}
|
||||||
|
// @ts-ignore
|
||||||
|
align={headCell.align}
|
||||||
|
sx={{ padding: 2 }}
|
||||||
|
width={headCell.width ? headCell.width : 'auto'}
|
||||||
|
>
|
||||||
|
{headCell.isSort ? (
|
||||||
|
<TableSortLabel
|
||||||
|
active={orders?.orderBy === headCell.id}
|
||||||
|
direction={orders?.orderBy === headCell.id ? orders.order : 'asc'}
|
||||||
|
onClick={createSortHandler(headCell.id)}
|
||||||
|
>
|
||||||
|
{headCell.label}
|
||||||
|
{orders?.orderBy === headCell.id ? (
|
||||||
|
<Box component="span" sx={visuallyHidden}>
|
||||||
|
{orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'}
|
||||||
|
</Box>
|
||||||
|
) : null}
|
||||||
|
</TableSortLabel>
|
||||||
|
) : (
|
||||||
|
headCell.label
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{/* ------------------ END TABLE HEADER ------------------ */}
|
{/* ------------------ END TABLE HEADER ------------------ */}
|
||||||
@@ -278,7 +754,7 @@ export default function List() {
|
|||||||
{dataTableIsLoading ? (
|
{dataTableIsLoading ? (
|
||||||
<TableBody>
|
<TableBody>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={8} align="center">
|
<TableCell colSpan={11} align="center">
|
||||||
Loading
|
Loading
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@@ -286,7 +762,7 @@ export default function List() {
|
|||||||
) : dataTableData.data.length === 0 ? (
|
) : dataTableData.data.length === 0 ? (
|
||||||
<TableBody>
|
<TableBody>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={8} align="center">
|
<TableCell colSpan={11} align="center">
|
||||||
No Data
|
No Data
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@@ -294,7 +770,7 @@ export default function List() {
|
|||||||
) : (
|
) : (
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{dataTableData.data.map((row) => (
|
{dataTableData.data.map((row) => (
|
||||||
<Row key={row.id} row={row} />
|
<Row key={row.id} row={row} isSelected={selectedRows.includes(row.id)} onSelect={handleRowSelect} />
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
)}
|
)}
|
||||||
@@ -305,7 +781,212 @@ export default function List() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<ImportForm />
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
sx={{ p: 2, justifyContent: 'space-between', alignItems: 'center' }}
|
||||||
|
>
|
||||||
|
<Grid item xs={12} md={12} lg={12}>
|
||||||
|
<form style={{ width: '100%' }}>
|
||||||
|
<Grid container spacing={1} sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id="file"
|
||||||
|
ref={importHospital}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
onChange={handleImportChange}
|
||||||
|
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain"
|
||||||
|
/>
|
||||||
|
{!currentImportFileName && (
|
||||||
|
<>
|
||||||
|
<Grid item xs={12} md={3}>
|
||||||
|
<TextField
|
||||||
|
id="search-input"
|
||||||
|
ref={searchInput}
|
||||||
|
variant="outlined"
|
||||||
|
value={searchText}
|
||||||
|
fullWidth
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
handleSearchSubmit(event);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: (
|
||||||
|
<InputAdornment position="start">
|
||||||
|
<Search />
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
placeholder: 'Search Code or Name',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={4} display="flex" sx={{ gap: '16px' }}>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DesktopDatePicker
|
||||||
|
value={startDate}
|
||||||
|
inputFormat="dd/MM/yyyy"
|
||||||
|
onChange={(value) => {
|
||||||
|
|
||||||
|
// loadDataTableData();
|
||||||
|
setStartDate(value);
|
||||||
|
}}
|
||||||
|
renderInput={(params) => <TextField {...params} fullWidth label="Start" />}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DesktopDatePicker
|
||||||
|
value={endDate}
|
||||||
|
inputFormat="dd/MM/yyyy"
|
||||||
|
onChange={(value) => {
|
||||||
|
setEndDate(value);
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
fullWidth
|
||||||
|
label="End"
|
||||||
|
// error={!!error}
|
||||||
|
// helperText={error?.message}
|
||||||
|
// {...other}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={2}>
|
||||||
|
{
|
||||||
|
providers && (
|
||||||
|
<Autocomplete
|
||||||
|
id="provider"
|
||||||
|
options={providers}
|
||||||
|
getOptionLabel={(option) => option.name || ''}
|
||||||
|
value={providers.find((item) => item.id === dataProvider) || null}
|
||||||
|
onChange={(event, value) => {
|
||||||
|
if (value) {
|
||||||
|
setDataProvider(value.id);
|
||||||
|
} else {
|
||||||
|
setDataProvider(null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
label="Provider"
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={3} display="flex" sx={{ gap: '16px' }}>
|
||||||
|
<FormControl >
|
||||||
|
<LoadingButton
|
||||||
|
id="upload-button"
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<UploadIcon />}
|
||||||
|
sx={{ p: 1.8 }}
|
||||||
|
loading={isLoadingImport}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<Typography variant="inherit" sx={{ marginLeft: 1 }}>
|
||||||
|
Import
|
||||||
|
</Typography>
|
||||||
|
</LoadingButton>
|
||||||
|
<Menu
|
||||||
|
id="import-button"
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
open={createMenu}
|
||||||
|
onClose={handleClose}
|
||||||
|
MenuListProps={{
|
||||||
|
'aria-labelledby': 'basic-button',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MenuItem onClick={handleImportButton}>
|
||||||
|
<Typography variant='body2'>Import</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleGetTemplate();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant='body2'> Download Template</Typography>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl >
|
||||||
|
<LoadingButton
|
||||||
|
id="upload-button"
|
||||||
|
variant="contained"
|
||||||
|
startIcon={<Download />}
|
||||||
|
sx={{ p: 1.8 }}
|
||||||
|
onClick={handleExportReport}
|
||||||
|
loading={isLoading}
|
||||||
|
>
|
||||||
|
<Typography variant="inherit" sx={{ marginLeft: 1 }}>
|
||||||
|
Export
|
||||||
|
</Typography>
|
||||||
|
</LoadingButton>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{currentImportFileName && (
|
||||||
|
<Grid item xs={12} md={12}>
|
||||||
|
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
|
||||||
|
<ButtonGroup variant="outlined" aria-label="outlined button group" fullWidth>
|
||||||
|
<Button onClick={handleImportButton} fullWidth>
|
||||||
|
{currentImportFileName ?? 'No File Selected'}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleCancelImportButton}
|
||||||
|
size="small"
|
||||||
|
fullWidth={false}
|
||||||
|
sx={{ p: 1.8 }}
|
||||||
|
>
|
||||||
|
<CancelIcon color="error" />
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
|
||||||
|
<LoadingButton
|
||||||
|
id="upload-button"
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<UploadIcon />}
|
||||||
|
sx={{ p: 1.8 }}
|
||||||
|
onClick={handleUpload}
|
||||||
|
loading={importLoading}
|
||||||
|
>
|
||||||
|
Upload
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
{importResult && (
|
||||||
|
<Stack direction={'row'} sx={{ px: 2, pb: 2 }}>
|
||||||
|
<Box sx={{ color: 'text.secondary' }}>
|
||||||
|
Last Import Result :{' '}
|
||||||
|
<Box sx={{ color: 'success.main', display: 'inline' }}>
|
||||||
|
{importResult.data.total_success_row ?? 0}
|
||||||
|
</Box>{' '}
|
||||||
|
Row Processed,{' '}
|
||||||
|
<Box sx={{ color: 'error.main', display: 'inline' }}>
|
||||||
|
{importResult.data.total_failed_row}
|
||||||
|
</Box>{' '}
|
||||||
|
Failed
|
||||||
|
{/* {importResult.data.failed_rows.map((row, index) => (
|
||||||
|
<Typography variant='body' key={index} color="error"> [Code={row.code ? row.code : 'Required'}]</Typography>
|
||||||
|
))} */}
|
||||||
|
<u onClick={handleExportReportFiled} style={{cursor:'pointer'}}>Download Data Filed</u>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</form>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
isLoading={dataTableIsLoading}
|
isLoading={dataTableIsLoading}
|
||||||
@@ -314,6 +995,43 @@ export default function List() {
|
|||||||
handlePageChange={handlePageChange}
|
handlePageChange={handlePageChange}
|
||||||
TableContent={<TableContent />}
|
TableContent={<TableContent />}
|
||||||
/>
|
/>
|
||||||
|
<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>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
|
||||||
|
<Stack spacing={2} padding={2}>
|
||||||
|
<Typography variant='body1'>Are you sure to {toTitleCase(approve)} this claim ?</Typography>
|
||||||
|
{approve == "decline" ? (
|
||||||
|
<Stack direction='row' spacing={2} marginTop={2}>
|
||||||
|
<TextField
|
||||||
|
id="outlined-multiline-static"
|
||||||
|
label="Reason decline"
|
||||||
|
multiline
|
||||||
|
rows={4} // Tentukan jumlah baris yang diinginkan
|
||||||
|
defaultValue=""
|
||||||
|
onChange={handleReasonDeclineChange}
|
||||||
|
variant="outlined"
|
||||||
|
sx={{width:'100%'}}
|
||||||
|
// fullWidth // Gunakan ini jika Anda ingin input memenuhi lebar Stack
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
): ''}
|
||||||
|
</Stack>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialogSubmit}>Cancel</Button>
|
||||||
|
<Button sx={{backgroundColor: (approve === 'decline' ? '' : '#19BBBB'), color: (approve === 'decline' ? '#FF4842' : ''), borderColor: '#FF4842'}} onClick={handleSubmitData} variant={(approve === 'decline' ? 'outlined' : 'contained')}>{(approve === "decline" ? 'Decline' : 'Approve')}</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,51 +145,62 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
|
|
||||||
const methods = useForm<any>({
|
const methods = useForm<any>({
|
||||||
resolver: yupResolver(validationSchema),
|
resolver: yupResolver(validationSchema),
|
||||||
defaultValues
|
defaultValues,
|
||||||
|
reValidateMode: "onChange"
|
||||||
});
|
});
|
||||||
|
|
||||||
let width = claimInput ? 2 : 2.36;
|
let width = claimInput ? 2 : 2.36;
|
||||||
|
|
||||||
const {fields, append, remove} = useFieldArray({name: 'benefit_data',control: methods.control});
|
const {fields, append, remove} = useFieldArray({name: 'benefit_data',control: methods.control,});
|
||||||
const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods
|
const { handleSubmit, reset, watch, setValue, setError, clearErrors, formState: { isDirty, isSubmitting, errors,isValid } } = methods
|
||||||
|
|
||||||
// Buat total data
|
const errorsExist = errors ? Object.keys(errors).length > 0 : false;
|
||||||
let totalAmountIncurred = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
// Calculate
|
||||||
return accumulator + (item.amount_incurred || 0);
|
|
||||||
}, 0);
|
|
||||||
let totalAmountApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
|
||||||
return accumulator + (item.amount_approved || 0);
|
|
||||||
}, 0);
|
|
||||||
let totalAmountNotApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
|
||||||
return accumulator + (item.amount_not_approved || 0);
|
|
||||||
}, 0);
|
|
||||||
let totalExcessPaid = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
|
||||||
return accumulator + (item.excess_paid || 0);
|
|
||||||
}, 0);
|
|
||||||
const benefitData = watch('benefit_data');
|
const benefitData = watch('benefit_data');
|
||||||
const [isDisableSave, setDisableSave] = useState(false)
|
const totalAll = () => {
|
||||||
|
let totalAmountIncurred = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
benefitData?.map((item, index) => {
|
return accumulator + (item.amount_incurred || 0);
|
||||||
totalAmountIncurred += parseFloat(item.amount_incurred);
|
}, 0);
|
||||||
totalAmountApproved += parseFloat(item.amount_approved);
|
let totalAmountApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
totalAmountNotApproved += parseFloat(item.amount_not_approved);
|
return accumulator + (item.amount_approved || 0);
|
||||||
totalExcessPaid += parseFloat(item.excess_paid);
|
}, 0);
|
||||||
|
let totalAmountNotApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
|
return accumulator + (item.amount_not_approved || 0);
|
||||||
|
}, 0);
|
||||||
|
let totalExcessPaid = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
|
||||||
|
return accumulator + (item.excess_paid || 0);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
if (totalAmountApproved != 0 && totalAmountIncurred != 0) {
|
benefitData?.map((item, index) => {
|
||||||
if (totalAmountApproved > totalAmountIncurred){
|
totalAmountIncurred += parseFloat(item.amount_incurred);
|
||||||
setValue(`benefit_data.${index}.amount_approved`, 0)
|
totalAmountApproved += parseFloat(item.amount_approved);
|
||||||
alert('Total Amount Approved tidak boleh lebih dari Total Incurred')
|
totalAmountNotApproved += parseFloat(item.amount_not_approved);
|
||||||
}
|
totalExcessPaid += parseFloat(item.excess_paid);
|
||||||
}
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
totalAmountIncurred,
|
||||||
|
totalAmountApproved,
|
||||||
|
totalAmountNotApproved,
|
||||||
|
totalExcessPaid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOnChangeNominal = (key) => {
|
||||||
|
if (totalAll().totalAmountApproved > totalAll().totalAmountIncurred){
|
||||||
|
// setValue(`benefit_data.${key}.amount_approved`, 0);
|
||||||
|
setError(`benefit_data.${key}.amount_approved`, {message: 'Amount Approve tidak boleh lebih dari Amount Incurred'});
|
||||||
|
} else {
|
||||||
|
clearErrors(`benefit_data.${key}.amount_approved`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Submit Form
|
// Submit Form
|
||||||
// =====================================
|
// =====================================
|
||||||
const submitHandler = async (data: BenefitConfigurationListType) => {
|
const submitHandler = async (data: BenefitConfigurationListType) => {
|
||||||
const mapData = data.benefit_data.map((item) => ({
|
const mapData = data.benefit_data.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
reason: item.reason.value
|
reason: item.reason ? item.reason.value : null
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const newData = {
|
const newData = {
|
||||||
@@ -206,8 +217,6 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate
|
|
||||||
|
|
||||||
const getContent = () => !addBenefit ? (
|
const getContent = () => !addBenefit ? (
|
||||||
<Stack spacing={2} sx={{marginTop: 2, padding: 2}} direction="column">
|
<Stack spacing={2} sx={{marginTop: 2, padding: 2}} direction="column">
|
||||||
<Stack direction="row" spacing={2}>
|
<Stack direction="row" spacing={2}>
|
||||||
@@ -281,6 +290,10 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
name={`benefit_data.${index}.amount_incurred`}
|
name={`benefit_data.${index}.amount_incurred`}
|
||||||
placeholder='Amount Incurred'
|
placeholder='Amount Incurred'
|
||||||
required
|
required
|
||||||
|
onChange={(event) => {
|
||||||
|
setValue(`benefit_data.${index}.amount_incurred`, event.target.value)
|
||||||
|
handleOnChangeNominal(index)}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -301,6 +314,10 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
name={`benefit_data.${index}.amount_approved`}
|
name={`benefit_data.${index}.amount_approved`}
|
||||||
placeholder='Amount Approved'
|
placeholder='Amount Approved'
|
||||||
required
|
required
|
||||||
|
onChange={(event) => {
|
||||||
|
setValue(`benefit_data.${index}.amount_approved`, event.target.value)
|
||||||
|
handleOnChangeNominal(index)}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -434,7 +451,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{fNumber(totalAmountIncurred)}
|
{fNumber(totalAll().totalAmountIncurred)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -450,7 +467,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{fNumber(totalAmountApproved)}
|
{fNumber(totalAll().totalAmountApproved)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -466,7 +483,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{fNumber(totalAmountNotApproved)}
|
{fNumber(totalAll().totalAmountNotApproved)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -482,7 +499,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{fNumber(totalExcessPaid)}
|
{fNumber(totalAll().totalExcessPaid)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -499,7 +516,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
|
|||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Stack direction="row" sx={{marginTop:3}} alignItems="center" justifyContent="space-between" spacing={2}>
|
<Stack direction="row" sx={{marginTop:3}} alignItems="center" justifyContent="space-between" spacing={2}>
|
||||||
<Button variant="outlined" onClick={handleCloseDialogBenefit}><Typography>Cancel</Typography></Button>
|
<Button variant="outlined" onClick={handleCloseDialogBenefit}><Typography>Cancel</Typography></Button>
|
||||||
<LoadingButton disabled={isDisableSave} type="submit" variant="contained" loading={isSubmitting}>
|
<LoadingButton disabled={errorsExist} type="submit" variant="contained" loading={isSubmitting}>
|
||||||
Save
|
Save
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -62,23 +62,36 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
defaultValues
|
defaultValues
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods;
|
const { handleSubmit, reset, watch, setValue, setError, clearErrors, formState: { isDirty, isSubmitting, errors } } = methods;
|
||||||
|
const errorsExist = errors ? Object.keys(errors).length > 0 : false;
|
||||||
|
const totalAll = () => {
|
||||||
|
// Ambil nilai dari form menggunakan watch
|
||||||
|
const amountIncurred = parseFloat(watch('amount_incurred'));
|
||||||
|
const amountApproved = parseFloat(watch('amount_approved'));
|
||||||
|
const amountNotApproved = parseFloat(watch('amount_not_approved'));
|
||||||
|
const excessPaid = parseFloat(watch('excess_paid'));
|
||||||
|
|
||||||
|
// Hitung total baru
|
||||||
|
const totalAmountIncurred = total.totalAmountIncurred - data?.amount_incurred + amountIncurred;
|
||||||
|
const totalAmountApproved = total.totalAmountApproved - data?.amount_approved + amountApproved;
|
||||||
|
const totalAmountNotApproved = total.totalAmountNotApproved - data?.amount_not_approved + amountNotApproved;
|
||||||
|
const totalExcessPaid = total.totalExcessPaid - data?.excess_paid + excessPaid;
|
||||||
|
|
||||||
// Ambil nilai dari form menggunakan watch
|
return {
|
||||||
const amountIncurred = parseFloat(watch('amount_incurred'));
|
totalAmountIncurred,
|
||||||
const amountApproved = parseFloat(watch('amount_approved'));
|
totalAmountApproved,
|
||||||
const amountNotApproved = parseFloat(watch('amount_not_approved'));
|
totalAmountNotApproved,
|
||||||
const excessPaid = parseFloat(watch('excess_paid'));
|
totalExcessPaid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Hitung total baru
|
const handleOnChangeNominal = (key) => {
|
||||||
const totalAmountIncurred = total.totalAmountIncurred - data?.amount_incurred + amountIncurred;
|
if (totalAll().totalAmountApproved > totalAll().totalAmountIncurred){
|
||||||
const totalAmountApproved = total.totalAmountApproved - data?.amount_approved + amountApproved;
|
// setValue(`benefit_data.${key}.amount_approved`, 0);
|
||||||
const totalAmountNotApproved = total.totalAmountNotApproved - data?.amount_not_approved + amountNotApproved;
|
setError(`amount_approved`, {message: 'Amount Approve tidak boleh lebih dari Amount Incurred'});
|
||||||
const totalExcessPaid = total.totalExcessPaid - data?.excess_paid + excessPaid;
|
} else {
|
||||||
|
clearErrors(`amount_approved`);
|
||||||
if (totalAmountApproved > totalAmountIncurred) {
|
}
|
||||||
alert('Total Approve tidak boleh melebihi Total Incurred')
|
|
||||||
setValue('amount_approved', data?.amount_approved)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (totalAmountIncurred !== (totalAmountApproved+totalAmountNotApproved)){
|
// if (totalAmountIncurred !== (totalAmountApproved+totalAmountNotApproved)){
|
||||||
@@ -142,6 +155,10 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
name={`amount_incurred`}
|
name={`amount_incurred`}
|
||||||
placeholder='Amount Incurred'
|
placeholder='Amount Incurred'
|
||||||
required
|
required
|
||||||
|
onChange={(event) => {
|
||||||
|
setValue(`amount_incurred`, event.target.value)
|
||||||
|
handleOnChangeNominal(id)}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -162,6 +179,10 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
name={`amount_approved`}
|
name={`amount_approved`}
|
||||||
placeholder='Amount Approved'
|
placeholder='Amount Approved'
|
||||||
required
|
required
|
||||||
|
onChange={(event) => {
|
||||||
|
setValue(`amount_approved`, event.target.value)
|
||||||
|
handleOnChangeNominal(id)}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -275,7 +296,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{totalAmountIncurred ? fNumber(totalAmountIncurred) : 0}
|
{totalAll().totalAmountIncurred ? fNumber(totalAll().totalAmountIncurred) : 0}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -291,7 +312,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{fNumber(totalAmountApproved)}
|
{totalAll().totalAmountApproved ? fNumber(totalAll().totalAmountApproved) : 0}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -307,7 +328,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{fNumber(totalAmountNotApproved)}
|
{totalAll().totalAmountNotApproved ? fNumber(totalAll().totalAmountNotApproved) : 0}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -323,7 +344,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||||
{fNumber(totalExcessPaid)}
|
{totalAll().totalExcessPaid ? fNumber(totalAll().totalExcessPaid) : 0}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -337,7 +358,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
|
|||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Stack direction="row" sx={{marginTop:3}} alignItems="center" justifyContent="space-between" spacing={2}>
|
<Stack direction="row" sx={{marginTop:3}} alignItems="center" justifyContent="space-between" spacing={2}>
|
||||||
<Button variant="outlined" onClick={handleCloseDialog}><Typography>Cancel</Typography></Button>
|
<Button variant="outlined" onClick={handleCloseDialog}><Typography>Cancel</Typography></Button>
|
||||||
<LoadingButton type="submit" variant="contained" loading={isSubmitting}>
|
<LoadingButton disabled={errorsExist} type="submit" variant="contained" loading={isSubmitting}>
|
||||||
Save
|
Save
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export default function Detail() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
const [requestLog, setRequestLog] = useState<DetailFinalLogType>();
|
const [requestLog, setRequestLog] = useState<DetailFinalLogType>();
|
||||||
|
const [isReversal, setIsReversal] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -77,6 +78,7 @@ export default function Detail() {
|
|||||||
.get('customer-service/request/'+id)
|
.get('customer-service/request/'+id)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setRequestLog(response.data.data)
|
setRequestLog(response.data.data)
|
||||||
|
setIsReversal(response.data.data.is_reversal)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -304,11 +306,15 @@ export default function Detail() {
|
|||||||
<Card sx={{padding:2}} >
|
<Card sx={{padding:2}} >
|
||||||
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
|
||||||
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Benefit</Typography>
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Benefit</Typography>
|
||||||
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
{
|
||||||
setDialogBenefit(true);
|
!isReversal ? (
|
||||||
}} >
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
<Typography variant="button" display="block">Benefit</Typography>
|
setDialogBenefit(true);
|
||||||
</Button>
|
}} >
|
||||||
|
<Typography variant="button" display="block">Benefit</Typography>
|
||||||
|
</Button>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
{requestLog?.benefit_data?.map((item, index) => (
|
{requestLog?.benefit_data?.map((item, index) => (
|
||||||
@@ -321,29 +327,33 @@ export default function Detail() {
|
|||||||
{item.benefit?.description}
|
{item.benefit?.description}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
|
{
|
||||||
<MoreMenu actions={
|
!isReversal ? (
|
||||||
<>
|
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
|
||||||
<MenuItem onClick={() => {
|
<MoreMenu actions={
|
||||||
setDialogEditBenefit(true)
|
<>
|
||||||
setIdBenefitData(item.id)
|
<MenuItem onClick={() => {
|
||||||
setBenefitConfigurationData(item)
|
setDialogEditBenefit(true)
|
||||||
}}
|
setIdBenefitData(item.id)
|
||||||
>
|
setBenefitConfigurationData(item)
|
||||||
<EditOutlined />
|
}}
|
||||||
Edit
|
>
|
||||||
</MenuItem>
|
<EditOutlined />
|
||||||
<MenuItem onClick={() => {
|
Edit
|
||||||
setIdBenefitData(item.id)
|
</MenuItem>
|
||||||
setDialogDeleteBenefit(true)
|
<MenuItem onClick={() => {
|
||||||
}}
|
setIdBenefitData(item.id)
|
||||||
>
|
setDialogDeleteBenefit(true)
|
||||||
<Delete color='error'/>
|
}}
|
||||||
Delete
|
>
|
||||||
</MenuItem>
|
<Delete color='error'/>
|
||||||
</>
|
Delete
|
||||||
} />
|
</MenuItem>
|
||||||
</Grid>
|
</>
|
||||||
|
} />
|
||||||
|
</Grid>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
@@ -619,13 +629,16 @@ export default function Detail() {
|
|||||||
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
||||||
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Files </Typography>
|
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Files </Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
{ !isReversal ? (
|
||||||
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
|
||||||
setDialogUploadFileLog(true)
|
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
|
||||||
}} >
|
setDialogUploadFileLog(true)
|
||||||
<Typography variant="button" display="block">Files</Typography>
|
}} >
|
||||||
</Button>
|
<Typography variant="button" display="block">Files</Typography>
|
||||||
</Stack>
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
) : null }
|
||||||
|
|
||||||
</Stack>
|
</Stack>
|
||||||
{requestLog?.files?.map((documentType, index) => (
|
{requestLog?.files?.map((documentType, index) => (
|
||||||
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{marginBottom: 2}} key={index}>
|
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{marginBottom: 2}} key={index}>
|
||||||
@@ -638,14 +651,17 @@ export default function Detail() {
|
|||||||
<Typography variant="body2" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
|
<Typography variant="body2" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
|
||||||
</a>
|
</a>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack direction="column" spacing={2}>
|
{ !isReversal ? (
|
||||||
<IconButton onClick={() => {
|
<Stack direction="column" spacing={2}>
|
||||||
setDialogDeleteFileLog(true)
|
<IconButton onClick={() => {
|
||||||
setPathFile(documentType.path)
|
setDialogDeleteFileLog(true)
|
||||||
}} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}>
|
setPathFile(documentType.path)
|
||||||
<Delete color='error' fontSize="small" />
|
}} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}>
|
||||||
</IconButton>
|
<Delete color='error' fontSize="small" />
|
||||||
</Stack>
|
</IconButton>
|
||||||
|
</Stack>
|
||||||
|
) : null }
|
||||||
|
|
||||||
</Stack>
|
</Stack>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|||||||
@@ -456,7 +456,7 @@ export default function Router() {
|
|||||||
element: <ClaimsCreate />,
|
element: <ClaimsCreate />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'claims/detail/:id',
|
path: 'claims/detail/:id/:id_claim',
|
||||||
element: <ClaimsDetail />,
|
element: <ClaimsDetail />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,5 +50,14 @@
|
|||||||
"txtNew" : "New",
|
"txtNew" : "New",
|
||||||
"txtBeforeThat" : "Before that",
|
"txtBeforeThat" : "Before that",
|
||||||
"txtDischargeDate" : "Discharge Date",
|
"txtDischargeDate" : "Discharge Date",
|
||||||
"txtPatner" : "Patner"
|
"txtPatner" : "Patner",
|
||||||
|
"txtSelected": "Selected",
|
||||||
|
"txtConfirmation": "Confirmation",
|
||||||
|
"txtReason": "Reason Decline",
|
||||||
|
"txtCancel": "Cancel",
|
||||||
|
"txtDecline": "Decline",
|
||||||
|
"txtApprove": "Approve",
|
||||||
|
"txtDialogConfirmation": "Are you sure you want to proceed with this action?",
|
||||||
|
"txtStartDate": "Start Date",
|
||||||
|
"txtEndDate": "End Date"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,5 +50,14 @@
|
|||||||
"txtNew" : "Baru",
|
"txtNew" : "Baru",
|
||||||
"txtBeforeThat" : "Sebelum",
|
"txtBeforeThat" : "Sebelum",
|
||||||
"txtDischargeDate" : "Tanggal Keluar",
|
"txtDischargeDate" : "Tanggal Keluar",
|
||||||
"txtPatner" : "Rekanan"
|
"txtPatner" : "Rekanan",
|
||||||
|
"txtSelected": "Terpilih",
|
||||||
|
"txtConfirmation": "Konfirmasi",
|
||||||
|
"txtReason": "Alasan Penolakan",
|
||||||
|
"txtCancel": "Batal",
|
||||||
|
"txtDecline": "Tolak",
|
||||||
|
"txtApprove": "Terima",
|
||||||
|
"txtDialogConfirmation": "Apakah Anda yakin ingin melanjutkan tindakan ini?",
|
||||||
|
"txtStartDate": "Tanggal Mulai",
|
||||||
|
"txtEndDate": "Tanggal Akhir"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
TableSortLabel,
|
TableSortLabel,
|
||||||
Box,
|
Box,
|
||||||
Card,
|
Card,
|
||||||
|
Checkbox,
|
||||||
Grid,
|
Grid,
|
||||||
FormControl,
|
FormControl,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
@@ -25,6 +26,10 @@ import {
|
|||||||
linearProgressClasses,
|
linearProgressClasses,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { visuallyHidden } from '@mui/utils';
|
import { visuallyHidden } from '@mui/utils';
|
||||||
|
|
||||||
|
import { DatePicker, LocalizationProvider, MobileDatePicker } from '@mui/x-date-pickers';
|
||||||
|
|
||||||
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||||
/* ---------------------------------- axios --------------------------------- */
|
/* ---------------------------------- axios --------------------------------- */
|
||||||
import axios from '../utils/axios';
|
import axios from '../utils/axios';
|
||||||
/* ---------------------------------- react --------------------------------- */
|
/* ---------------------------------- react --------------------------------- */
|
||||||
@@ -43,6 +48,8 @@ import { DivisionDataProps, Order, PaginationTableProps, TableListProps } from '
|
|||||||
import { InputAdornment } from '@mui/material';
|
import { InputAdornment } from '@mui/material';
|
||||||
import GetAppIcon from '@mui/icons-material/GetApp';
|
import GetAppIcon from '@mui/icons-material/GetApp';
|
||||||
import { LanguageContext } from '@/contexts/LanguageContext';
|
import { LanguageContext } from '@/contexts/LanguageContext';
|
||||||
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||||
|
|
||||||
/* --------------------------------- styled --------------------------------- */
|
/* --------------------------------- styled --------------------------------- */
|
||||||
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
|
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
|
||||||
@@ -71,6 +78,7 @@ export default function Table<T>({
|
|||||||
filterEndDate,
|
filterEndDate,
|
||||||
searchs,
|
searchs,
|
||||||
exportReport,
|
exportReport,
|
||||||
|
selected,
|
||||||
}: TableListProps<T>) {
|
}: TableListProps<T>) {
|
||||||
/* ------------------------------- handle sort ------------------------------ */
|
/* ------------------------------- handle sort ------------------------------ */
|
||||||
const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => {
|
const handleRequestSort = async (event: React.MouseEvent<unknown>, property: string) => {
|
||||||
@@ -98,34 +106,73 @@ export default function Table<T>({
|
|||||||
return (
|
return (
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{headCells &&
|
{selected.useSelected && selected.selectedRows.length > 0 ? (
|
||||||
headCells.map((headCell, index) => (
|
<>
|
||||||
<TableCell
|
<TableCell style={{ backgroundColor: '#D1F1F1', }} align="left" colSpan={selected.totRows} sx={{ padding: 2 }}>
|
||||||
key={index}
|
<Grid container alignItems="center" justifyContent="space-between">
|
||||||
sortDirection={orders?.orderBy === headCell.id ? orders.order : false}
|
<Grid item>
|
||||||
// @ts-ignore
|
<Stack direction="row" alignItems="center">
|
||||||
align={headCell.align}
|
<Checkbox checked={selected.selectAll} onChange={selected.handleSelectAll} />
|
||||||
sx={{ padding: 2 }}
|
<Typography variant='subtitle2'>
|
||||||
width={headCell.width ? headCell.width : 'auto'}
|
{selected.selectedRows.length > 0 ? selected.selectedRows.length : '0'} {localeData.txtSelected}
|
||||||
>
|
</Typography>
|
||||||
{headCell.isSort ? (
|
</Stack>
|
||||||
<TableSortLabel
|
</Grid>
|
||||||
active={orders?.orderBy === headCell.id}
|
<Grid item>
|
||||||
direction={orders?.orderBy === headCell.id ? orders.order : 'asc'}
|
<Stack direction="row" spacing={2}>
|
||||||
onClick={createSortHandler(headCell.id)}
|
{selected.useDecline ? (
|
||||||
>
|
<Button variant="text" color="error" startIcon={<CancelIcon />} onClick={() => {selected.setOpenDialogSubmit(true);selected.setValDialog('decline');}}>
|
||||||
{headCell.label}
|
<Typography variant='subtitle2'>{selected.txtDecline}</Typography>
|
||||||
{orders?.orderBy === headCell.id ? (
|
</Button>
|
||||||
<Box component="span" sx={visuallyHidden}>
|
):''}
|
||||||
{orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'}
|
<Button variant="text" color="primary" startIcon={<CheckCircleIcon />} onClick={() => {selected.setOpenDialogSubmit(true);selected.setValDialog('approve');}}>
|
||||||
</Box>
|
<Typography variant='subtitle2'>{selected.txtApprove}</Typography>
|
||||||
) : null}
|
</Button>
|
||||||
</TableSortLabel>
|
</Stack>
|
||||||
) : (
|
</Grid>
|
||||||
headCell.label
|
</Grid>
|
||||||
)}
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
</>
|
||||||
|
):(
|
||||||
|
<>
|
||||||
|
{selected.useSelected ? (
|
||||||
|
<TableCell>
|
||||||
|
<Checkbox checked={selected.selectAll} onChange={selected.handleSelectAll} />
|
||||||
|
</TableCell>
|
||||||
|
):''}
|
||||||
|
{headCells &&
|
||||||
|
headCells.map((headCell, index) => (
|
||||||
|
<TableCell
|
||||||
|
key={index}
|
||||||
|
sortDirection={orders?.orderBy === headCell.id ? orders.order : false}
|
||||||
|
// @ts-ignore
|
||||||
|
align={headCell.align}
|
||||||
|
sx={{ padding: 2 }}
|
||||||
|
width={headCell.width ? headCell.width : 'auto'}
|
||||||
|
>
|
||||||
|
{headCell.isSort ? (
|
||||||
|
<TableSortLabel
|
||||||
|
active={orders?.orderBy === headCell.id}
|
||||||
|
direction={orders?.orderBy === headCell.id ? orders.order : 'asc'}
|
||||||
|
onClick={createSortHandler(headCell.id)}
|
||||||
|
>
|
||||||
|
{headCell.label}
|
||||||
|
{orders?.orderBy === headCell.id ? (
|
||||||
|
<Box component="span" sx={visuallyHidden}>
|
||||||
|
{orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'}
|
||||||
|
</Box>
|
||||||
|
) : null}
|
||||||
|
</TableSortLabel>
|
||||||
|
) : (
|
||||||
|
headCell.label
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
);
|
);
|
||||||
@@ -162,7 +209,6 @@ export default function Table<T>({
|
|||||||
params.setAppliedParams(parameters);
|
params.setAppliedParams(parameters);
|
||||||
};
|
};
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// <Card>
|
// <Card>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
@@ -255,7 +301,7 @@ export default function Table<T>({
|
|||||||
{/* Start date */}
|
{/* Start date */}
|
||||||
{filterStartDate && filterStartDate.useFilter ? (
|
{filterStartDate && filterStartDate.useFilter ? (
|
||||||
<Grid item xs={12} lg={2} xl={2}>
|
<Grid item xs={12} lg={2} xl={2}>
|
||||||
<form onChange={(event) => filterStartDate.handleStartDateChange(event)}>
|
{/* <form onChange={(event) => filterStartDate.handleStartDateChange(event)}>
|
||||||
<TextField
|
<TextField
|
||||||
id="date-input"
|
id="date-input"
|
||||||
type="date"
|
type="date"
|
||||||
@@ -267,7 +313,18 @@ export default function Table<T>({
|
|||||||
shrink: true,
|
shrink: true,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form> */}
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DatePicker
|
||||||
|
label={localeData.txtStartDate}
|
||||||
|
value={filterStartDate.startDate}
|
||||||
|
onChange={(newValue:any) => {
|
||||||
|
filterStartDate.setStartDate( (newValue));
|
||||||
|
}}
|
||||||
|
inputFormat="dd-MM-yyyy"
|
||||||
|
renderInput={(params) => <TextField sx={{width:'40%'}} {...params} required/>}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
</Grid>
|
</Grid>
|
||||||
) : null }
|
) : null }
|
||||||
|
|
||||||
@@ -275,7 +332,7 @@ export default function Table<T>({
|
|||||||
|
|
||||||
{filterEndDate && filterEndDate.useFilter ? (
|
{filterEndDate && filterEndDate.useFilter ? (
|
||||||
<Grid item xs={12} lg={2} xl={2}>
|
<Grid item xs={12} lg={2} xl={2}>
|
||||||
<form onChange={(event) => filterEndDate.handleEndDateChange(event)}>
|
{/* <form onChange={(event) => filterEndDate.handleEndDateChange(event)}>
|
||||||
<TextField
|
<TextField
|
||||||
id="date-input"
|
id="date-input"
|
||||||
type="date"
|
type="date"
|
||||||
@@ -287,7 +344,18 @@ export default function Table<T>({
|
|||||||
shrink: true,
|
shrink: true,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form> */}
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DatePicker
|
||||||
|
label={localeData.txtEndDate}
|
||||||
|
value={filterEndDate.endDate}
|
||||||
|
onChange={(newValue:any) => {
|
||||||
|
filterEndDate.setEndDate( (newValue));
|
||||||
|
}}
|
||||||
|
inputFormat="dd-MM-yyyy"
|
||||||
|
renderInput={(params) => <TextField sx={{width:'40%'}} {...params} required/>}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
</Grid>
|
</Grid>
|
||||||
) : null }
|
) : null }
|
||||||
|
|
||||||
@@ -349,6 +417,20 @@ export default function Table<T>({
|
|||||||
) : rows && rows.length >= 1 ? (
|
) : rows && rows.length >= 1 ? (
|
||||||
rows.map((row, rowIndex) => (
|
rows.map((row, rowIndex) => (
|
||||||
<TableRow key={rowIndex}>
|
<TableRow key={rowIndex}>
|
||||||
|
{!selected.useSelected ? (
|
||||||
|
''
|
||||||
|
): (selected.useSelected && row.check_status === 'approved' && !row.check_claim ? (
|
||||||
|
<TableCell>
|
||||||
|
<Checkbox
|
||||||
|
checked={selected.selectedRows.includes(row.id)}
|
||||||
|
onChange={() => selected.handleCheckboxChange(row.id)}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
):(
|
||||||
|
<TableCell>
|
||||||
|
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
{headCells &&
|
{headCells &&
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
headCells.map((head, headIndex) => (
|
headCells.map((head, headIndex) => (
|
||||||
|
|||||||
@@ -118,6 +118,58 @@ export default function TableList() {
|
|||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// ----------------------------------------- handle selected ---------------------
|
||||||
|
const [selectAll, setSelectAll] = useState(false);
|
||||||
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
|
const [dataTableData, setDataTableData] = useState<any>();
|
||||||
|
const handleSelectAll = () => {
|
||||||
|
setSelectAll(!selectAll);
|
||||||
|
if (!selectAll) {
|
||||||
|
const requestedIds = dataTableData?.data
|
||||||
|
.filter((row: { status: string, check_claim:any }) => row.status === 'approved' && !row.check_claim)
|
||||||
|
.map((row: { id: any }) => row.id);
|
||||||
|
setSelectedRows(requestedIds);
|
||||||
|
} else {
|
||||||
|
setSelectedRows([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckboxChange = (id: any) => {
|
||||||
|
setSelectedRows(prevSelectedRows => {
|
||||||
|
const isSelected = prevSelectedRows.includes(id);
|
||||||
|
if (isSelected) {
|
||||||
|
return prevSelectedRows.filter(rowId => rowId !== id);
|
||||||
|
} else {
|
||||||
|
return [...prevSelectedRows, id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
||||||
|
const handleCloseDialogSubmit = () => {
|
||||||
|
setOpenDialogSubmit(false);
|
||||||
|
}
|
||||||
|
const [valDialog, setValDialog] = useState('');
|
||||||
|
const [reasonDecline, setReasonDecline] = useState('');
|
||||||
|
const handleReasonDeclineChange = (event: { target: { value: SetStateAction<string>; }; }) => {
|
||||||
|
setReasonDecline(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selected = {
|
||||||
|
useSelected: false,
|
||||||
|
selectAll: selectAll,
|
||||||
|
handleSelectAll: handleSelectAll,
|
||||||
|
selectedRows: selectedRows,
|
||||||
|
handleCheckboxChange : handleCheckboxChange,
|
||||||
|
totRows: 9,
|
||||||
|
useDecline: false,
|
||||||
|
txtDecline: 'Decline',
|
||||||
|
useApprove:true,
|
||||||
|
txtApprove: 'Submit Claim',
|
||||||
|
setOpenDialogSubmit: setOpenDialogSubmit,
|
||||||
|
setValDialog: setValDialog
|
||||||
|
};
|
||||||
|
|
||||||
/* ------------------------------ handle search ----------------------------- */
|
/* ------------------------------ handle search ----------------------------- */
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
|
|
||||||
@@ -252,12 +304,12 @@ export default function TableList() {
|
|||||||
label: localeData.txtStatus,
|
label: localeData.txtStatus,
|
||||||
isSort: true,
|
isSort: true,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
id: 'action',
|
// id: 'action',
|
||||||
align: 'right',
|
// align: 'right',
|
||||||
label: '',
|
// label: '',
|
||||||
isSort: false,
|
// isSort: false,
|
||||||
},
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
@@ -280,6 +332,7 @@ export default function TableList() {
|
|||||||
const response = await axios.get(`/get-claim-requests`, {
|
const response = await axios.get(`/get-claim-requests`, {
|
||||||
params: { ...parameters, type: 'final-log' },
|
params: { ...parameters, type: 'final-log' },
|
||||||
});
|
});
|
||||||
|
setDataTableData(response.data);
|
||||||
setData(
|
setData(
|
||||||
response.data.data.map((obj: any) => ({
|
response.data.data.map((obj: any) => ({
|
||||||
...obj,
|
...obj,
|
||||||
@@ -310,15 +363,15 @@ export default function TableList() {
|
|||||||
{obj.submission_date ? fDateSuffix(obj.submission_date) : ''}
|
{obj.submission_date ? fDateSuffix(obj.submission_date) : ''}
|
||||||
</Label>
|
</Label>
|
||||||
,
|
,
|
||||||
action:
|
// action:
|
||||||
<TableMoreMenu actions={
|
// <TableMoreMenu actions={
|
||||||
<>
|
// <>
|
||||||
<MenuItem onClick={() => navigate ('/claim/detail/'+obj.claim_request_id)}>
|
// <MenuItem onClick={() => navigate ('/claim/detail/'+obj.claim_request_id)}>
|
||||||
<Iconify icon="eva:eye-fill" />
|
// <Iconify icon="eva:eye-fill" />
|
||||||
View
|
// View
|
||||||
</MenuItem>
|
// </MenuItem>
|
||||||
</>
|
// </>
|
||||||
} />
|
// } />
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -357,6 +410,7 @@ export default function TableList() {
|
|||||||
params={params}
|
params={params}
|
||||||
searchs={searchs}
|
searchs={searchs}
|
||||||
filterStatus={filterStatus}
|
filterStatus={filterStatus}
|
||||||
|
selected={selected}
|
||||||
// filterStartDate={filterStartDate}
|
// filterStartDate={filterStartDate}
|
||||||
// filterEndDate={filterEndDate}
|
// filterEndDate={filterEndDate}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export default function DialogClaimSubmit({ member, getData, onClose, handleSubm
|
|||||||
<Card sx={{ p: 1, background: '#f4f6f8'}}>
|
<Card sx={{ p: 1, background: '#f4f6f8'}}>
|
||||||
<Stack direction="row">
|
<Stack direction="row">
|
||||||
<Avatar
|
<Avatar
|
||||||
src="https://minimal-assets-api.vercel.app/assets/images/avatars/avatar_5.jpg"
|
src=""
|
||||||
alt={member?.full_name ?? ''}
|
alt={member?.full_name ?? ''}
|
||||||
sx={{ marginTop: 1, width: 48, height: 48 }}
|
sx={{ marginTop: 1, width: 48, height: 48 }}
|
||||||
/>
|
/>
|
||||||
@@ -143,7 +143,7 @@ export default function DialogClaimSubmit({ member, getData, onClose, handleSubm
|
|||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
multiple
|
multiple
|
||||||
onChange={handleKondisiInputChange}
|
onChange={handleKondisiInputChange}
|
||||||
accept="application/pdf"
|
accept="application/pdf, image/*"
|
||||||
/>
|
/>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/* ---------------------------------- @mui ---------------------------------- */
|
/* ---------------------------------- @mui ---------------------------------- */
|
||||||
import { Stack, Button, MenuItem, SelectChangeEvent, Tab, Tabs, Card, Box } from '@mui/material';
|
import { Stack, Button, Checkbox, MenuItem, SelectChangeEvent, Tab, Tabs, Card, Box, IconButton, TextField } from '@mui/material';
|
||||||
/* ---------------------------------- axios --------------------------------- */
|
/* ---------------------------------- axios --------------------------------- */
|
||||||
// import axios from 'axios';
|
// import axios from 'axios';
|
||||||
import axios from '../../utils/axios';
|
import axios from '../../utils/axios';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
/* ---------------------------------- react --------------------------------- */
|
/* ---------------------------------- react --------------------------------- */
|
||||||
import { useContext, useEffect, useState } from 'react';
|
import { SetStateAction, useContext, useEffect, useState } from 'react';
|
||||||
|
|
||||||
/* -------------------------------- component ------------------------------- */
|
/* -------------------------------- component ------------------------------- */
|
||||||
import Iconify from '../../components/Iconify';
|
import Iconify from '../../components/Iconify';
|
||||||
@@ -30,6 +30,8 @@ import MuiDialog from '@/components/MuiDialog';
|
|||||||
import DialogMember from './DialogMember';
|
import DialogMember from './DialogMember';
|
||||||
import DialogClaimSubmit from './DialogClaimSubmit';
|
import DialogClaimSubmit from './DialogClaimSubmit';
|
||||||
import { fPostFormat } from '@/utils/formatTime';
|
import { fPostFormat } from '@/utils/formatTime';
|
||||||
|
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
|
||||||
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
|
||||||
export default function TableListFinalLog() {
|
export default function TableListFinalLog() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -68,6 +70,7 @@ export default function TableListFinalLog() {
|
|||||||
return `${day}${month}${year}`;
|
return `${day}${month}${year}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* setting up for the table */
|
/* setting up for the table */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
@@ -128,6 +131,85 @@ export default function TableListFinalLog() {
|
|||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// ----------------------------------------- handle selected ---------------------
|
||||||
|
const [selectAll, setSelectAll] = useState(false);
|
||||||
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
|
const [dataTableData, setDataTableData] = useState<any>();
|
||||||
|
const handleSelectAll = () => {
|
||||||
|
setSelectAll(!selectAll);
|
||||||
|
if (!selectAll) {
|
||||||
|
const requestedIds = dataTableData?.data
|
||||||
|
.filter((row: { status: string, check_claim:any }) => row.status === 'approved' && !row.check_claim)
|
||||||
|
.map((row: { id: any }) => row.id);
|
||||||
|
setSelectedRows(requestedIds);
|
||||||
|
} else {
|
||||||
|
setSelectedRows([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckboxChange = (id: any) => {
|
||||||
|
setSelectedRows(prevSelectedRows => {
|
||||||
|
const isSelected = prevSelectedRows.includes(id);
|
||||||
|
if (isSelected) {
|
||||||
|
return prevSelectedRows.filter(rowId => rowId !== id);
|
||||||
|
} else {
|
||||||
|
return [...prevSelectedRows, id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
||||||
|
const handleCloseDialogSubmit = () => {
|
||||||
|
setOpenDialogSubmit(false);
|
||||||
|
}
|
||||||
|
const [valDialog, setValDialog] = useState('');
|
||||||
|
const [reasonDecline, setReasonDecline] = useState('');
|
||||||
|
const handleReasonDeclineChange = (event: { target: { value: SetStateAction<string>; }; }) => {
|
||||||
|
setReasonDecline(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selected = {
|
||||||
|
useSelected: true,
|
||||||
|
selectAll: selectAll,
|
||||||
|
handleSelectAll: handleSelectAll,
|
||||||
|
selectedRows: selectedRows,
|
||||||
|
handleCheckboxChange : handleCheckboxChange,
|
||||||
|
totRows: 9,
|
||||||
|
useDecline: false,
|
||||||
|
txtDecline: 'Decline',
|
||||||
|
useApprove:true,
|
||||||
|
txtApprove: 'Submit Claim',
|
||||||
|
setOpenDialogSubmit: setOpenDialogSubmit,
|
||||||
|
setValDialog: setValDialog
|
||||||
|
};
|
||||||
|
const handleSubmitData = () => {
|
||||||
|
//approve or decline
|
||||||
|
// if (!reasonDecline && valDialog == 'decline') {
|
||||||
|
// enqueueSnackbar('Mohon isi alasan', { variant: 'warning' });
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
axios.post('/submit-claims', {
|
||||||
|
selectedRows: selectedRows
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if(response.data.meta.code === 200)
|
||||||
|
{
|
||||||
|
setOpenDialogSubmit(false);
|
||||||
|
enqueueSnackbar(response.data.meta.message, {variant : "success"});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
setOpenDialogSubmit(false);
|
||||||
|
enqueueSnackbar(response.data.meta.message, {variant : "error"});
|
||||||
|
}
|
||||||
|
getData();
|
||||||
|
setSelectedRows([]);
|
||||||
|
})
|
||||||
|
.catch(({response}) => {
|
||||||
|
enqueueSnackbar(response.data.errors ? response.data.errors[0] : (response.data ? response.data.meta.message : 'Opps, Something went Wrong!'), {variant : "error"})
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
});
|
||||||
|
};
|
||||||
/* ------------------------------ handle search ----------------------------- */
|
/* ------------------------------ handle search ----------------------------- */
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
|
|
||||||
@@ -335,11 +417,14 @@ export default function TableListFinalLog() {
|
|||||||
params: { ...parameters, search:searchText, order: order,
|
params: { ...parameters, search:searchText, order: order,
|
||||||
orderBy: orderBy, status:statusValue, type: 'final-log' },
|
orderBy: orderBy, status:statusValue, type: 'final-log' },
|
||||||
});
|
});
|
||||||
|
setDataTableData(response.data);
|
||||||
setData(
|
setData(
|
||||||
response.data.data.map((obj: any) => ({
|
response.data.data.map((obj: any) => ({
|
||||||
...obj,
|
...obj,
|
||||||
provider:formatTitleCase(obj.provider),
|
provider:formatTitleCase(obj.provider),
|
||||||
full_name:formatTitleCase(obj.full_name),
|
full_name:formatTitleCase(obj.full_name),
|
||||||
|
check_status: obj.status,
|
||||||
|
check_claim: obj.check_claim,
|
||||||
status:
|
status:
|
||||||
obj.status === 'requested' ? (
|
obj.status === 'requested' ? (
|
||||||
<Label color='primary'>
|
<Label color='primary'>
|
||||||
@@ -445,6 +530,7 @@ export default function TableListFinalLog() {
|
|||||||
params={params}
|
params={params}
|
||||||
searchs={searchs}
|
searchs={searchs}
|
||||||
filterStatus={filterStatus}
|
filterStatus={filterStatus}
|
||||||
|
selected={selected}
|
||||||
// filterStartDate={filterStartDate}
|
// filterStartDate={filterStartDate}
|
||||||
// filterEndDate={filterEndDate}
|
// filterEndDate={filterEndDate}
|
||||||
/>
|
/>
|
||||||
@@ -466,7 +552,6 @@ export default function TableListFinalLog() {
|
|||||||
member={dataViewClaimSubmit}
|
member={dataViewClaimSubmit}
|
||||||
getData={getData}
|
getData={getData}
|
||||||
onClose={(data:any, getData:any) => {
|
onClose={(data:any, getData:any) => {
|
||||||
console.log('Data returned:', data);
|
|
||||||
getData();
|
getData();
|
||||||
setOpenDialogClaimSubmit(false);
|
setOpenDialogClaimSubmit(false);
|
||||||
}}
|
}}
|
||||||
@@ -475,7 +560,43 @@ export default function TableListFinalLog() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
maxWidth="sm"
|
maxWidth="sm"
|
||||||
/>
|
/>
|
||||||
|
<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">{localeData.txtConfirmation}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<IconButton sx={{ color: '#FFF' }} onClick={handleCloseDialogSubmit}>
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Stack>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
|
||||||
|
<Stack spacing={2} padding={2}>
|
||||||
|
<Typography variant='body1'>{localeData.txtDialogConfirmation}</Typography>
|
||||||
|
{valDialog == "decline" ? (
|
||||||
|
<Stack direction='row' spacing={2} marginTop={2}>
|
||||||
|
<TextField
|
||||||
|
id="outlined-multiline-static"
|
||||||
|
label={localeData.txtReason}
|
||||||
|
multiline
|
||||||
|
rows={4}
|
||||||
|
defaultValue=""
|
||||||
|
onChange={handleReasonDeclineChange}
|
||||||
|
variant="outlined"
|
||||||
|
sx={{width:'100%'}}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
): ''}
|
||||||
|
</Stack>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="outlined" sx={{color: '#212B36', borderColor: '#919EAB52'}} onClick={handleCloseDialogSubmit}>{localeData.txtCancel}</Button>
|
||||||
|
<Button sx={{backgroundColor: (valDialog === 'decline' ? '' : '#19BBBB'), color: (valDialog === 'decline' ? '#FF4842' : ''), borderColor: '#FF4842'}} onClick={handleSubmitData} variant={(valDialog === 'decline' ? 'outlined' : 'contained')}>{(valDialog === "decline" ? localeData.txtDeclaine : 'Submit')}</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import { Stack, Button, MenuItem, SelectChangeEvent, Tab, Tabs, Card, Box } from
|
|||||||
import axios from '../../utils/axios';
|
import axios from '../../utils/axios';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
/* ---------------------------------- react --------------------------------- */
|
/* ---------------------------------- react --------------------------------- */
|
||||||
import { useContext, useEffect, useState } from 'react';
|
import { useContext, useEffect, useState, SetStateAction } from 'react';
|
||||||
|
|
||||||
/* -------------------------------- component ------------------------------- */
|
/* -------------------------------- component ------------------------------- */
|
||||||
import Iconify from '../../components/Iconify';
|
import Iconify from '../../components/Iconify';
|
||||||
@@ -132,6 +132,58 @@ export default function TableList() {
|
|||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// ----------------------------------------- handle selected ---------------------
|
||||||
|
const [selectAll, setSelectAll] = useState(false);
|
||||||
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
|
const [dataTableData, setDataTableData] = useState<any>();
|
||||||
|
const handleSelectAll = () => {
|
||||||
|
setSelectAll(!selectAll);
|
||||||
|
if (!selectAll) {
|
||||||
|
const requestedIds = dataTableData?.data
|
||||||
|
.filter((row: { status: string, check_claim:any }) => row.status === 'approved' && !row.check_claim)
|
||||||
|
.map((row: { id: any }) => row.id);
|
||||||
|
setSelectedRows(requestedIds);
|
||||||
|
} else {
|
||||||
|
setSelectedRows([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckboxChange = (id: any) => {
|
||||||
|
setSelectedRows(prevSelectedRows => {
|
||||||
|
const isSelected = prevSelectedRows.includes(id);
|
||||||
|
if (isSelected) {
|
||||||
|
return prevSelectedRows.filter(rowId => rowId !== id);
|
||||||
|
} else {
|
||||||
|
return [...prevSelectedRows, id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const [openDialogSubmit, setOpenDialogSubmit] = useState(false);
|
||||||
|
const handleCloseDialogSubmit = () => {
|
||||||
|
setOpenDialogSubmit(false);
|
||||||
|
}
|
||||||
|
const [valDialog, setValDialog] = useState('');
|
||||||
|
const [reasonDecline, setReasonDecline] = useState('');
|
||||||
|
const handleReasonDeclineChange = (event: { target: { value: SetStateAction<string>; }; }) => {
|
||||||
|
setReasonDecline(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selected = {
|
||||||
|
useSelected: false,
|
||||||
|
selectAll: selectAll,
|
||||||
|
handleSelectAll: handleSelectAll,
|
||||||
|
selectedRows: selectedRows,
|
||||||
|
handleCheckboxChange : handleCheckboxChange,
|
||||||
|
totRows: 9,
|
||||||
|
useDecline: false,
|
||||||
|
txtDecline: 'Decline',
|
||||||
|
useApprove:true,
|
||||||
|
txtApprove: 'Submit Claim',
|
||||||
|
setOpenDialogSubmit: setOpenDialogSubmit,
|
||||||
|
setValDialog: setValDialog
|
||||||
|
};
|
||||||
|
|
||||||
/* ------------------------------ handle search ----------------------------- */
|
/* ------------------------------ handle search ----------------------------- */
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
|
|
||||||
@@ -187,7 +239,7 @@ export default function TableList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// handle start date
|
// handle start date
|
||||||
const [startDateValue, setStartDateValue] = useState('');
|
const [startDateValue, setStartDateValue] = useState(null);
|
||||||
|
|
||||||
const handleStartDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
|
const handleStartDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -211,7 +263,7 @@ export default function TableList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// handle end date
|
// handle end date
|
||||||
const [endDateValue, setEndDateValue] = useState('');
|
const [endDateValue, setEndDateValue] = useState(null);
|
||||||
|
|
||||||
const handleEndDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
|
const handleEndDateChanges = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -328,6 +380,7 @@ export default function TableList() {
|
|||||||
params: { ...parameters, search:searchText, order: order,
|
params: { ...parameters, search:searchText, order: order,
|
||||||
orderBy: orderBy, status:statusValue, type: 'request-log' },
|
orderBy: orderBy, status:statusValue, type: 'request-log' },
|
||||||
});
|
});
|
||||||
|
setDataTableData(response.data);
|
||||||
setData(
|
setData(
|
||||||
response.data.data.map((obj: any) => ({
|
response.data.data.map((obj: any) => ({
|
||||||
...obj,
|
...obj,
|
||||||
@@ -440,8 +493,9 @@ export default function TableList() {
|
|||||||
params={params}
|
params={params}
|
||||||
searchs={searchs}
|
searchs={searchs}
|
||||||
filterStatus={filterStatus}
|
filterStatus={filterStatus}
|
||||||
// filterStartDate={filterStartDate}
|
selected={selected}
|
||||||
// filterEndDate={filterEndDate}
|
//filterStartDate={filterStartDate}
|
||||||
|
//filterEndDate={filterEndDate}
|
||||||
/>
|
/>
|
||||||
<MuiDialog
|
<MuiDialog
|
||||||
title={{name: nameMember}}
|
title={{name: nameMember}}
|
||||||
|
|||||||
BIN
public/files/Report-Data-Claim-Request.xlsx
Normal file
BIN
public/files/Report-Data-Claim-Request.xlsx
Normal file
Binary file not shown.
BIN
public/files/Template - Claim - Management.xlsx
Normal file
BIN
public/files/Template - Claim - Management.xlsx
Normal file
Binary file not shown.
BIN
public/files/Template Claim Request.xlsx
Normal file
BIN
public/files/Template Claim Request.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user