449 lines
15 KiB
TypeScript
449 lines
15 KiB
TypeScript
import * as Yup from 'yup';
|
|
import { yupResolver } from '@hookform/resolvers/yup';
|
|
import {
|
|
Autocomplete,
|
|
Box,
|
|
Button,
|
|
Card,
|
|
Collapse,
|
|
Container,
|
|
Divider,
|
|
Grid,
|
|
InputAdornment,
|
|
Paper,
|
|
Stack,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableRow,
|
|
TextField,
|
|
Typography,
|
|
} from '@mui/material';
|
|
import { Controller, useForm } from 'react-hook-form';
|
|
import { useParams, useNavigate } from 'react-router-dom';
|
|
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
|
|
import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from '../../components/hook-form';
|
|
import Page from '../../components/Page';
|
|
import useSettings from '../../hooks/useSettings';
|
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
// import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog';
|
|
import { styled } from '@mui/system';
|
|
import axios from '../../utils/axios';
|
|
import { enqueueSnackbar } from 'notistack';
|
|
import { LoadingButton } from '@mui/lab';
|
|
import { fCurrency } from '../../utils/formatNumber';
|
|
import Iconify from '../../components/Iconify';
|
|
import Form from './Form';
|
|
import Documents from './components/Documents';
|
|
import DiagnosisHistory from './components/DiagnosisHistory';
|
|
import ClaimItems from './components/ClaimItems';
|
|
import DialogMemberBenefit from './components/DialogMemberBenefit';
|
|
// import AutocompleteDiagnosis from '../../components/autocomplete/AutocompleteDiagnosis';
|
|
|
|
export default function ClaimsCreateUpdate() {
|
|
const { themeStretch } = useSettings();
|
|
const { id } = useParams();
|
|
|
|
const isEdit = id ? true : false;
|
|
|
|
const [currentClaim, setCurrentClaim] = useState();
|
|
const [documents, setDocuments] = useState([]);
|
|
|
|
const Item = styled(Paper)(({ theme }) => ({
|
|
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
|
|
...theme.typography.body2,
|
|
padding: theme.spacing(1),
|
|
textAlign: 'center',
|
|
color: theme.palette.text.secondary,
|
|
}));
|
|
|
|
// --------------------------------------------------------------
|
|
// Claim Item
|
|
const [claimItems, setClaimItems] = useState([]);
|
|
const [dialogAddClaimItemOpen, setDialogAddClaimItemOpen] = useState(false);
|
|
const [loadingClaimItems, setLoadingClaimItems] = useState(false);
|
|
|
|
const handleAddClaimItems = (items) => {
|
|
setClaimItems([...claimItems, ...items]);
|
|
};
|
|
|
|
const handleSaveClaimItems = () => {
|
|
console.log('Storing ', claimItems);
|
|
setLoadingClaimItems(true);
|
|
axios
|
|
.post(`claims/${id}/update-items`, {
|
|
benefit_items: claimItems.map((benefit) => ({
|
|
id: benefit.id,
|
|
biaya_diajukan: benefit.biaya_diajukan,
|
|
biaya_disetujui: benefit.biaya_disetujui,
|
|
})),
|
|
})
|
|
.then((res) => {
|
|
enqueueSnackbar(res.data.message, { variant: 'success' });
|
|
})
|
|
.catch((err) => {
|
|
setLoadingClaimItems(false);
|
|
enqueueSnackbar(err.response?.data?.message ?? err?.message, { variant: 'error' });
|
|
})
|
|
.then(() => {
|
|
setLoadingClaimItems(false);
|
|
});
|
|
};
|
|
|
|
// --------------------------------------------------------------
|
|
// Diagnosis
|
|
const [primaryDiagnosis, setPrimaryDiagnosis] = useState(null);
|
|
const [secondaryDiagnosis, setSecondaryDiagnosis] = useState(null);
|
|
const [loadingDiagnosis, setLoadingDiagnosis] = useState(false);
|
|
|
|
const handlePrimaryDiagnosisChange = ({ title, value }) => {
|
|
setPrimaryDiagnosis(value);
|
|
};
|
|
|
|
const handleSecondaryDiagnosisChange = ({ title, value }) => {
|
|
setSecondaryDiagnosis(value);
|
|
};
|
|
|
|
const handleSaveDiagnosis = () => {
|
|
setLoadingDiagnosis(true);
|
|
|
|
axios
|
|
.post(`claims/${id}/update-diagnosis`, {
|
|
primary: [primaryDiagnosis],
|
|
secondary: [secondaryDiagnosis],
|
|
})
|
|
.then((res) => {
|
|
enqueueSnackbar(res.data.message, { variant: 'success' });
|
|
})
|
|
.catch((err) => {
|
|
setLoadingDiagnosis(false);
|
|
enqueueSnackbar(err.response?.data?.message ?? err?.message, { variant: 'error' });
|
|
})
|
|
.then(() => {
|
|
setLoadingDiagnosis(false);
|
|
});
|
|
};
|
|
|
|
const handleDecline = () => {
|
|
axios
|
|
.post(`claims/${id}/decline`)
|
|
.then((res) => {
|
|
enqueueSnackbar(res.data.message, { variant: 'success' });
|
|
setCurrentClaim({ ...currentClaim, status: 'declined' });
|
|
})
|
|
.catch((err) => {
|
|
// setLoadingDiagnosis(false)
|
|
enqueueSnackbar(err.response?.data?.message ?? err?.message, { variant: 'error' });
|
|
})
|
|
.then(() => {
|
|
// setLoadingDiagnosis(false)
|
|
});
|
|
};
|
|
|
|
const handleApprove = () => {
|
|
axios
|
|
.post(`claims/${id}/approve`)
|
|
.then((res) => {
|
|
enqueueSnackbar(res.data.message, { variant: 'success' });
|
|
setCurrentClaim({ ...currentClaim, status: 'approved' });
|
|
})
|
|
.catch((err) => {
|
|
// setLoadingDiagnosis(false)
|
|
enqueueSnackbar(err.response?.data?.message ?? err?.message, { variant: 'error' });
|
|
})
|
|
.then(() => {
|
|
// setLoadingDiagnosis(false)
|
|
});
|
|
};
|
|
|
|
const handleReOpen = () => {
|
|
axios
|
|
.post(`claims/${id}/re-open`)
|
|
.then((res) => {
|
|
enqueueSnackbar(res.data.message, { variant: 'success' });
|
|
setCurrentClaim({ ...currentClaim, status: 'received' });
|
|
})
|
|
.catch((err) => {
|
|
// setLoadingDiagnosis(false)
|
|
enqueueSnackbar(err.response?.data?.message ?? err?.message, { variant: 'error' });
|
|
})
|
|
.then(() => {
|
|
// setLoadingDiagnosis(false)
|
|
});
|
|
};
|
|
|
|
// ---------------------------------------------------------------
|
|
// Initial LOG
|
|
const [loadingLog, setLoadingLog] = useState(false);
|
|
|
|
const handleDownloadLog = (claim_id) => {
|
|
setLoadingLog(true);
|
|
axios
|
|
.post(`generate-log/${claim_id}`, {
|
|
responseType: 'blob',
|
|
})
|
|
.then((response) => {
|
|
window.open(URL.createObjectURL(response.data));
|
|
setLoadingLog(false);
|
|
setOpenDialog(false);
|
|
})
|
|
.catch((response) => {
|
|
enqueueSnackbar(response.message, { variant: 'error' });
|
|
setLoadingLog(false);
|
|
});
|
|
};
|
|
|
|
// -------------------------------------------------
|
|
// Final LOG
|
|
const [loadingFinalLog, setLoadingFinalLog] = useState(false);
|
|
const handleDownloadFinalLog = (claim_id) => {
|
|
setLoadingFinalLog(true);
|
|
axios
|
|
.get(`final-log/${claim_id}`, {
|
|
responseType: 'blob',
|
|
})
|
|
.then((response) => {
|
|
window.open(URL.createObjectURL(response.data));
|
|
setLoadingFinalLog(false);
|
|
})
|
|
.catch((response) => {
|
|
enqueueSnackbar(response.message, { variant: 'error' });
|
|
setLoadingFinalLog(false);
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
axios.get('/claims/' + id).then(({ data }) => {
|
|
const claim = data.data;
|
|
const allFiles = [...(claim.claim_request ? claim.claim_request.files : []), ...claim.files];
|
|
|
|
setCurrentClaim(claim);
|
|
setDocuments(allFiles);
|
|
setClaimItems(claim.benefit_items);
|
|
});
|
|
}, [id]);
|
|
|
|
return (
|
|
<Page title={`Claim : ${currentClaim?.code}`}>
|
|
<Container maxWidth={themeStretch ? false : 'xl'}>
|
|
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
<HeaderBreadcrumbs
|
|
heading={`Claim : ${currentClaim?.code}`}
|
|
links={[
|
|
{ name: 'Dashboard', href: '/dashboard' },
|
|
{
|
|
name: 'Claim',
|
|
href: '/claims',
|
|
},
|
|
{ name: currentClaim?.code ?? '' },
|
|
]}
|
|
/>
|
|
|
|
{/* Action Button */}
|
|
<Stack direction="row" spacing={2} sx={{ position: 'relative', bottom: '15px' }}>
|
|
{(currentClaim?.status == 'requested' || currentClaim?.status == 'received') && (
|
|
<>
|
|
<LoadingButton
|
|
loading={false}
|
|
variant="outlined"
|
|
color="error"
|
|
onClick={() => {
|
|
handleDecline();
|
|
}}
|
|
>
|
|
Decline
|
|
</LoadingButton>
|
|
<LoadingButton
|
|
loading={false}
|
|
variant="contained"
|
|
onClick={() => {
|
|
handleApprove();
|
|
}}
|
|
>
|
|
Approve
|
|
</LoadingButton>
|
|
</>
|
|
)}
|
|
{(currentClaim?.status == 'declined' || currentClaim?.status == 'approved') && (
|
|
<LoadingButton
|
|
loading={false}
|
|
variant="contained"
|
|
onClick={() => {
|
|
handleReOpen();
|
|
}}
|
|
>
|
|
Re-Open
|
|
</LoadingButton>
|
|
)}
|
|
</Stack>
|
|
</Stack>
|
|
|
|
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginY: 2 }}>
|
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
|
<Typography>Status : {currentClaim?.status}</Typography>
|
|
{currentClaim?.status === 'approved' && (
|
|
<LoadingButton
|
|
loading={loadingFinalLog}
|
|
variant="contained"
|
|
onClick={() => {
|
|
handleDownloadFinalLog(currentClaim.id);
|
|
}}
|
|
>
|
|
Download Final LOG
|
|
</LoadingButton>
|
|
)}
|
|
</Stack>
|
|
</Paper>
|
|
|
|
<Box sx={{ flexGrow: 1 }}>
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={5}>
|
|
{/* Dokumen Tambahan */}
|
|
<Documents files={documents} />
|
|
|
|
{/* Riwayat Diagnosa */}
|
|
<DiagnosisHistory diagnosis={[]} />
|
|
|
|
{/* Ringkasan Data Member */}
|
|
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginTop: 2 }}>
|
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
|
<Stack direction="row" alignItems="center" spacing={1}>
|
|
<Iconify icon="eva:bell-fill" />
|
|
<Typography variant="body2" fontWeight={600}>
|
|
Ringkasan Data Nasabah
|
|
</Typography>
|
|
</Stack>
|
|
<Iconify icon="eva:eye-fill" />
|
|
</Stack>
|
|
|
|
<Paper sx={{ background: 'white', marginTop: 2, p: 2 }}>
|
|
<Stack>
|
|
<Box sx={{ flexGrow: 1 }}>
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={12}>
|
|
<Stack>
|
|
<Typography variant="body2" fontWeight={600}>
|
|
Nama Lengkap
|
|
</Typography>
|
|
<Typography variant="body2">
|
|
{currentClaim?.member?.full_name}
|
|
</Typography>
|
|
</Stack>
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
<Typography variant="body2" fontWeight={600}>
|
|
Nomor Polis
|
|
</Typography>
|
|
<Typography variant="body2">{currentClaim?.member?.full_name}</Typography>
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
<Typography variant="body2" fontWeight={600}>
|
|
Member ID
|
|
</Typography>
|
|
<Typography variant="body2">{currentClaim?.member?.member_id}</Typography>
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
<Typography variant="body2" fontWeight={600}>
|
|
Tipe Claim
|
|
</Typography>
|
|
<Typography variant="body2">
|
|
{currentClaim?.claim_request?.payment_type_name}
|
|
</Typography>
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
<Typography variant="body2" fontWeight={600}>
|
|
Tipe Nasabah
|
|
</Typography>
|
|
<Typography variant="body2">
|
|
{currentClaim?.member?.current_corporate?.name}
|
|
</Typography>
|
|
</Grid>
|
|
</Grid>
|
|
</Box>
|
|
</Stack>
|
|
</Paper>
|
|
</Paper>
|
|
</Grid>
|
|
|
|
<Grid item xs={7}>
|
|
{/* Diagnosis */}
|
|
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2 }}>
|
|
<Paper variant="outlined" sx={{ background: 'white', p: 2 }}>
|
|
<Stack spacing={2}>
|
|
{/* <AutocompleteDiagnosis
|
|
onChange={handlePrimaryDiagnosisChange}
|
|
textLabel="Diagnosa Utama (ICD-X)"
|
|
currentValue={
|
|
currentClaim?.primary_diagnosis ? currentClaim?.primary_diagnosis : null
|
|
}
|
|
/>
|
|
<AutocompleteDiagnosis
|
|
onChange={handleSecondaryDiagnosisChange}
|
|
textLabel="Diagnosa Tambahan (ICD-X)"
|
|
currentValue={
|
|
currentClaim?.secondary_diagnosis ? currentClaim?.secondary_diagnosis : null
|
|
}
|
|
/> */}
|
|
</Stack>
|
|
</Paper>
|
|
|
|
{(currentClaim?.status == 'requested' || currentClaim?.status == 'received') && (
|
|
<LoadingButton
|
|
variant="contained"
|
|
sx={{ marginTop: 2 }}
|
|
loading={loadingDiagnosis}
|
|
onClick={() => {
|
|
handleSaveDiagnosis();
|
|
}}
|
|
>
|
|
Simpan Claim Item
|
|
</LoadingButton>
|
|
)}
|
|
</Paper>
|
|
|
|
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginTop: 2 }}>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography sx={{ marginBottom: 1 }}>Client Benefit Configuration</Typography>
|
|
<Typography
|
|
onClick={() => {
|
|
setDialogAddClaimItemOpen(true);
|
|
}}
|
|
>
|
|
+ Add Benefit
|
|
</Typography>
|
|
</Stack>
|
|
<ClaimItems items={claimItems} setItems={setClaimItems} />
|
|
<Stack alignItems={'flex-end'}>
|
|
{(currentClaim?.status == 'requested' || currentClaim?.status == 'received') && (
|
|
<LoadingButton
|
|
variant="contained"
|
|
sx={{ marginTop: 2 }}
|
|
loading={loadingClaimItems}
|
|
onClick={() => {
|
|
handleSaveClaimItems();
|
|
}}
|
|
>
|
|
Simpan Claim Item
|
|
</LoadingButton>
|
|
)}
|
|
</Stack>
|
|
|
|
<DialogMemberBenefit
|
|
openDialog={dialogAddClaimItemOpen}
|
|
setOpenDialog={setDialogAddClaimItemOpen}
|
|
member={currentClaim?.member ?? null}
|
|
onSubmit={handleAddClaimItems}
|
|
/>
|
|
</Paper>
|
|
</Grid>
|
|
</Grid>
|
|
</Box>
|
|
</Container>
|
|
</Page>
|
|
);
|
|
}
|