Export Excel Invoice & Imporve Invoice
This commit is contained in:
@@ -440,7 +440,7 @@ import { DatePicker, MobileDatePicker } from '@mui/x-date-pickers';
|
||||
setIsLoading(false)
|
||||
enqueueSnackbar(response.data.message, { variant: 'success' });
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
navigate('/invoice-payment');
|
||||
}, 1000);
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
@@ -911,7 +911,11 @@ const handleGetClaimDetails = async () => {
|
||||
|
||||
|
||||
// Hitung Grand Total
|
||||
const grandTotal = dataLogs.reduce((sum, item) => sum + item.totalBilling, 0);
|
||||
const grandTotal = dataLogs.reduce(
|
||||
(sum, item) => sum + Number(item.totalBilling),
|
||||
0
|
||||
);
|
||||
|
||||
const [fileBukti, setFileBukti] = useState<any>([]);
|
||||
const removeBuktiFiles = (filesState:any, index:any) => {
|
||||
setFileBukti(
|
||||
@@ -976,7 +980,7 @@ const handleGetClaimDetails = async () => {
|
||||
}
|
||||
}, [invoicePayment]);
|
||||
|
||||
const [payments, setPayments] = useState([{ id: Date.now(), amount: "", existingFiles: [], files: [], paymentNumber: 1 }]);
|
||||
const [payments, setPayments] = useState([{ id: Date.now(), amount: "", existingFiles: [], files: [], noReference: "", paymentNumber: 1 }]);
|
||||
const fileInputRefs = useRef({});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -986,6 +990,7 @@ const handleGetClaimDetails = async () => {
|
||||
amount: fCurrency(parseFloat(payment.amount_paid)),
|
||||
existingFiles: Array.isArray(payment.files) ? payment.files : [],
|
||||
files: [],
|
||||
noReference: payment.no_reference,
|
||||
paymentNumber: payment.payment_number
|
||||
}));
|
||||
setPayments(mappedPayments);
|
||||
@@ -995,7 +1000,7 @@ const handleGetClaimDetails = async () => {
|
||||
|
||||
const handleAddPayment = () => {
|
||||
const newId = Date.now();
|
||||
setPayments([...payments, { id: newId, amount: "", existingFiles: [], files: [], paymentNumber: payments.length + 1 }]);
|
||||
setPayments([...payments, { id: newId, amount: "", existingFiles: [], files: [], noReference: "", paymentNumber: payments.length + 1 }]);
|
||||
fileInputRefs.current[newId] = null;
|
||||
};
|
||||
|
||||
@@ -1005,6 +1010,12 @@ const handleGetClaimDetails = async () => {
|
||||
setPayments(updatedPayments);
|
||||
};
|
||||
|
||||
const handleReferenceChange = (index, value) => {
|
||||
const updatedPayments = [...payments];
|
||||
updatedPayments[index].noReference = value;
|
||||
setPayments(updatedPayments);
|
||||
};
|
||||
|
||||
const handleFileChange = (index, event) => {
|
||||
const newFiles = Array.from(event.target.files);
|
||||
const updatedPayments = [...payments];
|
||||
@@ -1029,9 +1040,14 @@ const handleGetClaimDetails = async () => {
|
||||
};
|
||||
|
||||
const totalAmount = payments.reduce((sum, payment) => {
|
||||
const num = parseFloat(payment.amount.replace(/[^\d]/g, "")) || 0;
|
||||
const num =
|
||||
parseFloat(
|
||||
(payment.amount ?? '0').toString().replace(/[^\d]/g, '')
|
||||
) || 0;
|
||||
|
||||
return sum + num;
|
||||
}, 0);
|
||||
}, 0);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
@@ -1066,7 +1082,7 @@ const handleGetClaimDetails = async () => {
|
||||
|
||||
<Stack direction="row" spacing={2} width="100%">
|
||||
<Stack spacing={2} sx={{ width: '50%' }}>
|
||||
<Typography variant="subtitle1">Nomor Invoice *</Typography>
|
||||
<Typography variant="subtitle1">Nomor Invoice <span style={{color: 'red'}}>*</span></Typography>
|
||||
<TextField
|
||||
id="nomor_invoice"
|
||||
variant="outlined"
|
||||
@@ -1191,7 +1207,7 @@ const handleGetClaimDetails = async () => {
|
||||
|
||||
{/* Input Jumlah Bayar */}
|
||||
<Stack direction="row" spacing={2} width="100%">
|
||||
<Stack spacing={2} sx={{ width: "50%" }}>
|
||||
<Stack spacing={2} sx={{ width: "35%" }}>
|
||||
<Typography variant="subtitle1">Nominal Pembayaran</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
@@ -1202,7 +1218,7 @@ const handleGetClaimDetails = async () => {
|
||||
</Stack>
|
||||
|
||||
{/* Input File Bukti */}
|
||||
<Stack spacing={2} sx={{ width: "50%" }}>
|
||||
<Stack spacing={2} sx={{ width: "35%" }}>
|
||||
<Typography variant="subtitle1">Upload Bukti Pembayaran</Typography>
|
||||
<Stack>
|
||||
<Stack divider={<Divider orientation="horizontal" flexItem />} spacing={1}>
|
||||
@@ -1262,6 +1278,15 @@ const handleGetClaimDetails = async () => {
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Stack spacing={2} sx={{ width: "30%" }}>
|
||||
<Typography variant="subtitle1">No. Referensi</Typography>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
placeholder="Nomor Referensi"
|
||||
value={payment.noReference}
|
||||
onChange={(e) => handleReferenceChange(index, e.target.value)}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
))}
|
||||
|
||||
@@ -268,13 +268,13 @@ export default function Detail() {
|
||||
|
||||
{/* Input Jumlah Bayar */}
|
||||
<Stack direction="row" spacing={2} width="100%">
|
||||
<Stack spacing={2} sx={{ width: "50%" }}>
|
||||
<Stack spacing={2} sx={{ width: "35%" }}>
|
||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Nominal Pembayaran</Typography>
|
||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{fCurrency(parseFloat(file.amount_paid))}</Typography>
|
||||
</Stack>
|
||||
|
||||
{/* Input File Bukti */}
|
||||
<Stack spacing={2} sx={{ width: "50%" }}>
|
||||
<Stack spacing={2} sx={{ width: "35%" }}>
|
||||
<Typography variant='subtitle2' sx={style1} gutterBottom>Bukti Pembayaran</Typography>
|
||||
<Stack>
|
||||
<Stack divider={<Divider orientation="horizontal" flexItem />} spacing={1}>
|
||||
@@ -292,6 +292,10 @@ export default function Detail() {
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Stack spacing={2} sx={{ width: "30%" }}>
|
||||
<Typography variant='subtitle2' sx={style1} gutterBottom>No. Reference</Typography>
|
||||
<Typography variant='subtitle2' sx={style2} gutterBottom>{file.no_reference}</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
))}
|
||||
|
||||
@@ -146,35 +146,60 @@ import { ClearOutlined, LoopOutlined } from "@mui/icons-material";
|
||||
|
||||
var filter = Object.fromEntries([...searchParams.entries()]);
|
||||
setIsLoading(true)
|
||||
await axios
|
||||
.get('/invoice-payment/export',{
|
||||
params: {
|
||||
search: searchText,
|
||||
start_date: formattedDate ? formattedDate : null,
|
||||
end_date:formattedDate1,
|
||||
provider: dataProvider,
|
||||
status: dataStatus,
|
||||
order: order,
|
||||
orderBy: orderBy,
|
||||
page: perPage,
|
||||
}
|
||||
})
|
||||
.then((res) => {
|
||||
enqueueSnackbar('Data berhasil di Export', {
|
||||
variant: 'success',
|
||||
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||
});
|
||||
setIsLoading(false)
|
||||
|
||||
document.location.href = res.data.data.file_url;
|
||||
})
|
||||
.catch((err) =>
|
||||
enqueueSnackbar('Data Gagal di Export', {
|
||||
variant: 'error',
|
||||
anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||
})
|
||||
const res = await axios.get('/invoice-payment/export', {
|
||||
params: {
|
||||
// search: searchText,
|
||||
start_date: formattedDate ? formattedDate : null,
|
||||
end_date: formattedDate1,
|
||||
provider: dataProvider,
|
||||
status: dataStatus,
|
||||
order: order,
|
||||
orderBy: orderBy,
|
||||
},
|
||||
responseType: 'blob',
|
||||
});
|
||||
|
||||
);
|
||||
|
||||
|
||||
const url = window.URL.createObjectURL(new Blob([res.data]));
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.setAttribute('download', 'Report-Vale-Payment.xlsx');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
setIsLoading(false);
|
||||
|
||||
|
||||
// await axios
|
||||
// .get('/invoice-payment/export',{
|
||||
// params: {
|
||||
// search: searchText,
|
||||
// start_date: formattedDate ? formattedDate : null,
|
||||
// end_date:formattedDate1,
|
||||
// provider: dataProvider,
|
||||
// status: dataStatus,
|
||||
// order: order,
|
||||
// orderBy: orderBy,
|
||||
// page: perPage,
|
||||
// }
|
||||
// })
|
||||
// .then((res) => {
|
||||
// enqueueSnackbar('Data berhasil di Export', {
|
||||
// variant: 'success',
|
||||
// anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||
// });
|
||||
// setIsLoading(false)
|
||||
|
||||
// document.location.href = res.data.data.file_url;
|
||||
// })
|
||||
// .catch((err) =>
|
||||
// enqueueSnackbar('Data Gagal di Export', {
|
||||
// variant: 'error',
|
||||
// anchorOrigin: { horizontal: 'right', vertical: 'top' },
|
||||
// })
|
||||
|
||||
// );
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user