diff --git a/src/controllers/userController.js b/src/controllers/userController.js index 6e6e79ec..18c9422f 100644 --- a/src/controllers/userController.js +++ b/src/controllers/userController.js @@ -1645,6 +1645,11 @@ exports.getuserRequestbookingsforplansforsupplier = async (req, reply) => { } }; + +// Assuming you have these models imported somewhere above: +// const RecurringRequestedBooking = require("..."); +// const Supplier = require("..."); + exports.getuserRequestbookingsforplansforcustomer = async (req, reply) => { try { const { customerId } = req.params; @@ -1656,27 +1661,71 @@ exports.getuserRequestbookingsforplansforcustomer = async (req, reply) => { }); } - // 1) Find all bookings that include this supplier - const bookings = await RecurringRequestedBooking.find({ - customerId: customerId, - }) + // 1) Get bookings + const bookings = await RecurringRequestedBooking.find({ customerId }) .sort({ createdAt: -1 }) .lean(); - // 2) For each booking, expose only this supplier's subdocument - + if (!bookings.length) { + return reply.send({ + status_code: 200, + message: `Orders for customer ${customerId} fetched successfully`, + data: [], + }); + } + + // 2) Collect unique supplierIds from requested_suppliers + const supplierIdSet = new Set(); + for (const b of bookings) { + const rs = Array.isArray(b.requested_suppliers) ? b.requested_suppliers : []; + for (const s of rs) { + if (s && typeof s.supplierId === "string" && s.supplierId.trim() && s.supplierId !== "string") { + supplierIdSet.add(s.supplierId.trim()); + } + } + } + const supplierIds = Array.from(supplierIdSet); + + // 3) Fetch suppliers and index by supplierId + const suppliers = supplierIds.length + ? await Supplier.find({ supplierId: { $in: supplierIds } }) + .select("-__v") // tweak projection as you like + .lean() + : []; + + const supplierById = new Map(); + for (const s of suppliers) { + // Key is Supplier.supplierId (string), not _id + supplierById.set(s.supplierId, s); + } + + // 4) Attach supplier details into each requested_suppliers entry + const data = bookings.map((b) => { + const rs = Array.isArray(b.requested_suppliers) ? b.requested_suppliers : []; + const enriched = rs.map((item) => ({ + ...item, + supplier: supplierById.get(item?.supplierId) || null, // attach or null if not found + })); + return { + ...b, + requested_suppliers: enriched, + }; + }); - return reply.send({ status_code: 200, message: `Orders for customer ${customerId} fetched successfully`, - data:bookings, + data, }); } catch (err) { console.error(err); throw boom.boomify(err); } }; + + + + const mongoose = require('mongoose'); @@ -1837,4 +1886,114 @@ exports.estimationsget = async (req, reply) => { } catch (err) { throw boom.boomify(err); } -}; \ No newline at end of file +}; + + + +exports.updatePaymentForBooking = async (req, reply) => { + try { + const { bookingid } = req.params; + const { payment_mode, payment_reference_number } = req.body; + + if (!bookingid) { + return reply.code(400).send({ + status_code: 400, + message: 'bookingid (param) is required', + }); + } + + if (typeof payment_mode === 'undefined' && typeof payment_reference_number === 'undefined') { + return reply.code(400).send({ + status_code: 400, + message: 'At least one of payment_mode or payment_reference_number must be provided in body', + }); + } + + const update = {}; + if (typeof payment_mode !== 'undefined') update.payment_mode = payment_mode; + if (typeof payment_reference_number !== 'undefined') update.payment_reference_number = payment_reference_number; + + const updated = await Tankerbooking.findOneAndUpdate( + { bookingid }, + { $set: update }, + { new: true, runValidators: true } + ).lean(); + + if (!updated) { + return reply.code(404).send({ + status_code: 404, + message: `No booking found with bookingid ${bookingid}`, + }); + } + + return reply.code(200).send({ + status_code: 200, + message: 'Payment info updated successfully', + data: updated, + }); + } catch (err) { + console.error('updatePaymentForBooking error:', err); + // keep using boom as you used earlier + throw boom.boomify(err); + } +}; + + +// controllers/recurringRequestedBookingController.js + +exports.updateQuotedAmountForSupplier = async (req, reply) => { + try { + const { _id } = req.params; + const { supplierId, amount } = req.body; + + if (!_id) { + return reply.code(400).send({ status_code: 400, message: '_id (param) is required' }); + } + if (!supplierId) { + return reply.code(400).send({ status_code: 400, message: 'supplierId (body) is required' }); + } + if (typeof amount === 'undefined' || amount === null || amount === '') { + return reply.code(400).send({ status_code: 400, message: 'amount (body) is required' }); + } + + // convert amount to number if possible + const numericAmount = Number(amount); + if (Number.isNaN(numericAmount)) { + return reply.code(400).send({ status_code: 400, message: 'amount must be a valid number' }); + } + + // Atomic update using positional $ operator + const filter = { _id, 'requested_suppliers.supplierId': supplierId }; + const update = { $set: { 'requested_suppliers.$.quoted_amount': numericAmount } }; + + const updated = await RequestedBooking.findOneAndUpdate(filter, update, { + new: true, + runValidators: true, + }).lean(); + + if (!updated) { + // either booking _id not found OR supplierId not found inside requested_suppliers + // let's check which one + const bookingExists = await RequestedBooking.findById(_id).lean(); + if (!bookingExists) { + return reply.code(404).send({ status_code: 404, message: `Booking with _id ${_id} not found` }); + } + + // booking exists but supplier entry missing + return reply.code(404).send({ + status_code: 404, + message: `Supplier ${supplierId} not found in requested_suppliers for booking ${_id}`, + }); + } + + return reply.code(200).send({ + status_code: 200, + message: `quoted_amount updated for supplier ${supplierId}`, + data: updated, + }); + } catch (err) { + console.error('updateQuotedAmountForSupplier error:', err); + throw boom.boomify(err); + } +}; + diff --git a/src/models/tankers.js b/src/models/tankers.js index ba2a14ef..3083d03b 100644 --- a/src/models/tankers.js +++ b/src/models/tankers.js @@ -62,6 +62,7 @@ const tankersbookingSchema = new mongoose.Schema({ distrubance_price: { type: String, default: "none" }, amount_difference: { type: String, default: "none" }, payment_mode: { type: String, default: null }, + payment_reference_number:{type: String, default: null}, remarks : { type: String, default: null }, customerPhone : { type: String, default: null }, supplierPhone : { type: String, default: null }, diff --git a/src/routes/usersRoute.js b/src/routes/usersRoute.js index 1f67cf6b..84039bb8 100644 --- a/src/routes/usersRoute.js +++ b/src/routes/usersRoute.js @@ -1326,5 +1326,91 @@ fastify.route({ }); +fastify.route({ + method: 'PUT', + url: '/api/bookings/:bookingid/payment', + schema: { + description: 'Update payment details for a tanker booking', + tags: ['User'], + summary: 'Update payment info', + params: { + type: 'object', + properties: { + bookingid: { type: 'string', description: 'Booking ID' } + }, + required: ['bookingid'] + }, + body: { + type: 'object', + properties: { + payment_mode: { type: 'string', description: 'Payment mode (e.g., UPI, cash, card)' }, + payment_reference_number: { type: 'string', description: 'Reference/transaction ID from gateway' } + }, + // at least one should be provided — validated in controller + additionalProperties: false + }, + response: { + 200: { + type: 'object', + properties: { + status_code: { type: 'integer' }, + message: { type: 'string' }, + data: { type: 'object' } + } + }, + 400: { type: 'object' }, + 404: { type: 'object' } + }, + security: [ + { + basicAuth: [] + } + ] + }, + // preHandler: fastify.auth([fastify.authenticate]), // enable auth if needed + handler: userController.updatePaymentForBooking + }); + + fastify.route({ + method: 'PUT', + url: '/api/request-booking/:_id/supplier/quote', + schema: { + description: + 'Update quoted_amount for a supplier inside requested_suppliers for a requested booking', + tags: ['User'], + summary: 'Update supplier quoted amount by User', + params: { + type: 'object', + properties: { + _id: { type: 'string', description: 'Booking _id' }, + }, + required: ['_id'], + }, + body: { + type: 'object', + properties: { + supplierId: { type: 'string', description: 'Supplier ID' }, + amount: { type: ['number', 'string'], description: 'Quoted amount (number)' }, + }, + required: ['supplierId', 'amount'], + additionalProperties: false, + }, + response: { + 200: { + type: 'object', + }, + 400: { type: 'object' }, + 404: { type: 'object' }, + }, + security: [ + { + basicAuth: [], + }, + ], + }, + // preHandler: fastify.auth([fastify.authenticate]), // enable if needed + handler: userController.updateQuotedAmountForSupplier, + }); + next(); };