diff --git a/client/package-lock.json b/client/package-lock.json
index f94acbd..e55da04 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -11875,6 +11875,11 @@
"lodash": "^4.17.19"
}
},
+ "react-csv": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.0.3.tgz",
+ "integrity": "sha512-exyAdFLAxtuM4wNwLYrlKyPYLiJ7e0mv9tqPAd3kq+k1CiJFtznevR3yP0icv5q/y200w+lzNgi7TQn1Wrhu0w=="
+ },
"react-dev-utils": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
diff --git a/client/package.json b/client/package.json
index e2445b6..106834c 100644
--- a/client/package.json
+++ b/client/package.json
@@ -18,6 +18,7 @@
"react": "^17.0.2",
"react-bootstrap": "^1.6.1",
"react-chartjs-2": "^3.0.5",
+ "react-csv": "^2.0.3",
"react-dom": "^17.0.2",
"react-file-base64": "^1.0.3",
"react-google-login": "^5.2.2",
diff --git a/client/src/components/Ecommerce/CSVReportGeneration.js b/client/src/components/Ecommerce/CSVReportGeneration.js
new file mode 100644
index 0000000..05f2ae9
--- /dev/null
+++ b/client/src/components/Ecommerce/CSVReportGeneration.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import { CSVLink } from 'react-csv';
+
+function CSVReportGeneration({ data }) {
+
+ const csv_data = data
+ const headers = [
+ { label: "Date", key: "date" },
+ { label: "Product ID", key: "product_id" },
+ { label: "Product Name", key: "product_name" },
+ { label: "Price/Per unit", key: "product_price" },
+ { label: "Quantity", key: "product_qty" },
+ { label: "Total", key: "total" },
+ ]
+
+ const csvReport = {
+ filename: 'SalesReport.csv',
+ headers,
+ data:csv_data
+ }
+
+
+ return (
+
+ Export to CSV
+
+ )
+}
+
+export default CSVReportGeneration
diff --git a/client/src/components/Ecommerce/Charts/SalesPieChart.js b/client/src/components/Ecommerce/Charts/SalesPieChart.js
new file mode 100644
index 0000000..48ba83f
--- /dev/null
+++ b/client/src/components/Ecommerce/Charts/SalesPieChart.js
@@ -0,0 +1,88 @@
+import React from 'react';
+import { Pie } from 'react-chartjs-2';
+
+function SalesPieChart({ pie_data }) {
+
+
+ const dataLabel = []
+ const dataValues = []
+
+ for (let pd of pie_data) {
+ const val = parseInt(pd.value)
+ dataLabel.push(pd.name)
+ dataValues.push(val)
+ }
+
+ const bgColPalette = [
+ 'rgba(255, 99, 132, 0.2)', //Red
+ 'rgba(54, 162, 235, 0.2)', //Blue
+ 'rgba(255, 206, 86, 0.2)', // Yellow
+ 'rgba(75, 192, 192, 0.2)', // Green
+ 'rgba(153, 102, 255, 0.2)', // Purple
+ 'rgba(255, 159, 64, 0.2)', // Orange
+ 'rgba(255, 99, 132, 0.8)', //Red
+ 'rgba(54, 162, 235, 0.8)', //Blue
+ 'rgba(255, 206, 86, 0.8)', // Yellow
+ 'rgba(75, 192, 192, 0.8)', // Green
+ 'rgba(153, 102, 255, 0.8)', // Purple
+ 'rgba(255, 159, 64, 0.8)', // Orange
+ 'rgba(255, 99, 132,1)', //Red
+ 'rgba(54, 162, 235, 1)', //Blue
+ 'rgba(255, 206, 86, 1)', // Yellow
+ 'rgba(75, 192, 192, 1)', // Green
+ 'rgba(153, 102, 255, 1)', // Purple
+ 'rgba(255, 159, 64, 1)', // Orange
+ ]
+ const borderColPalette = [
+ 'rgba(255, 99, 132, 1)',
+ 'rgba(54, 162, 235, 1)',
+ 'rgba(255, 206, 86, 1)',
+ 'rgba(75, 192, 192, 1)',
+ 'rgba(153, 102, 255, 1)',
+ 'rgba(255, 159, 64, 1)',
+ 'rgba(255, 99, 132, 1)',
+ 'rgba(54, 162, 235, 1)',
+ 'rgba(255, 206, 86, 1)',
+ 'rgba(75, 192, 192, 1)',
+ 'rgba(153, 102, 255, 1)',
+ 'rgba(255, 159, 64, 1)',
+ 'rgba(255, 99, 132, 1)',
+ 'rgba(54, 162, 235, 1)',
+ 'rgba(255, 206, 86, 1)',
+ 'rgba(75, 192, 192, 1)',
+ 'rgba(153, 102, 255, 1)',
+ 'rgba(255, 159, 64, 1)',
+ ]
+
+
+ const background = []
+ const border = []
+
+ for (let i = 0; i < pie_data.length; i++){
+ background[i] = bgColPalette[i]
+ border[i] = borderColPalette[i]
+ }
+
+ const data = {
+ labels: dataLabel,
+ datasets: [
+ {
+ label: 'Contribution of each product',
+ data: dataValues,
+ backgroundColor:background ,
+ borderColor:border,
+ borderWidth: 1,
+ },
+ ],
+
+ };
+
+ return (
+
+
+ )
+}
+
+export default SalesPieChart
diff --git a/client/src/components/Ecommerce/SaleDataCategory.js b/client/src/components/Ecommerce/SaleDataCategory.js
index ab11a6a..059e1e0 100644
--- a/client/src/components/Ecommerce/SaleDataCategory.js
+++ b/client/src/components/Ecommerce/SaleDataCategory.js
@@ -17,7 +17,7 @@ const SaleDataCategory = ({onSelect,data}) => {
return (
- {selectedItem ? items.find(item => item.id === selectedItem).label : "Select Blog Category"}
+ {selectedItem ? items.find(item => item.id === selectedItem).label : "Select Month"}
diff --git a/client/src/components/Ecommerce/Screen/ProductListScreen.js b/client/src/components/Ecommerce/Screen/ProductListScreen.js
index 4b343ff..b7602df 100644
--- a/client/src/components/Ecommerce/Screen/ProductListScreen.js
+++ b/client/src/components/Ecommerce/Screen/ProductListScreen.js
@@ -79,15 +79,17 @@ function ProductListScreen({history}) {
- Name |
- Price |
- Category |
- In Stock |
+ Product ID |
+ Name |
+ Price |
+ Category |
+ In Stock |
{products.map(product=>(
+ {product._id} |
{product.name} |
৳ {product.price} |
{product.category} |
diff --git a/client/src/components/Ecommerce/Screen/SaleDataScreen.js b/client/src/components/Ecommerce/Screen/SaleDataScreen.js
index 70e2fdd..7bc0f95 100644
--- a/client/src/components/Ecommerce/Screen/SaleDataScreen.js
+++ b/client/src/components/Ecommerce/Screen/SaleDataScreen.js
@@ -8,6 +8,8 @@ import BarChart from '../Charts/BarChart';
import LineChart from '../Charts/LineChart';
import MonthBarChart from '../Charts/MonthBarChart';
import ProductSaleBarChart from '../Charts/ProductSaleBarChart';
+import SalesPieChart from '../Charts/SalesPieChart';
+import CSVReportGeneration from '../CSVReportGeneration';
import { monthData } from "../EcommSeedData";
import SaleDataCategory from '../SaleDataCategory';
import Sidebar from '../Sidebar';
@@ -18,14 +20,14 @@ function SaleDataScreen({ history }) {
const [monthSale, setMonthSale] = useState("")
const [productSale, setProductSale] = useState("")
const [search, setSearch] = useState("")
+ const [reportData, setReportData] = useState("")
+ const [salesPieData, setSalesPieData] = useState("")
const dispatch = useDispatch()
const { userInfo: { user,token } } = useSelector(state => state.userLogin)
const order = useSelector(state => state.orderSaleData)
- const { loading, error, orderSaleData } = order
-
- // if (orderSaleData) console.log(orderSaleData)
+ const { orderSaleData } = order
useEffect(() => {
@@ -38,7 +40,38 @@ function SaleDataScreen({ history }) {
const handleSelect = (e) => {
setGraphType(e)
-
+ }
+
+ const onSalesMonthSelect = (e) => {
+ const { totalOrder } = orderSaleData?.find(el => el.month === e)
+ const saleData = []
+ const salesPieData = []
+
+ for (let data of totalOrder) {
+ for (let pd of data.orderedItems) {
+ const date = data.createdAt.substring(0, 10);
+ const product_id = pd._id;
+ const product_name = pd.name;
+ const product_price = pd.price;
+ const product_qty = pd.qty;
+ const total = pd.price * pd.qty
+ saleData.push({ date, product_id, product_name, product_price, product_qty, total })
+
+ // for pie chart
+ salesPieData.push({ name: product_name, value: total })
+
+ }
+ }
+
+ // console.log(salesPieData);
+
+ // for pie chart
+ const res = Array.from(salesPieData.reduce(
+ (m, { name, value }) => m.set(name, (m.get(name) || 0) + value), new
+ Map()), ([name, value]) => ({ name, value }));
+
+ setSalesPieData(res)
+ setReportData(saleData)
}
const onMonthSelect = async (e) => {
@@ -52,7 +85,6 @@ function SaleDataScreen({ history }) {
}
}
const { data } = await axios.post(`/api/orders/saleDataByMonth`, { selectedMonth }, config)
-
setMonthSale(data)
} catch (error) {
@@ -72,7 +104,6 @@ function SaleDataScreen({ history }) {
}
}
const { data } = await axios.post(`/api/orders/saleByAProduct`, {product_id:search }, config)
- console.log(data);
setProductSale(data)
} catch (error) {
@@ -121,7 +152,20 @@ function SaleDataScreen({ history }) {
- {productSale && }
+ {productSale && }
+
+
+
Sales Report Generation
+
+ {reportData &&
}
+ {salesPieData &&
+
+
Contribution of sold products
+
+
+ }
+
+
>
diff --git a/client/src/styles/ecommerce.css b/client/src/styles/ecommerce.css
index d4a090b..ede16d6 100644
--- a/client/src/styles/ecommerce.css
+++ b/client/src/styles/ecommerce.css
@@ -243,3 +243,8 @@ main {
min-width: 33% !important;
margin-top: 1.5rem;
}
+.pie-heading {
+ text-align: center;
+ font-family: "Poppins";
+ margin: 0.5rem 0 2rem 0;
+}
diff --git a/server/controller/orderController.js b/server/controller/orderController.js
index 49674aa..89981df 100644
--- a/server/controller/orderController.js
+++ b/server/controller/orderController.js
@@ -110,17 +110,19 @@ const getSaleDataByYear = async (req, res) => {
saleDataByMonths.push({ month, totalOrder: saleByMonth, numOfOrder: saleByMonth.length })
}
+
// New
- const dd = new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 120).toISOString()
+ const numOfDays = 120
+ const dd = new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * numOfDays).toISOString()
- // console.log(dd.substring(0,10))
+ console.log(dd.substring(0,10))
const test = [
// Get only records created in the last 30 days
{
$match: {
"createdAt": {
- // $gte: new Date(`${dd}`)
- $gte: new Date(`${year}-07-01`), $lt: new Date(`${year}-07-31`)
+ $gte: new Date(`${dd.substring(0,10)}`)
+ // $gte: new Date(`${year}-07-01`), $lt: new Date(`${year}-07-31`)
}
}
},
@@ -141,12 +143,14 @@ const getSaleDataByYear = async (req, res) => {
]
- const dayCount = await Order.aggregate(test)
- const dayWiseSale = new Array(30).fill(0)
-
- for (let i of dayCount) {
- dayWiseSale[i.day]=dayWiseSale[i.day]+1
- }
+ // const dayCount = await Order.aggregate(test)
+ // console.log(dayCount)
+ // console.log(dayCount.length)
+
+ // const dayWiseSale = new Array(30).fill(0)
+ // for (let i of dayCount) {
+ // dayWiseSale[i.day]=dayWiseSale[i.day]+1
+ // }
return res.status(200).json(saleDataByMonths)