417 lines
16 KiB
TypeScript
Executable File
417 lines
16 KiB
TypeScript
Executable File
import * as Yup from 'yup';
|
|
import { yupResolver } from '@hookform/resolvers/yup';
|
|
import { Autocomplete, Button, Card, Collapse, Divider, Grid, 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';
|
|
|
|
export default function ClaimsCreate() {
|
|
const navigate = useNavigate();
|
|
|
|
const [member, setMember] = useState();
|
|
const selectedMemberDisplay = useRef<HTMLInputElement>(null);
|
|
|
|
const NewClaimSchema = Yup.object().shape({
|
|
member_id: Yup.string().required('Please select Member'),
|
|
total_claim: Yup.number().typeError('Claim should be a number').min(1, 'Claim cannot 0').required('Total Claim is required'),
|
|
diagnosis: Yup.object().required('Choose Diagnosis'),
|
|
benefit: Yup.object().required('Please Select Benefit')
|
|
});
|
|
|
|
const defaultValues = useMemo(
|
|
() => ({
|
|
member_id: null,
|
|
benefit_id: null,
|
|
diagnosis_id: null,
|
|
total_claim: 0,
|
|
benefit: null
|
|
}),
|
|
[]
|
|
);
|
|
|
|
const methods = useForm({
|
|
resolver: yupResolver(NewClaimSchema),
|
|
defaultValues,
|
|
});
|
|
|
|
const {
|
|
reset,
|
|
watch,
|
|
control,
|
|
setValue,
|
|
getValues,
|
|
setError,
|
|
handleSubmit,
|
|
formState: { isSubmitting },
|
|
} = methods;
|
|
|
|
const onSubmit = async (data: any) => {
|
|
axios.post('claims', getValues())
|
|
.then(function(res) {
|
|
console.log('SUCCESS', res)
|
|
enqueueSnackbar('Success Creating Claim', { variant: 'success' })
|
|
navigate('/claims');
|
|
})
|
|
.catch(function (err) {
|
|
console.log('ERROR CUK', err.data)
|
|
enqueueSnackbar('Failed Creating Claim', { variant: 'error' })
|
|
})
|
|
};
|
|
|
|
const [memberBenefits, setMemberBenefits] = useState([]);
|
|
const getMemberBenefits = (member) => {
|
|
axios.get(`members/${member.id}/benefits`)
|
|
.then( (res) => {
|
|
setMemberBenefits(res.data);
|
|
})
|
|
.catch( (err) => {
|
|
enqueueSnackbar('Failed getting member benefits', { variant: 'error' })
|
|
})
|
|
}
|
|
|
|
const [isMemberDialogOpen, setIsMemberDialogOpen] = useState(false);
|
|
|
|
const memberSelected = (selectedMember: any) => {
|
|
// Reset Selected Benefit
|
|
setMemberBenefits([]);
|
|
setValue('benefit_id', null);
|
|
setValue('benefit', null);
|
|
|
|
setMember(selectedMember);
|
|
setValue('member_id', selectedMember.id)
|
|
|
|
getMemberBenefits(selectedMember)
|
|
};
|
|
|
|
const [diagnosis, setDiagnosis] = useState([]);
|
|
|
|
const searchDiagnosis = (search) => {
|
|
axios.get('master/diagnosis/search', {params: {search}})
|
|
.then(function(res) {
|
|
setDiagnosis(res.data);
|
|
})
|
|
}
|
|
|
|
useEffect(() => { // Trigger First Search
|
|
axios.get('master/diagnosis/search')
|
|
.then(function(res) {
|
|
setDiagnosis(res.data);
|
|
})
|
|
|
|
}, [])
|
|
|
|
const [isEligible, setIsEligible] = useState<boolean|null>(null)
|
|
|
|
const [isCheckingLimit, setIsCheckingLimit] = useState(false)
|
|
const checkLimit = (event) => {
|
|
event.preventDefault();
|
|
|
|
console.log(getValues('diagnosis_id'))
|
|
if (!member || !getValues('diagnosis_id')) {
|
|
enqueueSnackbar('Please Check the Data', { variant: 'error' })
|
|
|
|
return false;
|
|
}
|
|
|
|
setIsCheckingLimit(true)
|
|
axios.post('check-limit', {
|
|
'member_id' : member.id,
|
|
'diagnosis' : getValues('diagnosis_id'),
|
|
'total_claim' : getValues('total_claim')
|
|
})
|
|
.then((res) => {
|
|
setIsEligible(true)
|
|
})
|
|
.catch((err) => {
|
|
enqueueSnackbar('Failed Checking Limit : ' + err.message ?? '', { variant: 'error' })
|
|
})
|
|
.then(() => {
|
|
setIsCheckingLimit(false)
|
|
})
|
|
}
|
|
|
|
const headStyle = {
|
|
fontWeight: 'bold'
|
|
};
|
|
|
|
return (
|
|
<Page title="Create Claim" sx={{ mx: 2 }}>
|
|
<HeaderBreadcrumbs
|
|
heading={'Create Claim'}
|
|
links={[
|
|
{ name: 'Dashboard', href: '/dashboard' },
|
|
{
|
|
name: 'Claims',
|
|
href: '/claims',
|
|
},
|
|
{
|
|
name: 'Create',
|
|
href: '/claims/create',
|
|
},
|
|
]}
|
|
/>
|
|
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={12}>
|
|
<Card sx={{ p: 2 }}>
|
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
|
<Stack spacing={3}>
|
|
|
|
<Typography variant="h6">Member</Typography>
|
|
|
|
<Stack spacing={2} direction="row">
|
|
<Grid item xs={12}>
|
|
<RHFTextField
|
|
name="member_id"
|
|
label="Member"
|
|
variant="outlined"
|
|
fullWidth
|
|
value={member?.name || ''}
|
|
ref={selectedMemberDisplay}
|
|
InputProps={{
|
|
readOnly: true,
|
|
}}
|
|
onClick={() => {setIsMemberDialogOpen(true)}}
|
|
/>
|
|
</Grid>
|
|
{/* <Grid item xs={2}>
|
|
<Button variant="outlined" fullWidth sx={{ p: 1.8 }} onClick={() => {
|
|
setIsMemberDialogOpen(true)
|
|
}}>
|
|
{member ? 'Change' : 'Search'}
|
|
</Button>
|
|
</Grid> */}
|
|
</Stack>
|
|
|
|
{ member && (
|
|
<Stack>
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={12} md={6}>
|
|
<Table border="light-700">
|
|
<TableBody>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Name</TableCell>
|
|
<TableCell align="left">{member.full_name}</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">DOB</TableCell>
|
|
<TableCell align="left">{member.birth_date} ({member.age + ' years'})</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Marital Status</TableCell>
|
|
<TableCell align="left">{member.marital_status}</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Record Type</TableCell>
|
|
<TableCell align="left">{member.record_type}</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Principal ID</TableCell>
|
|
<TableCell align="left">{member.principal_id} ({member.relation_with_principal})</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
</Table>
|
|
</Grid>
|
|
<Grid item xs={12} md={6}>
|
|
<Table border="light-700">
|
|
<TableBody>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Plan</TableCell>
|
|
<TableCell align="left">{member.current_plan.code}</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Active</TableCell>
|
|
<TableCell align="left">{member.current_plan.start} - {member.current_plan.end} (Active)</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Corporate Limit</TableCell>
|
|
<TableCell align="left">{fCurrency(0)} / {fCurrency(member.current_plan.limit_rules)}</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableCell style={headStyle} align="left">Plan Usage</TableCell>
|
|
<TableCell align="left">{fCurrency(0)} / {fCurrency(member.current_plan.limit_rules)}</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
</Table>
|
|
</Grid>
|
|
</Grid>
|
|
</Stack>
|
|
)}
|
|
|
|
<Controller
|
|
name="benefit"
|
|
control={control}
|
|
render={({ field: { onChange, value } }) => (
|
|
<Autocomplete
|
|
options={memberBenefits}
|
|
getOptionLabel={(option) =>
|
|
option ? `#${option.id} (${option.code}) ${option.description}` : ''
|
|
}
|
|
value={value || ''}
|
|
onChange={(event: any, newValue: any) => {
|
|
setValue('benefit_id', newValue?.id)
|
|
onChange(newValue);
|
|
}}
|
|
renderInput={(params) => (
|
|
<TextField
|
|
// name="benefit"
|
|
{...params}
|
|
label="Benefit"
|
|
variant="outlined"
|
|
fullWidth
|
|
// onKeyPress={(event) => {
|
|
// if (event.key === 'Enter')
|
|
// searchDiagnosis(event.target.value)
|
|
// }}
|
|
/>
|
|
)}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<Controller
|
|
name="diagnosis"
|
|
control={control}
|
|
render={({ field: { onChange, value } }) => (
|
|
<Autocomplete
|
|
options={diagnosis}
|
|
getOptionLabel={(option) =>
|
|
option ? `(${option.code}) ${option.name}` : ''
|
|
}
|
|
value={value || ''}
|
|
onChange={(event: any, newValue: any) => {
|
|
setValue('diagnosis_id', newValue?.id)
|
|
// setValue('diagnosis', newValue)
|
|
onChange(newValue);
|
|
}}
|
|
renderInput={(params) => (
|
|
<RHFTextField
|
|
name="diagnosis"
|
|
{...params}
|
|
label="Diagnosis"
|
|
variant="outlined"
|
|
fullWidth
|
|
onKeyPress={(event) => {
|
|
if (event.key === 'Enter')
|
|
searchDiagnosis(event.target.value)
|
|
}}
|
|
/>
|
|
)}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
{ isCheckingLimit && (
|
|
<Stack sx={{ backgroundColor: 'gray', paddingY: 1, paddingX: 1.5, mb: 2, borderRadius: '3-xl' }}>
|
|
{/* Checking */}
|
|
<Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
|
<Iconify
|
|
icon="bxs:info-circle"
|
|
width={12}
|
|
height={13}
|
|
sx={{ color: '#424242', marginRight: '6px' }}
|
|
/>
|
|
<Typography variant="caption" component="span">
|
|
Please Wait, Checking Eligibilty
|
|
</Typography>
|
|
</Typography>
|
|
</Stack>
|
|
)}
|
|
{ false && isCheckingLimit == false && isEligible == null && (
|
|
<Stack sx={{ backgroundColor: 'gray', paddingY: 1, paddingX: 1.5, mb: 2, borderRadius: '3-xl' }}>
|
|
{/* No Data Selected */}
|
|
<Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
|
<Iconify
|
|
icon="bxs:info-circle"
|
|
width={12}
|
|
height={13}
|
|
sx={{ color: '#424242', marginRight: '6px' }}
|
|
/>
|
|
<Typography variant="caption" component="span">
|
|
Please Select Diagnosis !
|
|
</Typography>
|
|
</Typography>
|
|
</Stack>
|
|
)}
|
|
{ (!isCheckingLimit && isEligible !== null) && isEligible && (
|
|
<Stack sx={{ backgroundColor: '#B2E8E8', paddingY: 1, paddingX: 1.5, mb: 2, borderRadius: '3-xl' }}>
|
|
{/* Eligible */}
|
|
<Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
|
<Iconify
|
|
icon="bxs:lock-alt"
|
|
width={12}
|
|
height={13}
|
|
sx={{ color: '#424242', marginRight: '6px' }}
|
|
/>
|
|
<Typography variant="caption" component="span">
|
|
Diagnosis is Eligible
|
|
</Typography>
|
|
</Typography>
|
|
<Typography sx={{ typography: 'caption', color: '#637381' }}>
|
|
125.000.000 / 125.000.000
|
|
</Typography>
|
|
</Stack>
|
|
)}
|
|
{ (!isCheckingLimit && isEligible !== null) && !isEligible && (
|
|
<Stack sx={{ backgroundColor: '#B2E8E8', paddingY: 1, paddingX: 1.5, mb: 2, borderRadius: '3-xl' }}>
|
|
{/* Not Eligible */}
|
|
<Typography sx={{ typography: 'caption', display: 'flex', alignItems: 'center' }}>
|
|
<Iconify
|
|
icon="bxs:lock-alt"
|
|
width={12}
|
|
height={13}
|
|
sx={{ color: '#424242', marginRight: '6px' }}
|
|
/>
|
|
<Typography variant="caption" component="span">
|
|
Not Eligible
|
|
</Typography>
|
|
</Typography>
|
|
<Typography sx={{ typography: 'caption', color: '#637381' }}>
|
|
125.000.000 / 125.000.000
|
|
</Typography>
|
|
</Stack>
|
|
)}
|
|
|
|
|
|
|
|
<RHFTextField type="number" name="total_claim" label="Total Claim" />
|
|
|
|
<LoadingButton onClick={handleSubmit(onSubmit)} variant="contained" color="success" style={{color: '#ffffff'}} size="large" fullWidth={true} loading={isCheckingLimit}>
|
|
Create Claim
|
|
</LoadingButton>
|
|
{ isEligible === true ? (
|
|
<LoadingButton onClick={handleSubmit(onSubmit)} variant="contained" color="success" style={{color: '#ffffff'}} size="large" fullWidth={true} loading={isCheckingLimit}>
|
|
Create Claim
|
|
</LoadingButton>
|
|
) : (
|
|
<LoadingButton onClick={checkLimit} variant="outlined" size="large" fullWidth={true} loading={isCheckingLimit}>
|
|
Check Limit
|
|
</LoadingButton>
|
|
)}
|
|
|
|
</Stack>
|
|
</FormProvider>
|
|
</Card>
|
|
</Grid>
|
|
</Grid>
|
|
|
|
<MemberSelectDialog
|
|
openDialog={isMemberDialogOpen}
|
|
setOpenDialog={setIsMemberDialogOpen}
|
|
onSelect={memberSelected}
|
|
></MemberSelectDialog>
|
|
</Page>
|
|
);
|
|
}
|