Fix and restyle salesmetrics component
This commit is contained in:
@@ -640,95 +640,47 @@ router.get('/best-sellers', async (req, res) => {
|
||||
router.get('/sales/metrics', async (req, res) => {
|
||||
const { startDate, endDate } = req.query;
|
||||
try {
|
||||
const [dailyData] = await executeQuery(`
|
||||
SELECT JSON_ARRAYAGG(
|
||||
JSON_OBJECT(
|
||||
'date', sale_date,
|
||||
'orders', COALESCE(total_orders, 0),
|
||||
'units', COALESCE(total_units, 0),
|
||||
'revenue', COALESCE(total_revenue, 0),
|
||||
'cogs', COALESCE(total_cogs, 0),
|
||||
'profit', COALESCE(total_profit, 0)
|
||||
)
|
||||
) as daily_data
|
||||
FROM (
|
||||
SELECT
|
||||
DATE(o.date) as sale_date,
|
||||
COUNT(DISTINCT o.order_number) as total_orders,
|
||||
SUM(o.quantity) as total_units,
|
||||
SUM(o.price * o.quantity) as total_revenue,
|
||||
SUM(p.cost_price * o.quantity) as total_cogs,
|
||||
SUM((o.price - p.cost_price) * o.quantity) as total_profit
|
||||
FROM orders o
|
||||
JOIN products p ON o.product_id = p.product_id
|
||||
WHERE o.canceled = false
|
||||
AND o.date BETWEEN ? AND ?
|
||||
GROUP BY DATE(o.date)
|
||||
) d
|
||||
`, [startDate, endDate]);
|
||||
|
||||
const [categoryData] = await executeQuery(`
|
||||
SELECT JSON_ARRAYAGG(
|
||||
JSON_OBJECT(
|
||||
'category', category_name,
|
||||
'orders', COALESCE(category_orders, 0),
|
||||
'units', COALESCE(category_units, 0),
|
||||
'revenue', COALESCE(category_revenue, 0)
|
||||
)
|
||||
) as category_data
|
||||
FROM (
|
||||
SELECT
|
||||
c.name as category_name,
|
||||
COUNT(DISTINCT o.order_number) as category_orders,
|
||||
SUM(o.quantity) as category_units,
|
||||
SUM(o.price * o.quantity) as category_revenue
|
||||
FROM orders o
|
||||
JOIN products p ON o.product_id = p.product_id
|
||||
JOIN product_categories pc ON p.product_id = pc.product_id
|
||||
JOIN categories c ON pc.category_id = c.id
|
||||
WHERE o.canceled = false
|
||||
AND o.date BETWEEN ? AND ?
|
||||
GROUP BY c.id, c.name
|
||||
) c
|
||||
`, [startDate, endDate]);
|
||||
|
||||
const [metrics] = await executeQuery(`
|
||||
// Get daily sales data
|
||||
const [dailyRows] = await executeQuery(`
|
||||
SELECT
|
||||
COALESCE(COUNT(DISTINCT DATE(o.date)), 0) as days_with_sales,
|
||||
COALESCE(COUNT(DISTINCT o.order_number), 0) as total_orders,
|
||||
COALESCE(SUM(o.quantity), 0) as total_units,
|
||||
COALESCE(SUM(o.price * o.quantity), 0) as total_revenue,
|
||||
COALESCE(SUM(p.cost_price * o.quantity), 0) as total_cogs,
|
||||
COALESCE(SUM((o.price - p.cost_price) * o.quantity), 0) as total_profit,
|
||||
COALESCE(AVG(daily.orders), 0) as avg_daily_orders,
|
||||
COALESCE(AVG(daily.units), 0) as avg_daily_units,
|
||||
COALESCE(AVG(daily.revenue), 0) as avg_daily_revenue
|
||||
DATE(o.date) as sale_date,
|
||||
COUNT(DISTINCT o.order_number) as total_orders,
|
||||
SUM(o.quantity) as total_units,
|
||||
SUM(o.price * o.quantity) as total_revenue,
|
||||
SUM(p.cost_price * o.quantity) as total_cogs,
|
||||
SUM((o.price - p.cost_price) * o.quantity) as total_profit
|
||||
FROM orders o
|
||||
JOIN products p ON o.product_id = p.product_id
|
||||
WHERE o.canceled = false
|
||||
AND o.date BETWEEN ? AND ?
|
||||
GROUP BY DATE(o.date)
|
||||
ORDER BY sale_date
|
||||
`, [startDate, endDate]);
|
||||
|
||||
// Get summary metrics
|
||||
const [metrics] = await executeQuery(`
|
||||
SELECT
|
||||
COUNT(DISTINCT o.order_number) as total_orders,
|
||||
SUM(o.quantity) as total_units,
|
||||
SUM(o.price * o.quantity) as total_revenue,
|
||||
SUM(p.cost_price * o.quantity) as total_cogs,
|
||||
SUM((o.price - p.cost_price) * o.quantity) as total_profit
|
||||
FROM orders o
|
||||
JOIN products p ON o.product_id = p.product_id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
DATE(date) as sale_date,
|
||||
COUNT(DISTINCT order_number) as orders,
|
||||
SUM(quantity) as units,
|
||||
SUM(price * quantity) as revenue
|
||||
FROM orders
|
||||
WHERE canceled = false
|
||||
GROUP BY DATE(date)
|
||||
) daily ON DATE(o.date) = daily.sale_date
|
||||
WHERE o.canceled = false
|
||||
AND o.date BETWEEN ? AND ?
|
||||
`, [startDate, endDate]);
|
||||
|
||||
const response = {
|
||||
totalOrders: parseInt(metrics.total_orders) || 0,
|
||||
totalUnitsSold: parseInt(metrics.total_units) || 0,
|
||||
totalRevenue: parseFloat(metrics.total_revenue) || 0,
|
||||
totalCogs: parseFloat(metrics.total_cogs) || 0,
|
||||
dailySales: JSON.parse(dailyData.daily_data || '[]').map(day => ({
|
||||
date: day.date,
|
||||
units: parseInt(day.units) || 0,
|
||||
revenue: parseFloat(day.revenue) || 0,
|
||||
cogs: parseFloat(day.cogs) || 0
|
||||
totalOrders: parseInt(metrics[0]?.total_orders) || 0,
|
||||
totalUnitsSold: parseInt(metrics[0]?.total_units) || 0,
|
||||
totalCogs: parseFloat(metrics[0]?.total_cogs) || 0,
|
||||
totalRevenue: parseFloat(metrics[0]?.total_revenue) || 0,
|
||||
dailySales: dailyRows.map(day => ({
|
||||
date: day.sale_date,
|
||||
units: parseInt(day.total_units) || 0,
|
||||
revenue: parseFloat(day.total_revenue) || 0,
|
||||
cogs: parseFloat(day.total_cogs) || 0
|
||||
}))
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user