From 178bf21f094c3a0e5d7c3054039e9217e14fd033 Mon Sep 17 00:00:00 2001 From: eyeaadil Date: Sat, 19 Oct 2024 23:16:24 +0530 Subject: [PATCH 1/6] fixed --- customer/src/controllers/booking.ts | 49 ++++++++++++++++---------- db/src/lib/models/booking.model.ts | 14 ++++---- db/src/lib/models/serviceItem.model.ts | 2 +- package-lock.json | 9 +++++ package.json | 1 + 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/customer/src/controllers/booking.ts b/customer/src/controllers/booking.ts index c94116d..a3d6c16 100644 --- a/customer/src/controllers/booking.ts +++ b/customer/src/controllers/booking.ts @@ -1,6 +1,7 @@ import { Booking, RequestWithUser, Service } from '@org/db'; import { ApiError } from '@org/utils'; import { NextFunction, Request, Response } from 'express'; +import moment from 'moment'; import mongoose, { Mongoose } from 'mongoose'; // Utility function for date validation @@ -10,7 +11,7 @@ const isValidDate = (date) => { type ExtraTask = { description: string; extraPrice: number; - timeAdded?: string; + // timeAdded?: string; }; type Location = { @@ -21,9 +22,10 @@ type Location = { type NewBookingData = { customer: mongoose.Types.ObjectId; service: mongoose.Types.ObjectId; - serviceProvider: mongoose.Types.ObjectId; + // serviceProvider: mongoose.Types.ObjectId; bookingDate: Date; - totalPrice: number; + bookingTime: string; + // totalPrice: number; serviceItems?: ExtraTask[]; location?: Location; }; @@ -37,16 +39,16 @@ export const createBooking = async (req: RequestWithUser, res: Response): Promis bookingTime, extraTasks, location, - totalPrice, - serviceProviderId, + // totalPrice, + // serviceProviderId, }: { serviceId: string; bookingDate: string; bookingTime: string; extraTasks?: ExtraTask[]; location?: Location; - totalPrice: number; - serviceProviderId: string; + // totalPrice: number; + // serviceProviderId: string; } = req.body; // Validate required fields @@ -87,20 +89,29 @@ export const createBooking = async (req: RequestWithUser, res: Response): Promis return; } - // Combine bookingDate and bookingTime into a proper Date object - const fullBookingDate = new Date(`${bookingDate}T${bookingTime}`); - if (isNaN(fullBookingDate.getTime())) { - res.status(400).json({ message: 'Invalid booking date or time format' }); - return; - } + // Combine date and time using moment.js + // const fullBookingDate = moment(`${bookingDate} ${bookingTime}`, 'YYYY-MM-DD hh:mm A'); + // if (!fullBookingDate.isValid()) { + // res.status(400).json({ message: 'Invalid booking date or time format' }); + // return; + // } + + + // Validate and format the date using moment.js + const formattedBookingDate = moment(bookingDate, 'YYYY-MM-DD').format('YYYY-MM-DD'); + if (!moment(formattedBookingDate, 'YYYY-MM-DD', true).isValid()) { + res.status(400).json({ message: 'Invalid booking date format. Use "YYYY-MM-DD"' }); + return; + } // Build the booking object const newBookingData: NewBookingData = { customer: customerId as any, - service: new mongoose.Types.ObjectId(serviceId), - serviceProvider: new mongoose.Types.ObjectId(serviceProviderId), - bookingDate: fullBookingDate, - totalPrice, + service: serviceId as any , + // serviceProvider: new mongoose.Types.ObjectId(serviceProviderId), + bookingDate: new Date(`${formattedBookingDate}T00:00:00Z`), // Only save the date part + bookingTime: bookingTime, // Save time as string + // totalPrice, }; // If extra tasks are provided, add them to the booking @@ -108,7 +119,7 @@ export const createBooking = async (req: RequestWithUser, res: Response): Promis newBookingData.serviceItems = extraTasks.map((task) => ({ description: task.description, extraPrice: task.extraPrice, - timeAdded: task.timeAdded || null, + // timeAdded: task.timeAdded || null, })); } @@ -116,7 +127,7 @@ export const createBooking = async (req: RequestWithUser, res: Response): Promis if (location) { newBookingData.location = location; } - + console.log(newBookingData) // Create the new booking const newBooking = await Booking.create(newBookingData); diff --git a/db/src/lib/models/booking.model.ts b/db/src/lib/models/booking.model.ts index bcb4a78..e26fffb 100644 --- a/db/src/lib/models/booking.model.ts +++ b/db/src/lib/models/booking.model.ts @@ -1,11 +1,6 @@ import mongoose from 'mongoose'; // Define the schema for an extra task -const extraTaskSchema = new mongoose.Schema({ - description: { type: String, required: true }, - extraPrice: { type: Number, required: true }, - timeAdded: { type: String }, -}); // Define a point schema for location data const pointSchema = new mongoose.Schema({ @@ -64,7 +59,14 @@ const bookingSchema = new mongoose.Schema({ ref: 'Agent', required: false, }, - extraTasks: [extraTaskSchema], // Include extra tasks in the booking + extraTasks: [{ + description:{ + type:String + }, + extraPrice:{ + type:String + } + }], // Include extra tasks in the booking location: { // Include location of the service (if applicable) type: pointSchema, index: '2dsphere', diff --git a/db/src/lib/models/serviceItem.model.ts b/db/src/lib/models/serviceItem.model.ts index c0156a7..3de1925 100644 --- a/db/src/lib/models/serviceItem.model.ts +++ b/db/src/lib/models/serviceItem.model.ts @@ -13,7 +13,7 @@ const serviceItemSchema = new mongoose.Schema({ }, cost: { type: Number, - required: true, + // required: true, }, imageUrl: { type: String, diff --git a/package-lock.json b/package-lock.json index 886709f..4b20290 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "dotenv": "^16.4.5", "express": "^4.18.1", "jsonwebtoken": "^9.0.2", + "moment": "^2.30.1", "mongoose": "^8.5.4", "multer": "^1.4.5-lts.1", "node-geocoder": "^4.4.0", @@ -11389,6 +11390,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, "node_modules/mongodb": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", diff --git a/package.json b/package.json index a1e37b8..187afc3 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dotenv": "^16.4.5", "express": "^4.18.1", "jsonwebtoken": "^9.0.2", + "moment": "^2.30.1", "mongoose": "^8.5.4", "multer": "^1.4.5-lts.1", "node-geocoder": "^4.4.0", From 83a63d06b09a4e4788f2037a141f652cc208ea1d Mon Sep 17 00:00:00 2001 From: eyeaadil Date: Mon, 21 Oct 2024 22:58:41 +0530 Subject: [PATCH 2/6] All contoller of bookings is fixed --- api-gateway/nginx.conf | 36 ++++----- customer/src/controllers/booking.ts | 120 ++++++++++++++-------------- customer/src/routes/bookingRoute.ts | 6 +- db/src/lib/models/booking.model.ts | 8 +- docker-compose.yaml | 78 +++++++++--------- 5 files changed, 119 insertions(+), 129 deletions(-) diff --git a/api-gateway/nginx.conf b/api-gateway/nginx.conf index dfdffaa..dbfcd4c 100644 --- a/api-gateway/nginx.conf +++ b/api-gateway/nginx.conf @@ -8,17 +8,17 @@ http { server auth:5001; } - # upstream customer { - # server customer:5002; - # } + upstream customer { + server customer:5002; + } - # upstream shopkeeper { - # server shopkeeper:5003; - # } + upstream shopkeeper { + server shopkeeper:5003; + } - # upstream agent { - # server agent:5000; - # } + upstream agent { + server agent:5000; + } server { listen 80; @@ -27,15 +27,15 @@ http { location /auth { proxy_pass http://auth; } - # location /customer { - # proxy_pass http://customer; - # } - # location /shopkeeper { - # proxy_pass http://shopkeeper; - # } - # location /agent { - # proxy_pass http://agent; - # } + location /customer { + proxy_pass http://customer; + } + location /shopkeeper { + proxy_pass http://shopkeeper; + } + location /agent { + proxy_pass http://agent; + } } # server { diff --git a/customer/src/controllers/booking.ts b/customer/src/controllers/booking.ts index a3d6c16..cc93e8f 100644 --- a/customer/src/controllers/booking.ts +++ b/customer/src/controllers/booking.ts @@ -1,17 +1,18 @@ import { Booking, RequestWithUser, Service } from '@org/db'; import { ApiError } from '@org/utils'; -import { NextFunction, Request, Response } from 'express'; +import { RequestId } from 'aws-sdk/clients/cloudwatchlogs'; +import { NextFunction, Request, RequestParamHandler, Response } from 'express'; import moment from 'moment'; -import mongoose, { Mongoose } from 'mongoose'; +import mongoose from 'mongoose'; + +/// Utility function for date validation +// const isValidDate = (date: string) => { +// return !isNaN(Date.parse(date)); +// }; -// Utility function for date validation -const isValidDate = (date) => { - return !isNaN(Date.parse(date)); -}; type ExtraTask = { description: string; extraPrice: number; - // timeAdded?: string; }; type Location = { @@ -22,44 +23,35 @@ type Location = { type NewBookingData = { customer: mongoose.Types.ObjectId; service: mongoose.Types.ObjectId; - // serviceProvider: mongoose.Types.ObjectId; bookingDate: Date; - bookingTime: string; - // totalPrice: number; - serviceItems?: ExtraTask[]; + bookingTime: string; + extraTasks?: ExtraTask[]; location?: Location; }; export const createBooking = async (req: RequestWithUser, res: Response): Promise => { try { - const customerId = req.user.id // Assuming customer ID is extracted from the authenticated user + const customerId = req.user.id; // Assuming customer ID is extracted from the authenticated user const { serviceId, bookingDate, bookingTime, extraTasks, location, - // totalPrice, - // serviceProviderId, }: { serviceId: string; bookingDate: string; bookingTime: string; extraTasks?: ExtraTask[]; location?: Location; - // totalPrice: number; - // serviceProviderId: string; } = req.body; // Validate required fields - if (!serviceId || !bookingDate || !bookingTime ) { + if (!serviceId || !bookingDate || !bookingTime) { res.status(400).json({ message: 'All fields are required' }); return; } - // Validate total price - - // Validate booking time (e.g., "10:00 AM", "2:30 PM") const timeRegex = /^(0?[1-9]|1[0-2]):([0-5]\d)\s?(AM|PM)$/i; if (!timeRegex.test(bookingTime)) { @@ -89,37 +81,26 @@ export const createBooking = async (req: RequestWithUser, res: Response): Promis return; } - // Combine date and time using moment.js - // const fullBookingDate = moment(`${bookingDate} ${bookingTime}`, 'YYYY-MM-DD hh:mm A'); - // if (!fullBookingDate.isValid()) { - // res.status(400).json({ message: 'Invalid booking date or time format' }); - // return; - // } - - - // Validate and format the date using moment.js - const formattedBookingDate = moment(bookingDate, 'YYYY-MM-DD').format('YYYY-MM-DD'); - if (!moment(formattedBookingDate, 'YYYY-MM-DD', true).isValid()) { - res.status(400).json({ message: 'Invalid booking date format. Use "YYYY-MM-DD"' }); - return; - } + // Validate and format the date using moment.js + const formattedBookingDate = moment(bookingDate, 'YYYY-MM-DD').format('YYYY-MM-DD'); + if (!moment(formattedBookingDate, 'YYYY-MM-DD', true).isValid()) { + res.status(400).json({ message: 'Invalid booking date format. Use "YYYY-MM-DD"' }); + return; + } // Build the booking object const newBookingData: NewBookingData = { customer: customerId as any, - service: serviceId as any , - // serviceProvider: new mongoose.Types.ObjectId(serviceProviderId), + service: serviceId as any, bookingDate: new Date(`${formattedBookingDate}T00:00:00Z`), // Only save the date part bookingTime: bookingTime, // Save time as string - // totalPrice, }; // If extra tasks are provided, add them to the booking if (extraTasks && extraTasks.length > 0) { - newBookingData.serviceItems = extraTasks.map((task) => ({ + newBookingData.extraTasks = extraTasks.map((task) => ({ description: task.description, extraPrice: task.extraPrice, - // timeAdded: task.timeAdded || null, })); } @@ -127,7 +108,7 @@ export const createBooking = async (req: RequestWithUser, res: Response): Promis if (location) { newBookingData.location = location; } - console.log(newBookingData) + // Create the new booking const newBooking = await Booking.create(newBookingData); @@ -139,46 +120,61 @@ export const createBooking = async (req: RequestWithUser, res: Response): Promis }; // Get Customer Bookings -export const getBookings = async (req, res) => { +export const getCustomerBookings = async (req: RequestWithUser, res: Response): Promise => { try { - const customerId = req.user.id; // Extract from the auth token + const customerId = req.user.id; // Assuming customer ID is extracted from authenticated user - const bookings = await Booking.find({ customer: customerId }); + // Validate that the customerId is a valid ObjectId + if (!mongoose.Types.ObjectId.isValid(customerId)) { + res.status(400).json({ message: 'Invalid customer ID' }); + return; + } - if (bookings.length === 0) { - return res.status(404).json({ message: 'No bookings found' }); + // Fetch all bookings associated with the customer + const customerBookings = await Booking.find({ customer: customerId }) + .sort({ bookingDate: -1 }); // Sort bookings by most recent first + + // Check if bookings are found + if (customerBookings.length === 0) { + res.status(404).json({ message: 'No bookings found for this customer' }); + return; } - res.status(200).json(bookings); + // Return the bookings + res.status(200).json(customerBookings); } catch (error) { + console.error(error); res.status(500).json({ message: error.message }); } }; - // Delete a Booking -export const deleteBooking = async (req, res) => { +export const deleteBooking = async (req: Request, res: Response): Promise => { try { - const customerId = req.user.id; - const bookingId = req.params.id; - - // Validation - if (!bookingId.match(/^[0-9a-fA-F]{24}$/)) { - // Check if bookingId is a valid ObjectId format - return res.status(400).json({ message: 'Invalid booking ID format' }); + // Get the booking ID from the request parameters + console.log("adihsjdfbhjfbdjhfbg",req.params); + const { id } = req.params; + + console.log("adillllllll",id); + // Check if the booking ID is a valid MongoDB ObjectId + if (!mongoose.Types.ObjectId.isValid(id)) { + res.status(400).json({ message: 'Invalid booking ID format' }); + return; } - const booking = await Booking.findById(bookingId); + // Find and delete the booking + const deletedBooking = await Booking.findByIdAndDelete(id); - if (!booking || booking.customer.toString() !== customerId) { - return res - .status(404) - .json({ message: 'Booking not found or not authorized' }); + // If no booking was found, return a 404 error + if (!deletedBooking) { + res.status(404).json({ message: 'Booking not found' }); + return; } - await Booking.findByIdAndDelete(bookingId); + // Return a success message res.status(200).json({ message: 'Booking deleted successfully' }); } catch (error) { - res.status(500).json({ message: error.message }); + console.error(error); + res.status(500).json({ message: 'Internal server error' }); } }; diff --git a/customer/src/routes/bookingRoute.ts b/customer/src/routes/bookingRoute.ts index fc14400..995254b 100644 --- a/customer/src/routes/bookingRoute.ts +++ b/customer/src/routes/bookingRoute.ts @@ -1,7 +1,7 @@ import express from 'express'; import { createBooking, - getBookings, + getCustomerBookings, deleteBooking, getServices, } from '../controllers/booking'; @@ -16,9 +16,9 @@ router.post('/book', verifyJWT, isAuthorized(['CLIENT']), createBooking); router.get('/services/:orgId', verifyJWT, getServices); // Route to get all bookings for a customer -router.get('/bookings', verifyJWT, getBookings); +router.get('/bookings', verifyJWT,isAuthorized(['CLIENT']),getCustomerBookings); // Route to delete a booking -router.delete('/bookings/:id', verifyJWT, deleteBooking); +router.delete('/bookings/:id', verifyJWT,isAuthorized(['CLIENT']),deleteBooking); export default router; diff --git a/db/src/lib/models/booking.model.ts b/db/src/lib/models/booking.model.ts index e26fffb..cc5a2f9 100644 --- a/db/src/lib/models/booking.model.ts +++ b/db/src/lib/models/booking.model.ts @@ -46,7 +46,7 @@ const bookingSchema = new mongoose.Schema({ }, totalPrice: { type: Number, - required: true, + // required: true, min: 0, }, paymentStatus: { @@ -71,12 +71,6 @@ const bookingSchema = new mongoose.Schema({ type: pointSchema, index: '2dsphere', }, - serviceItems: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'ServiceItem', - }, - ], }, { timestamps: true }); // Export the Booking model diff --git a/docker-compose.yaml b/docker-compose.yaml index ec54a06..f7757c2 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -8,24 +8,24 @@ services: ports: - "80:80" depends_on: - # - agent + - agent - auth - # - customer - # - shopkeeper + - customer + - shopkeeper - # agent: - # build: - # context: . - # dockerfile: Dockerfile - # args: - # PROJECT: agent - # env_file: - # - .env - # environment: - # - NODE_ENV=production - # ports: - # - "5000:5000" + agent: + build: + context: . + dockerfile: Dockerfile + args: + PROJECT: agent + env_file: + - .env + environment: + - NODE_ENV=production + ports: + - "5000:5000" auth: build: context: . @@ -39,28 +39,28 @@ services: ports: - "5001:5001" - # customer: - # build: - # context: . - # dockerfile: Dockerfile - # args: - # PROJECT: customer - # env_file: - # - .env - # environment: - # - NODE_ENV=production - # ports: - # - "5002:5002" - # shopkeeper: - # build: - # context: . - # dockerfile: Dockerfile - # args: - # PROJECT: shopkeeper - # env_file: - # - .env - # environment: - # - NODE_ENV=production - # ports: - # - "5003:5003" + customer: + build: + context: . + dockerfile: Dockerfile + args: + PROJECT: customer + env_file: + - .env + environment: + - NODE_ENV=production + ports: + - "5002:5002" + shopkeeper: + build: + context: . + dockerfile: Dockerfile + args: + PROJECT: shopkeeper + env_file: + - .env + environment: + - NODE_ENV=production + ports: + - "5003:5003" From d1867eaa14d5653344f59e87844e598925e74516 Mon Sep 17 00:00:00 2001 From: eyeaadil Date: Thu, 24 Oct 2024 22:49:14 +0530 Subject: [PATCH 3/6] Update readme --- README.md | 7 ++++ api-gateway/nginx.conf | 36 +++++++++---------- docker-compose.yaml | 78 +++++++++++++++++++++--------------------- 3 files changed, 64 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 1766c01..5331522 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +# To up the server using docker-compose +``` + docker-compose up --build + ``` +### Note : It will not restart on code change. You have to run this command again. + + # Org diff --git a/api-gateway/nginx.conf b/api-gateway/nginx.conf index dbfcd4c..dfdffaa 100644 --- a/api-gateway/nginx.conf +++ b/api-gateway/nginx.conf @@ -8,17 +8,17 @@ http { server auth:5001; } - upstream customer { - server customer:5002; - } + # upstream customer { + # server customer:5002; + # } - upstream shopkeeper { - server shopkeeper:5003; - } + # upstream shopkeeper { + # server shopkeeper:5003; + # } - upstream agent { - server agent:5000; - } + # upstream agent { + # server agent:5000; + # } server { listen 80; @@ -27,15 +27,15 @@ http { location /auth { proxy_pass http://auth; } - location /customer { - proxy_pass http://customer; - } - location /shopkeeper { - proxy_pass http://shopkeeper; - } - location /agent { - proxy_pass http://agent; - } + # location /customer { + # proxy_pass http://customer; + # } + # location /shopkeeper { + # proxy_pass http://shopkeeper; + # } + # location /agent { + # proxy_pass http://agent; + # } } # server { diff --git a/docker-compose.yaml b/docker-compose.yaml index f7757c2..35f1579 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -8,24 +8,24 @@ services: ports: - "80:80" depends_on: - - agent + # - agent - auth - - customer - - shopkeeper + # - customer + # - shopkeeper - agent: - build: - context: . - dockerfile: Dockerfile - args: - PROJECT: agent - env_file: - - .env - environment: - - NODE_ENV=production - ports: - - "5000:5000" + # agent: + # build: + # context: . + # dockerfile: Dockerfile + # args: + # PROJECT: agent + # env_file: + # - .env + # environment: + # - NODE_ENV=production + # ports: + # - "5000:5000" auth: build: context: . @@ -39,28 +39,28 @@ services: ports: - "5001:5001" - customer: - build: - context: . - dockerfile: Dockerfile - args: - PROJECT: customer - env_file: - - .env - environment: - - NODE_ENV=production - ports: - - "5002:5002" - shopkeeper: - build: - context: . - dockerfile: Dockerfile - args: - PROJECT: shopkeeper - env_file: - - .env - environment: - - NODE_ENV=production - ports: - - "5003:5003" + # customer: + # build: + # context: . + # dockerfile: Dockerfile + # args: + # PROJECT: customer + # env_file: + # - .env + # environment: + # - NODE_ENV=production + # ports: + # - "5002:5002" + # shopkeeper: + # build: + # context: . + # dockerfile: Dockerfile + # args: + # PROJECT: shopkeeper + # env_file: + # - .env + # environment: + # - NODE_ENV=production + # ports: + # - "5003:5003" From cc37091c780a9ad440cf09aaf9e926c802cd8069 Mon Sep 17 00:00:00 2001 From: eyeaadil Date: Sun, 27 Oct 2024 12:34:58 +0530 Subject: [PATCH 4/6] modify agent service --- agent/src/controllers/agentController.ts | 141 +++++++++++------------ agent/src/routes/agentRoutes.ts | 10 +- auth/src/controllers/auth.controller.ts | 1 + db/src/lib/models/agent.model.ts | 16 +-- 4 files changed, 80 insertions(+), 88 deletions(-) diff --git a/agent/src/controllers/agentController.ts b/agent/src/controllers/agentController.ts index fc9adb6..a16aa69 100644 --- a/agent/src/controllers/agentController.ts +++ b/agent/src/controllers/agentController.ts @@ -1,7 +1,7 @@ // import { Agent, Client, ServiceProvider } from '@org/db'; -import { Booking, ServiceItem } from '@org/db'; +import { Booking } from '@org/db'; @@ -10,20 +10,18 @@ import { Booking, ServiceItem } from '@org/db'; // Show all pending, in-progress, and completed bookings export const getAgentDashboard = async (req, res) => { try { - const agentId = req.user.id; + const agentId = req.user.id; // Find all bookings assigned to this agent - const bookings = await Booking.find({ agentId }) - .populate('serviceItems') // Populate service items in each booking - .populate('customerId', 'name') // Populate customer name for each booking - .populate('serviceProviderId', 'name'); // Populate service provider name + const bookings = await Booking.find({ agent: agentId }) + .populate('customer', 'name') // Populate customer name for each booking + .populate('serviceProvider', 'name'); // Populate service provider name // Filter bookings based on status const pendingBookings = bookings.filter(b => b.status === 'Pending'); const inProgressBookings = bookings.filter(b => b.status === 'In Progress'); const completedBookings = bookings.filter(b => b.status === 'Completed'); - // Send the data for the agent's dashboard res.status(200).json({ totalBookings: bookings.length, @@ -36,11 +34,11 @@ export const getAgentDashboard = async (req, res) => { } }; -// 1. Add a Service to a Booking (as described before) -export const addServiceToBooking = async (req, res) => { +// 1. Add an Extra Task to a Booking +export const addExtraTaskToBooking = async (req, res) => { try { const { bookingId } = req.params; - const { description, cost } = req.body; // Description and cost of the service + const { description, extraPrice } = req.body; // Find the booking const booking = await Booking.findById(bookingId); @@ -53,113 +51,106 @@ export const addServiceToBooking = async (req, res) => { return res.status(403).json({ error: 'Not authorized to modify this booking' }); } - // Create a new service item (problem identified by agent) - const serviceItem = new ServiceItem({ - bookingId, - description, - cost, - imageUrl: req.file ? req.file.path : null - }); - - - await serviceItem.save(); - - // Add the service item to the booking - booking.serviceItems.push(serviceItem._id); - booking.updatedAt = new Date(); + // Add the extra task to the booking + booking.extraTasks.push({ description, extraPrice }); + booking.updatedAt = new Date(); await booking.save(); res.status(201).json({ - message: 'Service added successfully', - serviceItem + message: 'Extra task added successfully', + extraTasks: booking.extraTasks, }); } catch (error) { - res.status(500).json({ error: 'Failed to add service to booking' }); + res.status(500).json({ error: 'Failed to add extra task to booking' }); } }; -// 2. Update a Service for a Booking -export const updateServiceInBooking = async (req, res) => { +// 2. Update an Extra Task in a Booking +export const updateExtraTaskInBooking = async (req, res) => { try { - const { serviceId } = req.params; - const { description, cost } = req.body; - // Find the service item - const serviceItem = await ServiceItem.findById(serviceId); - if (!serviceItem) { - return res.status(404).json({ error: 'Service item not found' }); + const { bookingId, taskIndex } = req.params; + const { description, extraPrice } = req.body; + + // Find the booking + const booking = await Booking.findById(bookingId); + if (!booking) { + return res.status(404).json({ error: 'Booking not found' }); + } + + // Check if the agent is allowed to modify this booking + if (!booking.agent || booking.agent.toString() !== req.user.id) { + return res.status(403).json({ error: 'Not authorized to modify this booking' }); } - // Check if the agent is allowed to modify this service - const booking = await Booking.findById(serviceItem.bookingId); - if (booking.agent.toString() !== req.user.id) { - return res.status(403).json({ error: 'Not authorized to modify this service' }); + // Check if the task index is valid + if (taskIndex >= booking.extraTasks.length || taskIndex < 0) { + return res.status(404).json({ error: 'Task not found' }); } - // Update service details - if (description) serviceItem.description = description; - if (cost) serviceItem.cost = cost; - serviceItem.updatedAt = new Date(); - await serviceItem.save(); + // Update the specific extra task + if (description) booking.extraTasks[taskIndex].description = description; + if (extraPrice) booking.extraTasks[taskIndex].extraPrice = extraPrice; + booking.updatedAt = new Date(); + await booking.save(); res.status(200).json({ - message: 'Service updated successfully', - serviceItem + message: 'Extra task updated successfully', + extraTasks: booking.extraTasks, }); } catch (error) { - res.status(500).json({ error: 'Failed to update service' }); + res.status(500).json({ error: 'Failed to update extra task' }); } }; -// 3. Delete a Service from a Booking -export const deleteServiceFromBooking = async (req, res) => { +// 3. Delete an Extra Task from a Booking +export const deleteExtraTaskFromBooking = async (req, res) => { try { - const { serviceId } = req.params; + const { bookingId, taskIndex } = req.params; - - const serviceItem = await ServiceItem.findById(serviceId); - if (!serviceItem) { - return res.status(404).json({ error: 'Service item not found' }); + // Find the booking + const booking = await Booking.findById(bookingId); + if (!booking) { + return res.status(404).json({ error: 'Booking not found' }); } - // Check if the agent is allowed to delete this service - const booking = await Booking.findById(serviceItem.bookingId); - if (booking.agent.toString() !== req.user.id) { - return res.status(403).json({ error: 'Not authorized to delete this service' }); + // Check if the agent is allowed to modify this booking + if (!booking.agent || booking.agent.toString() !== req.user.id) { + return res.status(403).json({ error: 'Not authorized to delete this task' }); } - // Remove the service item from the booking's serviceItems array - booking.serviceItems = booking.serviceItems.filter( - item => item.toString() !== serviceItem._id.toString() - ); - await booking.save(); + // Check if the task index is valid + if (taskIndex >= booking.extraTasks.length || taskIndex < 0) { + return res.status(404).json({ error: 'Task not found' }); + } - // Delete the service item - await ServiceItem.deleteOne({ _id: serviceItem._id }); + // Remove the task at the specified index + booking.extraTasks.splice(taskIndex, 1); + await booking.save(); - res.status(200).json({ message: 'Service deleted successfully' }); + res.status(200).json({ message: 'Extra task deleted successfully' }); } catch (error) { - res.status(500).json({ error: 'Failed to delete service' }); + res.status(500).json({ error: 'Failed to delete extra task' }); } }; -// 4. Get All Services of a Booking (for agent's dashboard) -export const getServicesForBooking = async (req, res) => { +// 4. Get All Extra Tasks of a Booking (for agent's dashboard) +export const getExtraTasksForBooking = async (req, res) => { try { const { bookingId } = req.params; // Find the booking - const booking = await Booking.findById(bookingId).populate('serviceItems'); + const booking = await Booking.findById(bookingId); if (!booking) { return res.status(404).json({ error: 'Booking not found' }); } - // Check if the agent is allowed to view services for this booking - if (booking.agent.toString() !== req.user.id) { - return res.status(403).json({ error: 'Not authorized to view services' }); + // Check if the agent is allowed to view tasks for this booking + if (!booking.agent || booking.agent.toString() !== req.user.id) { + return res.status(403).json({ error: 'Not authorized to view extra tasks' }); } - res.status(200).json({ services: booking.serviceItems }); + res.status(200).json({ extraTasks: booking.extraTasks }); } catch (error) { - res.status(500).json({ error: 'Failed to fetch services' }); + res.status(500).json({ error: 'Failed to fetch extra tasks' }); } }; diff --git a/agent/src/routes/agentRoutes.ts b/agent/src/routes/agentRoutes.ts index bb229fc..ca975aa 100644 --- a/agent/src/routes/agentRoutes.ts +++ b/agent/src/routes/agentRoutes.ts @@ -4,7 +4,7 @@ const router = express.Router(); import {verifyJWT} from '@org/utils' import multer from 'multer' -import {getAgentDashboard,updateServiceInBooking,deleteServiceFromBooking,getServicesForBooking,addServiceToBooking} from '../controllers/agentController' +import {getAgentDashboard,updateExtraTaskInBooking,deleteExtraTaskFromBooking,getExtraTasksForBooking,addExtraTaskToBooking} from '../controllers/agentController' // Setup Multer for image uploads const upload = multer({ dest: 'uploads/' }); @@ -12,15 +12,15 @@ const upload = multer({ dest: 'uploads/' }); router.get('/dashboard',verifyJWT,getAgentDashboard); // Add service to a booking (with image upload) -router.post('/booking/:bookingId/service',verifyJWT, upload.single('image'),addServiceToBooking); +router.post('/booking/:bookingId/service',verifyJWT, upload.single('image'),addExtraTaskToBooking); // Update a service in a booking -router.put('/service/:serviceId',verifyJWT, updateServiceInBooking); +router.put('/service/:serviceId',verifyJWT, updateExtraTaskInBooking); // Delete a service from a booking -router.delete('/service/:serviceId',verifyJWT, deleteServiceFromBooking); +router.delete('/service/:serviceId',verifyJWT, deleteExtraTaskFromBooking); // Get all services for a specific booking -router.get('/booking/:bookingId/services',verifyJWT,getServicesForBooking); +router.get('/booking/:bookingId/services',verifyJWT,getExtraTasksForBooking); export default router; diff --git a/auth/src/controllers/auth.controller.ts b/auth/src/controllers/auth.controller.ts index 662546c..762219f 100644 --- a/auth/src/controllers/auth.controller.ts +++ b/auth/src/controllers/auth.controller.ts @@ -91,6 +91,7 @@ const agentRegister = async ( if (agentExists) { return next(new ApiError('Agent already exists', 400)); } + const newAgent = await Agent.create(req.body); const token = sign( { diff --git a/db/src/lib/models/agent.model.ts b/db/src/lib/models/agent.model.ts index c335923..2053f7a 100644 --- a/db/src/lib/models/agent.model.ts +++ b/db/src/lib/models/agent.model.ts @@ -19,38 +19,38 @@ const agentSchema = new mongoose.Schema({ password: { type: String, required: true }, phoneNumber: { type: String, - required: true + // required: true }, address: { type: String, - required: true + // required: true }, location: { latitude: { type: Number, - required: true + // required: true }, longitude: { type: Number, - required: true + // required: true } }, services: { type: [String], // Array of services like coolerRepair, washingMachineRepair - required: true + // required: true }, serviceArea: { type: String, - required: true + // required: true }, availability: { type: String, - required: true + // required: true }, serviceProviderId: { type: mongoose.Schema.Types.ObjectId, ref: 'ServiceProvider', - required: true + // required: true }, customerId: [{ type: mongoose.Schema.Types.ObjectId, From c2dbc0d592dea8b99e8a491301ac3d60dd72068e Mon Sep 17 00:00:00 2001 From: eyeaadil Date: Sun, 27 Oct 2024 18:49:37 +0530 Subject: [PATCH 5/6] agent controller --- agent/src/controllers/agentController.ts | 1 + agent/src/routes/agentRoutes.ts | 4 ++-- shopkeeper/src/controllers/controller.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/agent/src/controllers/agentController.ts b/agent/src/controllers/agentController.ts index a16aa69..59010b2 100644 --- a/agent/src/controllers/agentController.ts +++ b/agent/src/controllers/agentController.ts @@ -12,6 +12,7 @@ export const getAgentDashboard = async (req, res) => { try { const agentId = req.user.id; + console.log("AAAAAAAAAAAAA",agentId); // Find all bookings assigned to this agent const bookings = await Booking.find({ agent: agentId }) .populate('customer', 'name') // Populate customer name for each booking diff --git a/agent/src/routes/agentRoutes.ts b/agent/src/routes/agentRoutes.ts index ca975aa..0575453 100644 --- a/agent/src/routes/agentRoutes.ts +++ b/agent/src/routes/agentRoutes.ts @@ -2,14 +2,14 @@ import express from 'express' const router = express.Router(); -import {verifyJWT} from '@org/utils' +import {isAuthorized, verifyJWT} from '@org/utils' import multer from 'multer' import {getAgentDashboard,updateExtraTaskInBooking,deleteExtraTaskFromBooking,getExtraTasksForBooking,addExtraTaskToBooking} from '../controllers/agentController' // Setup Multer for image uploads const upload = multer({ dest: 'uploads/' }); // Agent dashboard: View all bookings -router.get('/dashboard',verifyJWT,getAgentDashboard); +router.get('/dashboard',verifyJWT, isAuthorized(['AGENT']),getAgentDashboard); // Add service to a booking (with image upload) router.post('/booking/:bookingId/service',verifyJWT, upload.single('image'),addExtraTaskToBooking); diff --git a/shopkeeper/src/controllers/controller.ts b/shopkeeper/src/controllers/controller.ts index 8c7416f..f651205 100644 --- a/shopkeeper/src/controllers/controller.ts +++ b/shopkeeper/src/controllers/controller.ts @@ -204,7 +204,7 @@ export const assignAgentForaBooking =async (req :Request , res : Response, nex return next(new ApiError("Booking not Found " , 400 )) ; } booking.agent = agentId; - return new ApiResponse(res , 201 , "Booking Created" , { + return new ApiResponse(res , 201 , "Booking Assigned" , { agentName : agent.name , agentPhone : agent.phoneNumber, bookingId , From fe150aac2f8e34d879246cd6729bd8d1ca34a3cf Mon Sep 17 00:00:00 2001 From: eyeaadil Date: Sun, 27 Oct 2024 20:43:03 +0530 Subject: [PATCH 6/6] complete-agent-microservice --- agent/src/controllers/agentController.ts | 95 +++++++++++++++++++++++- agent/src/routes/agentRoutes.ts | 19 +++-- shopkeeper/src/controllers/controller.ts | 1 + 3 files changed, 105 insertions(+), 10 deletions(-) diff --git a/agent/src/controllers/agentController.ts b/agent/src/controllers/agentController.ts index 59010b2..5383d34 100644 --- a/agent/src/controllers/agentController.ts +++ b/agent/src/controllers/agentController.ts @@ -15,10 +15,9 @@ export const getAgentDashboard = async (req, res) => { console.log("AAAAAAAAAAAAA",agentId); // Find all bookings assigned to this agent const bookings = await Booking.find({ agent: agentId }) - .populate('customer', 'name') // Populate customer name for each booking - .populate('serviceProvider', 'name'); // Populate service provider name - - // Filter bookings based on status + // .populate('customer', 'name') // Populate customer name for each booking + // .populate('serviceProvider', 'name'); // Populate service provider name + // Filter bookings based on status const pendingBookings = bookings.filter(b => b.status === 'Pending'); const inProgressBookings = bookings.filter(b => b.status === 'In Progress'); const completedBookings = bookings.filter(b => b.status === 'Completed'); @@ -155,3 +154,91 @@ export const getExtraTasksForBooking = async (req, res) => { res.status(500).json({ error: 'Failed to fetch extra tasks' }); } }; + + + + + +export const updateBookingToInProgress = async (req, res) => { + try { + const { bookingId } = req.body; + const agentId = req.user.id; + + // Find the booking and ensure it belongs to the agent + const booking = await Booking.findOne({ + _id: bookingId, + agent: agentId + }); + + if (!booking) { + return res.status(404).json({ + error: 'Booking not found or not assigned to this agent' + }); + } + + // Validate current status + if (booking.status !== 'Pending') { + return res.status(400).json({ + error: 'Booking must be in Pending status to move to In Progress' + }); + } + + // Update the status + booking.status = 'In Progress'; + // booking.startTime = new Date(); // Optional: track when work started + await booking.save(); + + res.status(200).json({ + message: 'Booking status updated to In Progress', + booking + }); + + } catch (error) { + res.status(500).json({ + error: 'Failed to update booking status', + message: error.message + }); + } +}; + +export const updateBookingToCompleted = async (req, res) => { + try { + const { bookingId } = req.body; + const agentId = req.user.id; + + // Find the booking and ensure it belongs to the agent + const booking = await Booking.findOne({ + _id: bookingId, + agent: agentId + }); + + if (!booking) { + return res.status(404).json({ + error: 'Booking not found or not assigned to this agent' + }); + } + + // Validate current status + if (booking.status !== 'In Progress') { + return res.status(400).json({ + error: 'Booking must be in In Progress status to move to Completed' + }); + } + + // Update the status + booking.status = 'Completed'; + // booking.completionTime = new Date(); // Optional: track when work was completed + await booking.save(); + + res.status(200).json({ + message: 'Booking status updated to Completed', + booking + }); + + } catch (error) { + res.status(500).json({ + error: 'Failed to update booking status', + message: error.message + }); + } +}; diff --git a/agent/src/routes/agentRoutes.ts b/agent/src/routes/agentRoutes.ts index 0575453..fa5411d 100644 --- a/agent/src/routes/agentRoutes.ts +++ b/agent/src/routes/agentRoutes.ts @@ -4,7 +4,7 @@ const router = express.Router(); import {isAuthorized, verifyJWT} from '@org/utils' import multer from 'multer' -import {getAgentDashboard,updateExtraTaskInBooking,deleteExtraTaskFromBooking,getExtraTasksForBooking,addExtraTaskToBooking} from '../controllers/agentController' +import {getAgentDashboard,updateExtraTaskInBooking,deleteExtraTaskFromBooking,getExtraTasksForBooking,addExtraTaskToBooking,updateBookingToInProgress,updateBookingToCompleted} from '../controllers/agentController' // Setup Multer for image uploads const upload = multer({ dest: 'uploads/' }); @@ -12,15 +12,22 @@ const upload = multer({ dest: 'uploads/' }); router.get('/dashboard',verifyJWT, isAuthorized(['AGENT']),getAgentDashboard); // Add service to a booking (with image upload) -router.post('/booking/:bookingId/service',verifyJWT, upload.single('image'),addExtraTaskToBooking); +router.post('/booking/:bookingId/service',verifyJWT,addExtraTaskToBooking); // Update a service in a booking -router.put('/service/:serviceId',verifyJWT, updateExtraTaskInBooking); +router.put('/bookings/:bookingId/extra-task/:taskIndex', verifyJWT, updateExtraTaskInBooking); -// Delete a service from a booking -router.delete('/service/:serviceId',verifyJWT, deleteExtraTaskFromBooking); +// Delete a service from a booking +router.delete('/bookings/:bookingId/extra-task/:taskIndex', verifyJWT, deleteExtraTaskFromBooking); // Get all services for a specific booking -router.get('/booking/:bookingId/services',verifyJWT,getExtraTasksForBooking); +router.get('/bookings/:bookingId/extra-tasks',verifyJWT , getExtraTasksForBooking); + +// Route to update booking status to "In Progress" +router.put('/bookings/in-progress', verifyJWT, updateBookingToInProgress); + +// Route to update booking status to "Completed" +router.put('/bookings/completed', verifyJWT, updateBookingToCompleted); + export default router; diff --git a/shopkeeper/src/controllers/controller.ts b/shopkeeper/src/controllers/controller.ts index f651205..52346dc 100644 --- a/shopkeeper/src/controllers/controller.ts +++ b/shopkeeper/src/controllers/controller.ts @@ -204,6 +204,7 @@ export const assignAgentForaBooking =async (req :Request , res : Response, nex return next(new ApiError("Booking not Found " , 400 )) ; } booking.agent = agentId; + await booking.save(); return new ApiResponse(res , 201 , "Booking Assigned" , { agentName : agent.name , agentPhone : agent.phoneNumber,