diff --git a/src/_nav.js b/src/_nav.js index 47c9e9f..4b7a664 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -234,6 +234,13 @@ const _nav = [ // }, ], }, + { + component: CNavItem, + name: "Retailer Orders", + icon: , + to: "/retailer/order", + group: "RetailerOrders", + }, { component: CNavItem, name: "Announcement", diff --git a/src/routes.js b/src/routes.js index f972a8d..d39bec1 100644 --- a/src/routes.js +++ b/src/routes.js @@ -177,6 +177,8 @@ import SingleUserTask from "./views/Tasks/SingleUserTask"; import Tasks from "./views/Tasks/Task"; import DistributorLiqudations from "./views/PrincipalDistributors/DistributorLiqudation"; import UpdatePrincipalDistributor from "./views/PrincipalDistributors/updateprincipaldistributor"; +import RDViewOrder from "./views/RetailerOrders/ViewOrder"; +import RetailerOrder from "./views/RetailerOrders/RetailerOrder"; const routes = [ //dashboard @@ -821,6 +823,19 @@ const routes = [ element: InStoreQRCodeOrders, navName: "Orders", }, + // -------------RD ORDER------------ + { + path: "/rdorders/view/:id", + name: "View Order", + element: RDViewOrder, + navName: "RetailerOrders", + }, + { + path: "/retailer/order", + name: "Retaioler Order", + element: RetailerOrder, + navName: "RetailerOrders", + }, //-------------- End Order Management Routes--------------------------------------- // Announcement { diff --git a/src/views/RetailDistributors/DistributorOrders.js b/src/views/RetailDistributors/DistributorOrders.js index 1cc92dd..a459eec 100644 --- a/src/views/RetailDistributors/DistributorOrders.js +++ b/src/views/RetailDistributors/DistributorOrders.js @@ -444,17 +444,19 @@ const SingleDistributorOrder = () => { return ( - {item.productId.name} + {item.image.length > 0 && ( + {item.name} + )} - {item.productId.name} + {item.name} ₹{item.price} diff --git a/src/views/RetailDistributors/RetailDistributor.js b/src/views/RetailDistributors/RetailDistributor.js index 650f950..18547c5 100644 --- a/src/views/RetailDistributors/RetailDistributor.js +++ b/src/views/RetailDistributors/RetailDistributor.js @@ -132,9 +132,7 @@ const RetailDistributor = () => { ); if (response.data.success) { - toast.success( - "Password reset successfully! Email sent to Retailer." - ); + toast.success("Password reset successfully! Email sent to Retailer."); } } catch (error) { toast.error( @@ -464,7 +462,7 @@ const RetailDistributor = () => { Previous - {Array.from({ length: totalPages }, (_, index) => ( + {/* {Array.from({ length: totalPages }, (_, index) => (
  • { {index + 1}
  • - ))} + ))} */} + {Array.from( + { length: Math.min(3, totalPages) }, + (_, index) => { + let page = currentPage; + + // Adjust start page to keep current page centered if possible + if (totalPages > 3) { + if (currentPage === 1) page = 1; + else if (currentPage === totalPages) + page = totalPages - 2; + else page = currentPage - 1; + } + + return ( +
  • + setCurrentPage(page + index)} + aria-controls="datatable" + > + {page + index} + +
  • + ); + } + )}
  • { + 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("retailer"); + const [searchText, setSearchText] = useState(""); + const navigate = useNavigate(); + const token = isAutheticated(); + + // Fetch orders with pagination and search + const fetchOrders = async (page, limit, searchField, searchText) => { + setLoading(true); + try { + const response = await axios.get("/api/rd-order", { + headers: { + Authorization: `Bearer ${token}`, + }, + params: { + page: page + 1, // Adjusting for zero-based index in the UI + limit, + searchField, + searchText, + }, + }); + setOrders(response?.data?.orders || []); + setTotalOrders(response?.data?.totalOrders || 0); + } catch (error) { + console.error("Error fetching orders:", error); + } finally { + setLoading(false); + } + }; + + // Debounce API calls when search text changes + const debouncedFetchOrders = debounce( + (page, limit, searchField, searchText) => { + fetchOrders(page, limit, searchField, searchText); + }, + 500 + ); + + useEffect(() => { + debouncedFetchOrders(page, rowsPerPage, searchField, searchText); + return () => debouncedFetchOrders.cancel(); // Cleanup to avoid unnecessary calls + }, [page, rowsPerPage, searchField, searchText]); + + const handleSearchChange = (event) => { + setSearchText(event.target.value); + setPage(0); // Reset to first page on search + }; + + const handleSearchFieldChange = (event) => { + setSearchField(event.target.value); + setSearchText(""); // Reset search text on field change + setPage(0); // Reset to first page on field change + }; + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + return ( + + + Retailer Order List + + + + Search By + + + + + + + + + Order ID + Retailer Name + Respected PD + Order Date + Items + Order Value + Status + Action + + + + {loading ? ( + Array.from(new Array(rowsPerPage)).map((_, index) => ( + + + + + + )) + ) : orders.length > 0 ? ( + orders.map((order) => ( + + {order.uniqueId} + {order.addedBy?.name || "N/A"} + {order.pd?.name || "N/A"} + + {new Date(order.createdAt).toDateString()} + , {formatAMPM(order.createdAt)} + + {order.orderItem.length} + ₹ {order.grandTotal.toFixed(2)} + {order.status} + + + + + )) + ) : ( + + + Data not found + + + )} + +
    + +
    +
    + ); +}; + +// 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 || 12; + minutes = minutes < 10 ? "0" + minutes : minutes; + return `${hours}:${minutes} ${ampm}`; +}; + +export default RetailerOrder; diff --git a/src/views/RetailerOrders/ViewOrder.js b/src/views/RetailerOrders/ViewOrder.js new file mode 100644 index 0000000..345591b --- /dev/null +++ b/src/views/RetailerOrders/ViewOrder.js @@ -0,0 +1,287 @@ +import React, { useState, useEffect } from "react"; +import { + Box, + Typography, + Grid, + Button, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Paper, + Divider, +} from "@mui/material"; +import { useNavigate, useParams } from "react-router-dom"; +import { TableContainer } from "@material-ui/core"; +import axios from "axios"; // Import axios for HTTP requests +import { isAutheticated } from "src/auth"; +import InvoiceTable from "../orders/invoiceTable"; +import PendingOrderTable from "../orders/pendingOrderTable"; + +const RDViewOrder = () => { + const [order, setOrder] = useState(null); // State to store order details + const token = isAutheticated(); // State for delivery date + const [loading, setLoading] = useState(true); // Loading state + const [error, setError] = useState(null); // Error state + const navigate = useNavigate(); + const { id } = useParams(); + // Get order ID from URL params + + useEffect(() => { + const fetchOrderDetails = async () => { + try { + const response = await axios.get( + `/api/get-single-placed-order-rd/${id}`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + // console.log(response); + setOrder(response.data.singleOrder); + setLoading(false); + } catch (err) { + setError("Failed to fetch order details"); + setLoading(false); + } + }; + + fetchOrderDetails(); + }, [id]); + + if (loading) { + return Loading...; + } + + if (error) { + return {error}; + } + + return ( + + + + Order ID: {order?.uniqueId} + + + + + + + {order.invoices?.length > 0 && ( + <> + + Invoices + + + + )} + + Order Summary + + + + + + + + + Product + Price (₹) + Order Quantity + Subtotal (₹) + GST (%) + GST Amount (₹) + Total with GST (₹) + + + + {order?.orderItem.map((item, index) => { + const subtotal = item.price * item.quantity; + const gstAmount = ( + ((item.GST * item.price) / 100) * + item.quantity + ).toFixed(2); + const totalWithGST = ( + subtotal + parseFloat(gstAmount) + ).toFixed(2); + + return ( + + + {item.image.length > 0 && ( + {item.name} + )} + + {item.name} + + + ₹{item.price} + + {item.quantity} + + ₹{subtotal} + {item.GST}% + ₹{gstAmount} + ₹{totalWithGST} + + ); + })} + +
    +
    +
    +
    + {order.invoices?.length > 0 && ( + <> + {" "} + + Order Items{" "} + {order?.status == "pending" ? "to be Processed" : "Cancelled"} + + + + )} + + + + + + Order Summary + + + + Total Items: {order?.orderItem.length} + + + Total Subtotal: ₹{order?.subtotal} + Total GST: ₹{order?.gstTotal} + + Grand Total: ₹{order?.grandTotal} + + + + +
    +
    + + + + + + Retailer Details + + + SBU: {order?.addedBy.uniqueId} + + + Name: {order?.addedBy.name} + + + Email id: {order?.addedBy.email} + + + Number: {order?.addedBy.mobile_number} + + + + + Respected PD Details + + + SBU: {order?.pd.SBU} + + + Name: {order?.pd.name} + + + Email id: {order?.pd.email} + + + Number: {order?.pd.phone} + + + + + Bill Address + + {order?.billTo} + + + + Ship Address + + {order?.shipTo} + + + + Payment mode + + + {order?.paymentMode} + + + + + + Order Status + + {order?.status} + {order?.status === "cancelled" && ( + + {order?.order_Cancelled_Reason} + + )} + + + + +
    +
    + ); +}; +// 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 RDViewOrder; diff --git a/src/views/orders/ViewOrders.js b/src/views/orders/ViewOrders.js index bde6f35..cf979d2 100644 --- a/src/views/orders/ViewOrders.js +++ b/src/views/orders/ViewOrders.js @@ -335,9 +335,13 @@ const ViewOrders = () => { {order?.orderItem.map((item, index) => { const subtotal = item.price * item.quantity; - const gstAmount = - ((item.GST * item.price) / 100) * item.quantity; - const totalWithGST = subtotal + gstAmount; + const gstAmount = ( + ((item.GST * item.price) / 100) * + item.quantity + ).toFixed(2); + const totalWithGST = ( + subtotal + parseFloat(gstAmount) + ).toFixed(2); return ( diff --git a/src/views/orders/viewInoices.js b/src/views/orders/viewInoices.js index 770e841..ceaa01f 100644 --- a/src/views/orders/viewInoices.js +++ b/src/views/orders/viewInoices.js @@ -270,9 +270,9 @@ const ViewInvoices = () => { {invoice?.orderId?.orderItem.map((item, index) => { const subtotal = item.price * item.quantity; - const gstAmount = - ((item.GST * item.price) / 100) * item.quantity; - const totalWithGST = subtotal + gstAmount; + const gstAmount = (((item.GST * item.price) / 100) * item.quantity).toFixed(2); +const totalWithGST = (subtotal + parseFloat(gstAmount)).toFixed(2); + return (