pd order done
Some checks failed
NPM Installation / build (16.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (16.x, windows-latest) (push) Has been cancelled
NPM Installation / build (17.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (17.x, windows-latest) (push) Has been cancelled
NPM Installation / build (18.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (18.x, windows-latest) (push) Has been cancelled
Some checks failed
NPM Installation / build (16.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (16.x, windows-latest) (push) Has been cancelled
NPM Installation / build (17.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (17.x, windows-latest) (push) Has been cancelled
NPM Installation / build (18.x, ubuntu-latest) (push) Has been cancelled
NPM Installation / build (18.x, windows-latest) (push) Has been cancelled
This commit is contained in:
parent
03dbed7d14
commit
efb60cc3c1
@ -10,6 +10,10 @@ import ViewOrders from './views/pages/rdOrders/viewOrders'
|
|||||||
|
|
||||||
import PendingOrders from './views/pages/rdOrders/pendingOrders'
|
import PendingOrders from './views/pages/rdOrders/pendingOrders'
|
||||||
import CancelledOrders from './views/pages/rdOrders/cancelledOrders'
|
import CancelledOrders from './views/pages/rdOrders/cancelledOrders'
|
||||||
|
import ProcessingInvoices from './views/pages/rdOrders/processingInvoices'
|
||||||
|
import ViewInvoices from './views/pages/rdOrders/invoiceView'
|
||||||
|
import DispatchedInvoices from './views/pages/rdOrders/dispatchedInvoices'
|
||||||
|
import DeliveredInvoices from './views/pages/rdOrders/deliveredInvoices'
|
||||||
|
|
||||||
const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard'))
|
const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard'))
|
||||||
const Shop = React.lazy(() => import('./views/shops/Shop'))
|
const Shop = React.lazy(() => import('./views/shops/Shop'))
|
||||||
@ -35,6 +39,10 @@ const routes = [
|
|||||||
//RD Orders
|
//RD Orders
|
||||||
{ path: '/new', name: 'New', element: NewOrders },
|
{ path: '/new', name: 'New', element: NewOrders },
|
||||||
{ path: '/pending', name: 'New', element: PendingOrders },
|
{ path: '/pending', name: 'New', element: PendingOrders },
|
||||||
|
{ path: '/processing', name: 'New', element: ProcessingInvoices },
|
||||||
|
{ path: '/dispatched', name: 'New', element: DispatchedInvoices },
|
||||||
|
{ path: '/delivered', name: 'New', element: DeliveredInvoices },
|
||||||
|
{ path: '/invoice/:status/:id', name: 'New', element: ViewInvoices },
|
||||||
{ path: '/cancelled', name: 'New', element: CancelledOrders },
|
{ path: '/cancelled', name: 'New', element: CancelledOrders },
|
||||||
{ path: '/:status/:id', name: 'New', element: ViewOrders },
|
{ path: '/:status/:id', name: 'New', element: ViewOrders },
|
||||||
|
|
||||||
|
195
src/views/pages/rdOrders/deliveredInvoices.js
Normal file
195
src/views/pages/rdOrders/deliveredInvoices.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react'
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Typography,
|
||||||
|
TablePagination,
|
||||||
|
TextField,
|
||||||
|
MenuItem,
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
|
Select,
|
||||||
|
Skeleton,
|
||||||
|
} from '@mui/material'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
import { debounce } from 'lodash' // Import debounce from lodash
|
||||||
|
import Axios from '../../../axios'
|
||||||
|
|
||||||
|
const DeliveredInvoices = () => {
|
||||||
|
const [orders, setOrders] = useState([])
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [page, setPage] = useState(0) // 0-based page
|
||||||
|
const [rowsPerPage, setRowsPerPage] = useState(5)
|
||||||
|
const [totalOrders, setTotalOrders] = useState(0)
|
||||||
|
const [searchField, setSearchField] = useState('Order ID')
|
||||||
|
const [searchText, setSearchText] = useState('')
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const token = isAutheticated()
|
||||||
|
const searchRef = useRef()
|
||||||
|
const fetchOrdersDebounced = useRef(
|
||||||
|
debounce((page, limit, searchField, searchText) => {
|
||||||
|
fetchOrders(page, limit, searchField, searchText)
|
||||||
|
}, 500),
|
||||||
|
).current
|
||||||
|
|
||||||
|
const fetchOrders = async (page, limit, searchField = '', searchText = '') => {
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
const response = await Axios.get('/api/pd-get-delivered-invoices', {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
limit,
|
||||||
|
page: page + 1,
|
||||||
|
[searchField === 'Order ID' ? 'orderId' : 'invoiceId']: searchText || '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
console.log(response)
|
||||||
|
setOrders(response?.data?.invoices)
|
||||||
|
setTotalOrders(response?.data?.totalCount)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching orders:', error)
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchOrdersDebounced(page, rowsPerPage, searchField, searchText)
|
||||||
|
}, [page, rowsPerPage, searchField, searchText])
|
||||||
|
|
||||||
|
const handleSearchChange = (event) => {
|
||||||
|
const value = event.target.value
|
||||||
|
setSearchText(value)
|
||||||
|
searchRef.current = value
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearchFieldChange = (event) => {
|
||||||
|
setSearchField(event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(parseInt(event.target.value, 10))
|
||||||
|
setPage(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h4" mb={2} textAlign="center">
|
||||||
|
Delivered Invoice List
|
||||||
|
</Typography>
|
||||||
|
<Box display="flex" mb={2} alignItems="center">
|
||||||
|
<FormControl variant="outlined" sx={{ minWidth: 150, mr: 2 }}>
|
||||||
|
<InputLabel id="search-field-label">Search By</InputLabel>
|
||||||
|
<Select
|
||||||
|
labelId="search-field-label"
|
||||||
|
id="search-field"
|
||||||
|
value={searchField}
|
||||||
|
onChange={handleSearchFieldChange}
|
||||||
|
label="Search By"
|
||||||
|
>
|
||||||
|
<MenuItem value="Order ID">Order ID</MenuItem>
|
||||||
|
<MenuItem value="Invoice ID">Invoice ID</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<TextField
|
||||||
|
label={`Search by ${searchField}`}
|
||||||
|
variant="outlined"
|
||||||
|
value={searchText}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>Order ID</TableCell>
|
||||||
|
<TableCell>Invoice ID</TableCell>
|
||||||
|
<TableCell>Delivered Date</TableCell>
|
||||||
|
<TableCell>Items</TableCell>
|
||||||
|
<TableCell>Invoice Value</TableCell>
|
||||||
|
<TableCell>Status</TableCell>
|
||||||
|
<TableCell>Action</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{loading ? (
|
||||||
|
Array.from(new Array(rowsPerPage)).map((_, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell colSpan={6}>
|
||||||
|
<Skeleton height={40} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : orders.length > 0 ? (
|
||||||
|
orders.map((invoice) => (
|
||||||
|
<TableRow key={invoice._id}>
|
||||||
|
<TableCell>{invoice.orderId.uniqueId}</TableCell>
|
||||||
|
<TableCell>{invoice.invoiceId}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{new Date(invoice.courierstatus_timeline.delivered).toDateString()}
|
||||||
|
<span>, {formatAMPM(invoice.courierstatus_timeline.delivered)}</span>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{invoice.items.length}</TableCell>
|
||||||
|
<TableCell>{invoice.invoiceAmount}</TableCell>
|
||||||
|
<TableCell>{invoice.courierStatus}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => navigate(`/invoice/${invoice.courierStatus}/${invoice._id}`)}
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={6} align="center">
|
||||||
|
<Typography variant="body1">No data found</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
|
component="div"
|
||||||
|
count={totalOrders}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</TableContainer>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to format time as AM/PM
|
||||||
|
const formatAMPM = (date) => {
|
||||||
|
const hours = new Date(date).getHours()
|
||||||
|
const minutes = new Date(date).getMinutes()
|
||||||
|
const ampm = hours >= 12 ? 'PM' : 'AM'
|
||||||
|
const formattedHours = hours % 12 || 12
|
||||||
|
const formattedMinutes = minutes < 10 ? '0' + minutes : minutes
|
||||||
|
return `${formattedHours}:${formattedMinutes} ${ampm}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DeliveredInvoices
|
195
src/views/pages/rdOrders/dispatchedInvoices.js
Normal file
195
src/views/pages/rdOrders/dispatchedInvoices.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react'
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Typography,
|
||||||
|
TablePagination,
|
||||||
|
TextField,
|
||||||
|
MenuItem,
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
|
Select,
|
||||||
|
Skeleton,
|
||||||
|
} from '@mui/material'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
import { debounce } from 'lodash' // Import debounce from lodash
|
||||||
|
import Axios from '../../../axios'
|
||||||
|
|
||||||
|
const DispatchedInvoices = () => {
|
||||||
|
const [orders, setOrders] = useState([])
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [page, setPage] = useState(0) // 0-based page
|
||||||
|
const [rowsPerPage, setRowsPerPage] = useState(5)
|
||||||
|
const [totalOrders, setTotalOrders] = useState(0)
|
||||||
|
const [searchField, setSearchField] = useState('Order ID')
|
||||||
|
const [searchText, setSearchText] = useState('')
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const token = isAutheticated()
|
||||||
|
const searchRef = useRef()
|
||||||
|
const fetchOrdersDebounced = useRef(
|
||||||
|
debounce((page, limit, searchField, searchText) => {
|
||||||
|
fetchOrders(page, limit, searchField, searchText)
|
||||||
|
}, 500),
|
||||||
|
).current
|
||||||
|
|
||||||
|
const fetchOrders = async (page, limit, searchField = '', searchText = '') => {
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
const response = await Axios.get('/api/pd-get-dispatched-invoices', {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
limit,
|
||||||
|
page: page + 1,
|
||||||
|
[searchField === 'Order ID' ? 'orderId' : 'invoiceId']: searchText || '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
console.log(response)
|
||||||
|
setOrders(response?.data?.invoices)
|
||||||
|
setTotalOrders(response?.data?.totalCount)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching orders:', error)
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchOrdersDebounced(page, rowsPerPage, searchField, searchText)
|
||||||
|
}, [page, rowsPerPage, searchField, searchText])
|
||||||
|
|
||||||
|
const handleSearchChange = (event) => {
|
||||||
|
const value = event.target.value
|
||||||
|
setSearchText(value)
|
||||||
|
searchRef.current = value
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearchFieldChange = (event) => {
|
||||||
|
setSearchField(event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(parseInt(event.target.value, 10))
|
||||||
|
setPage(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h4" mb={2} textAlign="center">
|
||||||
|
Dispatched Invoice List
|
||||||
|
</Typography>
|
||||||
|
<Box display="flex" mb={2} alignItems="center">
|
||||||
|
<FormControl variant="outlined" sx={{ minWidth: 150, mr: 2 }}>
|
||||||
|
<InputLabel id="search-field-label">Search By</InputLabel>
|
||||||
|
<Select
|
||||||
|
labelId="search-field-label"
|
||||||
|
id="search-field"
|
||||||
|
value={searchField}
|
||||||
|
onChange={handleSearchFieldChange}
|
||||||
|
label="Search By"
|
||||||
|
>
|
||||||
|
<MenuItem value="Order ID">Order ID</MenuItem>
|
||||||
|
<MenuItem value="Invoice ID">Invoice ID</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<TextField
|
||||||
|
label={`Search by ${searchField}`}
|
||||||
|
variant="outlined"
|
||||||
|
value={searchText}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>Order ID</TableCell>
|
||||||
|
<TableCell>Invoice ID</TableCell>
|
||||||
|
<TableCell>Dispatched Date</TableCell>
|
||||||
|
<TableCell>Items</TableCell>
|
||||||
|
<TableCell>Invoice Value</TableCell>
|
||||||
|
<TableCell>Status</TableCell>
|
||||||
|
<TableCell>Action</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{loading ? (
|
||||||
|
Array.from(new Array(rowsPerPage)).map((_, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell colSpan={6}>
|
||||||
|
<Skeleton height={40} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : orders.length > 0 ? (
|
||||||
|
orders.map((invoice) => (
|
||||||
|
<TableRow key={invoice._id}>
|
||||||
|
<TableCell>{invoice.orderId.uniqueId}</TableCell>
|
||||||
|
<TableCell>{invoice.invoiceId}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{new Date(invoice.courierstatus_timeline.dispatched).toDateString()}
|
||||||
|
<span>, {formatAMPM(invoice.courierstatus_timeline.dispatched)}</span>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{invoice.items.length}</TableCell>
|
||||||
|
<TableCell>{invoice.invoiceAmount}</TableCell>
|
||||||
|
<TableCell>{invoice.courierStatus}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => navigate(`/invoice/${invoice.courierStatus}/${invoice._id}`)}
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={6} align="center">
|
||||||
|
<Typography variant="body1">No data found</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
|
component="div"
|
||||||
|
count={totalOrders}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</TableContainer>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to format time as AM/PM
|
||||||
|
const formatAMPM = (date) => {
|
||||||
|
const hours = new Date(date).getHours()
|
||||||
|
const minutes = new Date(date).getMinutes()
|
||||||
|
const ampm = hours >= 12 ? 'PM' : 'AM'
|
||||||
|
const formattedHours = hours % 12 || 12
|
||||||
|
const formattedMinutes = minutes < 10 ? '0' + minutes : minutes
|
||||||
|
return `${formattedHours}:${formattedMinutes} ${ampm}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DispatchedInvoices
|
@ -20,15 +20,16 @@ import {
|
|||||||
Divider,
|
Divider,
|
||||||
Chip,
|
Chip,
|
||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import onvoicesData from '../../assets/incoicedata.json'
|
|
||||||
import { useNavigate, useParams } from 'react-router-dom'
|
import { useNavigate, useParams } from 'react-router-dom'
|
||||||
import { TableContainer } from '@material-ui/core'
|
import { TableContainer } from '@mui/material'
|
||||||
import axios from 'axios' // Import axios for HTTP requests
|
import axios from 'axios' // Import axios for HTTP requests
|
||||||
import { isAutheticated } from 'src/auth'
|
import { isAutheticated } from 'src/auth'
|
||||||
import Swal from 'sweetalert2'
|
import Swal from 'sweetalert2'
|
||||||
import OrderDetailsDialog from './partialOrderModal'
|
import OrderDetailsDialog from './partialOrderModal'
|
||||||
import InvoiceTable from './invoiceTable'
|
import InvoiceTable from './invoiceTable'
|
||||||
import PendingOrderTable from './pendingOrderTable'
|
import PendingOrderTable from './pendingOrderTable'
|
||||||
|
import Axios from '../../../axios'
|
||||||
|
|
||||||
const ViewInvoices = () => {
|
const ViewInvoices = () => {
|
||||||
const [invoice, setInvoice] = useState(null) // State to store order details
|
const [invoice, setInvoice] = useState(null) // State to store order details
|
||||||
@ -53,7 +54,7 @@ const ViewInvoices = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchOrderDetails = async () => {
|
const fetchOrderDetails = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`/api/invoice/details/${id}`, {
|
const response = await Axios.get(`/api/pd-get-invoices/${id}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
@ -87,10 +88,11 @@ const ViewInvoices = () => {
|
|||||||
|
|
||||||
const handleConfirmUpdate = async (e) => {
|
const handleConfirmUpdate = async (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (invoiceStatus === 'dispatched') {
|
if (invoiceStatus === 'dispatched') {
|
||||||
const res = await axios.put(
|
const res = await Axios.put(
|
||||||
`/api/invoice/dispatched/${id}`,
|
`/api/pd-invoice/dispatched/${id}`,
|
||||||
{
|
{
|
||||||
courierName,
|
courierName,
|
||||||
couriertrackingId,
|
couriertrackingId,
|
||||||
@ -105,11 +107,11 @@ const ViewInvoices = () => {
|
|||||||
console.log(res)
|
console.log(res)
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
Swal.fire('Invoice Status updated', 'Invoice Dispatched', 'success')
|
Swal.fire('Invoice Status updated', 'Invoice Dispatched', 'success')
|
||||||
navigate(`/orders/dispatched`)
|
navigate(`/dispatched`)
|
||||||
}
|
}
|
||||||
} else if (invoiceStatus === 'delivered') {
|
} else if (invoiceStatus === 'delivered') {
|
||||||
const deli = await axios.put(
|
const deli = await Axios.put(
|
||||||
`/api/invoice/delivered/${id}`,
|
`/api/pd-invoice/delivered/${id}`,
|
||||||
{},
|
{},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -123,7 +125,7 @@ const ViewInvoices = () => {
|
|||||||
if (deli.status === 200) {
|
if (deli.status === 200) {
|
||||||
Swal.fire('Order Status updated', `Order Dispatched`, 'success')
|
Swal.fire('Order Status updated', `Order Dispatched`, 'success')
|
||||||
|
|
||||||
navigate(`/orders/delivered`)
|
navigate(`/delivered`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -154,7 +156,7 @@ const ViewInvoices = () => {
|
|||||||
<Typography variant="h4" sx={{ flexGrow: 1, textAlign: 'center' }}>
|
<Typography variant="h4" sx={{ flexGrow: 1, textAlign: 'center' }}>
|
||||||
Invoice Id : {invoice?.invoiceId}
|
Invoice Id : {invoice?.invoiceId}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button color="primary" onClick={() => navigate(`/orders/${status}`)} variant="contained">
|
<Button color="primary" onClick={() => navigate(-1)} variant="contained">
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
@ -305,9 +307,7 @@ const ViewInvoices = () => {
|
|||||||
<Typography variant="h5" sx={{ mb: '0.5rem' }}>
|
<Typography variant="h5" sx={{ mb: '0.5rem' }}>
|
||||||
Customer Details
|
Customer Details
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography sx={{ mb: '0.5rem' }}>
|
|
||||||
<strong>SBU:</strong> {invoice?.orderId?.addedBy.SBU}
|
|
||||||
</Typography>
|
|
||||||
<Typography sx={{ mb: '0.5rem' }}>
|
<Typography sx={{ mb: '0.5rem' }}>
|
||||||
<strong>Name:</strong> {invoice?.orderId?.addedBy.name}
|
<strong>Name:</strong> {invoice?.orderId?.addedBy.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -315,7 +315,7 @@ const ViewInvoices = () => {
|
|||||||
<strong>Email id:</strong> {invoice?.orderId?.addedBy.email}
|
<strong>Email id:</strong> {invoice?.orderId?.addedBy.email}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography sx={{ mb: '0.5rem' }}>
|
<Typography sx={{ mb: '0.5rem' }}>
|
||||||
<strong>Number:</strong> {invoice?.orderId?.addedBy.phone}
|
<strong>Number:</strong> {invoice?.orderId?.addedBy.mobile_number}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item sm={6} md={6} lg={6}>
|
<Grid item sm={6} md={6} lg={6}>
|
195
src/views/pages/rdOrders/processingInvoices.js
Normal file
195
src/views/pages/rdOrders/processingInvoices.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react'
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Typography,
|
||||||
|
TablePagination,
|
||||||
|
TextField,
|
||||||
|
MenuItem,
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
|
Select,
|
||||||
|
Skeleton,
|
||||||
|
} from '@mui/material'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { isAutheticated } from 'src/auth'
|
||||||
|
import { debounce } from 'lodash' // Import debounce from lodash
|
||||||
|
import Axios from '../../../axios'
|
||||||
|
|
||||||
|
const ProcessingInvoices = () => {
|
||||||
|
const [orders, setOrders] = useState([])
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [page, setPage] = useState(0) // 0-based page
|
||||||
|
const [rowsPerPage, setRowsPerPage] = useState(5)
|
||||||
|
const [totalOrders, setTotalOrders] = useState(0)
|
||||||
|
const [searchField, setSearchField] = useState('Order ID')
|
||||||
|
const [searchText, setSearchText] = useState('')
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const token = isAutheticated()
|
||||||
|
const searchRef = useRef()
|
||||||
|
const fetchOrdersDebounced = useRef(
|
||||||
|
debounce((page, limit, searchField, searchText) => {
|
||||||
|
fetchOrders(page, limit, searchField, searchText)
|
||||||
|
}, 500),
|
||||||
|
).current
|
||||||
|
|
||||||
|
const fetchOrders = async (page, limit, searchField = '', searchText = '') => {
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
const response = await Axios.get('/api/pd-get-processing-invoices', {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
limit,
|
||||||
|
page: page + 1,
|
||||||
|
[searchField === 'Order ID' ? 'orderId' : 'invoiceId']: searchText || '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
console.log(response)
|
||||||
|
setOrders(response?.data?.invoices)
|
||||||
|
setTotalOrders(response?.data?.totalCount)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching orders:', error)
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchOrdersDebounced(page, rowsPerPage, searchField, searchText)
|
||||||
|
}, [page, rowsPerPage, searchField, searchText])
|
||||||
|
|
||||||
|
const handleSearchChange = (event) => {
|
||||||
|
const value = event.target.value
|
||||||
|
setSearchText(value)
|
||||||
|
searchRef.current = value
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearchFieldChange = (event) => {
|
||||||
|
setSearchField(event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(parseInt(event.target.value, 10))
|
||||||
|
setPage(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h4" mb={2} textAlign="center">
|
||||||
|
Processing Invoice List
|
||||||
|
</Typography>
|
||||||
|
<Box display="flex" mb={2} alignItems="center">
|
||||||
|
<FormControl variant="outlined" sx={{ minWidth: 150, mr: 2 }}>
|
||||||
|
<InputLabel id="search-field-label">Search By</InputLabel>
|
||||||
|
<Select
|
||||||
|
labelId="search-field-label"
|
||||||
|
id="search-field"
|
||||||
|
value={searchField}
|
||||||
|
onChange={handleSearchFieldChange}
|
||||||
|
label="Search By"
|
||||||
|
>
|
||||||
|
<MenuItem value="Order ID">Order ID</MenuItem>
|
||||||
|
<MenuItem value="Invoice ID">Invoice ID</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<TextField
|
||||||
|
label={`Search by ${searchField}`}
|
||||||
|
variant="outlined"
|
||||||
|
value={searchText}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>Order ID</TableCell>
|
||||||
|
<TableCell>Invoice ID</TableCell>
|
||||||
|
<TableCell>Processing Date</TableCell>
|
||||||
|
<TableCell>Items</TableCell>
|
||||||
|
<TableCell>Invoice Value</TableCell>
|
||||||
|
<TableCell>Status</TableCell>
|
||||||
|
<TableCell>Action</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{loading ? (
|
||||||
|
Array.from(new Array(rowsPerPage)).map((_, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell colSpan={6}>
|
||||||
|
<Skeleton height={40} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : orders.length > 0 ? (
|
||||||
|
orders.map((invoice) => (
|
||||||
|
<TableRow key={invoice._id}>
|
||||||
|
<TableCell>{invoice.orderId.uniqueId}</TableCell>
|
||||||
|
<TableCell>{invoice.invoiceId}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{new Date(invoice.courierstatus_timeline.processing).toDateString()}
|
||||||
|
<span>, {formatAMPM(invoice.courierstatus_timeline.processing)}</span>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{invoice.items.length}</TableCell>
|
||||||
|
<TableCell>{invoice.invoiceAmount}</TableCell>
|
||||||
|
<TableCell>{invoice.courierStatus}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => navigate(`/invoice/${invoice.courierStatus}/${invoice._id}`)}
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={6} align="center">
|
||||||
|
<Typography variant="body1">No data found</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
|
component="div"
|
||||||
|
count={totalOrders}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</TableContainer>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to format time as AM/PM
|
||||||
|
const formatAMPM = (date) => {
|
||||||
|
const hours = new Date(date).getHours()
|
||||||
|
const minutes = new Date(date).getMinutes()
|
||||||
|
const ampm = hours >= 12 ? 'PM' : 'AM'
|
||||||
|
const formattedHours = hours % 12 || 12
|
||||||
|
const formattedMinutes = minutes < 10 ? '0' + minutes : minutes
|
||||||
|
return `${formattedHours}:${formattedMinutes} ${ampm}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProcessingInvoices
|
@ -126,6 +126,7 @@ const ViewOrders = () => {
|
|||||||
processquantity: item.remainingQuantity, // Add processquantity only for items with remainingQuantity > 0
|
processquantity: item.remainingQuantity, // Add processquantity only for items with remainingQuantity > 0
|
||||||
}))
|
}))
|
||||||
console.log(processingOrderInvoice)
|
console.log(processingOrderInvoice)
|
||||||
|
|
||||||
const cancellationRes = await Axios.post(
|
const cancellationRes = await Axios.post(
|
||||||
`/api/pd-process-order`,
|
`/api/pd-process-order`,
|
||||||
{
|
{
|
||||||
@ -139,14 +140,19 @@ const ViewOrders = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
console.log(cancellationRes, 'this is the resp')
|
||||||
if (cancellationRes.status === 200) {
|
if (cancellationRes.status === 200) {
|
||||||
Swal.fire('Order Status updated', `Order in processing`, 'success')
|
Swal.fire('Order Status updated', `Order in processing`, 'success')
|
||||||
navigate(`/pending`)
|
navigate(`/pending`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error.response.status === 400) {
|
||||||
|
Swal.fire('Stock not avaivalbe ', error.response.data.error, 'error')
|
||||||
|
} else {
|
||||||
Swal.fire('Something went wrong ', error.message, 'error')
|
Swal.fire('Something went wrong ', error.message, 'error')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Perform update logic here
|
// Perform update logic here
|
||||||
setOpnePartialModal(false)
|
setOpnePartialModal(false)
|
||||||
setOpenConfirmDialog(false)
|
setOpenConfirmDialog(false)
|
||||||
@ -208,14 +214,19 @@ const ViewOrders = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if (cancellationRes.status === 200) {
|
if (cancellationRes.status === 200) {
|
||||||
Swal.fire('Order Status updated', `Order in processing`, 'success')
|
Swal.fire('Order Status updated', `Order in processing`, 'success')
|
||||||
navigate(`/pending`)
|
navigate(`/pending`)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error.response.status === 400) {
|
||||||
|
Swal.fire('Stock not avaivalbe ', error.response.data.error, 'error')
|
||||||
|
} else {
|
||||||
Swal.fire('Something went wrong ', error.message, 'error')
|
Swal.fire('Something went wrong ', error.message, 'error')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const timelineData = [
|
const timelineData = [
|
||||||
{ event: 'Order Placed On', date: order?.createdAt },
|
{ event: 'Order Placed On', date: order?.createdAt },
|
||||||
|
Loading…
Reference in New Issue
Block a user