From ec3327b5afb3a774664c017bdfcbf9848e1bcf42 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Fri, 3 Nov 2023 13:53:37 +0700 Subject: [PATCH] Update Upload File Request Dashboard PrimeCenter --- .../Api/ClaimRequestController.php | 61 ++++ Modules/Internal/Routes/api.php | 1 + .../src/pages/ClaimRequests/Detail.tsx | 28 +- .../pages/ClaimRequests/DetailTimeline.tsx | 319 ++++++++++++++++-- .../src/sections/dashboard/TableList2.tsx | 2 +- 5 files changed, 378 insertions(+), 33 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php index 1d9018fb..69c7f0fa 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimRequestController.php @@ -573,6 +573,10 @@ class ClaimRequestController extends Controller $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') @@ -682,4 +686,61 @@ class ClaimRequestController extends Controller // Menghasilkan kode dengan format yang diinginkan return self::$code_prefix . '-' . str_pad($next_number, 5, '0', STR_PAD_LEFT); } + + public function requestFiles(Request $request, $claim_id) + { + + if ($request->hasFile('fileDiagnosis')) { + foreach ($request->fileDiagnosis as $file) { + $pathFile = File::storeFile('claim-diagnosis', $claim_id, $file); + File::updateOrCreate([ + 'fileable_type'=>'App\Models\ClaimRequest', + 'fileable_id' => $claim_id, + 'type' => 'claim-diagnosis', + 'name' => File::getFileName('claim-diagnosis', $claim_id, $file), + 'original_name' => $file->getClientOriginalName(), + 'extension' => $file->getClientOriginalExtension(), + 'path' => $pathFile, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id, + ]); + } + } + + if ($request->hasFile('fileKondisis')) { + foreach ($request->fileKondisis as $file) { + $pathFile = File::storeFile('claim-kondisi', $claim_id, $file); + File::updateOrCreate([ + 'fileable_type'=>'App\Models\ClaimRequest', + 'fileable_id' => $claim_id, + 'type' => 'claim-kondisi', + 'name' => File::getFileName('claim-kondisi', $claim_id, $file), + 'original_name' => $file->getClientOriginalName(), + 'extension' => $file->getClientOriginalExtension(), + 'path' => $pathFile, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id, + ]); + } + } + + if ($request->hasFile('fileResults')) { + foreach ($request->fileResults as $file) { + $pathFile = File::storeFile('claim-result', $claim_id, $file); + File::updateOrCreate([ + 'fileable_type'=>'App\Models\ClaimRequest', + 'fileable_id' => $claim_id, + 'type' => 'claim-result', + 'name' => File::getFileName('claim-result', $claim_id, $file), + 'original_name' => $file->getClientOriginalName(), + 'extension' => $file->getClientOriginalExtension(), + 'path' => $pathFile, + 'created_by' => auth()->user()->id, + 'updated_by' => auth()->user()->id, + ]); + } + } + + return Helper::responseJson(data: $request->toArray(), message: 'Invoice Success Uploaded'); + } } diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 42dfefa0..7168e772 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -260,6 +260,7 @@ Route::prefix('internal')->group(function () { 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('province', [ProvinceController::class, 'index']); diff --git a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx index b069d15b..6b4cac54 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/Detail.tsx @@ -40,6 +40,7 @@ export default function Detail() { const { themeStretch } = useSettings(); const [data, setData] = useState(); const [dataDialog, setDataDialog] = useState(); + const [document, setDocument] = useState(null); const { id } = useParams(); @@ -49,6 +50,7 @@ export default function Detail() { .then((response) => { setData(response.data); setDataDialog(response.data.data.dialog_submits); + setDocument(response.data.data.documents); }) .catch((error) => { @@ -71,11 +73,9 @@ export default function Detail() { const handleInvoiceInputChange = (event) => { if (event.target.files[0]) { - console.log('ok'); - - setFileInvoices([...fileInvoices, ...event.target.files]); + setFileInvoices([...fileInvoices, ...event.target.files]); } else { - console.log('NO FILE'); + console.log('NO FILE'); } }; const removeInvoiceFiles = (filesState, index) => { @@ -130,6 +130,8 @@ export default function Detail() { }; + const check_invoice = document?.find((dataInvoice) => dataInvoice.type === 'claim-invoice'); + return ( @@ -156,14 +158,16 @@ export default function Detail() { - - - Request Claim - - - + {!check_invoice ? ( + + + Request Claim + + + + ) : ''} diff --git a/frontend/dashboard/src/pages/ClaimRequests/DetailTimeline.tsx b/frontend/dashboard/src/pages/ClaimRequests/DetailTimeline.tsx index dd9d682e..f62a706d 100644 --- a/frontend/dashboard/src/pages/ClaimRequests/DetailTimeline.tsx +++ b/frontend/dashboard/src/pages/ClaimRequests/DetailTimeline.tsx @@ -5,16 +5,21 @@ import TimelineSeparator from '@mui/lab/TimelineSeparator'; import TimelineConnector from '@mui/lab/TimelineConnector'; import TimelineContent from '@mui/lab/TimelineContent'; import TimelineDot from '@mui/lab/TimelineDot'; -import {Typography, Card, Stack} from '@mui/material'; +import {Typography, Card, Stack, ButtonBase, Box, Divider} from '@mui/material'; import { styled } from '@mui/material/styles'; import Paper from '@mui/material/Paper'; import Button from '@mui/material/Button'; import AddIcon from '@mui/icons-material/Add'; import Iconify from '../../components/Iconify'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useRef } from 'react'; import { format } from 'date-fns'; import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'; import DescriptionIcon from '@mui/icons-material/Description'; +import { LoadingButton } from '@mui/lab'; +import axios from '../../utils/axios'; +import { makeFormData } from '@/utils/jsonToFormData'; +import { enqueueSnackbar } from 'notistack'; +import { useParams} from 'react-router-dom'; const Item1 = styled(Paper)(({ theme }) => ({ ...theme.typography.body2, @@ -48,6 +53,71 @@ export default function NoOppositeContent({data}) { } }, [data]); + + // Diagnosis + const fileRequestDocumentInputDiagnosis = useRef(null); + const [fileDiagnosis, setFileDiagnosis] = useState([]); + const handleRequestDocumentInputChangeDiagnosis = (event) => { + if (event.target.files[0]) { + setFileDiagnosis([...fileDiagnosis, ...event.target.files]); + } + }; + const removeFileDiagnois = (filesState, index) => { + setFileDiagnosis( + filesState.filter((file, fileIndex) => { + return fileIndex != index; + }) + ); + }; + // Kondisi + const fileRequestDocumentInputKondisi = useRef(null); + const [fileKondisi, setFileKondisi] = useState([]); + const handleRequestDocumentInputChangeKondisi = (event) => { + if (event.target.files[0]) { + setFileKondisi([...fileKondisi, ...event.target.files]); + } + }; + const removeFileKondisi = (filesState, index) => { + setFileKondisi( + filesState.filter((file, fileIndex) => { + return fileIndex != index; + }) + ); + }; + // Result + const fileRequestDocumentInputResult = useRef(null); + const [fileResult, setFileResult] = useState([]); + const handleRequestDocumentInputChangeResult = (event) => { + if (event.target.files[0]) { + setFileResult([...fileResult, ...event.target.files]); + } + }; + const removeFileResult = (filesState, index) => { + setFileResult( + filesState.filter((file, fileIndex) => { + return fileIndex != index; + }) + ); + }; + const { id } = useParams(); + const [submitLoading, setSubmitLoading] = useState(false); + const submitRequestFiles = () => { + setSubmitLoading(true); + const formData = makeFormData({ + fileDiagnosis: fileDiagnosis, + fileKondisis: fileKondisi, + fileResults: fileResult + }); + axios + .post('claim-requests/'+id+'/request-files', formData) + .then((response) => { + window.location.reload(); + }) + .catch(({ response }) => { + enqueueSnackbar(response.data.message ?? 'Something Went Wrong', { variant: 'error' }); + }); + } + const submitButton = requestFile?.find((dataRequestFile) => dataRequestFile.check_files === null); return ( <> {timeline?.map((dataTimeline, index) => ( @@ -79,24 +149,233 @@ export default function NoOppositeContent({data}) { {dataTimeline.status === 'reviewed' && requestFile ? ( <> - {requestFile?.map((dataRequestFile, index) => ( - - {dataRequestFile.description} - - - ))} + {submitButton ? ( + Request Document + ) : ( + Request Document Success Uploaded + )} + {/* Diagnosis */} + {requestFile?.map((dataRequestFile, index) => { + if(dataRequestFile.type !== 'claim-diagnosis' || dataRequestFile.check_files !== null){ + return null; + } + return ( + + + Diagnosis + + } + spacing={1} + sx={{ marginY: 2 }} + > + {fileDiagnosis && + fileDiagnosis.map((file, index) => ( + + + + {file.name ? file.name : '-'} + + { + removeFileDiagnois(fileDiagnosis, index); + }} + sx={{cursor: 'pointer'}} + > + + ))} + + fileRequestDocumentInputDiagnosis.current?.click()} + > + + + + Add Result + + + handleRequestDocumentInputChangeDiagnosis(event)} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain, application/pdf" + /> + + + ); + })} + {/* Kondisi */} + {requestFile?.map((dataRequestFile, index) => { + if(dataRequestFile.type !== 'claim-kondisi' || dataRequestFile.check_files !== null){ + return null; + } + return ( + + + Condition + + } + spacing={1} + sx={{ marginY: 2 }} + > + {fileKondisi && + fileKondisi.map((file, index) => ( + + + + {file.name ? file.name : '-'} + + { + removeFileKondisi(fileKondisi, index); + }} + sx={{cursor: 'pointer'}} + > + + ))} + + fileRequestDocumentInputKondisi.current?.click()} + > + + + + Add Result + + + handleRequestDocumentInputChangeKondisi(event)} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain, application/pdf" + /> + + + ); + })} + {/* Supporting Result */} + {requestFile?.map((dataRequestFile, index) => { + if(dataRequestFile.type !== 'claim-result' || dataRequestFile.check_files !== null){ + return null; + } + return ( + + + Supporting Result + + } + spacing={1} + sx={{ marginY: 2 }} + > + {fileResult && + fileResult.map((file, index) => ( + + + + {file.name ? file.name : '-'} + + { + removeFileResult(fileResult, index); + }} + sx={{cursor: 'pointer'}} + > + + ))} + + fileRequestDocumentInputResult.current?.click()} + > + + + + Add Result + + + handleRequestDocumentInputChangeResult(event)} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/plain, application/pdf" + /> + + + ); + })} + {submitButton ? ( + { + submitRequestFiles(); + }} + loading={submitLoading} + > + Submit + + ) : ''} ) : ''} diff --git a/frontend/hospital-portal/src/sections/dashboard/TableList2.tsx b/frontend/hospital-portal/src/sections/dashboard/TableList2.tsx index 22c895eb..f10f6048 100644 --- a/frontend/hospital-portal/src/sections/dashboard/TableList2.tsx +++ b/frontend/hospital-portal/src/sections/dashboard/TableList2.tsx @@ -77,7 +77,7 @@ export default function TableList2() { /* ------------------------------ handle order ------------------------------ */ const [order, setOrder] = useState('desc'); - const [orderBy, setOrderBy] = useState('member_id'); + const [orderBy, setOrderBy] = useState('submission_date'); const orders = { order: order,