REDROOM
PHP 8.2.30
Path:
Logout
Edit File
Size: 15.13 KB
Close
//home/byroehnu/easepay.easetack.com/controllers/dashboardController.js
Text
Base64
const { prisma } = require('../config/prisma'); const getDashboardOverview = async (req, res) => { try { const { timeframe = 'month' } = req.query; let startDate, endDate, compareStartDate, compareEndDate; const now = new Date(); // Set date ranges based on timeframe switch (timeframe) { case 'week': const weekStart = new Date(now.setDate(now.getDate() - now.getDay())); const weekEnd = new Date(weekStart); weekEnd.setDate(weekStart.getDate() + 6); startDate = new Date(weekStart.setHours(0, 0, 0, 0)); endDate = new Date(weekEnd.setHours(23, 59, 59, 999)); compareStartDate = new Date(startDate); compareStartDate.setDate(compareStartDate.getDate() - 7); compareEndDate = new Date(endDate); compareEndDate.setDate(compareEndDate.getDate() - 7); break; case 'month': startDate = new Date(now.getFullYear(), now.getMonth(), 1); endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999); compareStartDate = new Date(now.getFullYear(), now.getMonth() - 1, 1); compareEndDate = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999); break; case 'year': startDate = new Date(now.getFullYear(), 0, 1); endDate = new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999); compareStartDate = new Date(now.getFullYear() - 1, 0, 1); compareEndDate = new Date(now.getFullYear() - 1, 11, 31, 23, 59, 59, 999); break; default: startDate = new Date(now.getFullYear(), now.getMonth(), 1); endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999); compareStartDate = new Date(now.getFullYear(), now.getMonth() - 1, 1); compareEndDate = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999); } // Current period sales const currentSales = await prisma.sale.aggregate({ where: { userId: req.user.id, date: { gte: startDate, lte: endDate } }, _sum: { amount: true }, _count: { id: true } }); // Previous period sales for comparison const previousSales = await prisma.sale.aggregate({ where: { userId: req.user.id, date: { gte: compareStartDate, lte: compareEndDate } }, _sum: { amount: true }, _count: { id: true } }); // Current period expenses const currentExpenses = await prisma.expense.aggregate({ where: { userId: req.user.id, date: { gte: startDate, lte: endDate } }, _sum: { amount: true }, _count: { id: true } }); // Previous period expenses for comparison const previousExpenses = await prisma.expense.aggregate({ where: { userId: req.user.id, date: { gte: compareStartDate, lte: compareEndDate } }, _sum: { amount: true }, _count: { id: true } }); // Recent transactions (last 10) const recentTransactions = await prisma.$transaction([ prisma.sale.findMany({ where: { userId: req.user.id }, orderBy: { date: 'desc' }, take: 5, select: { id: true, amount: true, customerName: true, date: true, description: true } }), prisma.expense.findMany({ where: { userId: req.user.id }, orderBy: { date: 'desc' }, take: 5, select: { id: true, amount: true, vendor: true, date: true, description: true } }) ]); // Combine and sort transactions const allTransactions = [ ...recentTransactions[0].map(sale => ({ id: sale.id, type: 'sale', amount: sale.amount, description: sale.description || `Sale to ${sale.customerName}`, date: sale.date })), ...recentTransactions[1].map(expense => ({ id: expense.id, type: 'expense', amount: -expense.amount, description: expense.description || `Expense to ${expense.vendor}`, date: expense.date })) ].sort((a, b) => new Date(b.date) - new Date(a.date)).slice(0, 10); // Calculate metrics const currentRevenue = Number(currentSales._sum.amount) || 0; const previousRevenue = Number(previousSales._sum.amount) || 0; const currentExpenseTotal = Number(currentExpenses._sum.amount) || 0; const previousExpenseTotal = Number(previousExpenses._sum.amount) || 0; const revenueChange = previousRevenue > 0 ? ((currentRevenue - previousRevenue) / previousRevenue) * 100 : currentRevenue > 0 ? 100 : 0; const expenseChange = previousExpenseTotal > 0 ? ((currentExpenseTotal - previousExpenseTotal) / previousExpenseTotal) * 100 : currentExpenseTotal > 0 ? 100 : 0; const currentProfit = currentRevenue - currentExpenseTotal; const previousProfit = previousRevenue - previousExpenseTotal; const profitChange = previousProfit !== 0 ? ((currentProfit - previousProfit) / Math.abs(previousProfit)) * 100 : currentProfit > 0 ? 100 : currentProfit < 0 ? -100 : 0; const overview = { revenue: { current: currentRevenue, previous: previousRevenue, change: revenueChange, count: currentSales._count.id || 0 }, expenses: { current: currentExpenseTotal, previous: previousExpenseTotal, change: expenseChange, count: currentExpenses._count.id || 0 }, profit: { current: currentProfit, previous: previousProfit, change: profitChange }, recentTransactions: allTransactions, timeframe }; res.status(200).json({ success: true, data: overview }); } catch (error) { console.error('Get dashboard overview error:', error); res.status(500).json({ success: false, message: 'Failed to get dashboard overview' }); } }; const getSalesAnalytics = async (req, res) => { try { const { period = 'month' } = req.query; let groupBy, dateFormat; let dateRange = {}; const now = new Date(); switch (period) { case 'week': // Last 7 days dateRange = { gte: new Date(now.setDate(now.getDate() - 7)), lte: new Date() }; groupBy = 'date'; break; case 'month': // Last 30 days dateRange = { gte: new Date(now.setDate(now.getDate() - 30)), lte: new Date() }; groupBy = 'date'; break; case 'year': // Last 12 months dateRange = { gte: new Date(now.setMonth(now.getMonth() - 12)), lte: new Date() }; groupBy = 'date'; break; default: dateRange = { gte: new Date(now.setDate(now.getDate() - 30)), lte: new Date() }; groupBy = 'date'; } // Get sales data grouped by date const salesData = await prisma.sale.findMany({ where: { userId: req.user.id, date: dateRange }, select: { amount: true, date: true, category: true }, orderBy: { date: 'asc' } }); // Process data for charts const dailyData = {}; const categoryData = {}; salesData.forEach(sale => { const dateKey = sale.date.toISOString().split('T')[0]; const amount = Number(sale.amount); // Daily aggregation if (!dailyData[dateKey]) { dailyData[dateKey] = { date: dateKey, revenue: 0, count: 0 }; } dailyData[dateKey].revenue += amount; dailyData[dateKey].count += 1; // Category aggregation const category = sale.category || 'Uncategorized'; if (!categoryData[category]) { categoryData[category] = { category, revenue: 0, count: 0 }; } categoryData[category].revenue += amount; categoryData[category].count += 1; }); const analytics = { daily: Object.values(dailyData), categories: Object.values(categoryData), summary: { totalRevenue: salesData.reduce((sum, sale) => sum + Number(sale.amount), 0), totalSales: salesData.length, averageOrderValue: salesData.length > 0 ? salesData.reduce((sum, sale) => sum + Number(sale.amount), 0) / salesData.length : 0 } }; res.status(200).json({ success: true, data: analytics }); } catch (error) { console.error('Get sales analytics error:', error); res.status(500).json({ success: false, message: 'Failed to get sales analytics' }); } }; const getExpenseAnalytics = async (req, res) => { try { const { period = 'month' } = req.query; let dateRange = {}; const now = new Date(); switch (period) { case 'week': dateRange = { gte: new Date(now.setDate(now.getDate() - 7)), lte: new Date() }; break; case 'month': dateRange = { gte: new Date(now.setDate(now.getDate() - 30)), lte: new Date() }; break; case 'year': dateRange = { gte: new Date(now.setMonth(now.getMonth() - 12)), lte: new Date() }; break; default: dateRange = { gte: new Date(now.setDate(now.getDate() - 30)), lte: new Date() }; } // Get expenses data const expensesData = await prisma.expense.findMany({ where: { userId: req.user.id, date: dateRange }, select: { amount: true, date: true, category: true }, orderBy: { date: 'asc' } }); // Process data for charts const dailyData = {}; const categoryData = {}; expensesData.forEach(expense => { const dateKey = expense.date.toISOString().split('T')[0]; const amount = Number(expense.amount); // Daily aggregation if (!dailyData[dateKey]) { dailyData[dateKey] = { date: dateKey, expenses: 0, count: 0 }; } dailyData[dateKey].expenses += amount; dailyData[dateKey].count += 1; // Category aggregation const category = expense.category || 'Uncategorized'; if (!categoryData[category]) { categoryData[category] = { category, expenses: 0, count: 0 }; } categoryData[category].expenses += amount; categoryData[category].count += 1; }); const analytics = { daily: Object.values(dailyData), categories: Object.values(categoryData), summary: { totalExpenses: expensesData.reduce((sum, expense) => sum + Number(expense.amount), 0), totalCount: expensesData.length, averageExpense: expensesData.length > 0 ? expensesData.reduce((sum, expense) => sum + Number(expense.amount), 0) / expensesData.length : 0 } }; res.status(200).json({ success: true, data: analytics }); } catch (error) { console.error('Get expense analytics error:', error); res.status(500).json({ success: false, message: 'Failed to get expense analytics' }); } }; const getHomeDashboard = async (req, res) => { try { const userId = req.user.id; const businessId = req.user.businessId; // If applicable const now = new Date(); const startOfDay = new Date(now.setHours(0, 0, 0, 0)); const endOfDay = new Date(now.setHours(23, 59, 59, 999)); // 1. Today's Profit (Today's Sales - Today's Expenses) const todaysSales = await prisma.sale.aggregate({ where: { userId, date: { gte: startOfDay, lte: endOfDay } }, _sum: { amount: true } }); const todaysExpenses = await prisma.expense.aggregate({ where: { userId, date: { gte: startOfDay, lte: endOfDay } }, _sum: { amount: true } }); const todaysProfit = (Number(todaysSales._sum.amount) || 0) - (Number(todaysExpenses._sum.amount) || 0); // 2. Cash in Hand (All time CASH sales - All time CASH expenses) const cashSales = await prisma.sale.aggregate({ where: { userId, paymentMethod: 'CASH' }, _sum: { amount: true } }); const cashExpenses = await prisma.expense.aggregate({ where: { userId, paymentMethod: 'CASH' }, _sum: { amount: true } }); const cashInHand = (Number(cashSales._sum.amount) || 0) - (Number(cashExpenses._sum.amount) || 0); // 3. Money in Bank (All time TRANSFER/POS sales - All time TRANSFER/POS expenses) const bankSales = await prisma.sale.aggregate({ where: { userId, paymentMethod: { in: ['TRANSFER', 'POS'] } }, _sum: { amount: true } }); const bankExpenses = await prisma.expense.aggregate({ where: { userId, paymentMethod: { in: ['TRANSFER', 'POS'] } }, _sum: { amount: true } }); const moneyInBank = (Number(bankSales._sum.amount) || 0) - (Number(bankExpenses._sum.amount) || 0); // 4. Recent Activities (Last 10 combined) const recentSales = await prisma.sale.findMany({ where: { userId }, orderBy: { date: 'desc' }, take: 5, select: { id: true, amount: true, description: true, date: true, paymentMethod: true } }); const recentExpenses = await prisma.expense.findMany({ where: { userId }, orderBy: { date: 'desc' }, take: 5, select: { id: true, amount: true, description: true, date: true, paymentMethod: true } }); const recentInvoices = await prisma.invoice.findMany({ where: { userId }, orderBy: { createdAt: 'desc' }, take: 5, select: { id: true, invoiceNumber: true, total: true, status: true, createdAt: true, customerName: true } }); // Format and sort activities let activities = [ ...recentSales.map(s => ({ type: 'SALE', ...s, date: s.date })), ...recentExpenses.map(e => ({ type: 'EXPENSE', ...e, date: e.date })), ...recentInvoices.map(i => ({ type: 'INVOICE', ...i, date: i.createdAt })) ]; activities.sort((a, b) => new Date(b.date) - new Date(a.date)); activities = activities.slice(0, 10); // Keep only top 10 res.status(200).json({ success: true, data: { todaysProfit, cashInHand, moneyInBank, recentActivities: activities } }); } catch (error) { console.error('Get home dashboard error:', error); res.status(500).json({ success: false, message: 'Failed to get home dashboard data' }); } }; module.exports = { getDashboardOverview, getSalesAnalytics, getExpenseAnalytics, getHomeDashboard };
Save
Close
Exit & Reset
Text mode: syntax highlighting auto-detects file type.
Directory Contents
Dirs: 1 × Files: 17
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
controllers
DIR
-
drwxr-xr-x
2026-03-20 23:25:48
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
.htaccess
127 B
lr--r--r--
2026-03-14 01:49:22
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
advancedAuthController.js
15.34 KB
lrw-r--r--
2026-02-19 22:06:47
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
authController.js
30.77 KB
lrw-r--r--
2026-03-04 06:33:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
authController_copy.js
62.98 KB
lrw-r--r--
2026-03-01 23:46:52
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
businessController.js
10.79 KB
lrw-r--r--
2026-02-07 16:28:16
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
businessProfileController.js
14.17 KB
lrw-r--r--
2026-02-27 04:02:38
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
creditScoreController.js
6.32 KB
lrw-r--r--
2026-02-06 17:10:19
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
dashboardController.js
15.13 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
expenseController.js
8.50 KB
lrw-r--r--
2026-03-01 05:05:52
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
inventoryController.js
12.15 KB
lrw-r--r--
2026-02-27 04:02:38
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
invoiceController.js
25.39 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
reportController.js
17.61 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
saleController.js
6.45 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
settingsController.js
2.33 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
subscriptionController.js
12.78 KB
lrw-r--r--
2026-02-21 08:13:30
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
taxController.js
9.96 KB
lrw-r--r--
2026-03-01 05:05:51
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
webhookController.js
8.51 KB
lrw-r--r--
2026-02-20 19:31:28
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).