Skip to content

Commit

Permalink
🐛 Fix: Order Syncing (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
lksnjw authored Oct 12, 2024
1 parent f856308 commit 58f8cf1
Show file tree
Hide file tree
Showing 22 changed files with 343 additions and 172 deletions.
5 changes: 1 addition & 4 deletions backend/controllers/Admin/AcustomerController.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ export const getAllUsers = async (req, res) => {
}
}



// Fetch single user by ID
export const getUserById = async (req, res) => {
try {
Expand All @@ -26,7 +24,6 @@ export const getUserById = async (req, res) => {
}
}


// Update user by ID
export const updateUserById = async (req, res) => {
const {
Expand Down Expand Up @@ -107,4 +104,4 @@ export const getUserCount = async (req, res) => {
} catch (error) {
res.status(500).json({ error: 'Error fetching user count' })
}
}
}
3 changes: 1 addition & 2 deletions backend/controllers/Admin/Afarmer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import Farmer from '../../models/farmerModel'
import mongoose from 'mongoose'
export const getFarmersCount = async (req, res) => {
Expand All @@ -17,4 +16,4 @@ export const getAllFarmers = async (req, res) => {
} catch (error) {
res.status(500).json({ message: error.message })
}
}
}
87 changes: 78 additions & 9 deletions backend/controllers/DLDeliveryController.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,26 +95,42 @@ export const sendEmailToDriver = async (driver, delivery) => {

// Set up the email options
const mailOptions = {
from: process.env.EMAIL_USER,
from: `'FarmCart 🌱' <${process.env.EMAIL_USER}`,
to: driver.email,
subject: `Order Assignment: Order ${delivery.oID} Assigned to You`,
html: `
<h2>Hi ${driver.fullName},</h2>
<p>We are excited to inform you that you have been assigned to deliver the following order:</p>
<h3>Order Details</h3>
<ul>
<div style="font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px; text-align: center;">
<div style="max-width: 600px; margin: 0 auto; background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0px 4px 10px rgba(0,0,0,0.1); border: 2px solid #38A169;">
<h2 style="font-size: 24px; font-weight: bold; margin-bottom: 20px; color: #2D3748;">Hi ${driver.fullName},</h2>
<p style="font-size: 16px; line-height: 1.6; color: #4A5568;">
We are excited to inform you that you have been assigned to deliver the following order:
</p>
<h3 style="font-size: 20px; font-weight: bold; color: #2D3748; margin-top: 20px; text-align: left;">Order Details:</h3>
<ul style="text-align: left; font-size: 16px; line-height: 1.8; color: #4A5568; list-style: none; padding: 0;">
<li><strong>Order ID:</strong> ${delivery.oID}</li>
<li><strong>Tracking ID:</strong> ${delivery.trackingID}</li>
<li><strong>Shop Name:</strong> ${delivery.shopName}</li>
<li><strong>Pickup Address:</strong> ${delivery.pickupAddress}</li>
<li><strong>Customer Name:</strong> ${delivery.customerName}</li>
<li><strong>Drop-Off Address:</strong> ${delivery.dropOffAddress}</li>
</ul>
<p>For more details, please log in to the delivery portal or contact support if needed.</p>
<p style="font-size: 16px; line-height: 1.6; color: #4A5568; margin-top: 20px;">
For more details, please log in to the delivery portal or contact support if needed.
</p>
<br/>
<p>Thank you for being part of our delivery team!</p>
<p>Best Regards,</p>
<p><strong>Your Company Name</strong></p>
<p style="font-size: 16px; line-height: 1.6; color: #4A5568;">
Thank you for being part of our delivery team!
</p>
<p style="font-size: 16px; line-height: 1.6; color: #2D3748; font-weight: bold; margin-top: 20px;">Best Regards,</p>
<p style="font-size: 16px; color: #4A5568;">The FarmCart Team 🌱</p>
</div>
</div>
`,
}

Expand Down Expand Up @@ -293,3 +309,56 @@ export const getDeliveriesByDriver = async (req, res) => {
})
}
}

//
// deleteing the duplicated ones
// Function to clean up duplicate deliveries by orderID
export const cleanUpDuplicateDeliveries = async () => {
try {
// Find all deliveries grouped by orderID and check for duplicates
const duplicates = await DLDelivery.aggregate([
{
$group: {
_id: '$orderID', // Group by orderID
count: { $sum: 1 }, // Count occurrences of each orderID
docs: { $push: '$$ROOT' }, // Push all documents with the same orderID
},
},
{
$match: {
count: { $gt: 1 }, // Filter groups that have more than 1 occurrence
},
},
])

// Loop through each duplicate and keep the first created, delete the rest
for (const duplicate of duplicates) {
const sortedDocs = duplicate.docs.sort(
(a, b) =>
new Date(a.assignDateTime) - new Date(b.assignDateTime)
) // Sort by creation date (assignDateTime)

const [firstDoc, ...duplicatesToDelete] = sortedDocs

// Keep the first document and delete the rest
for (const doc of duplicatesToDelete) {
await DLDelivery.findByIdAndDelete(doc._id)
console.log(
`Deleted duplicate delivery with orderID: ${doc.orderID}`
)
}

console.log(
`Kept delivery for orderID: ${firstDoc.orderID}, removed ${duplicatesToDelete.length} duplicates`
)
}

if (duplicates.length === 0) {
/*
// console.log('No duplicate deliveries found.')
*/
}
} catch (error) {
console.error('Error cleaning up duplicate deliveries:', error)
}
}
54 changes: 40 additions & 14 deletions backend/controllers/DLEmailController.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,46 @@ export const sendApprovalEmail = asyncHandler(async (req, res) => {
to: driver.email,
subject: 'Farmcart: Approval Confirmation',
html: `
<p>Dear ${driver.fullName},</p>
<p>Congratulations! Your driver registration has been approved. Please click the button below to log in and complete your registration:</p>
<a href="${process.env.SITE_URL}${loginUrl}" style="
background-color: #4CAF50;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
border-radius: 5px;">
Click Here to Log In
</a>
<p>Alternatively, you can enter your ID to log in for the first time.</p>
<p>Regards,<br/>FarmCart Team</p>
<div style="font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px;">
<div style="max-width: 600px; margin: 0 auto; background-color: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border: 2px solid #4CAF50;">
<h2 style="text-align: center; color: #2E7D32; font-size: 24px; font-weight: bold;">FarmCart: Approval Confirmation</h2>
<p style="font-size: 16px; line-height: 1.6; color: #333;">
Dear <strong>${driver.fullName}</strong>,
</p>
<p style="font-size: 16px; line-height: 1.6; color: #333;">
Congratulations! Your driver registration has been approved.
</p>
<p style="font-size: 16px; line-height: 1.6; color: #333; font-weight: bold; color: #2E7D32;">
You can log in to your account by clicking the button below to complete your registration:
</p>
<div style="text-align: center; margin: 20px 0;">
<a href="${process.env.SITE_URL}${loginUrl}" style="
background-color: #4CAF50;
color: white;
padding: 12px 24px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
font-weight: bold;
border-radius: 5px;">
Click Here to Log In
</a>
</div>
<p style="font-size: 16px; line-height: 1.6; color: #333;">
Alternatively, you can enter your ID to log in for the first time.
</p>
<p style="font-size: 16px; line-height: 1.6; color: #333;">
Regards,<br/>FarmCart Team
</p>
</div>
</div>
`,
}

Expand Down
21 changes: 9 additions & 12 deletions backend/controllers/DLOcontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ const assignReadyOrders = async () => {
orderID: order._id.toString(),
})
if (existingDelivery) {
console.log(
`Order with ID ${order._id} already exists in DLDelivery.`
)
// console.log(
// `Order with ID ${order._id} already exists in DLDelivery.`
// )
continue // Skip this order if it already exists in DLDelivery
}

Expand Down Expand Up @@ -182,13 +182,10 @@ const assignReadyOrders = async () => {
await newDOrder.save()
/*console.log(`Order with ID ${order._id} has been successfully assigned to dOrder with new orderID ${newDOrder.orderID}.`)*/



// After saving the new dOrder, update the order status to "Assigning" in the Order model
order.orderStatus = ' Ready. '
await order.save() // Save the updated order
// console.log(`Order with ID ${order._id} has been marked as "Assigning" in the Order model.`)

// After saving the new dOrder, update the order status to "Assigning" in the Order model
order.orderStatus = ' Ready. '
await order.save() // Save the updated order
// console.log(`Order with ID ${order._id} has been marked as "Assigning" in the Order model.`)
}
} catch (error) {
console.error('Error assigning ready orders to dOrder:', error)
Expand Down Expand Up @@ -237,11 +234,11 @@ const syncDeliveryAndOrderStatus = async () => {
// Function to repeatedly check for ready orders every 5 seconds
const startOrderAssignment = () => {
/* console.log('Starting periodic check for ready orders...')*/
setInterval(assignReadyOrders, 5000) // Run the check every 5 seconds
setInterval(assignReadyOrders, 1000) // Run the check every 5 seconds
}

const startSyncDeliveryOrderStatus = () => {
setInterval(syncDeliveryAndOrderStatus, 5000) // Run every 5 seconds
setInterval(syncDeliveryAndOrderStatus, 1000) // Run every 5 seconds
}

export { startSyncDeliveryOrderStatus }
Expand Down
11 changes: 6 additions & 5 deletions backend/models/DLDeliveryModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ const DLDeliverySchema = new mongoose.Schema({
orderID: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Order',
required: [true,'Order ID is required'],
unique: [true,'Order ID is unique'],
required: [true, 'Order ID is required'],
unique: [true, 'Order ID is unique'],
},

oID: { type: String ,
required: [true,'Order ID is required'],
unique: [true,'Order ID is unique'],
oID: {
type: String,
required: [true, 'Order ID is required'],
unique: [true, 'Order ID is unique'],
},

driverID: {
Expand Down
6 changes: 2 additions & 4 deletions backend/models/DLOModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ const dorderSchema = new mongoose.Schema(
{
/* generate and store the oID:{type: String,}, */


oID: {
oID: {
type: String,
required: [true, 'Order ID required'], // Ensure each order has a unique ID
unique: [true, 'Order already exists']

unique: [true, 'Order already exists'],
},

orderID: {
Expand Down
10 changes: 9 additions & 1 deletion backend/models/OrderModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,15 @@ const orderSchema = new mongoose.Schema(
totalPrice: { type: Number, required: true },
orderStatus: {
type: String,
enum: ['Pending','Rejected', 'Ready',' .Ready. ', 'Picked Up', 'On The Way', 'Delivered'],
enum: [
'Pending',
'Rejected',
'Ready',
' Ready. ',
'Picked Up',
'On The Way',
'Delivered',
],
default: 'Pending',
},
deliveryDate: {
Expand Down
7 changes: 2 additions & 5 deletions backend/routes/Admin/AfarmerRoute.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import express from 'express'
import {
getFarmersCount,
getAllFarmers,
} from '../../controllers/Admin/Afarmer'
import { getFarmersCount, getAllFarmers } from '../../controllers/Admin/Afarmer'

const router = express.Router()

router.get('/', getAllFarmers)
router.post('/count', getFarmersCount)

export default router
export default router
4 changes: 2 additions & 2 deletions backend/routes/Admin/AuserRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import {
updateUserById,
deleteUserById,
validateUserPassword,
getUserCount
getUserCount,
} from '../../controllers/Admin/AcustomerController.js'

const router = express.Router()

router.get('/count',getUserCount)
router.get('/count', getUserCount)

// Get all users
router.get('/', getAllUsers)
Expand Down
10 changes: 8 additions & 2 deletions backend/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,22 @@ import driverRoutes from './routes/DLDriverRoutes.js' //DL
import { fileURLToPath } from 'url' //DL
import DLEmailRoutes from './routes/DLEmailRoutes.js' //DL
import oRoutes from './routes/DLORoutes.js' // DL
import { checkForAvailableDrivers } from './controllers/DLDeliveryController.js' //DL THIS IS CHECKING ALL ODRS AND ASSIGN DRIVERS
import {
checkForAvailableDrivers,
cleanUpDuplicateDeliveries,
} from './controllers/DLDeliveryController.js' //DL THIS IS CHECKING ALL ODRS AND ASSIGN DRIVERS
import deliveryRoutes from './routes/DLDeliveryRoute.js' //DL
import {
startOrderAssignment,
startSyncDeliveryOrderStatus,
} from './controllers/DLOcontroller.js' // Import the periodic check

// checkForAvailableDrivers() //DL

// {/*checkForAvailableDrivers() //DL
// startOrderAssignment()
// startSyncDeliveryOrderStatus() //DL
// cleanUpDuplicateDeliveries() */}


import { errorHandler, notFound } from './middlewares/errorMiddleware.js'

Expand Down
5 changes: 4 additions & 1 deletion frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ const router = createBrowserRouter(

{/* delivery and driver Routes */}
<Route path="/" element={<DLayout />}>
<Route path="/manager" element={<AdminLogin manager={true} />} />
<Route
path="/manager"
element={<AdminLogin manager={true} />}
/>
<Route element={<StaffPrivateRoute manager={true} />}>
<Route
path="/manager/approve-driver"
Expand Down
17 changes: 9 additions & 8 deletions frontend/src/Components/Admin/AstaffPrivateRoute.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { Navigate, Outlet } from 'react-router-dom';
import { Navigate, Outlet } from 'react-router-dom'

const StaffPrivateRoute = ({ manager }) => { // Destructure manager from props
const StaffPrivateRoute = ({ manager }) => {

Check failure on line 3 in frontend/src/Components/Admin/AstaffPrivateRoute.jsx

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

frontend/src/Components/Admin/AstaffPrivateRoute.jsx#L3

[react/prop-types] 'manager' is missing in props validation
// Destructure manager from props
// Check if the user is authenticated by checking for a token in local storage
const staff = localStorage.getItem('staffToken'); // Replace with your actual logic
const staff = localStorage.getItem('staffToken') // Replace with your actual logic

// Log the user state for debugging
console.log(staff);
console.log(staff)

// If staff token exists and manager prop is true, redirect to /manager
if (manager) {
return staff ? <Outlet /> : <Navigate to="/manager" replace />;
return staff ? <Outlet /> : <Navigate to="/manager" replace />
}

// If staff token exists, render the Outlet, otherwise navigate to /Admin
return staff ? <Outlet /> : <Navigate to="/Admin" replace />;
};
return staff ? <Outlet /> : <Navigate to="/Admin" replace />
}

export default StaffPrivateRoute;
export default StaffPrivateRoute
Loading

0 comments on commit 58f8cf1

Please sign in to comment.