Update Add Input Hospital Portal
This commit is contained in:
@@ -0,0 +1,448 @@
|
||||
import * as Yup from 'yup';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
|
||||
import MuiDialog from "@/components/MuiDialog";
|
||||
import { Autocomplete, Box, Button, Card, Checkbox, DialogActions, Grid, TextField, Typography } from "@mui/material";
|
||||
import { Paper } from "@mui/material";
|
||||
import { Stack } from '@mui/material';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { DetailFinalLogType } from "../Model/Types";
|
||||
import { fDateTimesecond, toTitleCase } from "@/utils/formatTime";
|
||||
import axios from "@/utils/axios";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useNavigate } from "react-router";
|
||||
import { BenefitConfigurationListType } from "../Model/Types";
|
||||
import { postEditBenefit } from "../Model/Functions";
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { FormProvider, RHFTextField } from "@/components/hook-form";
|
||||
import RHFTextFieldMoney from "@/components/hook-form/v2/RHFTextFieldMoney";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
import { find } from 'lodash';
|
||||
import { fNumber } from '@/utils/formatNumber';
|
||||
import palette from '@/theme/palette';
|
||||
|
||||
|
||||
type DialogDeleteType = {
|
||||
openDialog: boolean;
|
||||
setOpenDialog: any;
|
||||
onSubmit?: void;
|
||||
data: BenefitConfigurationListType|undefined;
|
||||
id: number|undefined;
|
||||
total: any
|
||||
}
|
||||
|
||||
type BenefitSelected = {
|
||||
id: number,
|
||||
description: string,
|
||||
benefit_id: number,
|
||||
family_plan: string,
|
||||
limit_amount: number,
|
||||
}
|
||||
|
||||
export default function DialogEditBenefit({id, data, setOpenDialog, openDialog, onSubmit, total} : DialogDeleteType ) {
|
||||
const handleCloseDialog = () => {
|
||||
setOpenDialog(false);
|
||||
}
|
||||
const [benefitSelected, setBenefitSelected] = useState<BenefitSelected[]>([]);
|
||||
|
||||
// setup form
|
||||
// ====================================
|
||||
const defaultValues: BenefitConfigurationListType = {
|
||||
request_log_id: 0,
|
||||
benefit_name: '',
|
||||
amount_incurred: 0,
|
||||
amount_approved: 0,
|
||||
amount_not_approved: 0,
|
||||
excess_paid: 0,
|
||||
keterangan: '-',
|
||||
description: '-',
|
||||
reason: null
|
||||
};
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
amount_incurred : Yup.string().typeError('').required(''),
|
||||
amount_approved : Yup.string().typeError('').required(''),
|
||||
amount_not_approved : Yup.string().typeError('').required(''),
|
||||
excess_paid : Yup.string().typeError('').required(''),
|
||||
});
|
||||
|
||||
const methods = useForm<any>({
|
||||
resolver: yupResolver(validationSchema),
|
||||
defaultValues
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
return {
|
||||
totalAmountIncurred,
|
||||
totalAmountApproved,
|
||||
totalAmountNotApproved,
|
||||
totalExcessPaid
|
||||
}
|
||||
}
|
||||
|
||||
const findItemById = (id) => {
|
||||
return total.benefit.find(item => item.id === id);
|
||||
}
|
||||
|
||||
const handleOnChangeNominal = (key) => {
|
||||
let benefitData = findItemById(data?.benefit_id)
|
||||
if (benefitData.family_plan == 'S' || benefitData.family_plan == 'F'){
|
||||
// Konversi nilai ke angka dengan aman
|
||||
let limitAmount = Number(benefitData.limit_amount) || 0;
|
||||
let limitAmountPlan = Number(benefitData.limit_amount_plan) || 0;
|
||||
|
||||
if (limitAmountPlan != 999999999){
|
||||
let realTimeUsage = totalAll().totalAmountApproved;
|
||||
console.log(limitAmountPlan, 'test')
|
||||
if (limitAmountPlan < realTimeUsage) {
|
||||
setError(`amount_approved`, { message: `Total Amount Approve sudah melebihi limit ${ fNumber(limitAmountPlan) } , silakan isikan di Amount Excess` });
|
||||
} else if (totalAll().totalAmountApproved > totalAll().totalAmountIncurred) {
|
||||
setError(`amount_approved`, { message: 'Total Amount Approve tidak boleh lebih dari Total Amount Incurred' });
|
||||
} else {
|
||||
clearErrors(`amount_approved`);
|
||||
}
|
||||
} else if (limitAmount != 999999999) {
|
||||
let memberUsage = Number(total.totalLimit[benefitData.id]) || 0;
|
||||
let amountApproved = Number(parseFloat(watch('amount_approved'))) || 0;
|
||||
// Hitung penggunaan waktu nyata
|
||||
let realTimeUsage = memberUsage + amountApproved;
|
||||
// Periksa apakah limitAmount lebih besar dari realTimeUsage
|
||||
if (limitAmount < realTimeUsage) {
|
||||
setError(`amount_approved`, { message: `Total Amount Approve sudah melebihi limit ${ fNumber(limitAmount) } , silakan isikan di Amount Excess` });
|
||||
} else 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`);
|
||||
}
|
||||
} else {
|
||||
if (totalAll().totalAmountApproved > totalAll().totalAmountIncurred) {
|
||||
setError(`amount_approved`, { message: 'Total Amount Approve tidak boleh lebih dari Total Amount Incurred' });
|
||||
} else {
|
||||
clearErrors(`amount_approved`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (totalAll().totalAmountApproved > totalAll().totalAmountIncurred){
|
||||
setError(`amount_approved`, {message: 'Amount Approve tidak boleh lebih dari Amount Incurred'});
|
||||
} else {
|
||||
clearErrors(`amount_approved`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleOnChangeNotApprove = (key, value) => {
|
||||
let amountApproved = Number(parseFloat(watch('amount_approved'))) || 0;
|
||||
let amountNotApproved = Number(parseFloat(watch('amount_not_approved'))) || 0;
|
||||
let amountIncurred = Number(parseFloat(watch('amount_incurred'))) || 0;
|
||||
setValue(`excess_paid`, value);
|
||||
console.log(amountApproved + amountNotApproved, amountIncurred, 'test')
|
||||
if ((amountApproved + amountNotApproved) !== amountIncurred) {
|
||||
setError(`amount_not_approved`, {message: 'Amount Not Approve tidak sama dengan total Amount Incurred'});
|
||||
} else {
|
||||
clearErrors(`amount_not_approved`);
|
||||
}
|
||||
};
|
||||
|
||||
// if (totalAmountIncurred !== (totalAmountApproved+totalAmountNotApproved)){
|
||||
// // alert('Total Incurred tidak sama dengan Total Approve + Total Not Approve')
|
||||
// // setValue('amount_approved', data?.amount_approved)
|
||||
// }
|
||||
|
||||
// Submit Form
|
||||
// =====================================
|
||||
const submitHandler = async (data: BenefitConfigurationListType) => {
|
||||
|
||||
const response = await postEditBenefit(id, data);
|
||||
|
||||
if (response == true) {
|
||||
reset();
|
||||
// navigate('custormer-service/final-log/detail/'+requestLog?.id);
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
|
||||
const reasons = [
|
||||
{ value: 'Wrong Setting', label: 'Wrong Setting' },
|
||||
{ value: 'Hospital Request', label: 'Hospital Request' }
|
||||
];
|
||||
|
||||
// Set Value Form
|
||||
// =====================================
|
||||
useEffect(() => {
|
||||
setValue('amount_incurred', data?.amount_incurred)
|
||||
setValue('amount_approved', data?.amount_approved)
|
||||
setValue('amount_not_approved', data?.amount_not_approved)
|
||||
setValue('excess_paid', data?.excess_paid)
|
||||
setValue('keterangan', data?.keterangan)
|
||||
setValue('reason', data?.reason)
|
||||
}, [data])
|
||||
|
||||
|
||||
const getContent = () => (
|
||||
<FormProvider methods={methods} onSubmit={handleSubmit(submitHandler)}>
|
||||
<Stack paddingX={2} paddingY={4}>
|
||||
{/* <Card sx={{padding:2}}> */}
|
||||
<Box sx={{ marginTop:'10px', marginBottom:'10px', py: '8px', px: '12px', border:'1px solid #919EAB52', borderRadius: '6px'}}>
|
||||
<Grid key={id} container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 'bold'}}>
|
||||
{data?.benefit?.description}
|
||||
</Typography>
|
||||
|
||||
</Grid>
|
||||
<Grid item xs={2}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" component="div">
|
||||
Amount Incurred*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFTextFieldMoney
|
||||
key={id}
|
||||
id='amount_incurred'
|
||||
name={`amount_incurred`}
|
||||
placeholder='Amount Incurred'
|
||||
required
|
||||
onChange={(event) => {
|
||||
setValue(`amount_incurred`, event.target.value)
|
||||
handleOnChangeNominal(id)}
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" component="div">
|
||||
Amount Approved*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFTextFieldMoney
|
||||
// onChange={() => append({amount_approved: ''}) }
|
||||
id='amount_approved'
|
||||
key={id}
|
||||
name={`amount_approved`}
|
||||
placeholder='Amount Approved'
|
||||
required
|
||||
onChange={(event) => {
|
||||
setValue(`amount_approved`, event.target.value)
|
||||
handleOnChangeNominal(id)}
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" component="div">
|
||||
Amount Not Approved*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFTextFieldMoney
|
||||
// onChange={() => append({amount_not_approved: ''}) }
|
||||
id='amount_not_approved'
|
||||
key={id}
|
||||
name={`amount_not_approved`}
|
||||
placeholder='Amount Not Approved'
|
||||
required
|
||||
onChange={(event) => {
|
||||
setValue(`amount_not_approved`, event.target.value)
|
||||
handleOnChangeNotApprove(id, event.target.value)}
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" component="div">
|
||||
Excess Paid*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFTextFieldMoney
|
||||
// onChange={() => append({excess_paid: ''}) }
|
||||
id='excess_paid'
|
||||
key={id}
|
||||
name={`excess_paid`}
|
||||
placeholder='Excess Paid'
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" component="div">
|
||||
Keterangan
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<RHFTextField
|
||||
// onChange={() => append({keterangan: ''}) }
|
||||
id='keterangan'
|
||||
key={id}
|
||||
name={`keterangan`}
|
||||
placeholder='Keterangan'
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={2}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" component="div">
|
||||
Reason*
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{display: 'flex', gap: 1}}>
|
||||
<Autocomplete
|
||||
options={reasons}
|
||||
getOptionLabel={(option) => option.label}
|
||||
fullWidth
|
||||
value={reasons.find((r) => r.value === watch('reason')) || null}// Use find to match the default value
|
||||
onChange={(event, newValue) => {
|
||||
setValue(`reason`, newValue?.value);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label="Reason"
|
||||
variant="outlined"
|
||||
required
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} marginTop={3}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body2" sx={{ fontWeight: 'bold'}}>
|
||||
Total Current Benefit
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Box sx={{ py: '8px', px: '12px', background: palette.light.grey[50012], borderRadius: '6px'}}>
|
||||
<Grid container spacing={1} alignItems={'end'}>
|
||||
{/* Amount Incurred */}
|
||||
<Grid item xs={2}>
|
||||
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ textAlign: 'right' }}>
|
||||
Amount Incurred
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||
{totalAll().totalAmountIncurred ? fNumber(totalAll().totalAmountIncurred) : 0}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Amount Approved */}
|
||||
<Grid item xs={2}>
|
||||
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ textAlign: 'right' }}>
|
||||
Amount Approved
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||
{totalAll().totalAmountApproved ? fNumber(totalAll().totalAmountApproved) : 0}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Amount Not Approved */}
|
||||
<Grid item xs={2}>
|
||||
<Grid container sx={{ borderRight: `0.5px solid ${palette.light.grey[400]}` }}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ textAlign: 'right' }}>
|
||||
Amount Not Approved
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||
{totalAll().totalAmountNotApproved ? fNumber(totalAll().totalAmountNotApproved) : 0}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Excess Paid* */}
|
||||
<Grid item xs={2}>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ textAlign: 'right' }}>
|
||||
Excess Paid
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
|
||||
{totalAll().totalExcessPaid ? fNumber(totalAll().totalExcessPaid) : 0}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
{/* </Card> */}
|
||||
<DialogActions>
|
||||
<Stack direction="row" sx={{marginTop:3}} alignItems="center" justifyContent="space-between" spacing={2}>
|
||||
<Button variant="outlined" onClick={handleCloseDialog}><Typography>Cancel</Typography></Button>
|
||||
<LoadingButton disabled={errorsExist} type="submit" variant="contained" loading={isSubmitting}>
|
||||
Save
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</DialogActions>
|
||||
</Stack>
|
||||
</FormProvider>
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<MuiDialog
|
||||
title={{name: "Edit Detail Benefit"}}
|
||||
openDialog={openDialog}
|
||||
setOpenDialog={setOpenDialog}
|
||||
content={getContent()}
|
||||
maxWidth="xl"
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user