Merge remote-tracking branch 'origin/staging' into origin/production

This commit is contained in:
Linksehat Staging Server
2024-03-05 13:41:28 +07:00
41 changed files with 3431 additions and 2144 deletions

View File

@@ -145,51 +145,62 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
const methods = useForm<any>({
resolver: yupResolver(validationSchema),
defaultValues
defaultValues,
reValidateMode: "onChange"
});
let width = claimInput ? 2 : 2.36;
const {fields, append, remove} = useFieldArray({name: 'benefit_data',control: methods.control});
const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods
// Buat total data
let totalAmountIncurred = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.amount_incurred || 0);
}, 0);
let totalAmountApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.amount_approved || 0);
}, 0);
let totalAmountNotApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.amount_not_approved || 0);
}, 0);
let totalExcessPaid = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.excess_paid || 0);
}, 0);
const {fields, append, remove} = useFieldArray({name: 'benefit_data',control: methods.control,});
const { handleSubmit, reset, watch, setValue, setError, clearErrors, formState: { isDirty, isSubmitting, errors,isValid } } = methods
const errorsExist = errors ? Object.keys(errors).length > 0 : false;
// Calculate
const benefitData = watch('benefit_data');
const [isDisableSave, setDisableSave] = useState(false)
benefitData?.map((item, index) => {
totalAmountIncurred += parseFloat(item.amount_incurred);
totalAmountApproved += parseFloat(item.amount_approved);
totalAmountNotApproved += parseFloat(item.amount_not_approved);
totalExcessPaid += parseFloat(item.excess_paid);
const totalAll = () => {
let totalAmountIncurred = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.amount_incurred || 0);
}, 0);
let totalAmountApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.amount_approved || 0);
}, 0);
let totalAmountNotApproved = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.amount_not_approved || 0);
}, 0);
let totalExcessPaid = (requestLog?.benefit_data || []).reduce((accumulator, item) => {
return accumulator + (item.excess_paid || 0);
}, 0);
if (totalAmountApproved != 0 && totalAmountIncurred != 0) {
if (totalAmountApproved > totalAmountIncurred){
setValue(`benefit_data.${index}.amount_approved`, 0)
alert('Total Amount Approved tidak boleh lebih dari Total Incurred')
}
}
benefitData?.map((item, index) => {
totalAmountIncurred += parseFloat(item.amount_incurred);
totalAmountApproved += parseFloat(item.amount_approved);
totalAmountNotApproved += parseFloat(item.amount_not_approved);
totalExcessPaid += parseFloat(item.excess_paid);
});
return {
totalAmountIncurred,
totalAmountApproved,
totalAmountNotApproved,
totalExcessPaid
}
}
const handleOnChangeNominal = (key) => {
if (totalAll().totalAmountApproved > totalAll().totalAmountIncurred){
// setValue(`benefit_data.${key}.amount_approved`, 0);
setError(`benefit_data.${key}.amount_approved`, {message: 'Amount Approve tidak boleh lebih dari Amount Incurred'});
} else {
clearErrors(`benefit_data.${key}.amount_approved`);
}
}
});
// Submit Form
// =====================================
const submitHandler = async (data: BenefitConfigurationListType) => {
const mapData = data.benefit_data.map((item) => ({
...item,
reason: item.reason.value
reason: item.reason ? item.reason.value : null
}));
const newData = {
@@ -206,8 +217,6 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
}
}
// Calculate
const getContent = () => !addBenefit ? (
<Stack spacing={2} sx={{marginTop: 2, padding: 2}} direction="column">
<Stack direction="row" spacing={2}>
@@ -281,6 +290,10 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
name={`benefit_data.${index}.amount_incurred`}
placeholder='Amount Incurred'
required
onChange={(event) => {
setValue(`benefit_data.${index}.amount_incurred`, event.target.value)
handleOnChangeNominal(index)}
}
/>
</Grid>
</Grid>
@@ -301,6 +314,10 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
name={`benefit_data.${index}.amount_approved`}
placeholder='Amount Approved'
required
onChange={(event) => {
setValue(`benefit_data.${index}.amount_approved`, event.target.value)
handleOnChangeNominal(index)}
}
/>
</Grid>
</Grid>
@@ -434,7 +451,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{fNumber(totalAmountIncurred)}
{fNumber(totalAll().totalAmountIncurred)}
</Typography>
</Grid>
</Grid>
@@ -450,7 +467,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{fNumber(totalAmountApproved)}
{fNumber(totalAll().totalAmountApproved)}
</Typography>
</Grid>
</Grid>
@@ -466,7 +483,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{fNumber(totalAmountNotApproved)}
{fNumber(totalAll().totalAmountNotApproved)}
</Typography>
</Grid>
</Grid>
@@ -482,7 +499,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{fNumber(totalExcessPaid)}
{fNumber(totalAll().totalExcessPaid)}
</Typography>
</Grid>
</Grid>
@@ -499,7 +516,7 @@ export default function DialogBenefit({requestLog, setOpenDialog, openDialog, cl
<DialogActions>
<Stack direction="row" sx={{marginTop:3}} alignItems="center" justifyContent="space-between" spacing={2}>
<Button variant="outlined" onClick={handleCloseDialogBenefit}><Typography>Cancel</Typography></Button>
<LoadingButton disabled={isDisableSave} type="submit" variant="contained" loading={isSubmitting}>
<LoadingButton disabled={errorsExist} type="submit" variant="contained" loading={isSubmitting}>
Save
</LoadingButton>
</Stack>

View File

@@ -62,23 +62,36 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
defaultValues
});
const { handleSubmit, reset, watch, setValue, formState: { isDirty, isSubmitting, errors } } = methods;
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;
// 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'));
return {
totalAmountIncurred,
totalAmountApproved,
totalAmountNotApproved,
totalExcessPaid
}
}
// 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;
if (totalAmountApproved > totalAmountIncurred) {
alert('Total Approve tidak boleh melebihi Total Incurred')
setValue('amount_approved', data?.amount_approved)
const handleOnChangeNominal = (key) => {
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`);
}
}
// if (totalAmountIncurred !== (totalAmountApproved+totalAmountNotApproved)){
@@ -142,6 +155,10 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
name={`amount_incurred`}
placeholder='Amount Incurred'
required
onChange={(event) => {
setValue(`amount_incurred`, event.target.value)
handleOnChangeNominal(id)}
}
/>
</Grid>
</Grid>
@@ -162,6 +179,10 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
name={`amount_approved`}
placeholder='Amount Approved'
required
onChange={(event) => {
setValue(`amount_approved`, event.target.value)
handleOnChangeNominal(id)}
}
/>
</Grid>
</Grid>
@@ -275,7 +296,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{totalAmountIncurred ? fNumber(totalAmountIncurred) : 0}
{totalAll().totalAmountIncurred ? fNumber(totalAll().totalAmountIncurred) : 0}
</Typography>
</Grid>
</Grid>
@@ -291,7 +312,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{fNumber(totalAmountApproved)}
{totalAll().totalAmountApproved ? fNumber(totalAll().totalAmountApproved) : 0}
</Typography>
</Grid>
</Grid>
@@ -307,7 +328,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{fNumber(totalAmountNotApproved)}
{totalAll().totalAmountNotApproved ? fNumber(totalAll().totalAmountNotApproved) : 0}
</Typography>
</Grid>
</Grid>
@@ -323,7 +344,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
</Grid>
<Grid item xs={12}>
<Typography variant="caption" sx={{ fontWeight: 'bold', textAlign: 'right' }}>
{fNumber(totalExcessPaid)}
{totalAll().totalExcessPaid ? fNumber(totalAll().totalExcessPaid) : 0}
</Typography>
</Grid>
</Grid>
@@ -337,7 +358,7 @@ export default function DialogEditBenefit({id, data, setOpenDialog, openDialog,
<DialogActions>
<Stack direction="row" sx={{marginTop:3}} alignItems="center" justifyContent="space-between" spacing={2}>
<Button variant="outlined" onClick={handleCloseDialog}><Typography>Cancel</Typography></Button>
<LoadingButton type="submit" variant="contained" loading={isSubmitting}>
<LoadingButton disabled={errorsExist} type="submit" variant="contained" loading={isSubmitting}>
Save
</LoadingButton>
</Stack>

View File

@@ -68,6 +68,7 @@ export default function Detail() {
const navigate = useNavigate();
const { themeStretch } = useSettings();
const [requestLog, setRequestLog] = useState<DetailFinalLogType>();
const [isReversal, setIsReversal] = useState(false);
const { id } = useParams();
@@ -77,6 +78,7 @@ export default function Detail() {
.get('customer-service/request/'+id)
.then((response) => {
setRequestLog(response.data.data)
setIsReversal(response.data.data.is_reversal)
})
.catch((error) => {
console.error(error);
@@ -304,11 +306,15 @@ export default function Detail() {
<Card sx={{padding:2}} >
<Stack direction="row" alignItems="center" sx={{marginBottom: 4}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Benefit</Typography>
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
setDialogBenefit(true);
}} >
<Typography variant="button" display="block">Benefit</Typography>
</Button>
{
!isReversal ? (
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
setDialogBenefit(true);
}} >
<Typography variant="button" display="block">Benefit</Typography>
</Button>
) : null
}
</Stack>
{requestLog?.benefit_data?.map((item, index) => (
@@ -321,29 +327,33 @@ export default function Detail() {
{item.benefit?.description}
</Typography>
</Grid>
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
<MoreMenu actions={
<>
<MenuItem onClick={() => {
setDialogEditBenefit(true)
setIdBenefitData(item.id)
setBenefitConfigurationData(item)
}}
>
<EditOutlined />
Edit
</MenuItem>
<MenuItem onClick={() => {
setIdBenefitData(item.id)
setDialogDeleteBenefit(true)
}}
>
<Delete color='error'/>
Delete
</MenuItem>
</>
} />
</Grid>
{
!isReversal ? (
<Grid item xs={6} sx={{ display: 'flex', placeContent: 'end' }}>
<MoreMenu actions={
<>
<MenuItem onClick={() => {
setDialogEditBenefit(true)
setIdBenefitData(item.id)
setBenefitConfigurationData(item)
}}
>
<EditOutlined />
Edit
</MenuItem>
<MenuItem onClick={() => {
setIdBenefitData(item.id)
setDialogDeleteBenefit(true)
}}
>
<Delete color='error'/>
Delete
</MenuItem>
</>
} />
</Grid>
) : null
}
</Grid>
</Grid>
<Grid item xs={12}>
@@ -619,13 +629,16 @@ export default function Detail() {
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
<Typography variant='subtitle1' sx={{color: '#19BBBB'}} gutterBottom>Files </Typography>
</Stack>
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
setDialogUploadFileLog(true)
}} >
<Typography variant="button" display="block">Files</Typography>
</Button>
</Stack>
{ !isReversal ? (
<Stack direction="column" spacing={2} sx={{marginBottom: 2}}>
<Button variant="outlined" startIcon={<AddIcon/>} sx={{marginLeft: 'auto'}} onClick={() => {
setDialogUploadFileLog(true)
}} >
<Typography variant="button" display="block">Files</Typography>
</Button>
</Stack>
) : null }
</Stack>
{requestLog?.files?.map((documentType, index) => (
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{marginBottom: 2}} key={index}>
@@ -638,14 +651,17 @@ export default function Detail() {
<Typography variant="body2" gutterBottom>{documentType.original_name ? documentType.original_name : '-'}</Typography>
</a>
</Stack>
<Stack direction="column" spacing={2}>
<IconButton onClick={() => {
setDialogDeleteFileLog(true)
setPathFile(documentType.path)
}} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}>
<Delete color='error' fontSize="small" />
</IconButton>
</Stack>
{ !isReversal ? (
<Stack direction="column" spacing={2}>
<IconButton onClick={() => {
setDialogDeleteFileLog(true)
setPathFile(documentType.path)
}} aria-label="delete" size="small" sx={{ marginLeft: 'auto' }}>
<Delete color='error' fontSize="small" />
</IconButton>
</Stack>
) : null }
</Stack>
))}