invoice and pendind

This commit is contained in:
ROSHAN GARG 2024-09-21 20:55:43 +05:30
parent 0fb2629812
commit b8ff92deb9
6 changed files with 408 additions and 4 deletions

View File

@ -165,6 +165,13 @@ const _nav = [
to: "/orders/delivered", to: "/orders/delivered",
group: "Orders", group: "Orders",
}, },
{
component: CNavItem,
name: "Pending",
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
to: "/orders/Pending",
group: "Orders",
},
{ {
component: CNavItem, component: CNavItem,
name: "Cancelled", name: "Cancelled",
@ -172,6 +179,7 @@ const _nav = [
to: "/orders/cancelled", to: "/orders/cancelled",
group: "Orders", group: "Orders",
}, },
// { // {
// component: CNavItem, // component: CNavItem,
// name: "In Store Cash Orders", // name: "In Store Cash Orders",

View File

@ -0,0 +1,97 @@
[
{
"invoiceId": "INV-001234",
"orderId": "ORDER-987654",
"items": [
{
"productId": "5f8d0d55b54764421b7156b1",
"SKU": "PRD-0001",
"name": "Wireless Mouse",
"categoryName": "Electronics",
"brandName": "Logitech",
"price": 1499,
"GST": 18,
"HSN_Code": 847160,
"processquantity": 2
},
{
"productId": "5f8d0d55b54764421b7156b2",
"SKU": "PRD-0002",
"name": "Keyboard",
"categoryName": "Electronics",
"brandName": "Dell",
"price": 2499,
"GST": 18,
"HSN_Code": 847160,
"processquantity": 1
}
],
"subtotal": 5497,
"gstTotal": 989.46,
"invoiceAmount": 6486.46,
"courier_name": "FedEx",
"courier_tracking_id": "TRK-123456789",
"courierStatus": "processing",
"courierstatus_timeline": {
"processing": "2023-09-18T09:00:00",
"dispatched": null,
"delivered": null
}
},
{
"invoiceId": "INV-001235",
"orderId": "ORDER-987655",
"items": [
{
"productId": "5f8d0d55b54764421b7156b3",
"SKU": "PRD-0003",
"name": "Smartphone",
"categoryName": "Mobile Phones",
"brandName": "Samsung",
"price": 19999,
"GST": 12,
"HSN_Code": 851712,
"processquantity": 1
}
],
"subtotal": 19999,
"gstTotal": 2399.88,
"invoiceAmount": 22398.88,
"courier_name": "DHL",
"courier_tracking_id": "TRK-987654321",
"courierStatus": "dispatched",
"courierstatus_timeline": {
"processing": "2023-09-15T10:00:00",
"dispatched": "2023-09-16T12:30:00",
"delivered": null
}
},
{
"invoiceId": "INV-001236",
"orderId": "ORDER-987656",
"items": [
{
"productId": "5f8d0d55b54764421b7156b4",
"SKU": "PRD-0004",
"name": "Laptop",
"categoryName": "Computers",
"brandName": "HP",
"price": 59999,
"GST": 18,
"HSN_Code": 847130,
"processquantity": 1
}
],
"subtotal": 59999,
"gstTotal": 10799.82,
"invoiceAmount": 70798.82,
"courier_name": "Blue Dart",
"courier_tracking_id": "TRK-1122334455",
"courierStatus": "delivered",
"courierstatus_timeline": {
"processing": "2023-09-10T08:00:00",
"dispatched": "2023-09-11T11:00:00",
"delivered": "2023-09-13T14:45:00"
}
}
]

View File

@ -152,6 +152,7 @@ import ViewPrincipalDistributorSC from "./views/SalesCoOrdinators/ViewPrincipalD
import ViewRetailDistributorSC from "./views/SalesCoOrdinators/ViewRetailDistributorSC"; import ViewRetailDistributorSC from "./views/SalesCoOrdinators/ViewRetailDistributorSC";
import ViewRetailDistributorPD from "./views/PrincipalDistributors/ViewRetailDistributorPD"; import ViewRetailDistributorPD from "./views/PrincipalDistributors/ViewRetailDistributorPD";
import MapRD from "./views/RetailDistributors/MapRD"; import MapRD from "./views/RetailDistributors/MapRD";
import PendingOrders from "./views/orders/pendingOrders";
const routes = [ const routes = [
//dashboard //dashboard
@ -224,7 +225,7 @@ const routes = [
element: ViewProductManual, element: ViewProductManual,
navName: "Product Management", navName: "Product Management",
}, },
//SalesCoOrdinator //SalesCoOrdinator
{ {
path: "/salescoordinator/edit/:id", path: "/salescoordinator/edit/:id",
name: "Edit SalesCoOrdinator", name: "Edit SalesCoOrdinator",
@ -644,6 +645,12 @@ const routes = [
element: DeliveredOrders, element: DeliveredOrders,
navName: "Orders", navName: "Orders",
}, },
{
path: "/orders/pending",
name: "Pending Orders",
element: PendingOrders,
navName: "Orders",
},
{ {
path: "/orders/cancelled", path: "/orders/cancelled",
name: "Cancelled Orders", name: "Cancelled Orders",

View File

@ -19,12 +19,14 @@ import {
TextField, TextField,
Divider, Divider,
} 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 "@material-ui/core";
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";
const ViewOrders = () => { const ViewOrders = () => {
const [order, setOrder] = useState(null); // State to store order details const [order, setOrder] = useState(null); // State to store order details
@ -295,7 +297,15 @@ const ViewOrders = () => {
<Grid container spacing={2}> <Grid container spacing={2}>
<Grid item md={8} xl={8} lg={8}> <Grid item md={8} xl={8} lg={8}>
<Box sx={{ padding: 2, background: "#fff" }}> <Box sx={{ padding: 2, background: "#fff" }}>
<Typography variant="h4" gutterBottom> {onvoicesData.length > 0 && (
<>
<Typography variant="h4" gutterBottom>
Invoices
</Typography>
<InvoiceTable invoices={onvoicesData} />
</>
)}
<Typography variant="h4" my={3} gutterBottom>
Order Summary Order Summary
</Typography> </Typography>
@ -506,6 +516,15 @@ const ViewOrders = () => {
<option value="cancelled">Cancelled</option> <option value="cancelled">Cancelled</option>
</> </>
)} )}
{status === "pending" && (
<>
<option value="processing">Processing</option>
<option value="partial-processing">
Partial Processing
</option>
<option value="cancelled">Cancelled</option>
</>
)}
{status === "processing" && ( {status === "processing" && (
<> <>
<option value="">Processing</option> <option value="">Processing</option>

View File

@ -0,0 +1,74 @@
import React, { useState, useEffect } from "react";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
Button,
Chip,
} from "@mui/material";
import axios from "axios";
import { Typography } from "@material-ui/core";
const InvoiceTable = ({ invoices }) => {
return (
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>Invoice ID</TableCell>
<TableCell>Items</TableCell>
<TableCell>Subtotal</TableCell>
<TableCell>GST Total</TableCell>
<TableCell>Invoice Amount</TableCell>
<TableCell>Courier Status</TableCell>
</TableRow>
</TableHead>
<TableBody>
{false ? (
<TableRow>
<TableCell colSpan={8} align="center">
Loading...
</TableCell>
</TableRow>
) : (
invoices.map((invoice) => (
<TableRow key={invoice.invoiceId}>
<TableCell>{invoice.invoiceId}</TableCell>
<TableCell>
{invoice.items.map((item) => (
<div key={item.productId}>
{item.name} ({item.SKU}) x {item.processquantity}
</div>
))}
</TableCell>
<TableCell>{invoice.subtotal}</TableCell>
<TableCell>{invoice.gstTotal}</TableCell>
<TableCell>{invoice.invoiceAmount}</TableCell>
<TableCell>
<Chip
label={invoice.courierStatus}
color={
invoice.courierStatus === "delivered"
? "success"
: invoice.courierStatus === "dispatched"
? "primary"
: "warning"
}
/>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</TableContainer>
);
};
export default InvoiceTable;

View File

@ -0,0 +1,199 @@
import React, { useState, useEffect } 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";
const PendingOrders = () => {
const [orders, setOrders] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(0);
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();
// Fetch orders with pagination
const fetchOrders = async (page, limit) => {
setLoading(true);
try {
const response = await axios.get("/api/get-pending-order-admin", {
headers: {
Authorization: `Bearer ${token}`,
},
params: {
page: page + 1, // Adjusting for zero-based index in the UI
limit,
searchField,
searchText,
},
});
// console.log(response);
setOrders(response?.data?.placedOrders);
setTotalOrders(response?.data?.totalOrders);
} catch (error) {
console.error("Error fetching orders:", error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchOrders(page, rowsPerPage);
}, [page, rowsPerPage, searchField, searchText]);
const handleSearchChange = (event) => {
setSearchText(event.target.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);
};
const filteredOrders = orders?.filter((order) => {
if (searchField === "Order ID") {
return order.uniqueId.toLowerCase().includes(searchText.toLowerCase());
}
if (searchField === "Status") {
return order.status.toLowerCase().includes(searchText.toLowerCase());
}
return true;
});
return (
<Box>
<Typography variant="h4" mb={2} textAlign="center">
Pending Order 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="Status">Status</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>Order Date</TableCell>
<TableCell>Items</TableCell>
<TableCell>Order 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>
))
) : filteredOrders.length > 0 ? (
filteredOrders.map((order) => (
<TableRow key={order._id}>
<TableCell>{order.uniqueId}</TableCell>
<TableCell>
{new Date(order.createdAt).toDateString()}
<span>, {formatAMPM(order.createdAt)}</span>
</TableCell>
<TableCell>{order.orderItem.length}</TableCell>
<TableCell>{order.grandTotal.toFixed(2)}</TableCell>
<TableCell>{order.status}</TableCell>
<TableCell>
<Button
variant="contained"
color="primary"
onClick={() =>
navigate(`/orders/${order.status}/${order._id}`)
}
>
View
</Button>
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={6} align="center">
<Typography variant="body1">Data not 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) => {
var hours = new Date(date).getHours();
var minutes = new Date(date).getMinutes();
var ampm = hours >= 12 ? "PM" : "AM";
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes < 10 ? "0" + minutes : minutes;
var strTime = hours + ":" + minutes + " " + ampm;
return strTime;
};
export default PendingOrders;