Files
aso/frontend/dashboard/src/pages/Claims/Show.tsx
2023-09-26 17:23:00 +07:00

522 lines
19 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 { useParams } from 'react-router-dom';
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs';
import Page from '../../components/Page';
import useSettings from '../../hooks/useSettings';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { styled } from '@mui/system';
import axios from '../../utils/axios';
import { enqueueSnackbar } from 'notistack';
import { LoadingButton } from '@mui/lab';
import { fDate } from '@/utils/formatTime';
import Iconify from '../../components/Iconify';
import Documents from './components/Documents';
import DiagnosisHistory from './components/DiagnosisHistory';
import ClaimItems from './components/ClaimItems';
import DialogMemberBenefit from './components/DialogMemberBenefit';
import ClaimDetail from './components/ClaimDetail';
import DialogHistoryPerawatan from './components/DialogHistoryPerawatan';
import { IconButton } from '@mui/material';
import { Tooltip } from '@mui/material';
import { useSelector } from 'react-redux';
export default function ClaimsCreateUpdate() {
const { themeStretch } = useSettings();
const { id } = useParams();
const isEdit = id ? true : false;
const [currentClaim, setCurrentClaim] = useState();
const [documents, setDocuments] = useState([]);
const claimsHistoryData = useSelector((state) => state.claimsHistory)
console.log(claimsHistoryData)
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]);
};
useEffect(() => {
if(claimsHistoryData) {
setClaimItems(claimsHistoryData)
}
},[claimsHistoryData])
const handleSaveClaimItems = () => {
console.log('Storing ', claimItems);
setLoadingClaimItems(true);
axios
.post(`claims/${id}/update-items`, {
benefit_items: claimItems.map((benefit) => {
return {
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);
});
};
const handlePrimaryDiagnosisChange = (diagnosisOption) => {
console.log('handle', diagnosisOption);
if (diagnosisOption) {
const { title, value } = diagnosisOption;
setPrimaryDiagnosis(value);
} else {
setPrimaryDiagnosis(null);
}
};
const handleSecondaryDiagnosisChange = ({ title, value }) => {
setSecondaryDiagnosis(value);
};
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);
});
};
// ----------------------------------------------------------------
// History Perawatan
const [openDialogHistoryPerawatan, setOpenDialogHistoryPerawatan] = useState(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]);
const handleSetFinalEncounter = (encounter) => {
const tempLastFinalEncounterId = currentClaim.final_encounter_id
axios.post(`/claims/${id}/set-final-encounter`, {
encounter_id: encounter.id
})
.then((res) => {
setCurrentClaim({...currentClaim, ...{final_encounter_id: encounter.id}})
enqueueSnackbar(res.data.message, {variant: 'success'})
})
.catch((err) => {
setCurrentClaim({...currentClaim, ...{final_encounter_id: tempLastFinalEncounterId}})
enqueueSnackbar(err.message, {variant: 'error'})
})
setCurrentClaim({...currentClaim, ...{final_encounter_id: encounter.id}})
}
// ------------------------------------------------------------------
// Edit History Perawatan
const [openDialogEditHistoryPerawatan, setOpenDialogEditHistoryPerawatan] = useState(false)
const [editedEncounter, setEditedEncounter] = useState(null)
const showEditEncounter = (encounter) => {
setEditedEncounter(encounter)
setOpenDialogEditHistoryPerawatan(true)
}
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>
<Stack direction="row" justifyContent="space-between" alignItems="center">
<Typography>Admission Date : {currentClaim?.claim_request?.submission_date}</Typography>
</Stack>
</Paper>
<Box sx={{ flexGrow: 1 }}>
<Grid container spacing={2}>
<Grid item xs={5}>
{/* Dokumen Tambahan */}
<Documents files={documents}></Documents>
{/* Riwayat Diagnosa */}
<DiagnosisHistory diagnosis={[]}></DiagnosisHistory>
{/* 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?.current_policy?.code}</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}>
{/* Claim Detail */}
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2 }}>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
sx={{ marginBottom: 2 }}
>
<Stack direction="row" alignItems="center" spacing={1}>
<Iconify icon="eva:bell-fill" />
<Typography variant="body2" fontWeight={600}>
History Perawatan
</Typography>
</Stack>
<Typography
onClick={() => {
setOpenDialogHistoryPerawatan(true);
}}
>
+ Tambah History Perawatan
</Typography>
</Stack>
{/* For Creation History Perawatan / Encounter */}
<DialogHistoryPerawatan
openDialog={openDialogHistoryPerawatan}
setOpenDialog={setOpenDialogHistoryPerawatan}
onChange={() => {}}
claim={currentClaim}
></DialogHistoryPerawatan>
<Paper sx={{ background: 'white', marginY: 2, p: 2 }}>
<Stack sx={{ maxHeight: '250px', overflowY: 'scroll' }}>
{currentClaim?.encounters && currentClaim?.encounters.map((encounter, index) => (
<React.Fragment key={index}>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
sx={{ marginY: 1 }}
>
<Stack>
<Typography fontWeight={'bold'} onClick={() => {showEditEncounter(encounter)}}><a href="#">{ encounter.class_name }</a></Typography>
<Typography sx={{ color: '#777', fontSize: '10px' }}>
({ fDate(encounter.start) } - { fDate(encounter.end) })
</Typography>
<Typography variant="body2">Diagnosis: { encounter.primary_diagnosis ? (`(${encounter.primary_diagnosis.diagnosis?.code}) ${encounter.primary_diagnosis.diagnosis?.name}`) : '-'}</Typography>
<Typography variant="body2">Dokter: { encounter.primary_doctor ? (`${encounter.primary_doctor.name}`) : '-'}</Typography>
</Stack>
<Tooltip title="Diagnosa Final">
<IconButton onClick={() => {handleSetFinalEncounter(encounter)}}>
<Iconify
icon="eva:checkmark-circle-2-fill"
color={currentClaim.final_encounter_id == encounter.id ? "green" : "gray"}
sx={{ margin: 2 }}
></Iconify>
</IconButton>
</Tooltip>
</Stack>
<Divider />
</React.Fragment>
))}
{(!currentClaim?.encounters || currentClaim?.encounters.length == 0) && (
<Typography>Belum ada History Perawatan</Typography>
)}
</Stack>
</Paper>
{/* For Editing History Perawatan / Encounter */}
<DialogHistoryPerawatan
openDialog={openDialogEditHistoryPerawatan}
setOpenDialog={setOpenDialogEditHistoryPerawatan}
onChange={() => {}}
claim={currentClaim}
encounter={editedEncounter}
></DialogHistoryPerawatan>
{/* <ClaimDetail claim={currentClaim} /> */}
</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}></ClaimItems>
<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>
);
}