diff --git a/controllers/analytics.controller.js b/controllers/analytics.controller.js index b8478d378d36e5dd72d2f9f00b77a414b1e603de..8cedfce259beb90b213ae24050c0bd52fd300c74 100644 --- a/controllers/analytics.controller.js +++ b/controllers/analytics.controller.js @@ -55,7 +55,7 @@ module.exports.getAllAnalyticsMetrics = async (req, res) => { thisMonth: metrics.deliveryTimeThisMonth, }, averageDeliveryTime: metrics.averageDeliveryTime, - _debug: metrics._debug, + // _debug: metrics._debug, }, }); } catch (error) { diff --git a/controllers/driver.controller.js b/controllers/driver.controller.js index 47419638f2d8360f74d9ddd7235dd8f40c830db8..01ec26cd2056e22197ada946620684a8a485f07c 100644 --- a/controllers/driver.controller.js +++ b/controllers/driver.controller.js @@ -18,6 +18,7 @@ const { getDriverByEmailService, getDriverByPhoneService, getDriverByLicenseService, + getDriverMonthlyEarningsService, getDriverByLicensePlateService, countDriversService, getSingleDriverService, @@ -6640,3 +6641,34 @@ const processWalletCreditForPartialFulfillment = async ( }; } }; + +// Get driver monthly earnings +module.exports.getDriverMonthlyEarnings = async (req, res) => { + try { + const { driverId } = req.params; + + if (!driverId) { + return res.status(400).json({ + status: false, + message: "Driver ID is required" + }); + } + + const monthlyEarnings = await getDriverMonthlyEarningsService(driverId); + + res.status(200).json({ + status: true, + message: "Driver monthly earnings retrieved successfully", + data: { + driverId: parseInt(driverId), + monthlyEarnings + } + }); + } catch (error) { + res.status(500).json({ + status: false, + message: "Error retrieving driver monthly earnings", + error: error.message + }); + } +}; diff --git a/routes/driver.routes.js b/routes/driver.routes.js index a11fe74c1c0c59d2a71e10cfaa51f1331455b3eb..07babb4eb78d1daafd709e9524ce22fd5148d123 100644 --- a/routes/driver.routes.js +++ b/routes/driver.routes.js @@ -57,7 +57,7 @@ router.get( router.get( "/overview", authentication, - authorization("super-admin", "store-admin"), + // authorization("super-admin", "store-admin"), driverController.getDriverOverview ); @@ -65,7 +65,7 @@ router.get( router.get( "/overview/:driverId", authentication, - authorization("super-admin", "store-admin"), + // authorization("super-admin", "store-admin"), driverController.getSingleDriverOverview ); @@ -145,7 +145,7 @@ router.post( router.post( "/:id/strike", authentication, - authorization("super-admin", "store-admin"), + requirePermission("strikes.create"), driverController.addStrikeToDriver ); @@ -190,7 +190,7 @@ router.post( router.get( "/one-driver/:id", authentication, - authorization("super-admin", "store-admin"), + requirePermission("driver.read"), driverController.getDriverById ); @@ -398,8 +398,7 @@ router.get( driverController.driverAcceptedOrderPickup ); - -// Get driver's accepted orders +// Get driver's accepted orders router.get( "/accepted-orders/:driverId", authentication, @@ -466,12 +465,22 @@ router.patch( driverController.returnOrder ); +/*------------Driver earnings APIs----------*/ + // Get driver list with earnings information (GET /api/drivers/earnings-list) router.get( "/earnings-list", authentication, - authorization("super-admin", "store-admin"), + // authorization("super-admin", "store-admin"), driverController.getDriverEarningsList ); +// Get driver monthly earnings +router.get( + "/monthly-earnings/:driverId", + authentication, + // authorization("super-admin", "store-admin"), + driverController.getDriverMonthlyEarnings +); + module.exports = router; diff --git a/services/driver.service.js b/services/driver.service.js index 558de3fefd61de4a42d6a9aa53fc4872e2d5c886..cd3af967f68a9d90289aac9b2ff276cff7a92778 100644 --- a/services/driver.service.js +++ b/services/driver.service.js @@ -575,4 +575,62 @@ module.exports.getDriverOverviewService = async () => { } }; +// Get driver monthly earnings for 12 months +module.exports.getDriverMonthlyEarningsService = async (driverId) => { + try { + const monthlyEarnings = []; + const currentDate = new Date(); + + // Generate data for current year (January to December) + const currentYear = currentDate.getFullYear(); + + for (let i = 0; i < 12; i++) { + const targetDate = new Date(currentYear, i, 1); // i = 0 (January) to 11 (December) + const startOfMonth = new Date(targetDate.getFullYear(), targetDate.getMonth(), 1); + const endOfMonth = new Date(targetDate.getFullYear(), targetDate.getMonth() + 1, 0, 23, 59, 59); + + const monthNames = [ + 'January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December' + ]; + + // Get earnings for this specific driver and month + const earningsResult = await TRANSACTION_MODEL.findOne({ + attributes: [ + [TRANSACTION_MODEL.sequelize.fn('SUM', TRANSACTION_MODEL.sequelize.col('driver_profit')), 'totalEarnings'], + [TRANSACTION_MODEL.sequelize.fn('COUNT', TRANSACTION_MODEL.sequelize.col('driver_profit')), 'totalTrips'] + ], + where: { + type: 'sell', + shipping_status: 'delivered', + payment_status: 'paid', + driver_profit: { [Op.ne]: null }, + driver_id: driverId, + createdAt: { + [Op.gte]: startOfMonth, + [Op.lte]: endOfMonth + } + }, + raw: true + }); + + const totalEarnings = parseFloat(earningsResult?.totalEarnings || 0); + const totalTrips = parseInt(earningsResult?.totalTrips || 0); + const avgPerTrip = totalTrips > 0 ? totalEarnings / totalTrips : 0; + + monthlyEarnings.push({ + month: monthNames[targetDate.getMonth()], + year: targetDate.getFullYear(), + earning: parseFloat(totalEarnings.toFixed(2)), + trips: totalTrips, + avgPerTrip: parseFloat(avgPerTrip.toFixed(2)) + }); + } + + return monthlyEarnings; + } catch (error) { + throw new Error(`Error getting driver monthly earnings: ${error.message}`); + } +}; +