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

This commit is contained in:
ROSHAN GARG 2024-10-03 16:33:02 +05:30
parent 03dbed7d14
commit efb60cc3c1
6 changed files with 620 additions and 16 deletions

View File

@ -10,6 +10,10 @@ import ViewOrders from './views/pages/rdOrders/viewOrders'
import PendingOrders from './views/pages/rdOrders/pendingOrders'
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 Shop = React.lazy(() => import('./views/shops/Shop'))
@ -35,6 +39,10 @@ const routes = [
//RD Orders
{ path: '/new', name: 'New', element: NewOrders },
{ 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: '/:status/:id', name: 'New', element: ViewOrders },

View 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

View 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

View File

@ -20,15 +20,16 @@ import {
Divider,
Chip,
} from '@mui/material'
import onvoicesData from '../../assets/incoicedata.json'
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 { isAutheticated } from 'src/auth'
import Swal from 'sweetalert2'
import OrderDetailsDialog from './partialOrderModal'
import InvoiceTable from './invoiceTable'
import PendingOrderTable from './pendingOrderTable'
import Axios from '../../../axios'
const ViewInvoices = () => {
const [invoice, setInvoice] = useState(null) // State to store order details
@ -53,7 +54,7 @@ const ViewInvoices = () => {
useEffect(() => {
const fetchOrderDetails = async () => {
try {
const response = await axios.get(`/api/invoice/details/${id}`, {
const response = await Axios.get(`/api/pd-get-invoices/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
@ -87,10 +88,11 @@ const ViewInvoices = () => {
const handleConfirmUpdate = async (e) => {
e.preventDefault()
try {
if (invoiceStatus === 'dispatched') {
const res = await axios.put(
`/api/invoice/dispatched/${id}`,
const res = await Axios.put(
`/api/pd-invoice/dispatched/${id}`,
{
courierName,
couriertrackingId,
@ -105,11 +107,11 @@ const ViewInvoices = () => {
console.log(res)
if (res.status === 200) {
Swal.fire('Invoice Status updated', 'Invoice Dispatched', 'success')
navigate(`/orders/dispatched`)
navigate(`/dispatched`)
}
} else if (invoiceStatus === 'delivered') {
const deli = await axios.put(
`/api/invoice/delivered/${id}`,
const deli = await Axios.put(
`/api/pd-invoice/delivered/${id}`,
{},
{
@ -123,7 +125,7 @@ const ViewInvoices = () => {
if (deli.status === 200) {
Swal.fire('Order Status updated', `Order Dispatched`, 'success')
navigate(`/orders/delivered`)
navigate(`/delivered`)
}
}
} catch (error) {
@ -154,7 +156,7 @@ const ViewInvoices = () => {
<Typography variant="h4" sx={{ flexGrow: 1, textAlign: 'center' }}>
Invoice Id : {invoice?.invoiceId}
</Typography>
<Button color="primary" onClick={() => navigate(`/orders/${status}`)} variant="contained">
<Button color="primary" onClick={() => navigate(-1)} variant="contained">
Back
</Button>
</Box>
@ -305,9 +307,7 @@ const ViewInvoices = () => {
<Typography variant="h5" sx={{ mb: '0.5rem' }}>
Customer Details
</Typography>
<Typography sx={{ mb: '0.5rem' }}>
<strong>SBU:</strong> {invoice?.orderId?.addedBy.SBU}
</Typography>
<Typography sx={{ mb: '0.5rem' }}>
<strong>Name:</strong> {invoice?.orderId?.addedBy.name}
</Typography>
@ -315,7 +315,7 @@ const ViewInvoices = () => {
<strong>Email id:</strong> {invoice?.orderId?.addedBy.email}
</Typography>
<Typography sx={{ mb: '0.5rem' }}>
<strong>Number:</strong> {invoice?.orderId?.addedBy.phone}
<strong>Number:</strong> {invoice?.orderId?.addedBy.mobile_number}
</Typography>
</Grid>
<Grid item sm={6} md={6} lg={6}>

View 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

View File

@ -126,6 +126,7 @@ const ViewOrders = () => {
processquantity: item.remainingQuantity, // Add processquantity only for items with remainingQuantity > 0
}))
console.log(processingOrderInvoice)
const cancellationRes = await Axios.post(
`/api/pd-process-order`,
{
@ -139,13 +140,18 @@ const ViewOrders = () => {
},
},
)
console.log(cancellationRes, 'this is the resp')
if (cancellationRes.status === 200) {
Swal.fire('Order Status updated', `Order in processing`, 'success')
navigate(`/pending`)
}
}
} catch (error) {
Swal.fire('Something went wrong ', error.message, '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')
}
}
// Perform update logic here
setOpnePartialModal(false)
@ -208,12 +214,17 @@ const ViewOrders = () => {
},
},
)
if (cancellationRes.status === 200) {
Swal.fire('Order Status updated', `Order in processing`, 'success')
navigate(`/pending`)
}
} catch (error) {
Swal.fire('Something went wrong ', error.message, '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')
}
}
}