From ccf7bee67a74ef22ca33778e334c3d2d0f352aab Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 23 Feb 2024 11:01:25 +0700 Subject: [PATCH 01/34] bugs fix dan fitur submission di claim request --- .../Api/ClaimRequestController.php | 17 ++- .../Controllers/Api/RequestLogController.php | 1 + .../Api/ClaimRequestController.php | 102 +++---------- Modules/Internal/Routes/api.php | 1 + .../Transformers/ClaimRequestShowResource.php | 1 + app/Models/ClaimRequest.php | 9 ++ ...725_add_coloumn_to_claim_request_table.php | 47 ++++++ .../Components/DialogConfirmation.tsx | 138 +++++++----------- .../src/pages/ClaimRequests/Detail.tsx | 76 ++++++++-- .../src/pages/ClaimRequests/List.tsx | 6 +- .../FinalLog/Components/DialogBenefit.tsx | 2 +- 11 files changed, 220 insertions(+), 180 deletions(-) create mode 100644 database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php diff --git a/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php b/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php index 3d27eb3a..ace8d239 100644 --- a/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php @@ -133,10 +133,21 @@ class ClaimRequestController extends Controller if ($request->hasFile('additional_files')) { foreach ($request->additional_files as $file) { - $pathFile = File::storeFile('additional-files', $newClaimRequest->id, $file); - $newClaimRequest->files()->updateOrCreate([ + $pathFile = File::storeFile('additional-files', $request->request_logs_id, $file); + // $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', - 'name' => File::getFileName('additional-files', $newClaimRequest->id, $file), + 'name' => File::getFileName('additional-files', $request->request_logs_id, $file), 'original_name' => $file->getClientOriginalName(), 'extension' => $file->getClientOriginalExtension(), 'path' => $pathFile, diff --git a/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php b/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php index 5105d85f..b7a07ebe 100644 --- a/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php +++ b/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php @@ -244,6 +244,7 @@ class RequestLogController extends Controller $results = DB::table('request_logs') ->leftJoin('members', 'request_logs.member_id', '=', 'members.id') + ->where('request_logs.deleted_at', null) ->when($request->input('search'), function ($query, $search) { $query->where(function ($query) use ($search) { $query->orWhere('request_logs.code', 'like', "%" . $search . "%") diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index b74a79be..c2ea4c9b 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -516,90 +516,6 @@ class ClaimRequestController extends Controller 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->load([ 'requestLog', @@ -788,4 +704,22 @@ class ClaimRequestController extends Controller return Helper::responseJson(data: $request->toArray(), message: 'Invoice Success Uploaded'); } + + 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); + + } } diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 20541d8a..d5f58fda 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -311,6 +311,7 @@ Route::prefix('internal')->group(function () { 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::post('claim-requests/{id}/approve', [ClaimRequestController::class, 'approve'])->name('claim-requests.approve'); + Route::post('claim-requests/{id}/submition', [ClaimRequestController::class, 'submition'])->name('claim-requests.submition'); Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show'); Route::post('claim-requests', [ClaimRequestController::class, 'createNew']); // Bagaskoro, BSD 2 November 2023 Route::post('claim-requests/{id}/update', [ClaimRequestController::class, 'update']); diff --git a/Modules/Internal/Transformers/ClaimRequestShowResource.php b/Modules/Internal/Transformers/ClaimRequestShowResource.php index 39923a97..cbb7e109 100644 --- a/Modules/Internal/Transformers/ClaimRequestShowResource.php +++ b/Modules/Internal/Transformers/ClaimRequestShowResource.php @@ -75,6 +75,7 @@ class ClaimRequestShowResource extends JsonResource $response = [ 'id' => $data['id'], 'code' => $data['code'], + 'status' => $data['status'], 'request_log_id' => $data['request_log_id'], 'request_log' => $requestLogData, 'provider' => $data['request_log']['organization']['name'], diff --git a/app/Models/ClaimRequest.php b/app/Models/ClaimRequest.php index cfed961a..0bf6d685 100644 --- a/app/Models/ClaimRequest.php +++ b/app/Models/ClaimRequest.php @@ -26,6 +26,15 @@ class ClaimRequest extends Model 'service_code', 'policy_id', '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', 'organization_id', 'code', diff --git a/database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php b/database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php new file mode 100644 index 00000000..be2a049e --- /dev/null +++ b/database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php @@ -0,0 +1,47 @@ +integer('claim_management') + ->default(0) + ->after('status') + ->comment('untuk flag request masuk ke final, jika 0 masih request dan 1 itu sudah masuk ke finallog'); + $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'); + }); + } +}; diff --git a/frontend/dashboard/src/pages/ClaimRequests/Components/DialogConfirmation.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/DialogConfirmation.tsx index ce78fa0b..259ffed7 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Components/DialogConfirmation.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/DialogConfirmation.tsx @@ -1,35 +1,30 @@ 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 { Stack } from '@mui/material'; import React, { useEffect, useState } from 'react'; -import { ClaimRequest, Files } from '@/@types/claims'; -import { fDateOnly, fDateTimesecond, toTitleCase } from "@/utils/formatTime"; +import { DetailClaimRequest } from "../Model/Types"; +import { fDateTimesecond, toTitleCase } from "@/utils/formatTime"; import axios from "@/utils/axios"; -import { enqueueSnackbar, useSnackbar } from "notistack"; +import { enqueueSnackbar } from "notistack"; import { useNavigate } from "react-router"; -import * as Yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; +import { RHFTextField } from "@/components/hook-form"; + type DialogConfirmationType = { openDialog: boolean; setOpenDialog: any; onSubmit?: void; 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 { enqueueSnackbar } = useSnackbar(); - + const [formData, setFormData] = useState({ - date: claimRequest?.date, - id: claimRequest?.id, - reason: claimRequest?.reason + }); - const handleChange = (field, value) => { setFormData((prevData) => ({ ...prevData, @@ -38,24 +33,28 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia }; + const handleApprove = () => { + setFormData((prevData) => ({ + ...prevData, + status: approve, + })); + handleSubmit(); + }; + + const handleSubmit = () => { axios - .post(`customer-service/request/final-log`, formData) + .post(`claim-requests/${requestLog?.id}/submition`, formData) .then((response) => { - enqueueSnackbar('Verification Request LOG Success', { variant: 'success' }); + enqueueSnackbar('Submition Claim Request Success', { variant: 'success' }); setOpenDialog(false); - if (requestLog?.service_type == 'Inpatient'){ - navigate('/case_management/inpatient_monitoring'); - } else { - navigate('/custormer-service/final-log'); - } + navigate('/claim-requests') }) .catch(({ response }) => { enqueueSnackbar(response.data.message ?? 'Something went wrong!', { variant: 'error' }); }); } - const style1 = { color: '#919EAB', width: '30%' @@ -66,34 +65,57 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia const marginBottom1 = { marginBottom: 1, } + const marginBottom2 = { marginBottom: 2, } + + const resetForm = () => { + setFormData({ + status: approve, + no_identitas: requestLog?.no_identitas ?? '', + keterangan: '', + hak_kamar_pasien: '', + penempatan_kamar: '', + }); + }; + const handleCloseDialog = () => { 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 = () => ( - Are you sure to {approve == 'approved' ? 'approve' : 'deciline'} this final log ? + Are you sure to submit this claim ? - Member ID - {requestLog?.member_id} - - - Policy Number - {requestLog?.policy_number} + Code + {requestLog?.code} Name {requestLog?.name} - Submission Date + Date Submission {requestLog?.submission_date ? fDateTimesecond(requestLog?.submission_date) : '-'} @@ -105,58 +127,10 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia {requestLog?.service_type} - - - - Discharge Date - handleChange('discharge_date', e.target.value)} - /> - - - Catatan - handleChange('catatan', e.target.value)} - /> - - - Diagnosis ICD - X - option.label} - fullWidth - value={icdOptions.filter((icd) => formData.icdCodes.includes(icd.value))} - onChange={(e, newValues) => handleChange('icdCodes', newValues.map((value) => value.value))} - renderInput={(params) => ( - - )} - /> - - - - {approve == 'approved' ? ( - - ) : ( - - ) } - + ); @@ -168,7 +142,7 @@ export default function DialogConfirmation({claimRequest, setOpenDialog, openDia openDialog={openDialog} setOpenDialog={setOpenDialog} content={getContent()} - maxWidth="xl" + maxWidth="md" /> ); } \ No newline at end of file diff --git a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx index a4d31d16..38a23045 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx @@ -38,6 +38,8 @@ import DialogDeleteFileLog from './Components/DialogDeleteFileLog'; import DialogBenefit from '../CustomerService/FinalLog/Components/DialogBenefit'; import DialogDeleteBenefit from '../CustomerService/FinalLog/Components/DialogDeleteBenefit'; import DialogEditBenefit from '../CustomerService/FinalLog/Components/DialogEditBenefit'; +import DialogConfirmation from './Components/DialogConfirmation'; + // ---------------------------------------------------------------------- @@ -49,6 +51,7 @@ export default function Detail() { const navigate = useNavigate(); const { themeStretch } = useSettings(); const [claimRequests, setClaimRequest] = useState(); + const [openDialogSubmit, setOpenDialogSubmit] = useState(false); const { id } = useParams(); @@ -421,7 +424,7 @@ export default function Detail() { - + Total Benefit @@ -436,12 +439,12 @@ export default function Detail() { - + Amount Incurred - + {totalAmountIncurred ? fNumber(totalAmountIncurred) : '0'} @@ -452,12 +455,12 @@ export default function Detail() { - + Amount Approved - + {totalAmountApproved ? fNumber(totalAmountApproved) : '0'} @@ -468,12 +471,12 @@ export default function Detail() { - + Amount Not Approved - + {totalAmountNotApproved ? fNumber(totalAmountNotApproved) : 0} @@ -484,12 +487,12 @@ export default function Detail() { - + Excess Paid - + {totalExcessPaid ? fNumber(totalExcessPaid) : 0} @@ -497,6 +500,23 @@ export default function Detail() { + + + + Biaya disetujui + + + + + {totalAmountApproved ? fNumber(totalAmountApproved) : '0'} + + + + + Nominal diatas 1 juta akan menunggu persetujuan senior analyst + + + @@ -504,6 +524,8 @@ export default function Detail() { : ( null )} + + @@ -542,6 +564,42 @@ export default function Detail() { requestLog={requestLog} openDialog={openDialogEditDetail} /> */} + + {(claimRequests?.status === 'requested') || (claimRequests?.status === 'decline') ? ( + + +
{/* Perubahan sintaksis disini */} + +
+
+ +
+ + +
+
+ ) : null}
diff --git a/frontend/dashboard/src/pages/ClaimRequests/List.tsx b/frontend/dashboard/src/pages/ClaimRequests/List.tsx index c2df449c..43a779ad 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/List.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/List.tsx @@ -468,8 +468,12 @@ export default function List() { {row.service_name} {row.payment_type_name} - { row.status == "requested" ? + { row.status == "requested" ? () : + row.status == "submission" ? + () : + row.status == "decline" ? + () : () } diff --git a/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx b/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx index c2e82765..9e0d9f6b 100644 --- a/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx +++ b/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx @@ -189,7 +189,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl const submitHandler = async (data: BenefitConfigurationListType) => { const mapData = data.benefit_data.map((item) => ({ ...item, - reason: item.reason.value + reason: item.reason ? item.reason.value : null })); const newData = { From bca43e30309a6ef501232d6740c74d5d26588b04 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Fri, 23 Feb 2024 13:48:36 +0700 Subject: [PATCH 02/34] Claim Management Report --- .../Http/Controllers/Api/ClaimController.php | 290 ++- Modules/Internal/Routes/api.php | 3 + .../dashboard/src/pages/Claims/Detail.tsx | 2099 +++++------------ frontend/dashboard/src/pages/Claims/Index.tsx | 4 +- frontend/dashboard/src/pages/Claims/List.tsx | 674 +++++- frontend/dashboard/src/routes/index.tsx | 2 +- .../sections/dashboard/DialogClaimSubmit.tsx | 2 +- 7 files changed, 1494 insertions(+), 1580 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index f120b1d4..7c358d90 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -21,9 +21,16 @@ use Modules\Internal\Transformers\ClaimEditResource; use Modules\Internal\Transformers\ClaimHistoryCareResource; 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 Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\View; +use Modules\Internal\Transformers\RequestLogResource; + +use App\Models\RequestLog; + use PDF; class ClaimController extends Controller @@ -34,41 +41,257 @@ class ClaimController extends Controller */ public function index(Request $request) { - // $serviceCode = 'IP'; - $claims = Claim::with([ - 'member', - 'member.currentCorporate', - 'member.currentCorporate.currentPolicy', - // 'member.currentPlan' => function($memberPlan) use ($serviceCode) { - // $memberPlan->where('plans.service_code', $serviceCode); - // }, - 'member.currentPlan' => function($memberPlan) { - $memberPlan->join('claim_requests', 'claim_requests.service_code', '=', 'plans.service_code'); - }, - '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 . "%"); - }); + $limit = $request->has('per_page') ? $request->input('per_page') : 10; + $results = DB::table('claims') + ->leftJoin('claim_requests', 'claims.claim_request_id','=', 'claim_requests.id') + ->leftJoin('request_logs', 'claim_requests.request_log_id','=', 'request_logs.id') + ->leftJoin('members', 'request_logs.member_id', '=', 'members.id') + ->when($request->input('search'), function ($query, $search) { + $query->where(function ($query) use ($search) { + $query->orWhere('members.name', 'like', "%" . $search . "%"); }); }) - ->where('status', '!=', 'requested') // Penjagaan agar approve baru masuk ke claim management - ->latest() - ->paginate(10); + ->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('claims.created_at', '>=', $start_date); + }); + }) + ->when($request->input('end_date') , function ($query, $end_date) { + $query->where(function ($query) use ($end_date) { + $query->where('claims.created_at', '<=', $end_date); + }); + }) + ->when($request->input('provider') , function ($query, $provider) { + $query->where(function ($query) use ($provider) { + $query->where('request_logs.organization_id', '=', $provider); + }); + }) + ->select( + 'claims.id', + 'request_logs.id AS id_log', + 'claims.code', + 'members.name', + DB::raw(' + (SELECT members.member_id FROM members WHERE members.id = claims.member_id LIMIT 1) AS member_id + '), + 'claims.created_at', + DB::raw(' + (SELECT plans.code FROM plans WHERE plans.id = claims.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 + '), + 'claims.status', + ) + ->paginate($limit); + - return response()->json($claims); + return response()->json(Helper::paginateResources($results)); + } + + 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('claims') + ->leftJoin('claim_requests', 'claims.claim_request_id','=', 'claim_requests.id') + ->leftJoin('request_logs', 'claim_requests.request_log_id','=', 'request_logs.id') + ->leftJoin('members', 'request_logs.member_id', '=', 'members.id') + ->when($request->input('search'), function ($query, $search) { + $query->where(function ($query) use ($search) { + $query->orWhere('members.name', '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('claims.created_at', '>=', $start_date); + }); + }) + ->when($request->input('end_date') , function ($query, $end_date) { + $query->where(function ($query) use ($end_date) { + $query->where('claims.created_at', '<=', $end_date); + }); + }) + ->when($request->input('provider') , function ($query, $provider) { + $query->where(function ($query) use ($provider) { + $query->where('request_logs.organization_id', '=', $provider); + }); + }) + ->select( + 'claims.id', + 'request_logs.id AS id_log', + 'claims.code', + 'members.name', + DB::raw(' + (SELECT members.member_id FROM members WHERE members.id = claims.member_id LIMIT 1) AS member_id + '), + 'claims.created_at', + DB::raw(' + (SELECT plans.code FROM plans WHERE plans.id = claims.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 + '), + 'claims.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 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('claims') + ->where('claims.id', '=', $id) + ->select('claims.status') + ->first(); + + $data['cek'] = $cek; + + $member = DB::table('claims') + ->join('claim_requests', 'claims.claim_request_id','=', 'claim_requests.id') + ->join('request_logs', 'claim_requests.request_log_id','=', 'request_logs.id') + ->join('members', 'request_logs.member_id', '=', 'members.id') + ->where('claims.id', '=', $id) + ->select('claims.code','members.name','claims.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,7 +557,7 @@ class ClaimController extends Controller 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') @@ -348,7 +571,8 @@ class ClaimController extends Controller ->where('claim_request_id', $id) ->update( [ - 'status' => 'declined' + 'status' => 'declined', + 'reason_decline' => $request->reasonDecline ? $request->reasonDecline : '' ] ); diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index d5f58fda..e29af216 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -235,6 +235,8 @@ Route::prefix('internal')->group(function () { Route::post('claims/{claim_id}/set-final-encounter', [ClaimEncounterController::class, 'setFinalEncounter']); Route::get('claims', [ClaimController::class, 'index']); + 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-diagnosis', [ClaimController::class, 'updateDiagnosis'])->name('claim.update-diagnosis'); Route::post('claims/{id}/decline', [ClaimController::class, 'decline'])->name('claim.decline'); @@ -248,6 +250,7 @@ Route::prefix('internal')->group(function () { Route::post('claims', [ClaimController::class, 'store']); Route::get('claims/{id}', [ClaimController::class, 'show']); + Route::get('claims/cek_status/{id}', [ClaimController::class, 'cekStatus']); Route::put('claims/{id}', [ClaimController::class, 'update']); Route::get('claims/{id}/edit', [ClaimController::class, 'edit']); Route::post('check-limit', [ClaimController::class, 'checkLimit']); diff --git a/frontend/dashboard/src/pages/Claims/Detail.tsx b/frontend/dashboard/src/pages/Claims/Detail.tsx index 28cf2c47..98af659a 100644 --- a/frontend/dashboard/src/pages/Claims/Detail.tsx +++ b/frontend/dashboard/src/pages/Claims/Detail.tsx @@ -1,637 +1,102 @@ -import * as Yup from 'yup'; -// mui import { Container, Grid, Stack, Typography, Card, - TextField, - Divider, - ButtonBase, - Box, + TableRow, + Tab, + TableCell, + Collapse, + AccordionSummary, + AccordionDetails, IconButton, - Autocomplete, - FormControl, - InputLabel, - Select, - FormHelperText, - MenuItem } from '@mui/material'; + TextField + } from '@mui/material'; // components -import Page from '../../components/Page'; +import Page from '@/components/Page'; // utils -import useSettings from '../../hooks/useSettings'; +import useSettings from '@/hooks/useSettings'; // react import { useNavigate, useParams, useLocation } from 'react-router-dom'; import { useEffect, useState, useRef, useMemo } from 'react'; -import axios from '../../utils/axios'; +import axios from '@/utils/axios'; // pages -import { format } from 'date-fns'; import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; -import Button from '@mui/material/Button'; -import AddIcon from '@mui/icons-material/Add'; -import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; -import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'; -import CloseIcon from '@mui/icons-material/Close'; -import FormGroup from '@mui/material/FormGroup'; -import FormControlLabel from '@mui/material/FormControlLabel'; -import Checkbox from '@mui/material/Checkbox'; -import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers'; -import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; -import { fPostFormat } from '@/utils/formatTime'; -import { fDate, fDateTime } from '../../utils/formatTime'; -import ListItemText from '@mui/material/ListItemText'; -import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; -import TableMoreMenu from '@/components/table/TableMoreMenu'; - -import { enqueueSnackbar } from 'notistack'; -import BenefitConfigurationList from './components/BenefitConfigurationList'; -import { map } from 'lodash'; - - -import { FormProvider, RHFDatepicker, RHFSelect, RHFTextField } from '@/components/hook-form'; -import { useFieldArray, useForm } from 'react-hook-form'; -import { ClaimHistoryCare } from '@/@types/claims'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { LoadingButton } from '@mui/lab'; -import { Delete, Edit, EditOffOutlined, EditTwoTone, LoopOutlined, RefreshOutlined } from '@mui/icons-material'; -import { fDateOnly, fDateTimeSuffix } from '@/utils/formatTime'; +import { fDate, fDateTimesecond, fDateTime } from '@/utils/formatTime'; +import { Button } from '@mui/material'; import Label from '@/components/Label'; -import RHFAutocomplete from '../../components/hook-form/RHFAutocompleteV2'; +import { Box } from '@mui/system'; +import { Accordion } from '@mui/material'; +import { Delete, EditOutlined, ExpandMore } from '@mui/icons-material'; +import AddIcon from '@mui/icons-material/Add'; + +import MoreMenu from '@/components/MoreMenu'; +import { MenuItem } from '@mui/material'; +import { fNumber } from '@/utils/formatNumber'; +import palette from '@/theme/palette'; + +import CloseIcon from '@mui/icons-material/Close'; +import { enqueueSnackbar } from 'notistack'; +import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'; + + // ---------------------------------------------------------------------- export default function Detail() { const location = useLocation(); const queryParams = new URLSearchParams(location.search); - const code = queryParams.get('code'); const navigate = useNavigate(); const { themeStretch } = useSettings(); - const [customerData, setCustomerData] = useState(null); - const [documentData, setDocumentData] = useState(null); - const [requestDocumentData, setRequestDocumentData] = useState(null); - const [serviceData, setServiceData] = useState(null); - const [serviceBenefitData, setServiceBenefitData] = useState(null); - const [dataDialog, setDataDialog] = useState(null); + const [requestLog, setRequestLog] = useState(); + const [statusClaim, setStatusClaim] = useState(''); + const [dataMember, setDataMember] = useState(''); + const { id } = useParams(); + const {id_claim} = useParams(); useEffect(() => { axios - .get('/claims/detail/'+id) + .get('customer-service/request/'+id) .then((response) => { - setCustomerData(response.data.data.customer_data); - setDocumentData(response.data.data.documents); - setRequestDocumentData(response.data.data.request_documents); - setServiceData(response.data.data.claim_services); - setServiceBenefitData(response.data.data.claim_service_benefits); - setDataDialog(response.data.data.dialog_submits); + setRequestLog(response.data.data) }) .catch((error) => { console.error(error); }); - getService(); + axios + .get('claims/cek_status/'+id_claim) + .then((response) => { + setStatusClaim(response.data.cek.status); + setDataMember(response.data.member); - }, []); - - function toTitleCase(str: string | null) { - return str.replace(/\w\S*/g, function(txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - }); - } + }) + .catch((error) => { + console.error(error); + }) + }, [id, id_claim]); const style1 = { color: '#919EAB', width: '30%' } + const style3 = { + color: '#919EAB', + width: '35%' + } const style2 = { width: '70%' } const marginBottom1 = { marginBottom: 1, } - - //Request - const [openDialogRequest, setOpenDialogRequest] = useState(false); - const handleCloseDialogRequest = () => { - setOpenDialogRequest(false); + const marginBottom2 = { + marginBottom: 2, } - const [conditionChecked, setConditionChecked] = useState(true); - const [diagnosisChecked, setDiagnosisChecked] = useState(false); - const [supportingResultChecked, setSupportingResultChecked] = useState(false); - - const handleConditionChange = (event) => { - setConditionChecked(event.target.checked); - }; - - const handleDiagnosisChange = (event) => { - setDiagnosisChecked(event.target.checked); - }; - - const handleSupportingResultChange = (event) => { - setSupportingResultChecked(event.target.checked); - }; - - const [noteField, setNoteField] = useState(''); - const [noteFieldError, setNoteFieldError] = useState(''); - const isRequiredFieldsFilled = () => { - return noteField.trim() !== ''; - }; - - const handelRequestDocument = () => { - const dataForm = { - claim_id: id, - condition: conditionChecked, - diagnosis: diagnosisChecked, - result: supportingResultChecked, - note: noteField, - } - axios - .post('/claims/request-documents', dataForm) - .then((response) => { - enqueueSnackbar('Success Request Document', { variant: 'success' }); - setOpenDialogRequest(false); - window.location.reload(); - }) - .catch((error) => { - enqueueSnackbar('Something Went Wrong', { variant: 'error' }); - }) - } - - /*---------------------- Handle History Hospital Care ----------------------------*/ - - interface FormValuesProps extends Partial { - taxes: boolean; - inStock: boolean; - } - - - /**------------- Handle History Hospital Care ---------------------*/ - const [currentClaimHistoryCare, setCurrentClaimHistoryCare] = useState(null); - const [organization, setOrganization] = useState([]); // Untuk Hospital - const [doctor, setDoctor] = useState([]); // Untuk Docter - const [corporate_id, setCorporateId] = useState(null); // Untuk Corporate - const [main_diagnosis, setMainDiagnosis] = useState([]); // Untuk Main diagnosis - const [claimHistoryId,setClaimHistoryId] = useState(null); // Untuk edit Claim History - - const [carehistory, setCarehistory] = useState(null); - const [isEdit,setEdit] = useState(false); - const [service_code, setServiceType] = useState(); - const handleCloseDialogUpdate = () => { - setOpenDialogRequest(false); - reset() - } - - useEffect( () => { - axios - .get('claims/'+id) - .then((response) => { - setCorporateId(response.data.data.corporate_id) - setCurrentClaimHistoryCare(response.data.data.history_hospital_care) - setServiceType(response.data.data.service_code) - - }) - }, [id]) - - useEffect( () => { - // setMainDiagnosis - axios - .get(`corporates/${corporate_id}/diagnosis`) - .then((response) => { - setMainDiagnosis(response.data.data) - }) - - // setOrganization atau hospital atau location - axios - .get(`corporates/${corporate_id}/hospitals`) - .then((response) => { - setOrganization(response.data.data) - }) - - }, [corporate_id]) - - useEffect( () => { - // setCarehistory - if (claimHistoryId != null) { - axios - .get('/claims/carehistory/'+claimHistoryId) - .then((response) => { - reset({ - service_code: response.data.data.service_code, - admission_date: response.data.data.admission_date, - discharge_date: response.data.data.discharge_date, - organization_id: response.data.data.organization_id, - practitioner_id: response.data.data.practitioner_id, - medical_record_number: response.data.data.medical_record_number, - symptoms: response.data.data.symptoms, - sign: response.data.data.sign, - main_diagnosis_id: response.data.data.main_diagnosis_id, - secondary_diagnosis_id: response.data.data.secondary_diagnosis.map((row: any) => ({ - value: { - id: row.id, - name: row.icd.name - } - })) - }); - - setCarehistory(response.data.data); - }) - .catch((error) => { - console.error(error); - }); - // setDoctor atau practioner - axios - .get('/doctors?search=&organization_id='+values.organization_id) - .then((response) => { - setDoctor(response.data.data); - - }) - .catch((error) => { - console.error(error); - }); - - // setMainDiagnosis - axios - .get(`corporates/${corporate_id}/diagnosis`) - .then((response) => { - setMainDiagnosis(response.data.data) - }) - - // setOrganization atau hospital atau location - axios - .get(`corporates/${corporate_id}/hospitals`) - .then((response) => { - setOrganization(response.data.data) - }) - } - - }, [claimHistoryId]) - - useEffect( () => { - reset(defaultValues); - }, [isEdit]) - - - const [openDialogHospitalCare, setOpenHospitalCare] = useState(false); - - const handleCloseDialogHospitalCare = () => { - setEdit(false) - setOpenHospitalCare(false); - setClaimHistoryId(null) - reset(); - } - - const [openDialogApproval, setOpenDialogApproval] = useState(false); - - const handleCloseDialogApprove = () => { - setOpenDialogApproval(false); - setEdit(false) - setClaimHistoryId(null); - reset(); - } - - /* Handle For Approve Claim */ - const handleApproveClaim = (id: number|null, claim_id: number|null) =>{ - // let data = { - // status: 1 - // } - // axios.post(`/claims/carehistory/${id}/approval`, data); - // setOpenDialogApproval(false) - // enqueueSnackbar( - // 'Claim Approve Successfully!', - // { variant: 'success' } - // ); - // window.location.reload(); - - const dataForm = { - status: 1, - claim_id: id - } - axios - .post(`/claims/carehistory/approval`, dataForm) - .then((response) => { - enqueueSnackbar('Claim Approve Successfully!', { variant: 'success' }); - setOpenDialogApproval(false); - window.location.reload(); - }) - .catch((error) => { - enqueueSnackbar('Something Went Wrong', { variant: 'error' }); - }) - - } - - // Handle Location Change - const handleLocationChange = (organization_id:number) => { - // if (newValue) { - const selectedValue = organization_id; - setValue('organization_id', selectedValue); - // let data = { - // ...values, - // practitioner_id: 0 - // } - // reset(data) - - axios - .get('/doctors?search=&organization_id=' + selectedValue) - .then((response) => { - setDoctor(response.data.data); - }) - .catch((error) => { - console.error(error); - }); - // } - } - - const handleDoctorChange = (event, newValue) => { - if (newValue) { - const selectedValue = newValue.id; - setValue('practitioner_id', selectedValue); - } - } - - const handleMainDiagnosisChange = (event, newValue) => { - if (newValue) { - const selectedValue = newValue.id; - setValue('main_diagnosis_id', selectedValue); - } - } - - const defaultValues = useMemo( - () => ({ - service_code: service_code, - secondary_diagnosis_id: [{ - value: { - name: "", - value: 0 - } - }], - admission_date: isEdit ? carehistory?.admission_date : '', - discharge_date: isEdit ? carehistory?.discharge_date : '', - organization_id: isEdit ? carehistory?.organization_id : '', - practitioner_id: isEdit ? carehistory?.practitioner_id : '', - medical_record_number: isEdit ? carehistory?.medical_record_number : '', - symptoms: isEdit ? carehistory?.symptoms : '', - sign: isEdit ? carehistory?.sign : '', - main_diagnosis_id: isEdit ? carehistory?.main_diagnosis_id : 0, - }), - [service_code] - ) - - let NewClaimHistoryCareSchema = Yup.object().shape({ - service_code: Yup.string().required('Name is required'), - // admission_date: Yup.date().required('Admisision Date is required'), - // discharge_date: Yup.date().required('Discharge Date is required'), - // organization_id: Yup.number().required('Location is required'), - // practitioner_id: Yup.number().required('Doctor is required'), - // medical_record_number: Yup.string().required('Medical Record is required'), - // symptoms: Yup.string().required('Symptoms is required'), - // sign: Yup.string().required('Sign is required'), - // main_diagnosis_id: Yup.number().required('Main Diagnosis is required'), - }); - - const methods = useForm({ - resolver: yupResolver(NewClaimHistoryCareSchema), - defaultValues, - }); - - const { - reset, - watch, - control, - setValue, - getValues, - setError, - handleSubmit, - resetField, - formState: { isSubmitting }, - } = methods; - - const values = watch(); - const valueOfLocation = organization.find((row) => row.organization_id === values.organization_id) - - const {fields, append, remove} = useFieldArray({name: "secondary_diagnosis_id", control}) - - const onSubmit = async (data: FormValuesProps) => { - if (isEdit){ - let newData = { - service_code: data.service_code, - admission_date: data.admission_date ? fDateOnly(data.admission_date) : null, - discharge_date: data.discharge_date ? fDateOnly(data.discharge_date) : null, - organization_id: data.organization_id, - practitioner_id: data.practitioner_id, - medical_record_number: data.medical_record_number, - symptoms: data.symptoms, - sign: data.sign, - secondary_diagnosis_id: data.secondary_diagnosis_id ? data.secondary_diagnosis_id.map((row) => row.value.id) : null, - main_diagnosis_id: data.main_diagnosis_id, - } - - const response:any = await axios.post(`/claims/carehistory/${claimHistoryId}/update`, newData); - // if (response.status == 'success'){ - setOpenHospitalCare(false) - enqueueSnackbar( - 'Claim Update Successfully!', - { variant: 'success' } - ); - navigate('/claims/detail/'+id); - window.location.reload(); - - // } - } else { - let newData = { - service_code: data.service_code, - admission_date: data.admission_date ? fDateOnly(data.admission_date) : null, - discharge_date: data.discharge_date ? fDateOnly(data.discharge_date) : null, - organization_id: data.organization_id, - practitioner_id: data.practitioner_id, - medical_record_number: data.medical_record_number, - symptoms: data.symptoms, - sign: data.sign, - secondary_diagnosis_id: data.secondary_diagnosis_id ? data.secondary_diagnosis_id.map((row) => row.value.id) : null, - main_diagnosis_id: data.main_diagnosis_id, - - } - - - const response:any = await axios.post(`/claims/${id}/carehistory`, newData); - // if (response.status == 'success'){ - setOpenHospitalCare(false) - enqueueSnackbar( - 'Claim Insert Successfully!', - { variant: 'success' } - ); - navigate('/claims/detail/'+id); - window.location.reload(); - // } - - } - - reset(); - } - - function secondaryDiagnosisOption() { - return fields.map((item, index) => { - return ( - - {`#${index+1}`} - - - opt.name} - isOptionEqualToValue={(opt, val) => opt.name === val.name} - label='Comparative Diagnosis (ICD-X)' - /> - - remove(index)}> - - - - - ) - }) - } - - function handleNewHospitalCare() { - setEdit(false); - setOpenHospitalCare(true); - reset(defaultValues); - } - - function handleEditHospitalCare(id: number) { - setClaimHistoryId(id); - setEdit(true); - setOpenHospitalCare(true); - reset(defaultValues); - } - - function handleUpdateHospitalCare(id: number) { - setOpenHospitalCare(false); - setClaimHistoryId(id); - setEdit(false); - setOpenDialogApproval(true); - } - - //Service - const [openDialogService, setOpenDialogService] = useState(false); - const handleCloseDialogService = () => { - setOpenDialogService(false); - } - const handleConditionChangeService = (event) => { - const selectedItem = event.target.value; - - if (valBenefitNames.includes(selectedItem)) { - // Item is already selected, remove it - setValBenefitNames(valBenefitNames.filter(item => item !== selectedItem)); - } else { - // Item is not selected, add it - setValBenefitNames([...valBenefitNames, selectedItem]); - } - }; - - //Data - const [serviceTypeData, setServiceTypeData] = useState(null); - const [benefitNameData, setBenefitNameData] = useState(null); - const [hospitalData, setHospitalData] = useState(null); - //Field - const currentDate = new Date(); - const formattedCurrentDate = format(currentDate, 'dd MMM yyyy'); - //Date Addmissions - const [dateAd, setDateAd] = useState(currentDate); - //Date Discharge - const [dateDis, setDateDis] = useState(currentDate); - //Service Type - const [valServiceType, setValServiceType] = useState(''); - const [valServiceTypeError, setValServiceTypeError] = useState(''); - //Benefit Name - const [valBenefitNames, setValBenefitNames] = useState([]); - const [valBenefitNameError, setValBenefitNameError] = useState(''); - //Hospital - const [valHospital, setValHospital] = useState(''); - const [valHospitalError, setValHospitalError] = useState(''); - //txt name - const [txtName, setTxtName] = useState('Add Service'); - //flag add or edit service - const [flagAddService, setFlagAddService] = useState('add'); - //id claim_services - const [idService, setIdService] = useState(null); - - - const isRequiredFieldsServiceType = () => { - return dateAd !== '' && dateDis !== '' && valServiceType !== '' && valBenefitNames.length > 0 && valHospital !== ''; - }; - - const getService = async () => { - try { - const response = await axios.get('/claims/get-services/' + id); - setServiceTypeData(response.data.data.service_type); - setValServiceType(response.data.data.service_type[0].id); - setBenefitNameData(response.data.data.benefit_name); - setHospitalData(response.data.data.hospital); - await Promise.all([ - setServiceTypeData(response.data.data.service_type), - setBenefitNameData(response.data.data.benefit_name), - setHospitalData(response.data.data.hospital), - ]); - - } catch (error) { - } - } - - - const handleAddService = async () => { - setTxtName('Add Service'); - setFlagAddService('add'); - setOpenDialogService(true); - } - - const handleEditService = async () => { - setDateAd(serviceData.addmission_date); - setDateDis(serviceData.discharge_date); - setIdService(serviceData.id); - - setOpenDialogService(true); - setTxtName('Edit Service'); - setFlagAddService('edit'); - - if (serviceTypeData) { - setValServiceType(serviceData.service_id); - setValHospital(serviceData.hospital_id); - setValBenefitNames(serviceBenefitData.benefit_id); - } - } - - const handelSaveServiceType = () => { - const dateAdd = dateAd ? fPostFormat(dateAd, 'yyyy-MM-dd') : null; - const dateDisc = dateDis ? fPostFormat(dateDis, 'yyyy-MM-dd') : null; - const data = { - flagAddService : flagAddService, - idService: idService, - claim_request_id: id, - dateAdd : dateAdd, - dateDisc : dateDisc, - serviceType : valServiceType, - benefitName : valBenefitNames, - hospital : valHospital - }; - axios - .post('/claims/save-services', data) - .then((response) => { - enqueueSnackbar('Success '+(flagAddService == 'add' ? 'Add' : 'Edit')+' Service', { variant: 'success' }); - handleCloseDialogService(); - window.location.reload(); - }) - .catch((error) => { - enqueueSnackbar('Something Went Wrong', { variant: 'error' }); - }) - } - - const [openDialogSubmit, setOpenDialogSubmit] = useState(false); const handleCloseDialogSubmit = () => { setOpenDialogSubmit(false); } @@ -640,12 +105,17 @@ export default function Detail() { const handleSubmitData = () => { //approve or decline + if(!reasonDecline && approve == 'decline') + { + enqueueSnackbar('Mohon isi alasan', { variant: 'warning' }); + return false; + } axios - .post('claims/'+id+'/'+decline) + .post('claims/'+id_claim+'/'+approve, {reasonDecline:reasonDecline}) .then((response) => { - enqueueSnackbar('Success '+toTitleCase(decline)+' Claim Request', { variant: 'success' }); + enqueueSnackbar('Success '+toTitleCase(approve)+' Claim Request', { variant: 'success' }); setOpenDialogSubmit(false); - window.location.reload(); + // window.location.reload(); }) .catch(({ response }) => { @@ -659,911 +129,590 @@ export default function Detail() { }; - const handelDownloadLog = () => { - axios - .get(`final-log/${id}`, { - responseType: 'blob', - }) - .then((response) => { - window.open(URL.createObjectURL(response.data)); - }) - .catch((response) => { - enqueueSnackbar(response.message, { variant: 'error' }); + function toTitleCase(str: string | null) { + return str.replace(/\w\S*/g, function(txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } + const [reasonDecline, setReasonDecline] = useState(''); + + const handleReasonDeclineChange = (event) => { + setReasonDecline(event.target.value); + // Tambahkan logika yang diperlukan di sini + }; + + const [openDialogSubmit, setOpenDialogSubmit] = useState(false); + const [openDialogEditDetail, setDialogDEditDetail] = useState(false); + const [openDialogBenefit, setDialogBenefit] = useState(false); + const [openDialogMedicine, setDialogMedicine] = useState(false); + + // Handel Delete Detail Benefit + const [idBenefitData, setIdBenefitData] = useState(); + const [openDialogDeleteBenefit, setDialogDeleteBenefit] = useState(false) + + const [idMedicineData, setIdMedicineData] = useState(); + const [openDialogDeleteMedicine, setDialogDeleteMedicine] = useState(false) + + const [approve, setApprove] = useState('') + + // Handle Edit Detail Benefit + const [openDialogEditBenefit, setDialogEditBenefit] = useState(false) + const [BenefitConfigurationData, setBenefitConfigurationData] = useState(); + + // Buat total data + const totalAmountIncurred = (requestLog?.benefit_data || []).reduce((accumulator, item) => { + return accumulator + (item.amount_incurred || 0); + }, 0); + const totalAmountApprove = (requestLog?.benefit_data || []).reduce((accumulator, item) => { + return accumulator + (item.amount_approved || 0); + }, 0); + const totalAmountNotApprove = (requestLog?.benefit_data || []).reduce((accumulator, item) => { + return accumulator + (item.amount_not_approved || 0); + }, 0); + const totalExcessPaid = (requestLog?.benefit_data || []).reduce((accumulator, item) => { + return accumulator + (item.excess_paid || 0); + }, 0); + + // Handle Delete File LOG + const [pathFile, setPathFile] = useState('') + const [dialogDeleteFIleLog, setDialogDeleteFileLog] = useState(false) + + // Handle Upload File LOG + const [dialogUploadFileLog, setDialogUploadFileLog] = useState(false) + return ( navigate(-1)} sx={{cursor:'pointer'}}/> - {(customerData && customerData.code ? customerData.code : '')} - {customerData ? ( - - - Status - {(customerData && customerData.status) ? toTitleCase(customerData.status) : ''} - - - Submission Date - {(customerData && customerData.submission_date) ? format(new Date(customerData.submission_date), "d MMM yyyy") : ''} - - - ) : ''} + {(requestLog && requestLog.code ? requestLog.code : '')} - {customerData ? ( + {/* Detail */} - - Summary of Customer Data - - Full Name - {customerData.name} - - - Policy Number - {customerData.payor_id} - - - Member ID - {customerData.member_id} - - - Claim Type - {toTitleCase(customerData.payment_type)} - - - Corporate Name - {toTitleCase(customerData.coporate_name)} - - - - ) : ''} - {documentData ? ( - - - {customerData?.status === 'received' ? ( - - Additional Documents - - - ) : ''} - - {documentData?.map((documentType, index) => ( - - - {documentType.type === 'claim-diagnosis' ? - 'Diagnosis' - : documentType.type === 'claim-kondisi' ? - 'Condition' - : documentType.type === 'claim-result' ? - 'Supporting Result' - : documentType.type === 'claim-invoice' ? - 'Invoice' - : ''} - - - - - {documentType.original_name ? documentType.original_name : '-'} - - - - ))} - - {requestDocumentData && requestDocumentData.length > 0 ? ( - Request Documents - ) : ''} - - {requestDocumentData?.map((documentType, index) => ( - - - - - - {documentType.type === 'claim-diagnosis' ? - 'Diagnosis' - : documentType.type === 'claim-kondisi' ? - 'Condition' - : documentType.type === 'claim-result' ? - 'Supporting Result' - : documentType.type === 'claim-invoice' ? - 'Invoice' - : ''} - - - - ))} - - {/* Dialog Request Documents */} - - - - - Request Document - - - - - - - - - - } - label="Condition Document" - /> - } - label="Diagnosis Document" - /> - } - label="Supporting Result Document" - /> - - - Notes* + + + + + Detail - { - setNoteField(e.target.value); - setNoteFieldError(e.target.value.trim() === '' ? 'This field is required' : ''); - }} - fullWidth - inputProps={{ maxLength: 50 }} - error={!!noteFieldError} - helperText={noteFieldError} - /> - - - - - - - - - - ): ''} - - - - - History of Hospital Care - {customerData?.status === 'received' ? ( - - ) : ''} - - - - {currentClaimHistoryCare?.map((claimHistoryCare, index) => - claimHistoryCare.status === 0 ? ( - {/* Tambahkan key untuk setiap elemen dalam loop */} - - {customerData?.status === 'received' ? ( - - - - handleEditHospitalCare(claimHistoryCare.id)}> - Edit - - handleUpdateHospitalCare(claimHistoryCare.id)}> - Update Status - - - }/> - - ) : ''} - - Admission Date : - { fDate(claimHistoryCare.admission_date)} {/* Perbaikan typo di 'admission_date' */} - - - Discharge Date : - { fDate(claimHistoryCare.discharge_date)} - - - Location : - {toTitleCase(claimHistoryCare.organization?.name)} - - - Doctor : - {toTitleCase(claimHistoryCare.practitioner?.code)} - {claimHistoryCare.person?.name} - - - Status : - {claimHistoryCare.status == 0 ? 'Pending' : 'Approv'} - - - Diagnosis : - #{index+1} {claimHistoryCare.icd?.code} - {claimHistoryCare.icd?.name} - - - - ) : null - )} - - - {/* Dialog for input and update */} - - - - - {isEdit ? 'Update' : 'Add'} History of Hospital Care - - - - - - - - - - - - Service Code - - - - - - - Admission Date* - - - - Discharge Date* - - - {/* Location */} - - Location* - { - return option.name ?? false - }} - isOptionEqualToValue={(option, value) =>{ - return option.organization_id == value.organization_id - }} - - onChange={(e, selectedOption) => { - if (selectedOption) { - const selectedOrganizationId = selectedOption.organization_id; - handleLocationChange(selectedOrganizationId); - } - }} - // value={organization.find(row => row.organization_id == values.organization_id)} - value={valueOfLocation ?? null} - - renderInput={(params) => ( - - )} - /> - - - {/* Dokter */} - - Doctor* - { - return option.name ?? false - }} - isOptionEqualToValue={(option, value) =>{ - return option.id === value.id - }} - - value={doctor.find(row => row.id == values.practitioner_id) ?? null} - - onChange={handleDoctorChange} - renderInput={(params) => ( - - )} - /> - - - - - Medical Record Number* - - - - Symptoms* - - - - Sign* - - - - Diagnosis* - - - {/* - - {/* Main Diagnosis */} - - { - return option.name ?? false - }} - isOptionEqualToValue={(option, value) =>{ - return option.id == value.main_diagnosis_id - }} - value={main_diagnosis.find(row => row.id == values.main_diagnosis_id) ?? null} - onChange={handleMainDiagnosisChange} - renderInput={(params) => ( - - )} - /> - - - - {secondaryDiagnosisOption()} - - - - - - - - - {isEdit ? 'Update' : 'Save'} - - - - - - - - - - - - {/* Dialog for approval */} - - - - - Add History of Hospital Care - - - - - - - - - - Are you sure to approve this hospital care ? - - - - - Admission Date - { carehistory ? fDate(carehistory?.admission_date) : '-'} - - - Discharge Date - {carehistory ? fDate(carehistory.discharge_date) : '-'} - - - Location - { carehistory ? carehistory.organization_name : '-'} - - - Doctor - {carehistory ? carehistory.practitioner_name : '-'} - - - Diagnosis - {carehistory ? carehistory?.main_diagnosis_name : '-'} - - - - - - - - - - - - - - - - - - - - - - - - Diagnostic History - - - {currentClaimHistoryCare?.map((claimHistoryCare, index) => - claimHistoryCare.status === 1 ? ( - {/* Tambahkan key untuk setiap elemen dalam loop */} - - - - - - Admission Date : - { fDate(claimHistoryCare.admission_date)} {/* Perbaikan typo di 'admission_date' */} - - - Discharge Date : - { fDate(claimHistoryCare.discharge_date)} - - - Location : - {toTitleCase(claimHistoryCare.organization?.name)} - - - Doctor : - {toTitleCase(claimHistoryCare.practitioner?.code)} - {claimHistoryCare.person?.name} - - - Status : - {claimHistoryCare.status == 0 ? 'Pending' : 'Approv'} - - - Diagnosis : - #{index+1} {claimHistoryCare.icd?.code} - {claimHistoryCare.icd?.name} - - - - ) : null - )} - - - - - - - Diagnosis Summary - - - {currentClaimHistoryCare?.map((claimHistoryCare, index) => - claimHistoryCare.status === 1 ? ( - {/* Tambahkan key untuk setiap elemen dalam loop */} - - - Symtomps : - { claimHistoryCare.symptoms} {/* Perbaikan typo di 'admission_date' */} - - - Sign : - { claimHistoryCare.sign} - - - Main Diagnosis : - {claimHistoryCare.icd?.name} - - - {/* {claimHistoryCare.comparative_diagnosis?.map((comparativeDiagnosis, i) => - ( - - {i == 0 ? 'Comparative Diagnosis :' : ''} - {comparativeDiagnosis.icd?.name} - - ) - )} */} - - {claimHistoryCare.comparative_diagnosis && claimHistoryCare.comparative_diagnosis.length > 0 && ( - claimHistoryCare.comparative_diagnosis.map((comparativeDiagnosis, i) => ( - - - {i === 0 ? 'Comparative Diagnosis :' : ''} - - - {comparativeDiagnosis.icd?.name} - - - )) - )} - - - - - ) : null - )} - - - - - - - Service - {!serviceData && customerData?.status === 'received' ? ( - - ) : ( - - {customerData?.status === 'received' ? ( - - handleEditService()}> - - Edit - - - } - /> - ) : ''} - - )} - - {serviceData ? ( - <> - - Admission Date - {serviceData && serviceData.addmission_date ? fDateTime(serviceData.addmission_date) : ''} - - - Discharge Date - {serviceData && serviceData.discharge_date ? fDateTime(serviceData.discharge_date) : ''} - - - Serice Type - {serviceData && serviceData.name_services ? serviceData.name_services : ''} - - - Benefit Name - {serviceBenefitData && serviceBenefitData.name_benefits ? serviceBenefitData.name_benefits : ''} - - - Hospital - {serviceData && serviceData.name_hospitals ? serviceData.name_hospitals : ''} - - - ): ''} - - {/* Dialog Service */} - - - - - {txtName} - - - - - - - - - - - - Admission Date* - - - { - setDateAd(newValue); - }} - inputFormat="dd MMM yyyy" - renderInput={(params) => } - /> - - - - - Discharge Date* - - - { - setDateDis(newValue); - }} - inputFormat="dd MMM yyyy" - renderInput={(params) => } - /> - - - - - - Service Type* - - - Service Type - - - {valServiceTypeError} - - - - - - Benefit Name* - - - Benefit Name - - - {valBenefitNameError} - - - - - - Hospital* - - - Hospital - - - {valHospitalError} - - - - - - - - - - - - - - - - {/* title */} - - Client Benefit Configuration - - {/* no benefit selected */} - { - false - ? - ( - - Tidak ada benefit yang dipilih - - ) - : - ( - - - - ) - } + {requestLog?.status_final_log != 'requested' ? ( + + + { + setDialogDEditDetail(true) + }}> + + Edit + + + } + /> + ) : null } + + + Provider + {requestLog?.provider} + + + Member ID + {requestLog?.member_id} + + + Policy Number + {requestLog?.policy_number} + + + Name + {requestLog?.name} + + + Date Of Birth + {requestLog?.date_of_birth ? fDate(requestLog?.date_of_birth) : '-'} + + + Marital Status + {requestLog?.marital_status} + + + Submission Date + {requestLog?.submission_date ? fDateTimesecond(requestLog?.submission_date) : '-'} + + + Admission Date + {requestLog?.admission_date ? fDateTimesecond(requestLog?.admission_date) : '-'} + + + + Discharge Date + {requestLog?.discharge_date ? fDateTimesecond(requestLog?.discharge_date) : '-'} + + + + No KTP + {requestLog?.no_identitas ? requestLog?.no_identitas : '-'} + + + Keterangan + {requestLog?.keterangan ? requestLog?.keterangan : '-'} + + + Hak Kamar Pasien + {requestLog?.hak_kamar_pasien ? requestLog?.hak_kamar_pasien : '-'} + + + Penempatan Kamar + {requestLog?.penempatan_kamar ? requestLog?.penempatan_kamar : '-'} + + + Catatan + {requestLog?.catatan ? requestLog?.catatan : '-'} + + + Diagnosis + + {requestLog?.diagnosis?.length > 0 ? ( +
    + {requestLog.diagnosis.map((diagnosisItem, index) => ( +
  • {diagnosisItem.code} - {diagnosisItem.name}
  • + // Replace 'name' with the property you want to display + ))} +
+ ) : ( +

No diagnosis available.

+ )} +
+
+ {/* */}
- - - <> - {(customerData && customerData.status === 'received') ? ( - <> - - - - ) : ( - <> - - - - - - ) } - - {/* Dialog Submits */} - - - - - Confirmation - - - - - - - - {dataDialog ? ( - - Are you sure to {toTitleCase(decline)} this claim ? - - - Code - {dataDialog.code} - - - Name - {dataDialog.name} - - - Date Submission - {fDateTime(dataDialog.submission_date)} - - - Claim Method - Service Type - - - Service Type - - {dataDialog.service_code === 'IP' ? 'Inpatient' : 'Outpatient'} - - - - - ) : ''} - - - - - - - + {/* Service */} + + {/* + */} + + {/* Exclusion */} + + {/* + */} + + + {/* Benefit */} + + + + Benefit + + + + {requestLog?.benefit_data?.map((item, index) => ( + + + + + + + {item.benefit?.description} + + + + + { + setDialogEditBenefit(true) + setIdBenefitData(item.id) + setBenefitConfigurationData(item) + }} + > + + Edit + + { + setIdBenefitData(item.id) + setDialogDeleteBenefit(true) + }} + > + + Delete + + + } /> + + + + + + + + {/* Amount Incurred */} + + + + + Amount Incurred + + + + + {fNumber(item.amount_incurred)} + + + + + + {/* Amount Approved */} + + + + + Amount Approved + + + + + {fNumber(item.amount_approved)} + + + + + + {/* Amount Not Approved */} + + + + + Amount Not Approved + + + + + {fNumber(item.amount_not_approved)} + + + + + + {/* Excess Paid* */} + + + + + Excess Paid* + + + + + {fNumber(item.excess_paid)} + + + + + + {/* Keterangan* */} + + + + + Keterangan* + + + + + {item.keterangan} + + + + + + + + + + + + ))} +
+
+ {requestLog?.benefit_data && requestLog.benefit_data.length > 0 ? ( + + + + + + + Total Benefit + + + + + + + + + + {/* Amount Incurred */} + + + + + Amount Incurred + + + + + {fNumber(totalAmountIncurred)} + + + + + + {/* Amount Approved */} + + + + + Amount Approved + + + + + {fNumber(totalAmountApprove)} + + + + + + {/* Amount Not Approved */} + + + + + Amount Not Approved + + + + + {fNumber(totalAmountNotApprove)} + + + + + + {/* Excess Paid* */} + + + + + Excess Paid + + + + + {fNumber(totalExcessPaid)} + + + + + + + + + + + ) + : ( + null + )} +
+ + {/* PR Buat pindahin ke componen */} + {/* + + */} + +
+ + {/* Medicine */} + + + + Medicine + + + + {requestLog?.medicine.map((item, index) => ( + + {item.medicine} + Rp. {fNumber(item.price)} + { + setIdMedicineData(item.id) + setDialogDeleteMedicine(true) + }}> + + + + + ))} + + + + + + {/* File */} + + + + + Files + + + + + + {requestLog?.files?.map((documentType, index) => ( + + + + {documentType.original_name ? documentType.original_name : '-'} + + + + + + + ))} + + + + + + {statusClaim == 'requested' ? ( + + + + <> +
+ +
+
+ +
+ + +
+ {/* Dialog Submits */} + + + + + Confirmation + + + + + + + + + + Are you sure to {toTitleCase(approve)} this claim ? + + + Code + {dataMember?.code} + + + Name + {dataMember?.name} + + + Date Submission + {dataMember?.created_at ? fDateTime(dataMember?.created_at) : ''} + + + Claim Method + Service Type + + + Service Type + + {dataMember?.service_type} + + + {approve == "decline" ? ( + + + + ): ''} + + + + + + + + +
+
+ ) : null} +
); -} +} \ No newline at end of file diff --git a/frontend/dashboard/src/pages/Claims/Index.tsx b/frontend/dashboard/src/pages/Claims/Index.tsx index 5fc6d983..78214d1e 100644 --- a/frontend/dashboard/src/pages/Claims/Index.tsx +++ b/frontend/dashboard/src/pages/Claims/Index.tsx @@ -7,7 +7,7 @@ import List from "./List"; export default function Claims() { - const pageTitle = 'Claim'; + const pageTitle = 'Claim Management'; return ( @@ -16,7 +16,7 @@ export default function Claims() { links={[ { name: 'Dashboard', href: '/dashboard' }, { - name: 'Claim', + name: 'Claim Management', href: '/claims', }, ]} diff --git a/frontend/dashboard/src/pages/Claims/List.tsx b/frontend/dashboard/src/pages/Claims/List.tsx index 5e1d01fd..06791385 100644 --- a/frontend/dashboard/src/pages/Claims/List.tsx +++ b/frontend/dashboard/src/pages/Claims/List.tsx @@ -1,6 +1,7 @@ // @mui import { Box, + Grid, Button, Card, Collapse, @@ -17,12 +18,24 @@ import { ButtonGroup, Tooltip, TableHead, + Checkbox, + InputAdornment, + TableSortLabel, + FormControl } 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 AssessmentIcon from '@mui/icons-material/Assessment'; // hooks import React, { ChangeEvent, useEffect, useRef, useState } from 'react'; import { Link, Navigate, useNavigate, useSearchParams } from 'react-router-dom'; + +import { LoadingButton } from '@mui/lab'; // components import axios from '../../utils/axios'; import { LaravelPaginatedData, LaravelPaginatedDataDefault } from '../../@types/paginated-data'; @@ -32,23 +45,146 @@ import EditRoundedIcon from '@mui/icons-material/EditRounded'; import { Chip } from '@mui/material'; import Iconify from '@/components/Iconify'; import { enqueueSnackbar } from 'notistack'; -import { fDate } from '../../utils/formatTime'; +import { fDate, fDateTime } from '../../utils/formatTime'; import { Claims } from '@/@types/claims'; import Label from '@/components/Label'; import { capitalizeFirstLetter } from '@/utils/formatString'; import TableMoreMenu from '@/components/table/TableMoreMenu'; import Edit from '@mui/icons-material/Edit'; 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() { + const [selectAll, setSelectAll] = useState(false); + const [selectedRows, setSelectedRows] = useState([]); + const [providers, setProviders] = useState(null); + // const [searchText, setSearchText] = useState(''); + const [order, setOrder] = useState('desc'); + const [orderBy, setOrderBy] = useState('created_at'); + const [perPage, setPerPage] = useState(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 === 'requested') // 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 [importResult, setImportResult] = useState(null); + const [startDate, setStartDate] = useState(null); + const [searchText, setSearchText] = useState(''); + const [endDate, setEndDate] = useState(null); 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) { // SEARCH const searchInput = useRef(null); - const [searchText, setSearchText] = useState(''); + + const handleSearchChange = (event: any) => { const newSearchText = event.target.value ?? ''; @@ -73,7 +209,7 @@ export default function List() { useEffect(() => { // Trigger First Search - setSearchText(searchParams.get('search') ?? ''); + // setSearchText(searchParams.get('search') ?? ''); }, []); return ( @@ -126,41 +262,232 @@ export default function List() { ); } + const searchInput = useRef(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 const [dataTableIsLoading, setDataTableLoading] = useState(true); const [dataTableData, setDataTableData] = useState( LaravelPaginatedDataDefault ); + + const loadDataTableData = async (appliedFilter: any | null = null) => { 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 response = await axios.get('/claims', { params: filter }); - // console.log(response.data); + const response = await axios.get('/claims', { + params: { + search: searchText, + start_date: formattedDate ? formattedDate : null, + end_date:formattedDate1, + provider: dataProvider, + order: order, + orderBy: orderBy, + page: perPage, + } + }); + setDataTableLoading(false); setDataTableData(response.data); }; + const getProvider = async () => { + const response = await axios.get('/claims/get-provider'); + setProviders(response.data) + } + const applyFilter = async (searchFilter: { search: string }) => { await loadDataTableData(searchFilter); setSearchParams(searchFilter); }; - + const handlePageChange = (event: ChangeEvent, value: number): void => { - const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]); - loadDataTableData(filter); - setSearchParams(filter); + setPerPage(value); }; - useEffect(() => { - loadDataTableData(); - }, []); + const [openDialogSubmit, setOpenDialogSubmit] = useState(false); + 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 }); + } + + + // useEffect(() => { + // loadDataTableData(); + // getProvider(); + // }, []); const headStyle = { 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) => { + handleRequestSort(event, property); + }; + const handleRequestSort = async (event: React.MouseEvent, 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 function createData(data: Claims): Claims { return { @@ -171,10 +498,18 @@ export default function List() { { /* ------------------ TABLE ROW ------------------ */ } - function Row(props: { row: ReturnType }) { - const { row } = props; + function Row(props: { row: ReturnType, isSelected: boolean, onSelect: (id: string) => void }) { + 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 test = 1000; + return ( *': { borderBottom: 'unset' } }}> @@ -183,16 +518,22 @@ export default function List() { {open ? : } */} - {row.claim_request?.code} + + {row?.status == 'requested' ? ( + + ):''} + + {row?.code} {/* {row.code} */} - {row.member?.current_plan?.code} - {row.member?.current_corporate?.payor_id} - {row.member?.current_corporate?.code} - {row.member?.current_corporate?.current_policy?.code} - {row.member?.member_id} - {row.benefit_desc} - - + {row?.name} + {row?.member_id} + {row?.created_at ? fDateTime(row?.created_at) : ''} + {row?.plan_code} + {row?.service_code} + {row?.corporate_policies} + {row?.provider} + Rp. {row?.tot_bill?.toLocaleString('id-ID')} + {row.status == 'draft' && ()} {row.status == 'requested' && ()} {row.status == 'received' && ()} @@ -202,18 +543,17 @@ export default function List() { {row.status == 'declined' && ()} - - navigate(`/claims/edit/${row.id}`) }> - - Edit - - navigate('/claims/detail/'+row.id+'') }> - - Detail - - - } /> + + + navigate('/claims/detail/'+row.id_log+'/'+row.id+'') }> + + Detail + + + } /> + + @@ -236,40 +576,77 @@ export default function List() { /* ------------------ END TABLE ROW ------------------ */ } + + function TableContent() { return ( {/* ------------------ TABLE HEADER ------------------ */} - {/* */} - - Code - - - Plan ID - - - Payor ID - - - Corporate ID - - - Policy Number - - - Member ID - - - Benefit Desc - - - Status - - - - + {selectedRows.length > 0 ? ( + <> + + + + {selectedRows.length > 0 ? selectedRows.length : '0'}  Selected + + + + + + + + + + + + + + ) : ( + <> + + + + {headCells && + headCells.map((headCell, index) => ( + + {headCell.isSort ? ( + + {headCell.label} + {orders?.orderBy === headCell.id ? ( + + {orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'} + + ) : null} + + ) : ( + headCell.label + )} + + ))} + + + )} + + {/* ------------------ END TABLE HEADER ------------------ */} @@ -278,7 +655,7 @@ export default function List() { {dataTableIsLoading ? ( - + Loading @@ -286,7 +663,7 @@ export default function List() { ) : dataTableData.data.length === 0 ? ( - + No Data @@ -294,7 +671,7 @@ export default function List() { ) : ( {dataTableData.data.map((row) => ( - + ))} )} @@ -305,7 +682,131 @@ export default function List() { return ( - + + +
+ + + { + if (event.key === 'Enter') { + handleSearchSubmit(event); + } + }} + InputProps={{ + startAdornment: ( + + + + ), + placeholder: 'Search Code or Name', + }} + /> + + + + { + + // loadDataTableData(); + setStartDate(value); + }} + renderInput={(params) => } + /> + + + + { + setEndDate(value); + }} + renderInput={(params) => ( + + )} + /> + + + + { + providers && ( + option.name || ''} + value={providers.find((item) => item.id === dataProvider) || null} + onChange={(event, value) => { + if (value) { + setDataProvider(value.id); + } else { + setDataProvider(null); + } + }} + renderInput={(params) => ( + + )} + /> + ) + } + + + + } + sx={{ p: 1.8 }} + // onClick={handleExportReport} + loading={isLoadingImport} + > + + Import + + + + + } + sx={{ p: 1.8 }} + onClick={handleExportReport} + loading={isLoading} + > + + Export + + + + + + +
+
} /> + + + + + Confirmation + + + + + + + + + + Are you sure to {toTitleCase(approve)} this claim ? + {approve == "decline" ? ( + + + + ): ''} + + + + + + +
); } diff --git a/frontend/dashboard/src/routes/index.tsx b/frontend/dashboard/src/routes/index.tsx index 0859ba78..23c0a50c 100644 --- a/frontend/dashboard/src/routes/index.tsx +++ b/frontend/dashboard/src/routes/index.tsx @@ -456,7 +456,7 @@ export default function Router() { element: , }, { - path: 'claims/detail/:id', + path: 'claims/detail/:id/:id_claim', element: , }, { diff --git a/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx b/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx index 914fa652..575a8053 100644 --- a/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx @@ -76,7 +76,7 @@ export default function DialogClaimSubmit({ member, getData, onClose, handleSubm From 1af8e0d27d2463eedf8a589dcdb1a18d361934e0 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 23 Feb 2024 14:53:19 +0700 Subject: [PATCH 03/34] update penjagaan --- .../FinalLog/Components/DialogBenefit.tsx | 95 +++++++++++-------- .../FinalLog/Components/DialogEditBenefit.tsx | 61 ++++++++---- 2 files changed, 97 insertions(+), 59 deletions(-) diff --git a/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx b/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx index 9e0d9f6b..b7855726 100644 --- a/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx +++ b/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogBenefit.tsx @@ -145,45 +145,56 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl const methods = useForm({ resolver: yupResolver(validationSchema), - defaultValues + defaultValues, + reValidateMode: "onChange" }); let width = claimInput ? 2 : 2.36; - const {fields, append, remove} = useFieldArray({name: 'benefit_data',control: methods.control}); - const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods - - // Buat total data - let totalAmountIncurred = (requestLog?.benefit_data || []).reduce((accumulator, item) => { - 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 {fields, append, remove} = useFieldArray({name: 'benefit_data',control: methods.control,}); + const { handleSubmit, reset, watch, setValue, setError, clearErrors, formState: { isDirty, isSubmitting, errors,isValid } } = methods + + const errorsExist = errors ? Object.keys(errors).length > 0 : false; + // Calculate const benefitData = watch('benefit_data'); - const [isDisableSave, setDisableSave] = useState(false) - - benefitData?.map((item, index) => { - totalAmountIncurred += parseFloat(item.amount_incurred); - totalAmountApproved += parseFloat(item.amount_approved); - totalAmountNotApproved += parseFloat(item.amount_not_approved); - totalExcessPaid += parseFloat(item.excess_paid); + const totalAll = () => { + let totalAmountIncurred = (requestLog?.benefit_data || []).reduce((accumulator, item) => { + 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); - if (totalAmountApproved != 0 && totalAmountIncurred != 0) { - if (totalAmountApproved > totalAmountIncurred){ - setValue(`benefit_data.${index}.amount_approved`, 0) - alert('Total Amount Approved tidak boleh lebih dari Total Incurred') - } - } + benefitData?.map((item, index) => { + totalAmountIncurred += parseFloat(item.amount_incurred); + totalAmountApproved += parseFloat(item.amount_approved); + 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 // ===================================== const submitHandler = async (data: BenefitConfigurationListType) => { @@ -206,8 +217,6 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl } } - // Calculate - const getContent = () => !addBenefit ? ( @@ -281,6 +290,10 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl name={`benefit_data.${index}.amount_incurred`} placeholder='Amount Incurred' required + onChange={(event) => { + setValue(`benefit_data.${index}.amount_incurred`, event.target.value) + handleOnChangeNominal(index)} + } /> @@ -301,6 +314,10 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl name={`benefit_data.${index}.amount_approved`} placeholder='Amount Approved' required + onChange={(event) => { + setValue(`benefit_data.${index}.amount_approved`, event.target.value) + handleOnChangeNominal(index)} + } /> @@ -434,7 +451,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl - {fNumber(totalAmountIncurred)} + {fNumber(totalAll().totalAmountIncurred)} @@ -450,7 +467,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl - {fNumber(totalAmountApproved)} + {fNumber(totalAll().totalAmountApproved)} @@ -466,7 +483,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl - {fNumber(totalAmountNotApproved)} + {fNumber(totalAll().totalAmountNotApproved)} @@ -482,7 +499,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl - {fNumber(totalExcessPaid)} + {fNumber(totalAll().totalExcessPaid)} @@ -499,7 +516,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl - + Save diff --git a/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogEditBenefit.tsx b/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogEditBenefit.tsx index bbd99c7f..11f0b03f 100644 --- a/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogEditBenefit.tsx +++ b/frontend/dashboard/src/pages/CustomerService/FinalLog/Components/DialogEditBenefit.tsx @@ -62,23 +62,36 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, 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 - 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')); + return { + totalAmountIncurred, + totalAmountApproved, + totalAmountNotApproved, + totalExcessPaid + } + } - // 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; - - if (totalAmountApproved > totalAmountIncurred) { - alert('Total Approve tidak boleh melebihi Total Incurred') - setValue('amount_approved', data?.amount_approved) + const handleOnChangeNominal = (key) => { + if (totalAll().totalAmountApproved > totalAll().totalAmountIncurred){ + // setValue(`benefit_data.${key}.amount_approved`, 0); + setError(`amount_approved`, {message: 'Amount Approve tidak boleh lebih dari Amount Incurred'}); + } else { + clearErrors(`amount_approved`); + } } // if (totalAmountIncurred !== (totalAmountApproved+totalAmountNotApproved)){ @@ -142,6 +155,10 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, name={`amount_incurred`} placeholder='Amount Incurred' required + onChange={(event) => { + setValue(`amount_incurred`, event.target.value) + handleOnChangeNominal(id)} + } /> @@ -162,6 +179,10 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, name={`amount_approved`} placeholder='Amount Approved' required + onChange={(event) => { + setValue(`amount_approved`, event.target.value) + handleOnChangeNominal(id)} + } /> @@ -275,7 +296,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, - {totalAmountIncurred ? fNumber(totalAmountIncurred) : 0} + {totalAll().totalAmountIncurred ? fNumber(totalAll().totalAmountIncurred) : 0} @@ -291,7 +312,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, - {fNumber(totalAmountApproved)} + {totalAll().totalAmountApproved ? fNumber(totalAll().totalAmountApproved) : 0} @@ -307,7 +328,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, - {fNumber(totalAmountNotApproved)} + {totalAll().totalAmountNotApproved ? fNumber(totalAll().totalAmountNotApproved) : 0} @@ -323,7 +344,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, - {fNumber(totalExcessPaid)} + {totalAll().totalExcessPaid ? fNumber(totalAll().totalExcessPaid) : 0} @@ -337,7 +358,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, - + Save From 79a097c95810e7f090b748a1379f8843c02a9002 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Fri, 23 Feb 2024 16:05:20 +0700 Subject: [PATCH 04/34] Update claim management migrasi table --- .../Http/Controllers/Api/ClaimController.php | 92 +++++++++---------- ...725_add_coloumn_to_claim_request_table.php | 2 +- ...52_add_coloumn_to_claim_requests_table.php | 43 +++++++++ .../dashboard/src/pages/Claims/Detail.tsx | 4 +- frontend/dashboard/src/pages/Claims/List.tsx | 2 +- 5 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 7c358d90..22453713 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -42,13 +42,15 @@ class ClaimController extends Controller public function index(Request $request) { $limit = $request->has('per_page') ? $request->input('per_page') : 10; - $results = DB::table('claims') - ->leftJoin('claim_requests', 'claims.claim_request_id','=', 'claim_requests.id') + $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_claim_management', 'like', "%" . $search . "%"); + $query->orWhere('members.member_id', 'like', "%" . $search . "%"); }); }) ->when($request->has('orderBy'), function ($query) use ($request) { @@ -59,12 +61,12 @@ class ClaimController extends Controller }) ->when($request->input('start_date') , function ($query, $start_date) { $query->where(function ($query) use ($start_date) { - $query->where('claims.created_at', '>=', $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('claims.created_at', '<=', $end_date); + $query->where('claim_requests.created_at', '<=', $end_date); }); }) ->when($request->input('provider') , function ($query, $provider) { @@ -72,17 +74,18 @@ class ClaimController extends Controller $query->where('request_logs.organization_id', '=', $provider); }); }) + ->where('claim_management', '=', 1) ->select( - 'claims.id', + 'claim_requests.id', 'request_logs.id AS id_log', - 'claims.code', + 'claim_requests.code_claim_management as code', 'members.name', DB::raw(' - (SELECT members.member_id FROM members WHERE members.id = claims.member_id LIMIT 1) AS member_id + (SELECT members.member_id FROM members WHERE members.id = claim_requests.member_id LIMIT 1) AS member_id '), - 'claims.created_at', + 'claim_requests.created_at', DB::raw(' - (SELECT plans.code FROM plans WHERE plans.id = claims.plan_id LIMIT 1) AS plan_code + (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 @@ -97,7 +100,7 @@ class ClaimController extends Controller (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 '), - 'claims.status', + 'claim_requests.status_claim_management as status', ) ->paginate($limit); @@ -136,13 +139,15 @@ class ClaimController extends Controller $headerRow = WriterEntityFactory::createRowFromArray($header, $style); $writer->addRow($headerRow); // ============================ - $results = DB::table('claims') - ->leftJoin('claim_requests', 'claims.claim_request_id','=', 'claim_requests.id') + $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_claim_management', 'like', "%" . $search . "%"); + $query->orWhere('members.member_id', 'like', "%" . $search . "%"); }); }) ->when($request->has('orderBy'), function ($query) use ($request) { @@ -153,12 +158,12 @@ class ClaimController extends Controller }) ->when($request->input('start_date') , function ($query, $start_date) { $query->where(function ($query) use ($start_date) { - $query->where('claims.created_at', '>=', $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('claims.created_at', '<=', $end_date); + $query->where('claim_requests.created_at', '<=', $end_date); }); }) ->when($request->input('provider') , function ($query, $provider) { @@ -166,17 +171,18 @@ class ClaimController extends Controller $query->where('request_logs.organization_id', '=', $provider); }); }) + ->where('claim_management', '=', 1) ->select( - 'claims.id', + 'claim_requests.id', 'request_logs.id AS id_log', - 'claims.code', + 'claim_requests.code_claim_management as code', 'members.name', DB::raw(' - (SELECT members.member_id FROM members WHERE members.id = claims.member_id LIMIT 1) AS member_id + (SELECT members.member_id FROM members WHERE members.id = claim_requests.member_id LIMIT 1) AS member_id '), - 'claims.created_at', + 'claim_requests.created_at', DB::raw(' - (SELECT plans.code FROM plans WHERE plans.id = claims.plan_id LIMIT 1) AS plan_code + (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 @@ -191,7 +197,7 @@ class ClaimController extends Controller (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 '), - 'claims.status', + 'claim_requests.status_claim_management as status', ) ->get(); $no=0; @@ -271,19 +277,18 @@ class ClaimController extends Controller public function cekStatus($id) { - $cek = DB::table('claims') - ->where('claims.id', '=', $id) - ->select('claims.status') + $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('claims') - ->join('claim_requests', 'claims.claim_request_id','=', 'claim_requests.id') + $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('claims.id', '=', $id) - ->select('claims.code','members.name','claims.created_at', DB::raw(' + ->where('claim_requests.id', '=', $id) + ->select('claim_requests.code_claim_management','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(); @@ -559,20 +564,15 @@ class ClaimController extends Controller 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') - ->where('claim_request_id', $id) + DB::table('claim_requests') + ->where('claim_requests.id', $id) ->update( [ - 'status' => 'declined', - 'reason_decline' => $request->reasonDecline ? $request->reasonDecline : '' + '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 ] ); @@ -594,19 +594,13 @@ class ClaimController extends Controller public function approve($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') - ->where('claim_request_id', $id) + DB::table('claim_requests') + ->where('claim_requests.id', $id) ->update( [ - 'status' => 'approved' + 'status_claim_management' => 'approved', + 'approval_date_claim_management' => date('Y-m-d H:i:s'), + 'approval_by_claim_management' => auth()->user()->id ] ); diff --git a/database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php b/database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php index be2a049e..09501950 100644 --- a/database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php +++ b/database/migrations/2024_02_23_091725_add_coloumn_to_claim_request_table.php @@ -17,7 +17,7 @@ return new class extends Migration $table->integer('claim_management') ->default(0) ->after('status') - ->comment('untuk flag request masuk ke final, jika 0 masih request dan 1 itu sudah masuk ke finallog'); + ->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(); diff --git a/database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php b/database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php new file mode 100644 index 00000000..631c0846 --- /dev/null +++ b/database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php @@ -0,0 +1,43 @@ +string('code_claim_management', 255)->after('claim_management'); + + }); + } + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + if ( + Schema::hasColumn('claim_requests', 'code_claim_management') + ) { + Schema::table('claim_requests', function (Blueprint $table) { + $table->dropColumn('code_claim_management'); + }); + } + } +}; diff --git a/frontend/dashboard/src/pages/Claims/Detail.tsx b/frontend/dashboard/src/pages/Claims/Detail.tsx index 98af659a..cef407f5 100644 --- a/frontend/dashboard/src/pages/Claims/Detail.tsx +++ b/frontend/dashboard/src/pages/Claims/Detail.tsx @@ -331,7 +331,7 @@ export default function Detail() { {item.benefit?.description} - + {/* { @@ -353,7 +353,7 @@ export default function Detail() { } /> - + */} diff --git a/frontend/dashboard/src/pages/Claims/List.tsx b/frontend/dashboard/src/pages/Claims/List.tsx index 06791385..455c3dfe 100644 --- a/frontend/dashboard/src/pages/Claims/List.tsx +++ b/frontend/dashboard/src/pages/Claims/List.tsx @@ -532,7 +532,7 @@ const dummyServices = [ {row?.service_code} {row?.corporate_policies} {row?.provider} - Rp. {row?.tot_bill?.toLocaleString('id-ID')} + Rp. {row?.tot_bill?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")} {row.status == 'draft' && ()} {row.status == 'requested' && ()} From 3ba4889713d7c6a76a78c7a5f1ecd9b83e091872 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Mon, 26 Feb 2024 21:55:45 +0700 Subject: [PATCH 05/34] Update code claim management --- .../Http/Controllers/Api/ClaimController.php | 10 ++--- ...52_add_coloumn_to_claim_requests_table.php | 43 ------------------- 2 files changed, 5 insertions(+), 48 deletions(-) delete mode 100644 database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 22453713..e0bfec89 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -49,7 +49,7 @@ class ClaimController extends Controller ->when($request->input('search'), function ($query, $search) { $query->where(function ($query) use ($search) { $query->orWhere('members.name', 'like', "%" . $search . "%"); - $query->orWhere('claim_requests.code_claim_management', 'like', "%" . $search . "%"); + $query->orWhere('claim_requests.code', 'like', "%" . $search . "%"); $query->orWhere('members.member_id', 'like', "%" . $search . "%"); }); }) @@ -78,7 +78,7 @@ class ClaimController extends Controller ->select( 'claim_requests.id', 'request_logs.id AS id_log', - 'claim_requests.code_claim_management as code', + '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 @@ -146,7 +146,7 @@ class ClaimController extends Controller ->when($request->input('search'), function ($query, $search) { $query->where(function ($query) use ($search) { $query->orWhere('members.name', 'like', "%" . $search . "%"); - $query->orWhere('claim_requests.code_claim_management', 'like', "%" . $search . "%"); + $query->orWhere('claim_requests.code', 'like', "%" . $search . "%"); $query->orWhere('members.member_id', 'like', "%" . $search . "%"); }); }) @@ -175,7 +175,7 @@ class ClaimController extends Controller ->select( 'claim_requests.id', 'request_logs.id AS id_log', - 'claim_requests.code_claim_management as code', + '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 @@ -288,7 +288,7 @@ class ClaimController extends Controller ->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_claim_management','members.name','claim_requests.created_at', DB::raw(' + ->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(); diff --git a/database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php b/database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php deleted file mode 100644 index 631c0846..00000000 --- a/database/migrations/2024_02_23_143652_add_coloumn_to_claim_requests_table.php +++ /dev/null @@ -1,43 +0,0 @@ -string('code_claim_management', 255)->after('claim_management'); - - }); - } - - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - if ( - Schema::hasColumn('claim_requests', 'code_claim_management') - ) { - Schema::table('claim_requests', function (Blueprint $table) { - $table->dropColumn('code_claim_management'); - }); - } - } -}; From cdb78739869a9aa009d6bb1d0bb3516db968d485 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 27 Feb 2024 10:32:18 +0700 Subject: [PATCH 06/34] bugs fix search --- frontend/dashboard/src/pages/ClaimRequests/List.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/dashboard/src/pages/ClaimRequests/List.tsx b/frontend/dashboard/src/pages/ClaimRequests/List.tsx index 43a779ad..1720ab48 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/List.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/List.tsx @@ -123,6 +123,11 @@ export default function List() { variant="outlined" fullWidth onChange={handleSearchChange} + onKeyDown={(event) => { + if (event.key === 'Enter') { + handleSearchSubmit(event); + } + }} value={searchText} placeholder='Search Code or Name...' /> From 40fb5956732581b2394ac522ef48207fe4a74053 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 27 Feb 2024 10:45:41 +0700 Subject: [PATCH 07/34] tambah upload extensen img --- .../src/sections/dashboard/DialogClaimSubmit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx b/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx index 575a8053..538aeb81 100644 --- a/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/DialogClaimSubmit.tsx @@ -143,7 +143,7 @@ export default function DialogClaimSubmit({ member, getData, onClose, handleSubm style={{ display: 'none' }} multiple onChange={handleKondisiInputChange} - accept="application/pdf" + accept="application/pdf, image/*" /> From f043165b157d2fca03dd00dcc3a97e8a3e441c60 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 27 Feb 2024 10:47:25 +0700 Subject: [PATCH 08/34] Import Claim Request --- .../Api/ClaimRequestController.php | 16 ++- .../Api/ClaimRequestController.php | 1 - .../Api/ClaimRequestController.php | 34 ++--- app/Helpers/Helper.php | 17 +++ app/Models/ClaimRequest.php | 78 +++-------- app/Services/ClaimRequestService.php | 121 ++++++++++++------ 6 files changed, 148 insertions(+), 119 deletions(-) diff --git a/Modules/Client/Http/Controllers/Api/ClaimRequestController.php b/Modules/Client/Http/Controllers/Api/ClaimRequestController.php index bd5bcc49..4c38a420 100644 --- a/Modules/Client/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Client/Http/Controllers/Api/ClaimRequestController.php @@ -19,7 +19,7 @@ class ClaimRequestController extends Controller * Display a listing of the resource. * @return Renderable */ - private static $code_prefix = 'CP'; + private static $code_prefix = 'CLAIM'; public function index() { return view('client::index'); @@ -224,10 +224,6 @@ class ClaimRequestController extends Controller 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')) ->whereRaw('SUBSTRING_INDEX(code, "-", -1) REGEXP "^[0-9]+$"') ->value('max_numeric_code'); @@ -247,8 +243,14 @@ class ClaimRequestController extends Controller { // 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 . '-' . 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); + } } diff --git a/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php b/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php index ace8d239..09b93693 100644 --- a/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/HospitalPortal/Http/Controllers/Api/ClaimRequestController.php @@ -276,7 +276,6 @@ class ClaimRequestController extends Controller $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); } public function get_claim_requests(Request $request) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index c2ea4c9b..6e73e4ae 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -25,7 +25,7 @@ use App\Models\Member; class ClaimRequestController extends Controller { - private static $code_prefix = 'CRQ-C'; + private static $code_prefix = 'CLAIM'; /** * Display a listing of the resource. @@ -429,6 +429,7 @@ class ClaimRequestController extends Controller $import = new ImportService(); $import->read($fileRead); $import->write($fileWrite, 'xsls'); + foreach ($import->sheetsIterator() as $sheetIndex => $sheet) { if ($sheetIndex == 1) { // Rename First Sheet to Writer $firstWriterSheet = $import->writer->getCurrentSheet(); @@ -445,6 +446,8 @@ class ClaimRequestController extends Controller $result_headers = array_merge($result_headers, ['Ingest Code', 'Ingest Note']); $import->addArrayToRow($result_headers); + + $doc_headers_indexes = []; foreach ($sheet->getRowIterator() as $index => $row) { if ($index == 1) { // First Row Must be Header @@ -465,21 +468,20 @@ class ClaimRequestController extends Controller } try { // Process the Row Data $claimRequestService = new ClaimRequestService(); - $claimRequestService->handleClaimRequestRow($row_data); - // Write Success Result to File // $import->read($fileRead); // $import->write($fileWrite, 'xsls'); $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; $import->addArrayToRow($result_headers, $sheet->getName()); - } catch (ImportRowException $e) { // Write Data Validation Error to File // $import->read($fileRead); // $import->write($fileWrite, 'xsls'); - $import->addArrayToRow(array_merge($row_data, [ 'Ingest Code' => $e->getCode(), 'Ingest Note' => $e->getMessage(), @@ -620,10 +622,6 @@ class ClaimRequestController extends Controller 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')) ->whereRaw('SUBSTRING_INDEX(code, "-", -1) REGEXP "^[0-9]+$"') ->value('max_numeric_code'); @@ -641,11 +639,17 @@ class ClaimRequestController extends Controller public static function makeCode($next_number) { - // Pastikan $next_number adalah integer positif - $next_number = max(1, (int) $next_number); - - // Menghasilkan kode dengan format yang diinginkan - return self::$code_prefix . '-' . str_pad($next_number, 5, '0', STR_PAD_LEFT); + // 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, 6, '0', STR_PAD_LEFT); + } public function requestFiles(Request $request, $claim_id) diff --git a/app/Helpers/Helper.php b/app/Helpers/Helper.php index d729682f..19088571 100644 --- a/app/Helpers/Helper.php +++ b/app/Helpers/Helper.php @@ -11,6 +11,7 @@ use Illuminate\Support\Facades\DB; use App\Models\Member; use App\Models\User; use App\Models\Service; +use DateTime; class Helper { @@ -426,4 +427,20 @@ class Helper 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; + } + } + } diff --git a/app/Models/ClaimRequest.php b/app/Models/ClaimRequest.php index 0bf6d685..fbab541a 100644 --- a/app/Models/ClaimRequest.php +++ b/app/Models/ClaimRequest.php @@ -52,69 +52,27 @@ class ClaimRequest extends Model ]; public static $doc_headers_to_field_map = [ - "PAYOR ID" => "payor_id", - "CORPORATE ID" => "corporate_id", - "POLICY NUMBER" => "policy_number", - "MEMBER ID" => "member_id", - "MEMBER NAME" => "member_name", - "RECORD TYPE (P/D)" => "record_type", - "BENEFIT CODE" => "benefit_code", - "BENEFIT DESC" => "benefit_desc", - "CLAIM TYPE" => "claim_type", - "CLAIM PROCESS STATUS" => "status", - "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", + "Code" => "code", + "Date Submission" => "date_submission", + "Total Billing" => "total_billing", + "Benefit Code" => "benefit_code", + "Amt Incurred" => "amount_incurred", + "Amt Approved" => "amount_apporve", + "Amt Not Approved" => "amount_not_apporve", + "Excess Paid" => "excess_paid", + "QC" => "qc", ]; public static $listing_doc_headers = [ - "PAYOR ID", - "CORPORATE ID", - "POLICY NUMBER", - "MEMBER ID", - "MEMBER NAME", - "RECORD TYPE (P/D)", - "CLAIM TYPE", - "CLAIM PROCESS STATUS", - "CLIENT CLAIM ID", - "REFERENCE NO", - "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", + "Code", + "Date Submission", + "Total Billing", + "Benefit Code", + "Amt Incurred", + "Amt Approved", + "Amt Not Approved", + "Excess Paid", + "QC", ]; diff --git a/app/Services/ClaimRequestService.php b/app/Services/ClaimRequestService.php index 3ecac549..78105beb 100644 --- a/app/Services/ClaimRequestService.php +++ b/app/Services/ClaimRequestService.php @@ -6,6 +6,9 @@ use App\Events\ClaimApproved; use App\Events\ClaimRequested; use App\Models\Claim; use App\Models\ClaimRequest; +use App\Models\RequestLog; +use App\Models\Benefit; +use App\Models\RequestLogBenefit; use App\Models\Organization; use App\Helpers\Helper; use App\Models\Icd; @@ -20,6 +23,7 @@ use Str; 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) { // try { @@ -36,20 +40,49 @@ class ClaimRequestService{ DB::beginTransaction(); + if ($status == 'submission'){ + $claimManagement = 1; + $submissionDateClaimManagement = $submissionDate; + $submissionByClaimManagement = auth()->user()->id; + $statusClaim = 'received'; + } else { + $claimManagement = 0; + $submissionDateClaimManagement = null; + $submissionByClaimManagement = null; + $statusClaim = null; + } + $claimRequestData = [ '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::create($claimRequestData); - + $claimRequest = ClaimRequest::updateOrCreate(['request_log_id' => $requestLogID],$claimRequestData); + $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'], + ]); + DB::commit(); return $claimRequest; @@ -60,8 +93,6 @@ class ClaimRequestService{ // } } - - public static function storeClaimManagement($row, $member, $claim_request_id){ try { $organization = 0; @@ -130,26 +161,49 @@ class ClaimRequestService{ } } - protected function validatePlanRow($row) - { - if (empty($row['member_id'])) { - throw new ImportRowException(__('Member ID Required'), 0, null, $row); - } - } - public function handleClaimRequestRow($row) { try { - $member = Member::where('member_id', $row['member_id'])->with(['currentPlan'])->first(); - if(!$member){ - throw new ImportRowException(__('Member Tidak ditemukan'), 0, null, $row); + $requestLog = RequestLog::where('code', $row['code'])->first(); + if(!$requestLog){ + 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); + + // $code = $row['client_claim_id']; + // dd($row['date_submission']); + $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( row: $row, @@ -157,26 +211,21 @@ class ClaimRequestService{ member: $member, paymentType: $paymentType, serviceCode: $serviceCode, + requestLogID: $requestLog->id, submissionDate: $submissionDate, status: $status, - organization_code: $organization_id + organization_code: $organization->code ); - $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); - + // $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' + // ]); return $newClaimRequest; } catch (\Exception $e) { throw $e; From 5c4e1e6c967771030c9359b9cc637245761676cd Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 27 Feb 2024 11:27:16 +0700 Subject: [PATCH 09/34] update --- app/Services/ClaimRequestService.php | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/app/Services/ClaimRequestService.php b/app/Services/ClaimRequestService.php index 78105beb..4ddb237b 100644 --- a/app/Services/ClaimRequestService.php +++ b/app/Services/ClaimRequestService.php @@ -69,20 +69,21 @@ class ClaimRequestService{ ]; $claimRequest = ClaimRequest::updateOrCreate(['request_log_id' => $requestLogID],$claimRequestData); - $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'], - ]); - + if (count($row)>0){ + $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'], + ]); + } DB::commit(); return $claimRequest; From 26e3cd5ac9c3a43939580b3a774995a704477a69 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 27 Feb 2024 11:30:19 +0700 Subject: [PATCH 10/34] update template claim --- Modules/Internal/Http/Controllers/Api/CorporateController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/CorporateController.php b/Modules/Internal/Http/Controllers/Api/CorporateController.php index e4218b27..91870d34 100644 --- a/Modules/Internal/Http/Controllers/Api/CorporateController.php +++ b/Modules/Internal/Http/Controllers/Api/CorporateController.php @@ -559,8 +559,8 @@ class CorporateController extends Controller break; case 'claim-request': return Helper::responseJson([ - 'file_name' => "Template Format Claim.xlsx", - "file_url" => url('files/Template Format Claim.xlsx') + 'file_name' => "Template Claim Request.xlsx", + "file_url" => url('files/Template Claim Request.xlsx') ]); break; case 'request-log': From 7c5fdaef78cca8cb32ab3a9a2391ab405740ee7c Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 27 Feb 2024 12:26:40 +0700 Subject: [PATCH 11/34] update template --- public/files/Template Claim Request.xlsx | Bin 0 -> 10003 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/files/Template Claim Request.xlsx diff --git a/public/files/Template Claim Request.xlsx b/public/files/Template Claim Request.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3edb4dd6cfe932c77120b91d6f78c71461b3b801 GIT binary patch literal 10003 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 IRu}{RA5PdoeE Date: Tue, 27 Feb 2024 13:37:38 +0700 Subject: [PATCH 12/34] update import --- .../Api/ClaimRequestController.php | 19 ++++--- app/Services/ClaimRequestService.php | 49 ++++++++----------- .../src/pages/ClaimRequests/List.tsx | 20 +++++++- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index 6e73e4ae..d72b1ea2 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -446,8 +446,9 @@ class ClaimRequestController extends Controller $result_headers = array_merge($result_headers, ['Ingest Code', 'Ingest Note']); $import->addArrayToRow($result_headers); - - + $imported_claim_data = 0; + $failed_claim_data = []; + $doc_headers_indexes = []; foreach ($sheet->getRowIterator() as $index => $row) { if ($index == 1) { // First Row Must be Header @@ -477,15 +478,19 @@ class ClaimRequestController extends Controller $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()); + $imported_claim_data++; } catch (ImportRowException $e) { // Write Data Validation Error to File // $import->read($fileRead); // $import->write($fileWrite, 'xsls'); - $import->addArrayToRow(array_merge($row_data, [ + $new_claim_data = $import->addArrayToRow(array_merge($row_data, [ 'Ingest Code' => $e->getCode(), 'Ingest Note' => $e->getMessage(), ]), $sheet->getName()); + + $failed_claim_data[] = ['row_number' => $index, 'error' => $e->getMessage(),'data' => $new_claim_data]; } // catch (\Exception $e) { // // throw new \Exception($e); @@ -504,14 +509,14 @@ class ClaimRequestController extends Controller $import->reader->close(); Storage::delete('temp/' . $file_name); $import->writer->close(); - return [ - // 'total_successed_row' => $imported_plan_data, - // 'total_failed_row' => count($failed_plan_data), - // 'failed_row' => $failed_plan_data, + 'result_file' => [ 'url' => Storage::disk('public')->url('temp/result-' . $file_name), 'name' => 'result-' . $file_name, + 'total_successed_row' => $imported_claim_data, + 'total_failed_row' => count($failed_claim_data), + 'failed_row' => $failed_claim_data, ] ]; } diff --git a/app/Services/ClaimRequestService.php b/app/Services/ClaimRequestService.php index 4ddb237b..7d58cf03 100644 --- a/app/Services/ClaimRequestService.php +++ b/app/Services/ClaimRequestService.php @@ -52,23 +52,27 @@ class ClaimRequestService{ $statusClaim = null; } - $claimRequestData = [ - '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, - ]; + 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); - $claimRequest = ClaimRequest::updateOrCreate(['request_log_id' => $requestLogID],$claimRequestData); if (count($row)>0){ $benefitData = Benefit::where('code', $row['benefit_code'])->first(); $requestLogData = RequestLogBenefit::updateOrCreate( @@ -194,9 +198,6 @@ class ClaimRequestService{ $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); - - // $code = $row['client_claim_id']; - // dd($row['date_submission']); $submissionDate = Helper::dateParser($row['date_submission']); $paymentType = $requestLog->payment_type; if ($row['qc'] == 'Y'){ @@ -205,7 +206,6 @@ class ClaimRequestService{ $status = 'requested'; } $serviceCode = $requestLog->service_code; - $newClaimRequest = $this->storeClaimRequest( row: $row, code: $code, @@ -218,15 +218,6 @@ class ClaimRequestService{ organization_code: $organization->code ); $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' - // ]); return $newClaimRequest; } catch (\Exception $e) { throw $e; diff --git a/frontend/dashboard/src/pages/ClaimRequests/List.tsx b/frontend/dashboard/src/pages/ClaimRequests/List.tsx index 1720ab48..6a9defb3 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/List.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/List.tsx @@ -366,14 +366,32 @@ export default function List() { )} {importResult && ( + // + // + // Last Import Result Report :{' '} + // + // {importResult.result_file?.name ?? '-'} + // + // + // + - Last Import Result Report :{' '} + Last Import Result :{' '} + + {importResult.result_file?.total_success_row ?? 0} + {' '} + Row Processed,{' '} + + {importResult.result_file?.total_failed_row} + {' '} + Failed, Report :{' '} {importResult.result_file?.name ?? '-'} + )} ); From c82bd31d572a3a5100ac3a91aff163000021549e Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Tue, 27 Feb 2024 14:20:05 +0700 Subject: [PATCH 13/34] Update Bulk request claim --- .../Controllers/Api/RequestLogController.php | 112 +++++++++++++++ Modules/HospitalPortal/Routes/api.php | 1 + .../hospital-portal/public/lang/en-US.json | 9 +- .../hospital-portal/public/lang/id-ID.json | 9 +- .../hospital-portal/src/components/Table.tsx | 112 +++++++++++---- .../src/sections/claim/TableList.tsx | 54 +++++++ .../sections/dashboard/TableListFinalLog.tsx | 135 +++++++++++++++++- .../sections/dashboard/TableListReqLog.tsx | 56 +++++++- 8 files changed, 450 insertions(+), 38 deletions(-) diff --git a/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php b/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php index b7a07ebe..44c9e01e 100644 --- a/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php +++ b/Modules/HospitalPortal/Http/Controllers/Api/RequestLogController.php @@ -13,6 +13,11 @@ use App\Models\File; use Dompdf\Dompdf; use Dompdf\Options; 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 { @@ -20,6 +25,7 @@ class RequestLogController extends Controller * Display a listing of the resource. * @return Renderable */ + private static $code_prefix = 'CLAIM'; public function requestLog(Request $request) { $data = [ @@ -820,4 +826,110 @@ class RequestLogController extends Controller 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); + } } diff --git a/Modules/HospitalPortal/Routes/api.php b/Modules/HospitalPortal/Routes/api.php index 17fdec66..3b73f731 100644 --- a/Modules/HospitalPortal/Routes/api.php +++ b/Modules/HospitalPortal/Routes/api.php @@ -56,6 +56,7 @@ Route::prefix('v1')->group(function() { Route::post('request-final-log', 'requestFinalLog'); Route::get('download-log/{request_log_id}', 'downlodLog'); Route::get('download-final-log/{request_log_id}', 'downlodFinalLog'); + Route::post('submit-claims', 'submitClaims'); }); //Notification Route::controller(NotificationController::class)->group(function() { diff --git a/frontend/hospital-portal/public/lang/en-US.json b/frontend/hospital-portal/public/lang/en-US.json index 8791f8a0..64b5efee 100644 --- a/frontend/hospital-portal/public/lang/en-US.json +++ b/frontend/hospital-portal/public/lang/en-US.json @@ -50,5 +50,12 @@ "txtNew" : "New", "txtBeforeThat" : "Before that", "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?" } diff --git a/frontend/hospital-portal/public/lang/id-ID.json b/frontend/hospital-portal/public/lang/id-ID.json index 6f85bbb5..96077fe4 100644 --- a/frontend/hospital-portal/public/lang/id-ID.json +++ b/frontend/hospital-portal/public/lang/id-ID.json @@ -50,5 +50,12 @@ "txtNew" : "Baru", "txtBeforeThat" : "Sebelum", "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?" } diff --git a/frontend/hospital-portal/src/components/Table.tsx b/frontend/hospital-portal/src/components/Table.tsx index a60bc862..6de87395 100644 --- a/frontend/hospital-portal/src/components/Table.tsx +++ b/frontend/hospital-portal/src/components/Table.tsx @@ -13,6 +13,7 @@ import { TableSortLabel, Box, Card, + Checkbox, Grid, FormControl, InputLabel, @@ -43,6 +44,8 @@ import { DivisionDataProps, Order, PaginationTableProps, TableListProps } from ' import { InputAdornment } from '@mui/material'; import GetAppIcon from '@mui/icons-material/GetApp'; import { LanguageContext } from '@/contexts/LanguageContext'; +import CancelIcon from '@mui/icons-material/Cancel'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; /* --------------------------------- styled --------------------------------- */ const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({ @@ -71,6 +74,7 @@ export default function Table({ filterEndDate, searchs, exportReport, + selected, }: TableListProps) { /* ------------------------------- handle sort ------------------------------ */ const handleRequestSort = async (event: React.MouseEvent, property: string) => { @@ -98,34 +102,73 @@ export default function Table({ return ( - {headCells && - headCells.map((headCell, index) => ( - - {headCell.isSort ? ( - - {headCell.label} - {orders?.orderBy === headCell.id ? ( - - {orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'} - - ) : null} - - ) : ( - headCell.label - )} + {selected.useSelected && selected.selectedRows.length > 0 ? ( + <> + + + + + + + {selected.selectedRows.length > 0 ? selected.selectedRows.length : '0'}   {localeData.txtSelected} + + + + + + {selected.useDecline ? ( + + ):''} + + + + - ))} + + ):( + <> + {selected.useSelected ? ( + + + + ):''} + {headCells && + headCells.map((headCell, index) => ( + + {headCell.isSort ? ( + + {headCell.label} + {orders?.orderBy === headCell.id ? ( + + {orders.order === 'desc' ? 'sorted descending' : 'sorted ascending'} + + ) : null} + + ) : ( + headCell.label + )} + + ))} + + + )} + + ); @@ -162,7 +205,6 @@ export default function Table({ params.setAppliedParams(parameters); }; /* -------------------------------------------------------------------------- */ - return ( // @@ -349,6 +391,20 @@ export default function Table({ ) : rows && rows.length >= 1 ? ( rows.map((row, rowIndex) => ( + {!selected.useSelected ? ( + '' + ): (selected.useSelected && row.check_status === 'approved' && !row.check_claim ? ( + + selected.handleCheckboxChange(row.id)} + /> + + ):( + + + + ))} {headCells && //@ts-ignore headCells.map((head, headIndex) => ( diff --git a/frontend/hospital-portal/src/sections/claim/TableList.tsx b/frontend/hospital-portal/src/sections/claim/TableList.tsx index 61badfaf..dcd4994e 100644 --- a/frontend/hospital-portal/src/sections/claim/TableList.tsx +++ b/frontend/hospital-portal/src/sections/claim/TableList.tsx @@ -118,6 +118,58 @@ export default function TableList() { /* -------------------------------------------------------------------------- */ + // ----------------------------------------- handle selected --------------------- + const [selectAll, setSelectAll] = useState(false); + const [selectedRows, setSelectedRows] = useState([]); + const [dataTableData, setDataTableData] = useState(); + 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; }; }) => { + 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 ----------------------------- */ const [searchText, setSearchText] = useState(''); @@ -280,6 +332,7 @@ export default function TableList() { const response = await axios.get(`/get-claim-requests`, { params: { ...parameters, type: 'final-log' }, }); + setDataTableData(response.data); setData( response.data.data.map((obj: any) => ({ ...obj, @@ -357,6 +410,7 @@ export default function TableList() { params={params} searchs={searchs} filterStatus={filterStatus} + selected={selected} // filterStartDate={filterStartDate} // filterEndDate={filterEndDate} /> diff --git a/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx b/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx index 010662dc..027d8ff0 100644 --- a/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx @@ -1,11 +1,11 @@ /* ---------------------------------- @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 --------------------------------- */ // import axios from 'axios'; import axios from '../../utils/axios'; import { styled } from '@mui/material/styles'; /* ---------------------------------- react --------------------------------- */ -import { useContext, useEffect, useState } from 'react'; +import { SetStateAction, useContext, useEffect, useState } from 'react'; /* -------------------------------- component ------------------------------- */ import Iconify from '../../components/Iconify'; @@ -30,6 +30,8 @@ import MuiDialog from '@/components/MuiDialog'; import DialogMember from './DialogMember'; import DialogClaimSubmit from './DialogClaimSubmit'; import { fPostFormat } from '@/utils/formatTime'; +import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; export default function TableListFinalLog() { const navigate = useNavigate(); @@ -68,6 +70,7 @@ export default function TableListFinalLog() { return `${day}${month}${year}`; } + /* -------------------------------------------------------------------------- */ /* 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(); + 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; }; }) => { + 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 ----------------------------- */ const [searchText, setSearchText] = useState(''); @@ -335,11 +417,14 @@ export default function TableListFinalLog() { params: { ...parameters, search:searchText, order: order, orderBy: orderBy, status:statusValue, type: 'final-log' }, }); + setDataTableData(response.data); setData( - response.data.data.map((obj: any) => ({ - ...obj, + response.data.data.map((obj: any) => ({ + ...obj, provider:formatTitleCase(obj.provider), full_name:formatTitleCase(obj.full_name), + check_status: obj.status, + check_claim: obj.check_claim, status: obj.status === 'requested' ? ( - {requestLog?.status_final_log != 'requested' ? ( + {/* {requestLog?.status_final_log != 'requested' ? ( } /> - ) : null } + ) : null } */} @@ -614,7 +614,7 @@ export default function Detail() { - {statusClaim == 'requested' ? ( + {statusClaim == 'received' ? ( From a0aa57ebe478301369125a326ac58cbd0690de97 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Tue, 27 Feb 2024 15:13:09 +0700 Subject: [PATCH 16/34] Update --- frontend/dashboard/src/pages/Claims/List.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/dashboard/src/pages/Claims/List.tsx b/frontend/dashboard/src/pages/Claims/List.tsx index 455c3dfe..1da79aca 100644 --- a/frontend/dashboard/src/pages/Claims/List.tsx +++ b/frontend/dashboard/src/pages/Claims/List.tsx @@ -97,7 +97,7 @@ const dummyServices = [ setSelectAll(!selectAll); if (!selectAll) { const requestedIds = dataTableData.data - .filter(row => row.status === 'requested') // Memfilter baris dengan status 'requested' + .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 { @@ -519,7 +519,7 @@ const dummyServices = [ */} - {row?.status == 'requested' ? ( + {row?.status == 'received' ? ( ):''} From 41449fa6b1689a2781383ceff6a18e77be940c68 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 27 Feb 2024 15:22:30 +0700 Subject: [PATCH 17/34] update filter --- .../Controllers/Api/ClaimRequestController.php | 14 +++++++++++--- .../dashboard/src/pages/ClaimRequests/List.tsx | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index f4c3b2cd..38d6a30e 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -22,6 +22,7 @@ use App\Models\File; use App\Models\FilesMcu; use Illuminate\Support\Facades\DB; use App\Models\Member; +use Carbon\Carbon; class ClaimRequestController extends Controller { @@ -41,11 +42,18 @@ class ClaimRequestController extends Controller }); }) ->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) { - $q->where('submission_date', '<', $endDate); + ->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); }) diff --git a/frontend/dashboard/src/pages/ClaimRequests/List.tsx b/frontend/dashboard/src/pages/ClaimRequests/List.tsx index 6a9defb3..de1957a1 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/List.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/List.tsx @@ -157,7 +157,7 @@ export default function List() { { try { From 72a97957b5f576769a217293b64552230c188e71 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Wed, 28 Feb 2024 09:43:32 +0700 Subject: [PATCH 18/34] update listing --- .../Http/Controllers/Api/ClaimController.php | 5 +++-- .../Http/Controllers/Api/ClaimController.php | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Modules/Client/Http/Controllers/Api/ClaimController.php b/Modules/Client/Http/Controllers/Api/ClaimController.php index d2029dbc..77365d3c 100644 --- a/Modules/Client/Http/Controllers/Api/ClaimController.php +++ b/Modules/Client/Http/Controllers/Api/ClaimController.php @@ -21,6 +21,7 @@ use Box\Spout\Writer\Common\Creator\WriterEntityFactory; use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; use Box\Spout\Common\Entity\Style\CellAlignment; use Box\Spout\Common\Entity\Style\Color; +use Carbon\Carbon; class ClaimController extends Controller { @@ -315,8 +316,8 @@ class ClaimController extends Controller // ->where('request_logs.status_final_log', '=', 'approved') ->where('request_logs.deleted_at', '=', null) ->when($start != 'all' && $end != 'all', function ($query) use ($start, $end) { - $query->where('request_logs.submission_date', '>=', $start) - ->where('request_logs.submission_date', '<=', $end); + $query->where('request_logs.submission_date', '>=',Carbon::parse($start)->subDay()) + ->where('request_logs.submission_date', '<=',Carbon::parse($end)->addDay()); }) ->select( DB::raw('1 AS no'), diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index e0bfec89..cc6df37f 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -45,7 +45,7 @@ class ClaimController extends Controller $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') + // ->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 . "%"); @@ -84,8 +84,18 @@ class ClaimController extends Controller (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 = member_plans.plan_id LIMIT 1) AS plan_code + (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 From c60d1bfe65c19d4021dd9936625a458d68aeb64e Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Thu, 29 Feb 2024 09:15:10 +0700 Subject: [PATCH 19/34] Update status --- .../Http/Controllers/Api/ClaimController.php | 2 ++ .../Transformers/ClaimRequestShowResource.php | 1 + .../Transformers/RequestLogShowResource.php | 8 ++++++++ .../dashboard/src/pages/ClaimRequests/Detail.tsx | 16 +++++++++++++++- .../dashboard/src/pages/ClaimRequests/List.tsx | 2 +- .../src/pages/ClaimRequests/Model/Types.tsx | 1 + frontend/dashboard/src/pages/Claims/Detail.tsx | 2 +- 7 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index cc6df37f..12dac77c 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -579,6 +579,7 @@ class ClaimController extends Controller ->where('claim_requests.id', $id) ->update( [ + 'status' => 'declined', 'status_claim_management' => 'declined', 'reason_decline' => $request->reasonDecline ? $request->reasonDecline : '', 'approval_date_claim_management' => date('Y-m-d H:i:s'), @@ -608,6 +609,7 @@ class ClaimController extends Controller ->where('claim_requests.id', $id) ->update( [ + 'status' => 'approved', 'status_claim_management' => 'approved', 'approval_date_claim_management' => date('Y-m-d H:i:s'), 'approval_by_claim_management' => auth()->user()->id diff --git a/Modules/Internal/Transformers/ClaimRequestShowResource.php b/Modules/Internal/Transformers/ClaimRequestShowResource.php index cbb7e109..458970a8 100644 --- a/Modules/Internal/Transformers/ClaimRequestShowResource.php +++ b/Modules/Internal/Transformers/ClaimRequestShowResource.php @@ -99,6 +99,7 @@ class ClaimRequestShowResource extends JsonResource 'service_type' => Helper::serviceName( $data['request_log']['service_code']), 'claim_method' => $data['request_log']['payment_type'], 'files' => $data['request_log']['files'], + 'reason_decline' => $data['reason_decline'], // 'benefit_data' => $benefitDetailLog, ]; diff --git a/Modules/Internal/Transformers/RequestLogShowResource.php b/Modules/Internal/Transformers/RequestLogShowResource.php index ebb5aa43..d289310f 100644 --- a/Modules/Internal/Transformers/RequestLogShowResource.php +++ b/Modules/Internal/Transformers/RequestLogShowResource.php @@ -10,6 +10,7 @@ use App\Models\RequestLogBenefit; use App\Models\RequestLogMedicine; use App\Models\Organization; use App\Models\Exclusion; +use App\Models\ClaimRequest; use App\Models\Icd; use App\Helpers\Helper; use App\Models\CorporatePolicy; @@ -36,6 +37,12 @@ class RequestLogShowResource extends JsonResource $benefitDetailLog = RequestLogBenefit::with('benefit')->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(); + $claimRequest = ClaimRequest::where('request_log_id', $requestLog['id'])->first(); + if ($claimRequest) { + $claimCode = $claimRequest->code; + } else { + $claimCode = '-'; + } if ($provider){ $providerName = $provider->name; @@ -95,6 +102,7 @@ class RequestLogShowResource extends JsonResource $data = [ 'id' => $requestLog['id'], 'code' => $requestLog['code'], + 'code_claim' => $claimCode, 'member_id' => $requestLog['member']['member_id'], 'corporate_id' => $corporateId, 'policy_number' =>$policyNumber->code ? $policyNumber->code : '-', diff --git a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx index 38a23045..0d85c4f6 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx @@ -529,6 +529,20 @@ export default function Detail() { + { claimRequests?.status === 'declined' ? ( + + + Reason + + + + Reason Decline + {claimRequests?.reason_decline} + + + + ) : null } + {/* PR Buat pindahin ke componen */} {/* */} - {(claimRequests?.status === 'requested') || (claimRequests?.status === 'decline') ? ( + {(claimRequests?.status === 'requested') || (claimRequests?.status === 'declined') ? (
{/* Perubahan sintaksis disini */} diff --git a/frontend/dashboard/src/pages/ClaimRequests/List.tsx b/frontend/dashboard/src/pages/ClaimRequests/List.tsx index de1957a1..295d0c9d 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/List.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/List.tsx @@ -495,7 +495,7 @@ export default function List() { () : row.status == "submission" ? () : - row.status == "decline" ? + row.status == "declined" ? () : () } diff --git a/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx b/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx index e62ad097..782bc315 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Model/Types.tsx @@ -51,6 +51,7 @@ export type DetailClaimRequest = { benefit_data : BenefitData[], diagnosis : Diagnosis[], request_log : RequestLogType | undefined, + reason_decline : string, } export type RequestLogType = { diff --git a/frontend/dashboard/src/pages/Claims/Detail.tsx b/frontend/dashboard/src/pages/Claims/Detail.tsx index 0f7f03f2..c1d62748 100644 --- a/frontend/dashboard/src/pages/Claims/Detail.tsx +++ b/frontend/dashboard/src/pages/Claims/Detail.tsx @@ -186,7 +186,7 @@ export default function Detail() { navigate(-1)} sx={{cursor:'pointer'}}/> - {(requestLog && requestLog.code ? requestLog.code : '')} + {(requestLog && requestLog.code_claim ? requestLog.code_claim : '')} {/* Detail */} From b8cdfc1d747b30b09e2ef91692d7281d1e65e48c Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Thu, 29 Feb 2024 09:30:46 +0700 Subject: [PATCH 20/34] update bugs fix hospital --- app/Services/ClaimRequestService.php | 58 ++++++++++++++++++---------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/app/Services/ClaimRequestService.php b/app/Services/ClaimRequestService.php index 7d58cf03..7d1a7e88 100644 --- a/app/Services/ClaimRequestService.php +++ b/app/Services/ClaimRequestService.php @@ -36,7 +36,7 @@ class ClaimRequestService{ 'code' => $row['provider_code'] ]), 403, null, $row); } - }; + } DB::beginTransaction(); @@ -51,8 +51,42 @@ class ClaimRequestService{ $submissionByClaimManagement = null; $statusClaim = null; } + if (count($row)>0){ + 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); - if($row['total_billing']) { + $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, @@ -68,25 +102,7 @@ class ClaimRequestService{ 'policy_id' => $member->currentPolicy->id ?? null, 'organization_id' => $organization ? $organization->id : 0, ]; - } else { - $data = []; - } - $claimRequest = ClaimRequest::updateOrCreate(['request_log_id' => $requestLogID],$data); - - if (count($row)>0){ - $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'], - ]); + $claimRequest = ClaimRequest::updateOrCreate(['request_log_id' => $requestLogID],$data); } DB::commit(); From c57b4e63a987b950a61d24d11c83b78922f84c22 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Thu, 29 Feb 2024 12:12:42 +0700 Subject: [PATCH 21/34] bugs fix export excel --- .../Http/Controllers/Api/ClaimController.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 12dac77c..1fdb9a3a 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -152,7 +152,7 @@ class ClaimController extends Controller $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') + // ->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 . "%"); @@ -192,8 +192,18 @@ class ClaimController extends Controller '), 'claim_requests.created_at', DB::raw(' - (SELECT plans.code FROM plans WHERE plans.id = member_plans.plan_id LIMIT 1) AS plan_code + (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 '), From 547ecc0271cfa9521972984fc9fb91aa9655de22 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Thu, 29 Feb 2024 16:13:36 +0700 Subject: [PATCH 22/34] update tombol submit claim --- .../src/sections/dashboard/TableListFinalLog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx b/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx index 027d8ff0..4473836f 100644 --- a/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/TableListFinalLog.tsx @@ -472,7 +472,7 @@ export default function TableListFinalLog() { Download Final LOG ):''} - {!obj.check_claim && obj.status === 'requested' ? ( + {!obj.check_claim && obj.status === 'approved' ? ( handleRequestClaimSubmit(obj.member_id, obj.service_code, obj.id, obj.full_name, obj.no_polis, obj.submission_date) }> Submit Claim From 19bddcdd22c579402d0211a15171990b3128ae1a Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 1 Mar 2024 09:17:30 +0700 Subject: [PATCH 23/34] export import claim request --- .../Http/Controllers/Api/ClaimController.php | 1 + .../Http/Controllers/Api/ClaimController.php | 18 +- .../Api/ClaimRequestController.php | 297 +++++++++++++++++- Modules/Internal/Routes/api.php | 3 +- app/Models/ClaimRequest.php | 12 +- .../src/pages/ClaimRequests/List.tsx | 4 +- 6 files changed, 316 insertions(+), 19 deletions(-) diff --git a/Modules/Client/Http/Controllers/Api/ClaimController.php b/Modules/Client/Http/Controllers/Api/ClaimController.php index 77365d3c..2fdabfc8 100644 --- a/Modules/Client/Http/Controllers/Api/ClaimController.php +++ b/Modules/Client/Http/Controllers/Api/ClaimController.php @@ -456,6 +456,7 @@ class ClaimController extends Controller //Data Benefit $dataClaimLog = DB::table('request_log_benefits') ->where('request_log_benefits.request_log_id', '=', $item->id) + ->where('request_log_benefits.deleted_at', null) ->select( '*', DB::raw(' diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 1fdb9a3a..4165c2ff 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -192,15 +192,15 @@ class ClaimController extends Controller '), '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 - '), + (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 // '), diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index 38d6a30e..b65c5682 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -17,11 +17,18 @@ use App\Services\ClaimRequestService; use App\Exceptions\ImportRowException; 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\FilesMcu; use Illuminate\Support\Facades\DB; use App\Models\Member; +use App\Models\MemberPlan; +use App\Models\Plan; +use App\Models\RequestLogBenefit; use Carbon\Carbon; class ClaimRequestController extends Controller @@ -53,7 +60,6 @@ class ClaimRequestController extends Controller } }) - ->when($request->service_code, function ($q, $serviceCode) { $q->whereIn('service_code', $serviceCode); }) @@ -70,7 +76,7 @@ class ClaimRequestController extends Controller }) ->with(['member', 'files', 'service', 'member.currentPolicy']) ->paginate(); - + return Helper::paginateResources(ClaimRequestResource::collection($claimRequests)); } @@ -722,6 +728,293 @@ class ClaimRequestController extends Controller 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){ + 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'; diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index e29af216..5df7062b 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -315,13 +315,14 @@ Route::prefix('internal')->group(function () { 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}/submition', [ClaimRequestController::class, 'submition'])->name('claim-requests.submition'); - Route::get('claim-requests/{id}', [ClaimRequestController::class, 'show'])->name('claim-requests.show'); + 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/{id}/update', [ClaimRequestController::class, 'update']); Route::post('claim-requests/import', [ClaimRequestController::class, 'importClaim'])->name('claim-requests.importClaim'); Route::get('claim-requests/detail/{id}', [ClaimRequestController::class, 'claimRequestDetail']); Route::post('claim-requests/{id}/invoice-files', [ClaimRequestController::class, 'invoiceFiles']); 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']); diff --git a/app/Models/ClaimRequest.php b/app/Models/ClaimRequest.php index fbab541a..71db5a57 100644 --- a/app/Models/ClaimRequest.php +++ b/app/Models/ClaimRequest.php @@ -52,26 +52,28 @@ class ClaimRequest extends Model ]; public static $doc_headers_to_field_map = [ - "Code" => "code", - "Date Submission" => "date_submission", + "Code LOG" => "code", + "Date Claim Submission" => "date_submission", "Total Billing" => "total_billing", "Benefit Code" => "benefit_code", "Amt Incurred" => "amount_incurred", "Amt Approved" => "amount_apporve", "Amt Not Approved" => "amount_not_apporve", "Excess Paid" => "excess_paid", + "Reason" => "reason", "QC" => "qc", ]; public static $listing_doc_headers = [ - "Code", - "Date Submission", + "Code LOG", + "Date Claim Submission", "Total Billing", "Benefit Code", "Amt Incurred", "Amt Approved", "Amt Not Approved", - "Excess Paid", + "Excess Paid", + "Reason", "QC", ]; diff --git a/frontend/dashboard/src/pages/ClaimRequests/List.tsx b/frontend/dashboard/src/pages/ClaimRequests/List.tsx index 295d0c9d..20437328 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/List.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/List.tsx @@ -279,7 +279,7 @@ export default function List() { } const handleGetData = (type :string) => { - axios.get(`corporates/${corporate_id}/data-plan-benefit`) + axios.get(`claim-requests/export`) .then((response) => { const link = document.createElement('a'); link.href = response.data.data.file_url; @@ -416,7 +416,7 @@ export default function List() { setDataTableLoading(true); const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); const response = await axios.get('/claim-requests', { params: filter }); - console.log(response.data); + setDataTableLoading(false); From 1937a3e5728dcbe9f2ede649a493c8e529e655fa Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 1 Mar 2024 09:26:36 +0700 Subject: [PATCH 24/34] update --- public/files/Report-Data-Claim-Request.xlsx | Bin 0 -> 5306 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/files/Report-Data-Claim-Request.xlsx diff --git a/public/files/Report-Data-Claim-Request.xlsx b/public/files/Report-Data-Claim-Request.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6bebb95af5235d0d405bea511e697758ee74a01f GIT binary patch literal 5306 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 literal 0 HcmV?d00001 From 0c9a0aebc6ba7aee7a1c71d1d004e24f49e9d6a7 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 1 Mar 2024 10:11:16 +0700 Subject: [PATCH 25/34] filter tanggal sama --- .../Internal/Http/Controllers/Api/ClaimRequestController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index b65c5682..5b8a7904 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -56,7 +56,7 @@ class ClaimRequestController extends Controller if ($request->start_date != $request->end_date) { $q->where('submission_date', '<', Carbon::parse($endDate)->addDay()); } else { - $q->where('submission_date', '<=', Carbon::parse($endDate)); + $q->where('submission_date', '=', Carbon::parse($endDate)); } }) From 99e53fed8110c701bae3bfd9d6be3558db7193e8 Mon Sep 17 00:00:00 2001 From: Linksehat Staging Server Date: Fri, 1 Mar 2024 10:14:27 +0700 Subject: [PATCH 26/34] update --- public/files/Report-Data-Claim-Request.xlsx | Bin 0 -> 3527 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/files/Report-Data-Claim-Request.xlsx diff --git a/public/files/Report-Data-Claim-Request.xlsx b/public/files/Report-Data-Claim-Request.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..dc4a77901a292297c7d09a3c20b3e8b9311d5ef7 GIT binary patch literal 3527 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 Date: Fri, 1 Mar 2024 10:20:03 +0700 Subject: [PATCH 27/34] update --- .../Internal/Http/Controllers/Api/ClaimRequestController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index 5b8a7904..3c56293d 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -56,7 +56,7 @@ class ClaimRequestController extends Controller if ($request->start_date != $request->end_date) { $q->where('submission_date', '<', Carbon::parse($endDate)->addDay()); } else { - $q->where('submission_date', '=', Carbon::parse($endDate)); + $q->where('submission_date', '<', Carbon::parse($endDate)->addDay()); } }) From e138e9553fbf3294e1f435e9d5cf3111366e838f Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 1 Mar 2024 10:27:35 +0700 Subject: [PATCH 28/34] update --- frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx b/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx index c1e6307d..1d956a40 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/CreateUpdate.tsx @@ -32,7 +32,7 @@ export default function ClaimsCreateUpdate() { useEffect(() => { if (isEdit) { - axios.get('/claim-requests/' + id).then((res) => { + axios.get('/claim-requests/' + id + '/show').then((res) => { setCurrentClaim(res.data.data); }); From 7ff889919d99e6cd53109b6d8d21a9ffbcaeab35 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 1 Mar 2024 10:45:44 +0700 Subject: [PATCH 29/34] update if data null --- .../Internal/Http/Controllers/Api/ClaimRequestController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index 3c56293d..eec5be19 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -865,7 +865,7 @@ class ClaimRequestController extends Controller $payor = '-'; } - if ($requestLogData){ + if (!$requestLogData->isEmpty()){ foreach($requestLogData as $key => $data){ $no++; if ($key == 0){ From ab65d53aca7c8b133cc8270db15c083fba7894d9 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Fri, 1 Mar 2024 11:08:07 +0700 Subject: [PATCH 30/34] update --- app/Models/ClaimRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/ClaimRequest.php b/app/Models/ClaimRequest.php index 71db5a57..61b7fcf3 100644 --- a/app/Models/ClaimRequest.php +++ b/app/Models/ClaimRequest.php @@ -73,7 +73,7 @@ class ClaimRequest extends Model "Amt Approved", "Amt Not Approved", "Excess Paid", - "Reason", + // "Reason", "QC", ]; From 3bae411dc60dc0fcaad98d6f6da894a685f6208b Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Mon, 4 Mar 2024 09:36:26 +0700 Subject: [PATCH 31/34] fitur is reversal --- .../Transformers/ClaimRequestShowResource.php | 12 ++ .../Transformers/RequestLogShowResource.php | 14 ++- .../ClaimRequests/Components/FormEdit.tsx | 13 ++- .../src/pages/ClaimRequests/Detail.tsx | 107 +++++++++++------- .../pages/CustomerService/FinalLog/Detail.tsx | 102 ++++++++++------- 5 files changed, 155 insertions(+), 93 deletions(-) diff --git a/Modules/Internal/Transformers/ClaimRequestShowResource.php b/Modules/Internal/Transformers/ClaimRequestShowResource.php index 458970a8..d56bbd75 100644 --- a/Modules/Internal/Transformers/ClaimRequestShowResource.php +++ b/Modules/Internal/Transformers/ClaimRequestShowResource.php @@ -71,6 +71,17 @@ class ClaimRequestShowResource extends JsonResource '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 = [ 'id' => $data['id'], @@ -101,6 +112,7 @@ class ClaimRequestShowResource extends JsonResource 'files' => $data['request_log']['files'], 'reason_decline' => $data['reason_decline'], // 'benefit_data' => $benefitDetailLog, + 'is_reversal' => $isReversal, // untuk penjagaan, jika true tidak bisa di edit/hapus lagi ]; diff --git a/Modules/Internal/Transformers/RequestLogShowResource.php b/Modules/Internal/Transformers/RequestLogShowResource.php index d289310f..1591701a 100644 --- a/Modules/Internal/Transformers/RequestLogShowResource.php +++ b/Modules/Internal/Transformers/RequestLogShowResource.php @@ -40,8 +40,19 @@ class RequestLogShowResource extends JsonResource $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){ @@ -97,7 +108,7 @@ class RequestLogShowResource extends JsonResource ->whereIn('code', $diagnosis) ->select('code', 'name') ->get(); - } + } $data = [ 'id' => $requestLog['id'], @@ -136,6 +147,7 @@ class RequestLogShowResource extends JsonResource 'catatan' => $requestLog['catatan'], 'reason' => $requestLog['reason'], 'diagnosis' => $icd, + 'is_reversal' => $isReversal, // untuk penjagaan, jika true tidak bisa di edit/hapus lagi ]; diff --git a/frontend/dashboard/src/pages/ClaimRequests/Components/FormEdit.tsx b/frontend/dashboard/src/pages/ClaimRequests/Components/FormEdit.tsx index 80811203..256aaea9 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Components/FormEdit.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Components/FormEdit.tsx @@ -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 useEffect(() => { setDate(currentClaim?.submission_date) }, [currentClaim]); - console.log(date); - useEffect(() => { if (isEdit && currentClaim) { reset(defaultValues); @@ -254,7 +252,6 @@ export default function FormEdit({ isEdit, currentClaim }: Props) { ) - return ( @@ -310,10 +307,14 @@ export default function FormEdit({ isEdit, currentClaim }: Props) { setDate(field.value)} + value={field.value} + onChange={() => + setDate(field.value) + } + dateFormat='dd MMM yyyy HH:mm:ss' /> )} + /> diff --git a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx index 0d85c4f6..647f632c 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx @@ -52,6 +52,7 @@ export default function Detail() { const { themeStretch } = useSettings(); const [claimRequests, setClaimRequest] = useState(); const [openDialogSubmit, setOpenDialogSubmit] = useState(false); + const [isReversal, setIsReversal] = useState(false); const { id } = useParams(); @@ -60,6 +61,7 @@ export default function Detail() { .get('claim-requests/detail/'+id) .then((response) => { setClaimRequest(response.data.data) + setIsReversal(response.data.data.is_reversal) }) .catch((error) => { console.error(error); @@ -226,13 +228,18 @@ export default function Detail() { Document - - - + { + !isReversal ? ( + + + + ) : null + } + {claimRequests?.files?.map((documentType, index) => ( @@ -253,14 +260,19 @@ export default function Detail() { {documentType.original_name ? documentType.original_name : '-'} - - { - setDialogDeleteFileLog(true) - setPathFile(documentType.path) - }} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}> - - - + { + !isReversal ? ( + + { + setDialogDeleteFileLog(true) + setPathFile(documentType.path) + }} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}> + + + + ) : null + } + ))} @@ -284,11 +296,15 @@ export default function Detail() { Benefit - + { + !isReversal ? ( + + ) : null + } @@ -301,29 +317,34 @@ export default function Detail() { {item.benefit?.description} - - - { - setDialogEditBenefit(true) - setIdBenefitData(item.id) - setBenefitConfigurationData(item) - }} - > - - Edit - - { - setIdBenefitData(item.id) - setDialogDeleteBenefit(true) - }} - > - - Delete - - - } /> - + { + !isReversal ? ( + + + { + setDialogEditBenefit(true) + setIdBenefitData(item.id) + setBenefitConfigurationData(item) + }} + > + + Edit + + { + setIdBenefitData(item.id) + setDialogDeleteBenefit(true) + }} + > + + Delete + + + } /> + + ) : null + } + diff --git a/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx b/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx index b9497245..02a158e7 100644 --- a/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx +++ b/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx @@ -68,6 +68,7 @@ export default function Detail() { const navigate = useNavigate(); const { themeStretch } = useSettings(); const [requestLog, setRequestLog] = useState(); + const [isReversal, setIsReversal] = useState(false); const { id } = useParams(); @@ -77,6 +78,7 @@ export default function Detail() { .get('customer-service/request/'+id) .then((response) => { setRequestLog(response.data.data) + setIsReversal(response.data.data.is_reversal) }) .catch((error) => { console.error(error); @@ -283,11 +285,15 @@ export default function Detail() { Benefit - + { + !isReversal ? ( + + ) : null + } {requestLog?.benefit_data?.map((item, index) => ( @@ -300,29 +306,33 @@ export default function Detail() { {item.benefit?.description} - - - { - setDialogEditBenefit(true) - setIdBenefitData(item.id) - setBenefitConfigurationData(item) - }} - > - - Edit - - { - setIdBenefitData(item.id) - setDialogDeleteBenefit(true) - }} - > - - Delete - - - } /> - + { + !isReversal ? ( + + + { + setDialogEditBenefit(true) + setIdBenefitData(item.id) + setBenefitConfigurationData(item) + }} + > + + Edit + + { + setIdBenefitData(item.id) + setDialogDeleteBenefit(true) + }} + > + + Delete + + + } /> + + ) : null + } @@ -598,13 +608,16 @@ export default function Detail() { Files - - - + { !isReversal ? ( + + + + ) : null } + {requestLog?.files?.map((documentType, index) => ( @@ -617,14 +630,17 @@ export default function Detail() { {documentType.original_name ? documentType.original_name : '-'} - - { - setDialogDeleteFileLog(true) - setPathFile(documentType.path) - }} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}> - - - + { !isReversal ? ( + + { + setDialogDeleteFileLog(true) + setPathFile(documentType.path) + }} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}> + + + + ) : null } + ))} From 39ccf2a0b576e2a77f1909cf256a8df96a7f2cd9 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Mon, 4 Mar 2024 09:54:07 +0700 Subject: [PATCH 32/34] Update Hospital portal --- .../hospital-portal/public/lang/en-US.json | 4 ++- .../hospital-portal/public/lang/id-ID.json | 4 ++- .../hospital-portal/src/components/Table.tsx | 34 ++++++++++++++++--- .../src/sections/claim/TableList.tsx | 30 ++++++++-------- .../sections/dashboard/TableListReqLog.tsx | 8 ++--- 5 files changed, 55 insertions(+), 25 deletions(-) diff --git a/frontend/hospital-portal/public/lang/en-US.json b/frontend/hospital-portal/public/lang/en-US.json index 64b5efee..e11ef130 100644 --- a/frontend/hospital-portal/public/lang/en-US.json +++ b/frontend/hospital-portal/public/lang/en-US.json @@ -57,5 +57,7 @@ "txtCancel": "Cancel", "txtDecline": "Decline", "txtApprove": "Approve", - "txtDialogConfirmation": "Are you sure you want to proceed with this action?" + "txtDialogConfirmation": "Are you sure you want to proceed with this action?", + "txtStartDate": "Start Date", + "txtEndDate": "End Date" } diff --git a/frontend/hospital-portal/public/lang/id-ID.json b/frontend/hospital-portal/public/lang/id-ID.json index 96077fe4..d3f59306 100644 --- a/frontend/hospital-portal/public/lang/id-ID.json +++ b/frontend/hospital-portal/public/lang/id-ID.json @@ -57,5 +57,7 @@ "txtCancel": "Batal", "txtDecline": "Tolak", "txtApprove": "Terima", - "txtDialogConfirmation": "Apakah Anda yakin ingin melanjutkan tindakan ini?" + "txtDialogConfirmation": "Apakah Anda yakin ingin melanjutkan tindakan ini?", + "txtStartDate": "Tanggal Mulai", + "txtEndDate": "Tanggal Akhir" } diff --git a/frontend/hospital-portal/src/components/Table.tsx b/frontend/hospital-portal/src/components/Table.tsx index 6de87395..7334e85b 100644 --- a/frontend/hospital-portal/src/components/Table.tsx +++ b/frontend/hospital-portal/src/components/Table.tsx @@ -26,6 +26,10 @@ import { linearProgressClasses, } from '@mui/material'; import { visuallyHidden } from '@mui/utils'; + +import { DatePicker, LocalizationProvider, MobileDatePicker } from '@mui/x-date-pickers'; + +import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; /* ---------------------------------- axios --------------------------------- */ import axios from '../utils/axios'; /* ---------------------------------- react --------------------------------- */ @@ -297,7 +301,7 @@ export default function Table({ {/* Start date */} {filterStartDate && filterStartDate.useFilter ? ( -
filterStartDate.handleStartDateChange(event)}> + {/* filterStartDate.handleStartDateChange(event)}> ({ shrink: true, }} /> - + */} + + { + filterStartDate.setStartDate( (newValue)); + }} + inputFormat="dd-MM-yyyy" + renderInput={(params) => } + /> +
) : null } @@ -317,7 +332,7 @@ export default function Table({ {filterEndDate && filterEndDate.useFilter ? ( -
filterEndDate.handleEndDateChange(event)}> + {/* filterEndDate.handleEndDateChange(event)}> ({ shrink: true, }} /> - + */} + + { + filterEndDate.setEndDate( (newValue)); + }} + inputFormat="dd-MM-yyyy" + renderInput={(params) => } + /> +
) : null } diff --git a/frontend/hospital-portal/src/sections/claim/TableList.tsx b/frontend/hospital-portal/src/sections/claim/TableList.tsx index dcd4994e..17dcf2c4 100644 --- a/frontend/hospital-portal/src/sections/claim/TableList.tsx +++ b/frontend/hospital-portal/src/sections/claim/TableList.tsx @@ -304,12 +304,12 @@ export default function TableList() { label: localeData.txtStatus, isSort: true, }, - { - id: 'action', - align: 'right', - label: '', - isSort: false, - }, + // { + // id: 'action', + // align: 'right', + // label: '', + // isSort: false, + // }, ]; @@ -363,15 +363,15 @@ export default function TableList() { {obj.submission_date ? fDateSuffix(obj.submission_date) : ''} , - action: - - navigate ('/claim/detail/'+obj.claim_request_id)}> - - View - - - } /> + // action: + // + // navigate ('/claim/detail/'+obj.claim_request_id)}> + // + // View + // + // + // } /> })) ); diff --git a/frontend/hospital-portal/src/sections/dashboard/TableListReqLog.tsx b/frontend/hospital-portal/src/sections/dashboard/TableListReqLog.tsx index 8cb70e4d..7fe20e82 100644 --- a/frontend/hospital-portal/src/sections/dashboard/TableListReqLog.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/TableListReqLog.tsx @@ -239,7 +239,7 @@ export default function TableList() { }; // handle start date - const [startDateValue, setStartDateValue] = useState(''); + const [startDateValue, setStartDateValue] = useState(null); const handleStartDateChanges = async (event: React.FormEvent) => { event.preventDefault(); @@ -263,7 +263,7 @@ export default function TableList() { }; // handle end date - const [endDateValue, setEndDateValue] = useState(''); + const [endDateValue, setEndDateValue] = useState(null); const handleEndDateChanges = async (event: React.FormEvent) => { event.preventDefault(); @@ -494,8 +494,8 @@ export default function TableList() { searchs={searchs} filterStatus={filterStatus} selected={selected} - // filterStartDate={filterStartDate} - // filterEndDate={filterEndDate} + //filterStartDate={filterStartDate} + //filterEndDate={filterEndDate} /> Date: Tue, 5 Mar 2024 10:36:01 +0700 Subject: [PATCH 33/34] Update import claim management --- .../Http/Controllers/Api/ClaimController.php | 157 +++++++++++++++ Modules/Internal/Routes/api.php | 3 + frontend/dashboard/src/pages/Claims/List.tsx | 188 +++++++++++++++++- .../files/Template - Claim - Management.xlsx | Bin 0 -> 8414 bytes 4 files changed, 344 insertions(+), 4 deletions(-) create mode 100644 public/files/Template - Claim - Management.xlsx diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 4165c2ff..832cddc3 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -26,6 +26,9 @@ use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; use Box\Spout\Common\Entity\Style\CellAlignment; use Illuminate\Support\Facades\DB; 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; @@ -119,6 +122,94 @@ class ClaimController extends Controller 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'; @@ -280,6 +371,72 @@ class ClaimController extends Controller "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') diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 5df7062b..b9353597 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -235,6 +235,9 @@ Route::prefix('internal')->group(function () { Route::post('claims/{claim_id}/set-final-encounter', [ClaimEncounterController::class, 'setFinalEncounter']); 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'); diff --git a/frontend/dashboard/src/pages/Claims/List.tsx b/frontend/dashboard/src/pages/Claims/List.tsx index 1da79aca..5de5511c 100644 --- a/frontend/dashboard/src/pages/Claims/List.tsx +++ b/frontend/dashboard/src/pages/Claims/List.tsx @@ -291,9 +291,9 @@ const dummyServices = [ }, ]; - const handleClick = () => { + // const handleClick = () => { - } + // } @@ -393,6 +393,105 @@ const dummyServices = [ function send_bulk(id) { return axios.post(`claims/${id}/${approve}`, { reasonDecline: reasonDecline }); } + + + const [anchorEl, setAnchorEl] = React.useState(null); + const createMenu = Boolean(anchorEl); + const importHospital = useRef(null); + const [currentImportFileName, setCurrentImportFileName] = useState(null); + const [importLoading, setImportLoading] = useState(false); + const [importResult, setImportResult] = useState(null); + const handleClick = (event: React.MouseEvent) => { + 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(() => { @@ -690,6 +789,16 @@ const dummyServices = [
+ + {!currentImportFileName && ( + <> } sx={{ p: 1.8 }} - // onClick={handleExportReport} loading={isLoadingImport} + onClick={handleClick} > Import + + + Import + + { + handleGetTemplate(); + }} + > + Download Template + + + + )} + {currentImportFileName && ( + + + + + + + + } + sx={{ p: 1.8 }} + onClick={handleUpload} + loading={importLoading} + > + Upload + + + + )} + {importResult && ( + + + Last Import Result :{' '} + + {importResult.data.total_success_row ?? 0} + {' '} + Row Processed,{' '} + + {importResult.data.total_failed_row} + {' '} + Failed + {/* {importResult.data.failed_rows.map((row, index) => ( + [Code={row.code ? row.code : 'Required'}] + ))} */} +  Download Data Filed + + + )} - +
diff --git a/public/files/Template - Claim - Management.xlsx b/public/files/Template - Claim - Management.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..658920b24976d590b665d55667f29807fb80fb33 GIT binary patch literal 8414 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 N8nJSRjQ;1-{{XSeOfvug literal 0 HcmV?d00001 From e3586237165d2bda153d21a52abea1cf8c1511ed Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Tue, 5 Mar 2024 11:37:36 +0700 Subject: [PATCH 34/34] tambah keterangan di detail alarm center --- .../Api/CorporateMemberController.php | 2 +- .../AlarmCenter/DataServiceMonitoring.php | 2 + .../pages/AlarmCenter/ServiceMonitoring.tsx | 40 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Modules/Client/Http/Controllers/Api/CorporateMemberController.php b/Modules/Client/Http/Controllers/Api/CorporateMemberController.php index b113a246..ceb75d10 100644 --- a/Modules/Client/Http/Controllers/Api/CorporateMemberController.php +++ b/Modules/Client/Http/Controllers/Api/CorporateMemberController.php @@ -229,7 +229,7 @@ class CorporateMemberController extends Controller 'service:code,name', '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 = []; if (count($data->requestLogBenefits) > 0) { diff --git a/Modules/Client/Transformers/AlarmCenter/DataServiceMonitoring.php b/Modules/Client/Transformers/AlarmCenter/DataServiceMonitoring.php index 9ae4657d..849e1f91 100644 --- a/Modules/Client/Transformers/AlarmCenter/DataServiceMonitoring.php +++ b/Modules/Client/Transformers/AlarmCenter/DataServiceMonitoring.php @@ -105,6 +105,8 @@ class DataServiceMonitoring extends JsonResource 'name' => $requestLogBenefit->benefit->description, ]; })->all() ?? null, + 'keterangan' => $this->keterangan ?? null, + 'catatan' => $this->catatan ?? null, 'benefitTotal' => $this->benefitTotal ?? null, 'hospital' => $this->organization->name ?? null, 'admissionDate' => $this->submission_date ?? null, diff --git a/frontend/client-portal/src/pages/AlarmCenter/ServiceMonitoring.tsx b/frontend/client-portal/src/pages/AlarmCenter/ServiceMonitoring.tsx index 09b8b6bf..bbbb1f7b 100644 --- a/frontend/client-portal/src/pages/AlarmCenter/ServiceMonitoring.tsx +++ b/frontend/client-portal/src/pages/AlarmCenter/ServiceMonitoring.tsx @@ -203,6 +203,8 @@ type ServiceMonitoringProps = { }[]; }> >; + keterangan: string; + catatan: string; }; export default function ServiceMonitoring() { @@ -591,6 +593,44 @@ export default function ServiceMonitoring() { )} */} + {/* Keterangan */} + + + + {loading ? : 'Keterangan'} + + + + + {loading ? ( + + ) : data && data.keterangan ? ( + data.keterangan + ) : ( + '-' + )} + + + + {/* Catatan */} + + + + {loading ? : 'Catatan'} + + + + + {loading ? ( + + ) : data && data.catatan ? ( + data.catatan + ) : ( + '-' + )} + + +