|
|
@ -654,6 +654,110 @@ exports.assignTeamMemberToQuotation = async (request, reply) => {
|
|
|
|
// );
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return reply.send({
|
|
|
|
|
|
|
|
// simplydata: {
|
|
|
|
|
|
|
|
// error: false,
|
|
|
|
|
|
|
|
// message: "Active quotations fetched successfully",
|
|
|
|
|
|
|
|
// quotations: enrichedQuotations,
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// } catch (err) {
|
|
|
|
|
|
|
|
// console.error("Error fetching quotations:", err);
|
|
|
|
|
|
|
|
// return reply.status(500).send({
|
|
|
|
|
|
|
|
// simplydata: {
|
|
|
|
|
|
|
|
// error: true,
|
|
|
|
|
|
|
|
// message: "Internal server error",
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// exports.getQuotationsByInstallationAndTeamMember = async (request, reply) => {
|
|
|
|
|
|
|
|
// try {
|
|
|
|
|
|
|
|
// const { installationId, teamMemberId } = request.params;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (!installationId || !teamMemberId) {
|
|
|
|
|
|
|
|
// return reply.status(400).send({
|
|
|
|
|
|
|
|
// simplydata: {
|
|
|
|
|
|
|
|
// error: true,
|
|
|
|
|
|
|
|
// message: "Both installationId and teamMemberId are required",
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 🔹 Find quotations matching installationId and assignedTeamMembers
|
|
|
|
|
|
|
|
// let quotations = await Order.find({
|
|
|
|
|
|
|
|
// installationId,
|
|
|
|
|
|
|
|
// assignedTeamMembers: teamMemberId,
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (!quotations || quotations.length === 0) {
|
|
|
|
|
|
|
|
// return reply.status(404).send({
|
|
|
|
|
|
|
|
// simplydata: {
|
|
|
|
|
|
|
|
// error: true,
|
|
|
|
|
|
|
|
// message: "No quotations found for this installation and team member",
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // ✅ Step 1: update master_connections where work_status is missing to 'active'
|
|
|
|
|
|
|
|
// for (const order of quotations) {
|
|
|
|
|
|
|
|
// let updated = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (Array.isArray(order.master_connections)) {
|
|
|
|
|
|
|
|
// for (const mc of order.master_connections) {
|
|
|
|
|
|
|
|
// if (!mc.work_status) {
|
|
|
|
|
|
|
|
// mc.work_status = 'active';
|
|
|
|
|
|
|
|
// updated = true;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (updated) {
|
|
|
|
|
|
|
|
// await order.save();
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Re-fetch quotations as lean after update
|
|
|
|
|
|
|
|
// quotations = await Order.find({
|
|
|
|
|
|
|
|
// installationId,
|
|
|
|
|
|
|
|
// assignedTeamMembers: teamMemberId,
|
|
|
|
|
|
|
|
// }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // ✅ Filter: keep only quotations where at least one master_connections.work_status === 'active'
|
|
|
|
|
|
|
|
// quotations = quotations.filter(q =>
|
|
|
|
|
|
|
|
// Array.isArray(q.master_connections) &&
|
|
|
|
|
|
|
|
// q.master_connections.some(mc => mc.work_status === 'active')
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // If no quotations left after filtering, return empty list
|
|
|
|
|
|
|
|
// if (!quotations.length) {
|
|
|
|
|
|
|
|
// return reply.send({
|
|
|
|
|
|
|
|
// simplydata: {
|
|
|
|
|
|
|
|
// error: false,
|
|
|
|
|
|
|
|
// message: "No active quotations found for this installation and team member",
|
|
|
|
|
|
|
|
// quotations: [],
|
|
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 🔹 Enrich each quotation with customer details & keep only active master_connections
|
|
|
|
|
|
|
|
// const enrichedQuotations = await Promise.all(
|
|
|
|
|
|
|
|
// quotations.map(async (quotation) => {
|
|
|
|
|
|
|
|
// const customer = await User.findOne({ customerId: quotation.customerId }).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const activeMasters = quotation.master_connections?.filter(mc =>
|
|
|
|
|
|
|
|
// mc.work_status === 'active'
|
|
|
|
|
|
|
|
// ) || [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return {
|
|
|
|
|
|
|
|
// ...quotation,
|
|
|
|
|
|
|
|
// master_connections: activeMasters,
|
|
|
|
|
|
|
|
// customer: customer || null,
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
// return reply.send({
|
|
|
|
// return reply.send({
|
|
|
|
// simplydata: {
|
|
|
|
// simplydata: {
|
|
|
|
// error: false,
|
|
|
|
// error: false,
|
|
|
@ -750,10 +854,15 @@ exports.getQuotationsByInstallationAndTeamMember = async (request, reply) => {
|
|
|
|
mc.work_status === 'active'
|
|
|
|
mc.work_status === 'active'
|
|
|
|
) || [];
|
|
|
|
) || [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 🔹 Take work_status of the first active master (if exists)
|
|
|
|
|
|
|
|
const work_status = activeMasters.length > 0 ? activeMasters[0].work_status : null;
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
...quotation,
|
|
|
|
...quotation,
|
|
|
|
|
|
|
|
work_status,
|
|
|
|
master_connections: activeMasters,
|
|
|
|
master_connections: activeMasters,
|
|
|
|
customer: customer || null,
|
|
|
|
customer: customer || null,
|
|
|
|
|
|
|
|
// ✅ add work_status field outside master_connections
|
|
|
|
};
|
|
|
|
};
|
|
|
|
})
|
|
|
|
})
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -777,7 +886,6 @@ exports.getQuotationsByInstallationAndTeamMember = async (request, reply) => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.getDepartmentByFirstName = async (req, reply) => {
|
|
|
|
exports.getDepartmentByFirstName = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
let { firstName } = req.params;
|
|
|
|
let { firstName } = req.params;
|
|
|
@ -3748,12 +3856,27 @@ exports.getMasterWithSlaves = async (req, reply) => {
|
|
|
|
...master,
|
|
|
|
...master,
|
|
|
|
masterName,
|
|
|
|
masterName,
|
|
|
|
location,
|
|
|
|
location,
|
|
|
|
hardwareId: master.hardwareId // keep hardwareId here explicitly if needed
|
|
|
|
hardwareId: master.hardwareId
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 👉 Find slaves connected to this master
|
|
|
|
|
|
|
|
const slaves = await Insensors.find({
|
|
|
|
|
|
|
|
customerId,
|
|
|
|
|
|
|
|
connected_to: hardwareId,
|
|
|
|
|
|
|
|
type: 'slave'
|
|
|
|
|
|
|
|
}).lean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add masterName & location to each slave
|
|
|
|
|
|
|
|
const enrichedSlaves = slaves.map(slave => ({
|
|
|
|
|
|
|
|
...slave,
|
|
|
|
|
|
|
|
masterName,
|
|
|
|
|
|
|
|
location
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
return reply.send({
|
|
|
|
return reply.send({
|
|
|
|
success: true,
|
|
|
|
success: true,
|
|
|
|
master: enrichedMaster
|
|
|
|
master: enrichedMaster,
|
|
|
|
|
|
|
|
slaves: enrichedSlaves
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
@ -3763,6 +3886,7 @@ exports.getMasterWithSlaves = async (req, reply) => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.getPendingMasterSlaveSummary = async (req, reply) => {
|
|
|
|
exports.getPendingMasterSlaveSummary = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const { customerId } = req.params;
|
|
|
|
const { customerId } = req.params;
|
|
|
|