diff --git a/src/_nav.js b/src/_nav.js index bb31db6..0b04308 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -104,13 +104,6 @@ const _nav = [ to: "/retail-distributor", group: "RetailDistributor", }, - // { - // component: CNavItem, - // name: "Opening Inventory", - // icon: , - // to: "/opening-inventory", - // group: "OpeningInventory", - // }, { component: CNavItem, name: "Attendance", @@ -146,6 +139,22 @@ const _nav = [ to: "/sales", group: "Sales", }, + { + component: CNavGroup, + name: "Reports", + icon: , + group: "", + + items: [ + { + component: CNavItem, + name: "Opening Inventory", + icon: , + to: "/reports/opening-inventory", + group: "Reports", + }, + ], + }, { component: CNavGroup, name: "Orders", diff --git a/src/routes.js b/src/routes.js index 6a2ef09..5a57df1 100644 --- a/src/routes.js +++ b/src/routes.js @@ -165,9 +165,9 @@ import TodayTask from "./views/Tasks/TodayTasks"; import Sales from "./views/Sales/Sales"; import SingleSales from "./views/Sales/SingleSale"; import MobileApp from "./views/configuration/MobileApp"; -import PDOpeningInventory from "./views/OpeningInventory/PDOpeningInventory"; import DistributorOpeningInventory from "./views/PrincipalDistributors/OpeningInventory"; import UploadOpeningInventory from "./views/PrincipalDistributors/UploadOpeningInventory"; +import OpeningInventoryReports from "./views/Reports/OpeningInventoryReports"; const routes = [ //dashboard @@ -433,7 +433,13 @@ const routes = [ navName: "Distributor", }, //----------------------- End Product Management Routes------------------------------------------------ - + //---------------Reports------------ + { + path: "/reports/opening-inventory", + name: "Reports Opening Inventory", + element: OpeningInventoryReports, + navName: "Reports", + }, //Departure // { path: "/departures", name: "Departures", element: Departures }, // { path: "/departure/add", name: "Add Departure", element: AddDeparture }, @@ -677,20 +683,6 @@ const routes = [ navName: "Website Related", }, //-------------------------------End website related routes---------------------------------- -//-------------------------------Opening Inventory routes---------------------------------- -{ - path: "/opening-inventory", - name: "Opening Inventory", - element: PDOpeningInventory, - navName: "Opening Inventory", -}, -{ - path: "/opening-inventory/pd/:id", - name: "Opening Inventory", - element: PDOpeningInventory, - navName: "Opening Inventory", -}, -//-------------------------------End Opening Inventory routes---------------------------------- //--------------Order Management Routes--------------------------------------- { path: "/orders/new", @@ -819,7 +811,12 @@ const routes = [ navName: "Configuration", }, { path: "/logo", name: "Logo", element: Logo, navName: "Configuration" }, - { path: "/mobile-app", name: "MobileApp", element: MobileApp, navName: "Configuration" }, + { + path: "/mobile-app", + name: "MobileApp", + element: MobileApp, + navName: "Configuration", + }, //----------------- End Configuration Routes----------------------------------- //-----------------Affiliate & Coupons Routes----------------------------------- diff --git a/src/views/Brands/Brands.js b/src/views/Brands/Brands.js index 0a0dd7d..5651153 100644 --- a/src/views/Brands/Brands.js +++ b/src/views/Brands/Brands.js @@ -55,8 +55,8 @@ const Brands = () => { setLoading(true); // Set loading to true before fetching const response = await axios.get("/api/brand/getBrands", { params: { - page, - show: itemPerPage, + // page, + // show: itemPerPage, brandName: nameRef.current?.value || "", }, // Include pagination and search }); @@ -72,7 +72,7 @@ const Brands = () => { useEffect(() => { getBrands(); - }, [page, itemPerPage]); // Trigger fetch when these values change + }, []); const handleEditClick = (_id, brandName) => { setOpen(true); @@ -177,8 +177,7 @@ const Brands = () => { } }; - const getPageCount = () => - Math.max(1, Math.ceil(brands.length / itemPerPage)); + const getPageCount = () => Math.max(1, Math.ceil(brands?.length / itemPerPage)); const debouncedSearch = useCallback( debounce(() => { setPage(1); @@ -371,7 +370,7 @@ const Brands = () => { { ) : ( brands && - brands.map((item, i) => ( + brands + .slice( + (`${page}` - 1) * itemPerPage, + `${page}` * itemPerPage + ) + .map((item, i) => (
{item.brandName}
diff --git a/src/views/Categories/categories.js b/src/views/Categories/categories.js index ebdd031..dad0b83 100644 --- a/src/views/Categories/categories.js +++ b/src/views/Categories/categories.js @@ -57,8 +57,8 @@ const Categories = () => { setLoading(true); const response = await axios.get("/api/category/getCategories", { params: { - page, - show: itemPerPage, + // page, + // show: itemPerPage, categoryName: nameRef.current?.value || "", }, // Include pagination and search }); @@ -75,7 +75,7 @@ const Categories = () => { useEffect(() => { getCategories(); - }, [page, itemPerPage]); + }, []); const handleEditClick = (_id, categoryName) => { setOpen(true); @@ -415,7 +415,7 @@ const Categories = () => { { ) : ( category && - category.map((item, i) => ( + category + .slice( + (`${page}` - 1) * itemPerPage, + `${page}` * itemPerPage + ) + .map((item, i) => (
{item.categoryName}
diff --git a/src/views/OpeningInventory/PDOpeningInventory.js b/src/views/OpeningInventory/PDOpeningInventory.js deleted file mode 100644 index 3a3d58d..0000000 --- a/src/views/OpeningInventory/PDOpeningInventory.js +++ /dev/null @@ -1,304 +0,0 @@ -import React, { useState, useEffect, useRef, useCallback } from "react"; -import { Link } from "react-router-dom"; -import axios from "axios"; -import { isAutheticated } from "src/auth"; -import swal from "sweetalert"; -import debounce from "lodash.debounce"; -const PDOpeningInventory = () => { - const token = isAutheticated(); - const [loading, setLoading] = useState(true); - const [users, setUsers] = useState([]); - const [totalPages, setTotalPages] = useState(1); - const [currentPage, setCurrentPage] = useState(1); - const [itemPerPage, setItemPerPage] = useState(10); - const [totalData, setTotalData] = useState(0); - const nameRef = useRef(); - const SBURef = useRef(); - const getUsers = async () => { - setLoading(true); - try { - const res = await axios.get(`/api/allpd/stock`, { - headers: { - Authorization: `Bearer ${token}`, - }, - params: { - page: currentPage, - show: itemPerPage, - name: nameRef.current.value, - SBU: SBURef.current.value, - }, - }); - // console.log(res.data); - setUsers(res?.data?.data); - setTotalData(res.data?.pagination?.totalRecords); - setTotalPages(res.data?.pagination?.totalPages); - } catch (error) { - swal({ - title: error, - text: "please login to access the resource or refresh the page ", - icon: "error", - button: "Retry", - dangerMode: true, - }); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - getUsers(); - }, [itemPerPage, currentPage]); - - const debouncedSearch = useCallback( - debounce(() => { - setCurrentPage(1); - getUsers(); - }, 500), - [] - ); - - const handleSearchChange = () => { - debouncedSearch(); - }; - - - return ( -
-
-
-
-
-
-
- Principal Distributor Opening Inventory -
-
-
-
- -
-
-
-
-
-
-
- -
-
-
- - -
-
- - -
-
- -
- - - - - - - - - - - - - - {loading ? ( - - - - ) : users.length > 0 ? ( - users.map((user, i) => ( - - - - - - - - - - )) - ) : ( - - - - )} - -
Unique IdSBUNameEmailMobile NmuberDate Registered - Opening Inventory -
-
Loading....
-
{user?.userId.uniqueId}{user.userId.SBU ? user.userId.SBU : "N/A"}{user.userId.name}{user.userId.email}{user.userId.phone} - {new Date(user.createdAt).toLocaleString( - "en-IN", - { - // weekday: "short", - month: "short", - day: "numeric", - year: "numeric", - // hour: "numeric", - // minute: "numeric", - // hour12: true, - } - )} - - - - -
-
No Principal Distributor found!
-
-
- - -
-
-
-
-
-
-
- ); -}; - -export default PDOpeningInventory; diff --git a/src/views/PrincipalDistributors/OpeningInventory.js b/src/views/PrincipalDistributors/OpeningInventory.js index 084cfbd..a111523 100644 --- a/src/views/PrincipalDistributors/OpeningInventory.js +++ b/src/views/PrincipalDistributors/OpeningInventory.js @@ -251,7 +251,7 @@ const DistributorOpeningInventory = () => { className="font-bold capitalize" onClick={() => navigate( - `/principaldistributor/opening-inventory/upload/${id}`, + `/${distributortype}/opening-inventory/upload/${id}`, { replace: true, } diff --git a/src/views/PrincipalDistributors/UploadOpeningInventory.js b/src/views/PrincipalDistributors/UploadOpeningInventory.js index 2369265..cdd41f8 100644 --- a/src/views/PrincipalDistributors/UploadOpeningInventory.js +++ b/src/views/PrincipalDistributors/UploadOpeningInventory.js @@ -44,7 +44,9 @@ const UploadOpeningInventory = () => { formData.append("file", file); const { data } = await axios.post( - `/api/openinginventories/upload/${id}`, + distributortype === "principaldistributor" + ? `/api/openinginventories/pd/upload/${id}` + : `/api/openinginventories/rd/upload/${id}`, formData, { headers: { diff --git a/src/views/Reports/OpeningInventoryReports.js b/src/views/Reports/OpeningInventoryReports.js new file mode 100644 index 0000000..33ec6c2 --- /dev/null +++ b/src/views/Reports/OpeningInventoryReports.js @@ -0,0 +1,409 @@ +import React, { useState, useEffect, useRef, useCallback } from "react"; +import { Link } from "react-router-dom"; +import axios from "axios"; +import Button from "@material-ui/core/Button"; +import { useNavigate } from "react-router-dom"; +import { isAutheticated } from "src/auth"; +import swal from "sweetalert"; +import debounce from "lodash.debounce"; +import { toast } from "react-hot-toast"; +const OpeningInventoryReports = () => { + const token = isAutheticated(); + const navigate = useNavigate(); + const [loading, setLoading] = useState(false); + const [productsData, setProductsData] = useState([]); + const [categories, setCategories] = useState([]); + const [brands, setBrands] = useState([]); + + const nameRef = useRef(); + const categoryRef = useRef(); + const brandRef = useRef(); + + const [currentPage, setCurrentPage] = useState(1); + const [itemPerPage, setItemPerPage] = useState(10); + const [totalData, setTotalData] = useState(0); + + const getProductsData = async () => { + setLoading(true); + try { + const response = await axios.get(`/api/report/opening-inventory`, { + headers: { + Authorization: `Bearer ${token}`, + }, + params: { + page: currentPage, + show: itemPerPage, + name: nameRef.current?.value || "", + category: categoryRef.current?.value || "", + brand: brandRef.current?.value || "", + }, + }); + // console.log(response.data); + setProductsData(response.data?.data || []); + setTotalData(response.data?.pagination?.total || 0); + } catch (err) { + const msg = err?.response?.data?.msg || "Something went wrong!"; + swal({ + title: "Error", + text: msg, + icon: "error", + button: "Retry", + dangerMode: true, + }); + } finally { + setLoading(false); + } + }; + + const getCatagories = () => { + axios + .get(`/api/category/getCategories`, { + headers: { + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }) + .then((res) => { + // console.log(res?.data?.categories); + setCategories(res?.data?.categories); + }); + }; + const getBrands = () => { + axios + .get(`/api/brand/getBrands`, { + headers: { + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }) + .then((res) => { + // console.log(res?.data?.brands); + setBrands(res?.data?.brands); + }); + }; + + useEffect(() => { + getCatagories(); + getBrands(); + }, []); + + useEffect(() => { + getProductsData(); + }, [itemPerPage, currentPage]); + + const debouncedSearch = useCallback( + debounce(() => { + setCurrentPage(1); + getProductsData(); + }, 500), + [] + ); + + const handleSearchChange = () => { + debouncedSearch(); + }; + + return ( +
+
+
+
+
+
+
+ Opening Inventory Reports +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + {loading ? ( + + + + ) : productsData?.length > 0 ? ( + productsData?.map((product, i) => ( + + + + + + + + + + )) + ) : ( + + + + )} + +
+ SKU Code + + SKU Description + + Category Name + + Brand Name + + At PD and RD + + All PDs + + All RDs +
+ Loading... +
+ {product.SKU} + + {product.name} + + {product.category || "Category Not selected"} + + {product.brand || "Brand Not selected"} + + {product.allPdAndRd} + {product.allPDs}{product.allRDs}
+
No Product Available...
+
+
+ +
+
+
+ Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "} + {Math.min(currentPage * itemPerPage, totalData)} of{" "} + {totalData} entries +
+
+ +
+
+
    +
  • + setCurrentPage((prev) => prev - 1)} + disabled={loading} + > + Previous + +
  • + + {!(currentPage - 1 < 1) && ( +
  • + + setCurrentPage((prev) => prev - 1) + } + disabled={loading} + > + {currentPage - 1} + +
  • + )} + +
  • + + {currentPage} + +
  • + + {!( + (currentPage + 1) * itemPerPage - itemPerPage > + totalData - 1 + ) && ( +
  • + { + setCurrentPage((prev) => prev + 1); + }} + disabled={loading} + > + {currentPage + 1} + +
  • + )} + +
  • + totalData - 1 + ) + ? "paginate_button page-item next" + : "paginate_button page-item next disabled" + } + > + setCurrentPage((prev) => prev + 1)} + disabled={loading} + > + Next + +
  • +
+
+
+
+
+
+
+
+
+
+
+ ); +}; + +export default OpeningInventoryReports; diff --git a/src/views/RetailDistributors/RetailDistributor.js b/src/views/RetailDistributors/RetailDistributor.js index 89448df..cdd05a1 100644 --- a/src/views/RetailDistributors/RetailDistributor.js +++ b/src/views/RetailDistributors/RetailDistributor.js @@ -282,6 +282,18 @@ const RetailDistributor = () => { Stock + + + ))