diff --git a/controllers/analytics.controller.js b/controllers/analytics.controller.js index f4e81d400b458292cc9a441be307fcfefb16398d..b8478d378d36e5dd72d2f9f00b77a414b1e603de 100644 --- a/controllers/analytics.controller.js +++ b/controllers/analytics.controller.js @@ -5,14 +5,14 @@ const { getCategoryBrandMetricsService, getCustomerMetricsService, getOrderMetricsService, - getAllAnalyticsMetricsService + getAllAnalyticsMetricsService, } = require("../services/analytics.service"); // Get all analytics metrics module.exports.getAllAnalyticsMetrics = async (req, res) => { try { const metrics = await getAllAnalyticsMetricsService(); - + res.status(200).json({ status: true, message: "Analytics metrics retrieved successfully", @@ -20,37 +20,49 @@ module.exports.getAllAnalyticsMetrics = async (req, res) => { stores: { total: metrics.stores.total, active: metrics.stores.active, - inactive: metrics.stores.inactive + inactive: metrics.stores.inactive, }, drivers: { total: metrics.drivers.total, onDuty: metrics.drivers.onDuty, - offDuty: metrics.drivers.offDuty + offDuty: metrics.drivers.offDuty, }, products: { total: metrics.products.total, active: metrics.products.active, - inactive: metrics.products.inactive + inactive: metrics.products.inactive, }, categories: metrics.categories, brands: metrics.brands, customers: { total: metrics.customers.total, active: metrics.customers.active, - newLast7Days: metrics.customers.newLast7Days + newLast7Days: metrics.customers.newLast7Days, }, orders: { today: metrics.orders.today, thisWeek: metrics.orders.thisWeek, - thisMonth: metrics.orders.thisMonth - } - } + thisMonth: metrics.orders.thisMonth, + }, + revenueData: { + revenueToday: metrics.revenueToday, + revenueThisWeek: metrics.revenueThisWeek, + revenueThisMonth: metrics.revenueThisMonth, + }, + deliveryTime: { + today: metrics.deliveryTimeToday, + thisWeek: metrics.deliveryTimeThisWeek, + thisMonth: metrics.deliveryTimeThisMonth, + }, + averageDeliveryTime: metrics.averageDeliveryTime, + _debug: metrics._debug, + }, }); } catch (error) { res.status(500).json({ status: false, message: "Error retrieving analytics metrics", - error: error.message + error: error.message, }); } }; @@ -59,21 +71,21 @@ module.exports.getAllAnalyticsMetrics = async (req, res) => { module.exports.getStoreMetrics = async (req, res) => { try { const metrics = await getStoreMetricsService(); - + res.status(200).json({ status: true, message: "Store metrics retrieved successfully", data: { total: metrics.total, active: metrics.active, - inactive: metrics.inactive - } + inactive: metrics.inactive, + }, }); } catch (error) { res.status(500).json({ status: false, message: "Error retrieving store metrics", - error: error.message + error: error.message, }); } }; @@ -82,21 +94,21 @@ module.exports.getStoreMetrics = async (req, res) => { module.exports.getDriverMetrics = async (req, res) => { try { const metrics = await getDriverMetricsService(); - + res.status(200).json({ status: true, message: "Driver metrics retrieved successfully", data: { total: metrics.total, onDuty: metrics.onDuty, - offDuty: metrics.offDuty - } + offDuty: metrics.offDuty, + }, }); } catch (error) { res.status(500).json({ status: false, message: "Error retrieving driver metrics", - error: error.message + error: error.message, }); } }; @@ -105,21 +117,21 @@ module.exports.getDriverMetrics = async (req, res) => { module.exports.getProductMetrics = async (req, res) => { try { const metrics = await getProductMetricsService(); - + res.status(200).json({ status: true, message: "Product metrics retrieved successfully", data: { total: metrics.total, active: metrics.active, - inactive: metrics.inactive - } + inactive: metrics.inactive, + }, }); } catch (error) { res.status(500).json({ status: false, message: "Error retrieving product metrics", - error: error.message + error: error.message, }); } }; @@ -128,20 +140,20 @@ module.exports.getProductMetrics = async (req, res) => { module.exports.getCategoryBrandMetrics = async (req, res) => { try { const metrics = await getCategoryBrandMetricsService(); - + res.status(200).json({ status: true, message: "Category and brand metrics retrieved successfully", data: { categories: metrics.categories, - brands: metrics.brands - } + brands: metrics.brands, + }, }); } catch (error) { res.status(500).json({ status: false, message: "Error retrieving category and brand metrics", - error: error.message + error: error.message, }); } }; @@ -150,21 +162,21 @@ module.exports.getCategoryBrandMetrics = async (req, res) => { module.exports.getCustomerMetrics = async (req, res) => { try { const metrics = await getCustomerMetricsService(); - + res.status(200).json({ status: true, message: "Customer metrics retrieved successfully", data: { total: metrics.total, active: metrics.active, - newLast7Days: metrics.newLast7Days - } + newLast7Days: metrics.newLast7Days, + }, }); } catch (error) { res.status(500).json({ status: false, message: "Error retrieving customer metrics", - error: error.message + error: error.message, }); } }; @@ -173,21 +185,21 @@ module.exports.getCustomerMetrics = async (req, res) => { module.exports.getOrderMetrics = async (req, res) => { try { const metrics = await getOrderMetricsService(); - + res.status(200).json({ status: true, message: "Order metrics retrieved successfully", data: { today: metrics.today, thisWeek: metrics.thisWeek, - thisMonth: metrics.thisMonth - } + thisMonth: metrics.thisMonth, + }, }); } catch (error) { res.status(500).json({ status: false, message: "Error retrieving order metrics", - error: error.message + error: error.message, }); } }; diff --git a/services/analytics.service.js b/services/analytics.service.js index 0842f7896e775541aa9da740761851ad5bb2109f..f63fffb9810992e198bd7f3467ab218929de1954 100644 --- a/services/analytics.service.js +++ b/services/analytics.service.js @@ -168,6 +168,141 @@ const getOrderMetricsService = async () => { } }; +// Get revenue metrics +const getRevenueMetricsService = async () => { + try { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + const weekAgo = new Date(); + weekAgo.setDate(weekAgo.getDate() - 7); + + const monthAgo = new Date(); + monthAgo.setMonth(monthAgo.getMonth() - 1); + + const revenueToday = await ORDER_MODEL.sum('total_amount', { + where: { + createdAt: { [Op.gte]: today }, + payment_status: 'paid' + } + }); + + const revenueThisWeek = await ORDER_MODEL.sum('total_amount', { + where: { + createdAt: { [Op.gte]: weekAgo }, + payment_status: 'paid' + } + }); + + const revenueThisMonth = await ORDER_MODEL.sum('total_amount', { + where: { + createdAt: { [Op.gte]: monthAgo }, + payment_status: 'paid' + } + }); + + return { + today: revenueToday || 0, + thisWeek: revenueThisWeek || 0, + thisMonth: revenueThisMonth || 0 + }; + } catch (error) { + throw new Error(`Error getting revenue metrics: ${error.message}`); + } +}; + +// Get delivery time metrics +const getDeliveryTimeMetricsService = async () => { + try { + const today = new Date(); + today.setHours(0, 0, 0, 0); + const tomorrow = new Date(today); + tomorrow.setDate(tomorrow.getDate() + 1); + + const weekAgo = new Date(); + weekAgo.setDate(weekAgo.getDate() - 7); + + const monthAgo = new Date(); + monthAgo.setMonth(monthAgo.getMonth() - 1); + + // Helper function to calculate average delivery time + const calculateAverageDeliveryTime = (orders) => { + if (orders.length === 0) { + return "0 hours 0 minutes"; + } + + let totalDeliveryTime = 0; + orders.forEach(order => { + const deliveryTime = new Date(order.delivered_at) - new Date(order.createdAt); + totalDeliveryTime += deliveryTime; + }); + + const averageDeliveryTimeMs = totalDeliveryTime / orders.length; + const averageDeliveryTimeMinutes = Math.round(averageDeliveryTimeMs / (1000 * 60)); + + const hours = Math.floor(averageDeliveryTimeMinutes / 60); + const minutes = averageDeliveryTimeMinutes % 60; + + return `${hours} hours ${minutes} minutes`; + }; + + // Get orders delivered today + const todayOrders = await ORDER_MODEL.findAll({ + where: { + order_status: 'delivered', + delivered_at: { + [Op.gte]: today, + [Op.lt]: tomorrow + } + }, + attributes: ['createdAt', 'delivered_at'] + }); + + // Get orders delivered this week + const weekOrders = await ORDER_MODEL.findAll({ + where: { + order_status: 'delivered', + delivered_at: { [Op.gte]: weekAgo } + }, + attributes: ['createdAt', 'delivered_at'] + }); + + // Get orders delivered this month + const monthOrders = await ORDER_MODEL.findAll({ + where: { + order_status: 'delivered', + delivered_at: { [Op.gte]: monthAgo } + }, + attributes: ['createdAt', 'delivered_at'] + }); + + // Get all delivered orders for overall average + const allDeliveredOrders = await ORDER_MODEL.findAll({ + where: { + order_status: 'delivered', + delivered_at: { [Op.ne]: null } + }, + attributes: ['createdAt', 'delivered_at'] + }); + + return { + today: calculateAverageDeliveryTime(todayOrders), + thisWeek: calculateAverageDeliveryTime(weekOrders), + thisMonth: calculateAverageDeliveryTime(monthOrders), + overall: calculateAverageDeliveryTime(allDeliveredOrders), + // Debug info (you can remove this later) + _debug: { + todayOrdersCount: todayOrders.length, + weekOrdersCount: weekOrders.length, + monthOrdersCount: monthOrders.length, + totalOrdersCount: allDeliveredOrders.length + } + }; + } catch (error) { + throw new Error(`Error getting delivery time metrics: ${error.message}`); + } +}; + // Get all analytics metrics const getAllAnalyticsMetricsService = async () => { try { @@ -178,6 +313,8 @@ const getAllAnalyticsMetricsService = async () => { categoryBrandMetrics, customerMetrics, orderMetrics, + revenueMetrics, + averageDeliveryTime ] = await Promise.all([ getStoreMetricsService(), getDriverMetricsService(), @@ -185,6 +322,8 @@ const getAllAnalyticsMetricsService = async () => { getCategoryBrandMetricsService(), getCustomerMetricsService(), getOrderMetricsService(), + getRevenueMetricsService(), + getDeliveryTimeMetricsService() ]); return { @@ -195,6 +334,14 @@ const getAllAnalyticsMetricsService = async () => { brands: categoryBrandMetrics.brands, customers: customerMetrics, orders: orderMetrics, + revenueToday: revenueMetrics.today, + revenueThisWeek: revenueMetrics.thisWeek, + revenueThisMonth: revenueMetrics.thisMonth, + deliveryTimeToday: averageDeliveryTime.today, + deliveryTimeThisWeek: averageDeliveryTime.thisWeek, + deliveryTimeThisMonth: averageDeliveryTime.thisMonth, + averageDeliveryTime: averageDeliveryTime.overall, + _debug: averageDeliveryTime._debug }; } catch (error) { throw new Error(`Error getting all analytics metrics: ${error.message}`);