From b64416ac7e069291f73607d179d216964ffa58bc Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 4 Mar 2025 15:28:58 +0530 Subject: [PATCH 1/7] changes --- src/controllers/storeController.js | 36 +++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index 3f1c9a22..e6baac8a 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -1499,7 +1499,7 @@ exports.createquotationforSensor = async (req, reply) => { const i_id = await generatequatationId(); const quatationId = `AWQU${i_id}`; const { surveyId } = req.params; - const { customerId, masters, slaves, sensors, motor_switches, electricals } = req.body; + const { customerId, masters, slaves, sensors, motor_switches, electricals,storeId } = req.body; // Format electricals field const formattedElectricals = electricals.map((item) => ({ @@ -1541,6 +1541,7 @@ exports.createquotationforSensor = async (req, reply) => { const newQuotation = new SensorQuotation({ quatationId, customerId, + storeId, surveyId, quote_status: "sentfromsurvey", masters, @@ -1679,17 +1680,30 @@ exports.createEstimationPrice = async (req, reply) => { exports.getallquotationdata = async (req, reply) => { try { - await SensorQuotation.find({}) - .exec() - .then((docs) => { - reply.send({ status_code: 200, data: docs, count: docs.length }); - }) - .catch((err) => { - console.log(err); - reply.send({ error: err }); - }); + const quotations = await SensorQuotation.find({}).lean(); // Use lean() for better performance + + // Extract unique customerIds from quotations + const customerIds = [...new Set(quotations.map((q) => q.customerId).filter(Boolean))]; + + // Fetch customer details for all unique customerIds + const customers = await User.find({ customerId: { $in: customerIds } }).lean(); + + // Convert customer array to a dictionary for quick lookup + const customerMap = customers.reduce((acc, customer) => { + acc[customer.customerId] = customer; + return acc; + }, {}); + + // Attach customer details to quotations + const enrichedQuotations = quotations.map((quotation) => ({ + ...quotation, + customerDetails: customerMap[quotation.customerId] || null, // Attach customer details if found + })); + + reply.send({ status_code: 200, data: enrichedQuotations, count: enrichedQuotations.length }); } catch (err) { - throw boom.boomify(err); + console.error(err); + reply.send({ error: err.message }); } }; From fd9ed2c3c7d3e00143e3e84d42a694b4d8fa3fca Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 4 Mar 2025 15:29:22 +0530 Subject: [PATCH 2/7] changes --- src/controllers/storeController.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index e6baac8a..48a3068b 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -1499,7 +1499,7 @@ exports.createquotationforSensor = async (req, reply) => { const i_id = await generatequatationId(); const quatationId = `AWQU${i_id}`; const { surveyId } = req.params; - const { customerId, masters, slaves, sensors, motor_switches, electricals,storeId } = req.body; + const { customerId, masters, slaves, sensors, motor_switches, electricals } = req.body; // Format electricals field const formattedElectricals = electricals.map((item) => ({ @@ -1541,7 +1541,7 @@ exports.createquotationforSensor = async (req, reply) => { const newQuotation = new SensorQuotation({ quatationId, customerId, - storeId, + surveyId, quote_status: "sentfromsurvey", masters, @@ -1560,6 +1560,7 @@ exports.createquotationforSensor = async (req, reply) => { message: 'Quotation for sensors created successfully.', data: savedQuotation, }); + } catch (error) { console.error('Error creating quotation:', error); reply.code(500).send({ From a9b702970eca94b021e54246602686bfb8b42a60 Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 4 Mar 2025 15:30:45 +0530 Subject: [PATCH 3/7] changes --- src/controllers/storeController.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index 48a3068b..f7d5bd65 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -1560,7 +1560,7 @@ exports.createquotationforSensor = async (req, reply) => { message: 'Quotation for sensors created successfully.', data: savedQuotation, }); - + } catch (error) { console.error('Error creating quotation:', error); reply.code(500).send({ @@ -1695,6 +1695,7 @@ exports.getallquotationdata = async (req, reply) => { return acc; }, {}); + // Attach customer details to quotations const enrichedQuotations = quotations.map((quotation) => ({ ...quotation, From 5ff84502d0481e937e28da4f58706aaec9cbba8b Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 4 Mar 2025 16:38:19 +0530 Subject: [PATCH 4/7] quote accept by store --- src/controllers/storeController.js | 53 ++++++++++++++++++++++--- src/models/store.js | 63 ++++++++++++++++++++++++++++-- src/routes/storeRoute.js | 29 ++++++++++++++ 3 files changed, 136 insertions(+), 9 deletions(-) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index f7d5bd65..875f392d 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -11,7 +11,7 @@ const fastify = require("fastify")({ }, }); -const {Order,Iotprice, Install, ProfilePictureInstall, SensorQuotation,generateinstallationId,Store,WaterLeverSensor,MotorSwitchSenso,Insensors,generatequatationId, HardwareCart, ServiceCart, Sales} = require("../models/store"); +const {Order,EstimationOrder,Iotprice, Install, ProfilePictureInstall, SensorQuotation,generateinstallationId,Store,WaterLeverSensor,MotorSwitchSenso,Insensors,generatequatationId, HardwareCart, ServiceCart, Sales} = require("../models/store"); const { User,Counter, generateBookingId,resetCounter,generateCustomerId,ProfilePicture} = require('../models/User') @@ -1695,7 +1695,7 @@ exports.getallquotationdata = async (req, reply) => { return acc; }, {}); - + // Attach customer details to quotations const enrichedQuotations = quotations.map((quotation) => ({ ...quotation, @@ -1711,6 +1711,8 @@ exports.getallquotationdata = async (req, reply) => { + + exports.saveQuotationData = async (req, reply) => { try { const { quotationId } = req.params; // Retrieve the quotationId from the request parameters @@ -1918,7 +1920,7 @@ exports.handleEstimation = async (req, reply) => { } // If accepted, generate unique Order ID - const lastOrder = await Order.findOne().sort({ createdAt: -1 }); + const lastOrder = await EstimationOrder.findOne().sort({ createdAt: -1 }); let orderId = "AWS001"; if (lastOrder) { const lastNumber = parseInt(lastOrder.orderId.replace("AWS", ""), 10) + 1; @@ -1926,7 +1928,7 @@ exports.handleEstimation = async (req, reply) => { } // Create a new order in the database - const newOrder = new Order({ + const newOrder = new EstimationOrder({ orderId, customerId, items, @@ -1960,7 +1962,7 @@ exports.editOrder = async (req, reply) => { } // Find the existing order - const existingOrder = await Order.findOne({ orderId }); + const existingOrder = await EstimationOrder.findOne({ orderId }); if (!existingOrder) { return reply.code(404).send({ message: "Order not found" }); @@ -1995,7 +1997,7 @@ exports.getOrdersByCustomer = async (req, reply) => { } // Fetch orders with status 'pending' or 'accepted' for the given customer - const orders = await Order.find({ + const orders = await EstimationOrder.find({ customerId, status: { $in: ["pending", "accepted"] } }); @@ -2016,3 +2018,42 @@ exports.getOrdersByCustomer = async (req, reply) => { } }; +exports.acceptQuotation = async (req, reply) => { + try { + const { quotationId } = req.params; + const { action } = req.body; + + if (action !== "accept") { + return reply.status(400).send({ error: "Invalid action" }); + } + + // Find the quotation by ID + const quotation = await SensorQuotation.findOne({ quatationId: quotationId }); + + if (!quotation) { + return reply.status(404).send({ error: "Quotation not found" }); + } + + // Convert quotation to an order object + const newOrder = new Order({ + ...quotation.toObject(), // Copy all fields + status: "pending", // Set status to "pending" + }); + + // Save to the Orders collection + await newOrder.save(); + + // Delete the record from SensorQuotation + await SensorQuotation.deleteOne({ quatationId: quotationId }); + + return reply.send({ + status_code: 200, + message: "Quotation accepted and moved to Orders", + data: newOrder, + }); + + } catch (err) { + console.error("Error accepting quotation:", err); + return reply.status(500).send({ error: "Internal server error" }); + } +}; \ No newline at end of file diff --git a/src/models/store.js b/src/models/store.js index cc2a7031..68f52458 100644 --- a/src/models/store.js +++ b/src/models/store.js @@ -370,7 +370,7 @@ const iotpriceSchema = new mongoose.Schema({ cost: { type: Number, default: null }, }); -const orderSchema = new mongoose.Schema({ +const estimationorderSchema = new mongoose.Schema({ orderId: { type: String, unique: true, required: true }, customerId: { type: String, required: true }, items: { type: Array, required: true }, @@ -382,6 +382,7 @@ const orderSchema = new mongoose.Schema({ const sensorquotationSchema = new mongoose.Schema({ customerId: { type: String }, surveyId: { type: String, default: null }, + storeId: { type: String, default: null }, installationId: { type: String, default: null }, quatationId: { type: String, default: null }, masters: { type: String }, @@ -405,9 +406,13 @@ const sensorquotationSchema = new mongoose.Schema({ wire: { type: String, default: null }, switch: { type: String, default: null }, text: { type: String, default: null }, + available_quantity: { type: String, default: null }, }, ], master_type_quantity_price: { type: String, default: null }, + master_available_quantity: { type: String, default: null }, + slave_available_quantity: { type: String, default: null }, + sensor_available_quantity: { type: String, default: null }, master_type_total_price: { type: String, default: null }, sensor_type_quantity_price: { type: String , default: null}, sensor_type_total_price: { type: String , default: null}, @@ -416,6 +421,56 @@ const sensorquotationSchema = new mongoose.Schema({ qutation_total_price: { type: String, default: null }, }); + + + + +const orderSchema = new mongoose.Schema({ + customerId: { type: String }, + surveyId: { type: String, default: null }, + storeId: { type: String, default: null }, + installationId: { type: String, default: null }, + quatationId: { type: String, default: null }, + masters: { type: String }, + masters_quantity_price: { type: String }, + masters_total_price: { type: String }, + slaves: { type: String }, + sensors: { type: String }, + slaves_quantity_price: { type: String }, + slaves_total_price: { type: String }, + motor_switches: { type: String }, + motor_switches_quantity_price: { type: String }, + motor_switches_total_price: { type: String }, + quote_status: { type: String, default: null }, + quoted_amount: { type: String, default: null }, + comments: { type: String, default: null }, + datetime: { type: String, default: null }, + updated_at: { type: String, default: null }, + electricals: [ + { + type: { type: String, default: null }, + wire: { type: String, default: null }, + switch: { type: String, default: null }, + text: { type: String, default: null }, + available_quantity: { type: String, default: null }, + }, + ], + master_type_quantity_price: { type: String, default: null }, + master_available_quantity: { type: String, default: null }, + slave_available_quantity: { type: String, default: null }, + sensor_available_quantity: { type: String, default: null }, + master_type_total_price: { type: String, default: null }, + sensor_type_quantity_price: { type: String, default: null }, + sensor_type_total_price: { type: String, default: null }, + switch_type_quantity_price: { type: String, default: null }, + switch_type_total_price: { type: String, default: null }, + qutation_total_price: { type: String, default: null }, + status: { type: String, default: "pending" }, // Status field added +}); + + + + const hardwareCartSchema = new mongoose.Schema({ productId: { type: String}, productName: { type: String }, @@ -510,7 +565,9 @@ const salesSchema = new mongoose.Schema({ const Iotprice = mongoose.model('Iotprice', iotpriceSchema); const Insensors = mongoose.model('Insensors', insensorsSchema); - const Order = mongoose.model('Orders', orderSchema); + const Order = mongoose.model('Order', orderSchema); + const EstimationOrder = mongoose.model('EstimationOrder', estimationorderSchema); + const Store = mongoose.model("Store", storeSchema); const WaterLeverSensor = mongoose.model('WaterLeverSensor', waterLeverSensorInSchema); const ProfilePictureStore = mongoose.model('ProfilePictureStore', profilePictureStoreSchema); @@ -527,4 +584,4 @@ const Iotprice = mongoose.model('Iotprice', iotpriceSchema); - module.exports = {Order,Iotprice,Sales, Install,Survey, ProfilePictureInstall, SensorQuotation,generateinstallationId,Store,ProfilePictureStore,WaterLeverSensor,MotorSwitchSensor,Insensors,generatequatationId, HardwareCart, ServiceCart}; + module.exports = {Order,EstimationOrder,Iotprice,Sales, Install,Survey, ProfilePictureInstall, SensorQuotation,generateinstallationId,Store,ProfilePictureStore,WaterLeverSensor,MotorSwitchSensor,Insensors,generatequatationId, HardwareCart, ServiceCart}; diff --git a/src/routes/storeRoute.js b/src/routes/storeRoute.js index e788bcd1..791f26c2 100644 --- a/src/routes/storeRoute.js +++ b/src/routes/storeRoute.js @@ -1654,5 +1654,34 @@ fastify.post("/api/cart/installationService", { }, handler: storeController.addToCartService }); + + +fastify.post("/api/acceptquotation/:quotationId", { + schema: { + tags: ["Install"], + description: "Accepts a quotation and moves it to the Orders database", + summary: "Accepts a quotation", + params: { + type: "object", + properties: { + quotationId: { type: "string" }, + }, + }, + body: { + type: "object", + properties: { + action: { type: "string" }, + }, + required: ["action"], + }, + security: [ + { + basicAuth: [], + }, + ], + }, + // preHandler: fastify.auth([fastify.authenticate]), // Uncomment if authentication is needed + handler: storeController.acceptQuotation, +}); next(); }; From e66c69418e60a4d2257b9b111753961f52bc32b6 Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 4 Mar 2025 16:47:18 +0530 Subject: [PATCH 5/7] changes in accept quotation --- src/controllers/storeController.js | 49 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index 875f392d..0dc5fedf 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -2021,11 +2021,9 @@ exports.getOrdersByCustomer = async (req, reply) => { exports.acceptQuotation = async (req, reply) => { try { const { quotationId } = req.params; - const { action } = req.body; + let { action } = req.body; - if (action !== "accept") { - return reply.status(400).send({ error: "Invalid action" }); - } + action = action.toLowerCase(); // Convert action to lowercase // Find the quotation by ID const quotation = await SensorQuotation.findOne({ quatationId: quotationId }); @@ -2034,26 +2032,37 @@ exports.acceptQuotation = async (req, reply) => { return reply.status(404).send({ error: "Quotation not found" }); } - // Convert quotation to an order object - const newOrder = new Order({ - ...quotation.toObject(), // Copy all fields - status: "pending", // Set status to "pending" - }); + if (action === "reject") { + // Update status to "rejected" in SensorQuotation + await SensorQuotation.updateOne({ quatationId: quotationId }, { $set: { status: "rejected" } }); - // Save to the Orders collection - await newOrder.save(); + return reply.send({ + status_code: 200, + message: "Quotation rejected successfully", + }); + } else if (action === "accept") { + // Convert quotation to an order object + const newOrder = new Order({ + ...quotation.toObject(), // Copy all fields + status: "pending", // Set status to "pending" + }); - // Delete the record from SensorQuotation - await SensorQuotation.deleteOne({ quatationId: quotationId }); + // Save to the Orders collection + await newOrder.save(); - return reply.send({ - status_code: 200, - message: "Quotation accepted and moved to Orders", - data: newOrder, - }); + // Delete the record from SensorQuotation + await SensorQuotation.deleteOne({ quatationId: quotationId }); + return reply.send({ + status_code: 200, + message: "Quotation accepted and moved to Orders", + data: newOrder, + }); + } else { + return reply.status(400).send({ error: "Invalid action" }); + } } catch (err) { - console.error("Error accepting quotation:", err); + console.error("Error processing quotation:", err); return reply.status(500).send({ error: "Internal server error" }); } -}; \ No newline at end of file +}; From 8f76754911a9d4ea07d107e5b2f463f53df724b1 Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 4 Mar 2025 17:05:48 +0530 Subject: [PATCH 6/7] Added get for orders based on storeId --- src/controllers/storeController.js | 24 ++++++++++++++++++++++++ src/routes/storeRoute.js | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index 0dc5fedf..bcb33432 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -2066,3 +2066,27 @@ exports.acceptQuotation = async (req, reply) => { return reply.status(500).send({ error: "Internal server error" }); } }; + + +exports.getOrdersByStoreId = async (req, reply) => { + try { + const { storeId } = req.params; + + if (!storeId) { + return reply.status(400).send({ error: "storeId is required" }); + } + + // Fetch orders with the matching storeId + const orders = await Order.find({ storeId }); + + return reply.send({ + status_code: 200, + message: "Orders fetched successfully", + data: orders, + }); + } catch (err) { + console.error("Error fetching orders:", err); + return reply.status(500).send({ error: "Internal server error" }); + } +}; + diff --git a/src/routes/storeRoute.js b/src/routes/storeRoute.js index 791f26c2..93395ccb 100644 --- a/src/routes/storeRoute.js +++ b/src/routes/storeRoute.js @@ -1683,5 +1683,29 @@ fastify.post("/api/acceptquotation/:quotationId", { // preHandler: fastify.auth([fastify.authenticate]), // Uncomment if authentication is needed handler: storeController.acceptQuotation, }); + + +fastify.get("/api/ordersofstore/:storeId", { + schema: { + tags: ["Install"], + description: "Fetches orders based on storeId", + summary: "Get orders by storeId", + params: { + type: "object", + properties: { + storeId: { type: "string" }, + }, + required: ["storeId"], + }, + security: [ + { + basicAuth: [], + }, + ], + }, + handler: storeController.getOrdersByStoreId, +}); + + next(); }; From 7932e3027bfc18e70c69193cc60c634a87899a94 Mon Sep 17 00:00:00 2001 From: Varun Date: Tue, 4 Mar 2025 17:12:24 +0530 Subject: [PATCH 7/7] changes in accept quotatioin --- src/controllers/storeController.js | 7 ++++--- src/routes/storeRoute.js | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index bcb33432..9e440f0f 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -2021,7 +2021,7 @@ exports.getOrdersByCustomer = async (req, reply) => { exports.acceptQuotation = async (req, reply) => { try { const { quotationId } = req.params; - let { action } = req.body; + let { action, storeId } = req.body; action = action.toLowerCase(); // Convert action to lowercase @@ -2041,9 +2041,10 @@ exports.acceptQuotation = async (req, reply) => { message: "Quotation rejected successfully", }); } else if (action === "accept") { - // Convert quotation to an order object + // Convert quotation to an order object and include storeId const newOrder = new Order({ - ...quotation.toObject(), // Copy all fields + ...quotation.toObject(), // Copy all fields from quotation + storeId: storeId, // Ensure storeId is included status: "pending", // Set status to "pending" }); diff --git a/src/routes/storeRoute.js b/src/routes/storeRoute.js index 93395ccb..f034f0f6 100644 --- a/src/routes/storeRoute.js +++ b/src/routes/storeRoute.js @@ -1314,6 +1314,7 @@ fastify.post("/api/createquotationforSensor/:surveyId", { type: "object", properties: { customerId: { type: "string" }, + masters: { type: "string" }, slaves: { type: "string" }, sensors: { type: "string" }, @@ -1671,6 +1672,7 @@ fastify.post("/api/acceptquotation/:quotationId", { type: "object", properties: { action: { type: "string" }, + storeId: { type: "string" }, }, required: ["action"], },