485 lines
18 KiB
JavaScript
485 lines
18 KiB
JavaScript
import React, { useRef, useState, useEffect } from 'react';
|
|
import { useLocation } from 'react-router-dom';
|
|
import { useTheme } from '@mui/material/styles';
|
|
// import nearleLogo from '../../assets/images/nearleLogo.png';
|
|
import logo_nearle1 from '../../../assets/images/logo-nearle1.png';
|
|
import axios from 'axios';
|
|
import dayjs from 'dayjs';
|
|
import Loader from 'components/Loader';
|
|
import { enqueueSnackbar } from 'notistack';
|
|
import { DownloadOutlined, PrinterFilled } from '@ant-design/icons';
|
|
import ReactToPrint, { useReactToPrint } from 'react-to-print';
|
|
import { SearchOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons';
|
|
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
// import jsPDF from 'jspdf';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { FaArrowLeft } from 'react-icons/fa6';
|
|
import { FaIndianRupeeSign } from 'react-icons/fa6';
|
|
|
|
// import autoTable from 'jspdf-autotable';
|
|
import {
|
|
Grid,
|
|
Button,
|
|
Divider,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableContainer,
|
|
TableHead,
|
|
TablePagination,
|
|
TableRow,
|
|
Tabs,
|
|
Tab,
|
|
Typography,
|
|
Box,
|
|
OutlinedInput,
|
|
InputAdornment,
|
|
IconButton,
|
|
Tooltip,
|
|
Dialog,
|
|
DialogTitle,
|
|
DialogContent,
|
|
Stack,
|
|
Chip,
|
|
DialogActions,
|
|
TextField
|
|
} from '@mui/material';
|
|
|
|
const InvoicePreview = () => {
|
|
const [selected, setselected] = useState({});
|
|
const location = useLocation();
|
|
const navigate = useNavigate();
|
|
console.log('previewSelect', location.state);
|
|
const componentRef = useRef(null);
|
|
const [tabletype, settabletype] = useState(true);
|
|
const [paydialog, setpaydialog] = useState(false);
|
|
const [refnumber, setRefnumber] = useState('');
|
|
const [remarks, setRemarks] = useState('');
|
|
const theme = useTheme();
|
|
useEffect(() => {
|
|
setselected(location.state);
|
|
}, []);
|
|
// ================================================= || formatNumberToRupees || =================================================
|
|
|
|
function formatNumberToRupees(value) {
|
|
return new Intl.NumberFormat('en-IN', {
|
|
style: 'currency',
|
|
currency: 'INR',
|
|
minimumFractionDigits: 2
|
|
}).format(value);
|
|
}
|
|
|
|
useEffect(() => {
|
|
console.log('refnumber', refnumber);
|
|
console.log('remarks', remarks);
|
|
}, [refnumber, remarks]);
|
|
|
|
// ================================================= || updatePayment || =================================================
|
|
|
|
const updatePayment = async () => {
|
|
try {
|
|
const updateResponse = await axios.put(`${process.env.REACT_APP_URL}/invoice/updatestatus`, {
|
|
salesid: selected.salesid,
|
|
referenceno: refnumber,
|
|
referencedate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
billstatus: 2,
|
|
paymentremarks: remarks
|
|
});
|
|
if (updateResponse.status) {
|
|
enqueueSnackbar(' Updated Successfully ', {
|
|
variant: 'success',
|
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
autoHideDuration: 1000
|
|
});
|
|
}
|
|
console.log('updateResponse', updateResponse);
|
|
} catch (error) {
|
|
console.log('updateResponse', error);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Stack direction="row" justifyContent="Space-between" alignItems={'center'} spacing={2} sx={{ px: 2.5, py: 1, bgcolor: '#eeeeee' }}>
|
|
{/* // ================================================= || Invoice Details || ================================================= */}
|
|
|
|
<Stack direction={'row'} alignItems={'center'} spacing={2}>
|
|
<Tooltip title="back">
|
|
<IconButton
|
|
color="primary"
|
|
onClick={() => {
|
|
navigate('/invoice');
|
|
}}
|
|
>
|
|
<FaArrowLeft size={'large'} />
|
|
</IconButton>
|
|
</Tooltip>
|
|
|
|
<Stack alignItems={'center'}>
|
|
<Typography variant="h3" color={'primary'}>
|
|
Invoice Details
|
|
</Typography>
|
|
<Chip
|
|
size="small"
|
|
color="warning"
|
|
variant="outlined"
|
|
sx={{ bgcolor: theme.palette.warning.lighter }}
|
|
label={`Invoice No :${'\u00a0\u00a0'}${selected.invoiceno}`}
|
|
/>
|
|
</Stack>
|
|
</Stack>
|
|
|
|
<Stack direction={'row'} spacing={2}>
|
|
{/* <Button
|
|
variant="outlined"
|
|
color="primary"
|
|
sx={{
|
|
'&:hover': {
|
|
backgroundColor: 'primary.main',
|
|
color: 'primary.contrastText'
|
|
}
|
|
}}
|
|
onClick={() => {
|
|
setpaydialog(true);
|
|
}}
|
|
>
|
|
{' '}
|
|
<FaIndianRupeeSign />
|
|
Update Payment
|
|
</Button> */}
|
|
<ReactToPrint
|
|
trigger={() => (
|
|
<Button
|
|
size="small"
|
|
startIcon={<PrinterFilled />}
|
|
variant="outlined"
|
|
color="primary"
|
|
sx={{
|
|
'&:hover': {
|
|
backgroundColor: 'primary.main',
|
|
color: 'primary.contrastText'
|
|
}
|
|
}}
|
|
>
|
|
Print
|
|
</Button>
|
|
)}
|
|
content={() => componentRef.current}
|
|
/>
|
|
</Stack>
|
|
</Stack>
|
|
|
|
{/* // ================================================= || Date row || ================================================= */}
|
|
|
|
<Box sx={{ pb: 2.5, border: '1px solid #eee' }}>
|
|
<div ref={componentRef} style={{ width: '100%' }}>
|
|
<Box id="print" sx={{ p: 2.5 }}>
|
|
<Box sx={{ pb: 2.5 }}>
|
|
<Stack
|
|
sx={{
|
|
flexDirection: 'row',
|
|
// bgcolor: theme.palette.primary.main,
|
|
border: '1px solid #eee',
|
|
px: 3
|
|
}}
|
|
justifyContent="space-between"
|
|
>
|
|
<Box sx={{ pt: 0.5 }}>
|
|
<Stack direction="row" spacing={2}>
|
|
<img src={logo_nearle1} style={{ width: '150px', height: '50px' }} />{' '}
|
|
</Stack>
|
|
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography
|
|
sx={{
|
|
overflow: 'hidden',
|
|
color: theme.palette.primary.main
|
|
}}
|
|
variant="subtitle1"
|
|
>
|
|
Invoice No :
|
|
</Typography>
|
|
<Typography sx={{ color: theme.palette.primary.main }}>{`${'\u00a0\u00a0'}${selected.invoiceno}`}</Typography>
|
|
</Stack>
|
|
</Box>
|
|
<Box sx={{ pt: 2.5, pb: 1.75 }}>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography sx={{ pl: 4, color: theme.palette.primary.main }} variant="subtitle1">
|
|
Date :{' '}
|
|
</Typography>
|
|
<Typography sx={{ color: theme.palette.primary.main }}>
|
|
{dayjs(selected.transactiondate).format('DD-MM-YYYY')}
|
|
</Typography>
|
|
</Stack>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography
|
|
sx={{
|
|
pr: 2,
|
|
overflow: 'hidden',
|
|
color: theme.palette.primary.main
|
|
}}
|
|
variant="subtitle1"
|
|
>
|
|
Due Date :
|
|
</Typography>
|
|
<Typography sx={{ color: theme.palette.primary.main }}>{dayjs(selected.dueDate).format('DD-MM-YYYY')}</Typography>
|
|
</Stack>
|
|
</Box>
|
|
</Stack>
|
|
{/* // ================================================= || from to || ================================================= */}
|
|
|
|
<Box sx={{ pt: 2.5 }}>
|
|
<Grid container spacing={2} justifyContent="space-between" direction="row">
|
|
<Grid item xs={6}>
|
|
<Box
|
|
sx={{
|
|
border: 1,
|
|
minHeight: 240,
|
|
borderColor: 'grey.200',
|
|
borderRadius: 0.5,
|
|
p: 2.5
|
|
}}
|
|
>
|
|
<Grid container direction="row">
|
|
<Grid item md={8}>
|
|
<Stack spacing={2}>
|
|
<Typography variant="h5">From:</Typography>
|
|
<Stack sx={{ width: '100%' }}>
|
|
<Typography variant="subtitle1">Nearle Technology Privite Limited.</Typography>
|
|
<Typography color="secondary">
|
|
424, 4<sup>th</sup>floor,
|
|
</Typography>
|
|
<Typography color="secondary">Red rose towers,</Typography>
|
|
<Typography color="secondary">DB Road, RS Puram,</Typography>
|
|
<Typography color="secondary">641002.</Typography>
|
|
<Typography color="secondary">care@nearle.in</Typography>
|
|
<Typography color="secondary">9047968666</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
</Box>
|
|
</Grid>
|
|
<Grid item xs={6}>
|
|
<Box
|
|
sx={{
|
|
border: 1,
|
|
minHeight: 240,
|
|
borderColor: 'grey.200',
|
|
borderRadius: 0.5,
|
|
p: 2.5
|
|
}}
|
|
>
|
|
<Grid container direction="row">
|
|
<Grid item md={8}>
|
|
<Stack spacing={2}>
|
|
<Typography variant="h5">To:</Typography>
|
|
<Stack sx={{ width: '100%' }}>
|
|
<Typography variant="subtitle1">{selected.tenantname}</Typography>
|
|
<Typography color="secondary">{selected.address}</Typography>
|
|
<Typography color="secondary">{selected.suburb}</Typography>
|
|
<Typography color="secondary">{selected.city}</Typography>
|
|
<Typography color="secondary">{selected.state}</Typography>{' '}
|
|
</Stack>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
</Box>
|
|
</Grid>
|
|
</Grid>
|
|
</Box>
|
|
</Box>
|
|
{/* // ================================================= || invoice table || ================================================= */}
|
|
|
|
<TableContainer
|
|
// sx={{
|
|
// ...(tabletype
|
|
// ? {
|
|
// maxHeight: 430,
|
|
// mt: -3,
|
|
// "&::-webkit-scrollbar": {
|
|
// width: "4px", // Width of vertical scrollbar
|
|
// height: "4px", // Height of horizontal scrollbar
|
|
// },
|
|
// "&::-webkit-scrollbar-thumb": {
|
|
// backgroundColor: "#65387A", // Color of the scrollbar thumb
|
|
// },
|
|
// }
|
|
// : {}),
|
|
// }}
|
|
>
|
|
<Table>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>S.No</TableCell>
|
|
<TableCell>Particulars</TableCell>
|
|
<TableCell>Unit</TableCell>
|
|
<TableCell>Quantity</TableCell>
|
|
<TableCell align="right">Rate</TableCell>
|
|
{/* {selected && selected.pricingtypeid === 73 && ( */}
|
|
<TableCell>Other Charges</TableCell>
|
|
{/* )} */}
|
|
<TableCell align="right">Amount</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
{selected.tenantsalesdetails && (
|
|
<TableBody>
|
|
<TableRow>
|
|
<TableCell>1</TableCell>
|
|
<TableCell>
|
|
<Typography>
|
|
{`Invoice from ${dayjs(selected.tenantsalesdetails[0].fromdate).format('DD-MM-YYYY')} to ${dayjs(
|
|
selected.tenantsalesdetails[0].todate
|
|
).format('DD-MM-YYYY')}`}
|
|
</Typography>
|
|
</TableCell>
|
|
<TableCell>
|
|
<Typography>{selected.tenantsalesdetails[0].pricingtype}</Typography>
|
|
</TableCell>
|
|
|
|
<TableCell>
|
|
<Typography>{`${selected.tenantsalesdetails[0].quantity}km`}</Typography>
|
|
</TableCell>
|
|
<TableCell>
|
|
<Typography align="right">{`₹ ${selected.tenantsalesdetails[0].baserate.toFixed(2)}`}</Typography>
|
|
</TableCell>
|
|
{/* {selected.tenantsalesdetails[0].pricingtypeid == 73 && ( */}
|
|
<TableCell align="center">
|
|
<Typography>{`₹ ${selected.tenantsalesdetails[0].othercharges}.00`}</Typography>
|
|
</TableCell>
|
|
{/* )} */}
|
|
<TableCell align="right">
|
|
<Typography>{`₹ ${selected.tenantsalesdetails[0].amount}.00`}</Typography>
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
)}
|
|
</Table>
|
|
</TableContainer>
|
|
<Divider />
|
|
<Box sx={{ p: 2.5 }}>
|
|
<Grid container direction="row" justifyContent="flex-end">
|
|
<Grid item md={4}>
|
|
<Stack spacing={2}>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography color="secondary">Sub Total:</Typography>
|
|
<Typography variant="h6">{formatNumberToRupees(selected.salesamount)}</Typography>
|
|
</Stack>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography color="secondary">Discount:</Typography>
|
|
<Typography variant="h6" color={theme.palette.error.main}>
|
|
- {formatNumberToRupees(selected.discountamt)}
|
|
</Typography>
|
|
</Stack>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography color={theme.palette.grey[500]}>Tax:</Typography>
|
|
<Typography variant="h6" color={theme.palette.success.main}>
|
|
+ {formatNumberToRupees(selected.taxamount)}
|
|
</Typography>
|
|
</Stack>
|
|
<Stack direction="row" justifyContent="space-between">
|
|
<Typography sx={{ pr: 2 }} variant="subtitle1">
|
|
Grand Total:
|
|
</Typography>
|
|
<Typography variant="h6">{formatNumberToRupees(Math.round(selected.totalamount))}</Typography>
|
|
</Stack>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
</Box>
|
|
</Box>
|
|
<Divider />
|
|
<Box sx={{ p: 2.5 }}>
|
|
<Typography>Notes: {selected.remarks}</Typography>
|
|
</Box>
|
|
|
|
<Divider />
|
|
</div>
|
|
</Box>
|
|
|
|
{/* ================================================= || updatePayment Dialog || ================================================= */}
|
|
<Dialog
|
|
open={paydialog}
|
|
onClose={() => {
|
|
setpaydialog(false);
|
|
}}
|
|
maxWidth={'sm'}
|
|
fullWidth
|
|
>
|
|
<DialogTitle sx={{ bgcolor: theme.palette.primary.main }}>
|
|
<Stack direction={'row'} spacing={1}>
|
|
<Typography variant="h2" sx={{ color: 'white' }}>
|
|
₹
|
|
</Typography>
|
|
<Typography variant="h3" sx={{ color: 'white' }}>
|
|
Update Payment
|
|
</Typography>
|
|
</Stack>
|
|
</DialogTitle>
|
|
<DialogContent dividers>
|
|
<Stack spacing={1} sx={{ mb: 2 }}>
|
|
<Typography>Reference No</Typography>
|
|
<TextField
|
|
type="number"
|
|
placeholder="Enter Reference Number"
|
|
sx={{ width: '100%' }}
|
|
onChange={(e) => {
|
|
setRefnumber(e.target.value);
|
|
}}
|
|
/>
|
|
</Stack>
|
|
<Stack spacing={2} sx={{ mb: 2 }}>
|
|
<Typography>Remarks</Typography>
|
|
<TextField
|
|
multiline
|
|
required
|
|
placeholder="Enter Remarks"
|
|
sx={{ width: '100%' }}
|
|
onChange={(e) => {
|
|
setRemarks(e.target.value);
|
|
}}
|
|
/>
|
|
</Stack>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button
|
|
variant="outlined"
|
|
sx={{
|
|
'&:hover': {
|
|
backgroundColor: 'primary.main',
|
|
color: 'primary.contrastText'
|
|
},
|
|
m: 2
|
|
}}
|
|
onClick={() => {
|
|
setpaydialog(false);
|
|
}}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
<Button
|
|
variant="outlined"
|
|
disabled={refnumber == '' || remarks == ''}
|
|
sx={{
|
|
'&:hover': {
|
|
backgroundColor: 'primary.main',
|
|
color: 'primary.contrastText'
|
|
},
|
|
m: 2
|
|
}}
|
|
onClick={() => {
|
|
setpaydialog(false);
|
|
updatePayment();
|
|
navigate('/invoice');
|
|
}}
|
|
>
|
|
Update
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default InvoicePreview;
|