ashok 3 months ago
commit a2e6c130ae

@ -2830,10 +2830,13 @@ exports.getPendingOrdersByInstallationAndTeamMember = async (req, reply) => {
// Keep only master_connections with work_status === 'pending'
const pendingMasters = order.master_connections.filter(mc => mc.work_status === 'pending');
const pendingWorkStatuses = pendingMasters.map(mc => mc.work_status);
return {
...order.toObject(),
master_connections: pendingMasters,
customer: customer || null,
work_status: pendingMasters.length > 0 ? pendingMasters[0].work_status : null,
customer: customer || null,
allocated_sensors: allocatedSensors,
};
})

@ -1138,18 +1138,131 @@ fastify.post("/api/uploads-material-recieved/:customerId/:installationId", async
});
// fastify.post("/api/installLogin", {
// schema: {
// description: "This is for Login Install",
// tags: ["Installation"],
// summary: "This is for Login Install",
// body: {
// type: "object",
// required: ["type", "phone", "password"],
// properties: {
// type: { type: "string", description: "User role type (e.g., 'admin', 'manager')" },
// phone: { type: "string", description: "Registered phone number" },
// password: { type: "string", description: "Password for authentication" },
// },
// },
// },
// async handler(req, reply) {
// try {
// const { type, phone, password } = req.body;
// // Check if user exists in the Department Schema
// const user = await Deparments.findOne({ phone });
// if (!user) {
// return reply.code(400).send({ message: "User not found" });
// }
// // Verify Password
// const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
// if (!isMatch) {
// return reply.code(400).send({ message: "Invalid credentials" });
// }
// // Check if department details already exist in installation schema
// let installation = await Install.findOne({ phone });
// if (!installation) {
// // Create a new entry in installation schema with departmentId as installationId
// installation = new Install({
// phone: user.phone,
// installationId: user.departmentId, // Store departmentId in installationId
// firstName: user.firstName,
// lastName: user.lastName,
// email: user.email,
// alternativeNumber: user.alternativeContactNumber,
// departmentName: user.departmentName,
// designation: user.desginationName,
// reportingManager: user.reportingManager,
// city: user.city,
// zone: user.zone,
// address1: user.address1,
// address2: user.address2,
// profile: {
// state: user.state,
// country: user.country,
// role: type, // Store type in profile.role
// },
// });
// await installation.save();
// }
// // Ensure `type` is stored in `profile.role`
// if (!installation.profile?.role) {
// installation.profile.role = type;
// await installation.save(); // Save the updated type
// }
// // Fetch profile picture if available
// const profilePicture = await ProfilePictureInstall.findOne({ customerId: installation._id });
// // Generate JWT Token
// const token = fastify.jwt.sign(
// { userId: user._id, phone: user.phone, role: installation.profile?.role },
// "your_secret_key",
// { expiresIn: "7d" }
// );
// // Construct response payload
// const responsePayload = {
// simplydata: {
// error: false,
// apiversion: fastify.config.APIVERSION,
// access_token: token,
// email: installation.emails || [],
// installationId: installation.installationId,
// phone: installation.phone,
// address1: installation.address1,
// address2: installation.address2,
// phoneVerified: installation.phoneVerified,
// oneTimePasswordSetFlag: installation.oneTimePasswordSetFlag,
// type: installation.profile?.role || "user", // Default to "user" if not available
// fcmIds: installation.fcmId || null,
// team: installation.team,
// city: installation.city,
// manager: installation.manager,
// firstName: installation.firstName,
// lastName: installation.lastName,
// address: installation.address || "",
// alternativeNumber: installation.alternativeNumber || null,
// profilePicture: profilePicture ? profilePicture.pictureUrl : null, // Include profile picture URL if available
// },
// };
// return reply.send(responsePayload);
// } catch (error) {
// console.error("Login Error:", error);
// return reply.code(500).send({ message: "Internal server error" });
// }
// },
// });
fastify.post("/api/installLogin", {
schema: {
description: "This is for Login Install",
description: "Login as Installation Manager",
tags: ["Installation"],
summary: "This is for Login Install",
summary: "Installation Manager login",
body: {
type: "object",
required: ["type", "phone", "password"],
properties: {
type: { type: "string", description: "User role type (e.g., 'admin', 'manager')" },
type: { type: "string", enum: ["Installation_Manager"], description: "Login type" },
phone: { type: "string", description: "Registered phone number" },
password: { type: "string", description: "Password for authentication" },
password: { type: "string", description: "Password" },
},
},
},
@ -1157,28 +1270,24 @@ fastify.post("/api/installLogin", {
try {
const { type, phone, password } = req.body;
// Check if user exists in the Department Schema
const user = await Deparments.findOne({ phone });
// Find department record
const user = await Deparments.findOne({ phone }).lean();
if (!user) {
return reply.code(400).send({ message: "User not found" });
}
// Verify Password
// Validate password
const isMatch = await bcrypt.compare(password, user.services.password.bcrypt);
if (!isMatch) {
return reply.code(400).send({ message: "Invalid credentials" });
return reply.code(401).send({ message: "Invalid credentials" });
}
// Check if department details already exist in installation schema
// Find or create installation document
let installation = await Install.findOne({ phone });
if (!installation) {
// Create a new entry in installation schema with departmentId as installationId
installation = new Install({
phone: user.phone,
installationId: user.departmentId, // Store departmentId in installationId
phone,
installationId: user.departmentId,
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
@ -1193,194 +1302,269 @@ fastify.post("/api/installLogin", {
profile: {
state: user.state,
country: user.country,
role: type, // Store type in profile.role
role: type, // store login type
},
});
await installation.save();
}
// Ensure `type` is stored in `profile.role`
if (!installation.profile?.role) {
} else if (!installation.profile?.role) {
installation.profile.role = type;
await installation.save(); // Save the updated type
await installation.save();
}
// Fetch profile picture if available
const profilePicture = await ProfilePictureInstall.findOne({ customerId: installation._id });
// Generate JWT Token
// Generate JWT
const token = fastify.jwt.sign(
{ userId: user._id, phone: user.phone, role: installation.profile?.role },
"your_secret_key",
{ userId: user._id, phone, role: type },
"your_secret_key", // replace with config
{ expiresIn: "7d" }
);
// Construct response payload
const responsePayload = {
simplydata: {
error: false,
apiversion: fastify.config.APIVERSION,
return reply.send({
success: true,
message: "Login successful",
data: {
access_token: token,
email: installation.emails || [],
installationId: installation.installationId,
phone: installation.phone,
address1: installation.address1,
address2: installation.address2,
phoneVerified: installation.phoneVerified,
oneTimePasswordSetFlag: installation.oneTimePasswordSetFlag,
type: installation.profile?.role || "user", // Default to "user" if not available
fcmIds: installation.fcmId || null,
team: installation.team,
city: installation.city,
manager: installation.manager,
firstName: installation.firstName,
lastName: installation.lastName,
address: installation.address || "",
alternativeNumber: installation.alternativeNumber || null,
profilePicture: profilePicture ? profilePicture.pictureUrl : null, // Include profile picture URL if available
city: installation.city,
email: installation.emails?.map(e => e.email) || [],
type: installation.profile?.role || type,
team: installation.team,
manager: installation.manager,
fcmId: installation.fcmId,
alternativeNumber: installation.alternativeNumber,
phoneVerified: installation.phoneVerified,
},
};
return reply.send(responsePayload);
} catch (error) {
console.error("Login Error:", error);
return reply.code(500).send({ message: "Internal server error" });
});
} catch (err) {
console.error("installLogin error:", err);
reply.code(500).send({ message: "Internal server error" });
}
},
}
});
// fastify.post("/api/teamMemberLogin", {
// schema: {
// description: "Login API for team members",
// tags: ["Installation"],
// summary: "Login as a Team Member",
// body: {
// type: "object",
// required: ["type", "phone", "password"],
// properties: {
// type: { type: "string", description: "Role type of the user (e.g., 'team_member')" },
// phone: { type: "string", description: "Registered phone number of the team member" },
// password: { type: "string", description: "Password for authentication" },
// },
// },
// },
// async handler(request, reply) {
// try {
// const { type, phone, password } = request.body;
// // ✅ Step 1: Find the team member in `Deparments`
// const department = await Deparments.findOne({
// "team_member.team_member.phone": phone
// });
// if (!department) {
// return reply.status(401).send({
// simplydata: {
// error: true,
// message: "Invalid phone number",
// },
// });
// }
// // ✅ Step 2: Find the specific team member
// const teamMember = department.team_member.team_member.find(
// (member) => member.phone === phone
// );
// if (!teamMember) {
// return reply.status(401).send({
// simplydata: {
// error: true,
// message: "Invalid phone number",
// },
// });
// }
// // ✅ Step 3: Verify password
// const isPasswordValid = await bcrypt.compare(password, teamMember.password);
// if (!isPasswordValid) {
// return reply.status(401).send({
// simplydata: {
// error: true,
// message: "Invalid phone number or password",
// },
// });
// }
// console.log("Team Member First Name:", teamMember.firstName); // ✅ Debugging
// // ✅ Step 4: Check if this team member already exists in `Install`
// let installation = await Install.findOne({
// installationId: department.departmentId
// });
// if (!installation) {
// return reply.status(404).send({
// simplydata: {
// error: true,
// message: "Installation not found",
// },
// });
// }
// // Check if team member already exists in Install schema
// const existingTeamMember = installation.team_member.team_member.find(
// (member) => member.phone === phone
// );
// if (!existingTeamMember) {
// // ✅ Step 5: Add team member details to `Install` schema
// installation.team_member.team_member.push({
// teamMemberId: teamMember.teamMemberId,
// firstName: teamMember.firstName,
// phone: teamMember.phone,
// email: teamMember.email,
// alternativePhone: teamMember.alternativePhone,
// installationTeamMemId: installation.installationId,
// password: teamMember.password, // Store hashed password
// status: teamMember.status || "active",
// type: type, // Store login type
// });
// await installation.save();
// }
// // ✅ Step 6: Generate JWT token
// const token = fastify.jwt.sign(
// { phone: teamMember.phone, role: type, installationId: installation.installationId },
// "JWT_SECRET",
// { expiresIn: "1h" }
// );
// return reply.send({
// simplydata: {
// error: false,
// message: "Login successful",
// access_token: token,
// phone: teamMember.phone,
// firstName: teamMember.firstName || null, // ✅ Now included
// teamMemberId: teamMember.teamMemberId,
// alternativePhone: teamMember.alternativePhone || null,
// email: teamMember.email || null,
// status: teamMember.status || "active",
// type: teamMember.type,
// installationId: installation.installationId
// },
// });
// } catch (err) {
// console.error("Error logging in:", err);
// reply.status(500).send({
// simplydata: {
// error: true,
// message: "Internal server error",
// },
// });
// }
// },
// });
fastify.post("/api/teamMemberLogin", {
schema: {
description: "Login API for team members",
description: "Login as Installation Team Member",
tags: ["Installation"],
summary: "Login as a Team Member",
summary: "Team member login",
body: {
type: "object",
required: ["type", "phone", "password"],
properties: {
type: { type: "string", description: "Role type of the user (e.g., 'team_member')" },
phone: { type: "string", description: "Registered phone number of the team member" },
password: { type: "string", description: "Password for authentication" },
type: { type: "string", enum: ["Installation_TeamMember"], description: "Login type" },
phone: { type: "string", description: "Team member phone" },
password: { type: "string", description: "Password" },
},
},
},
async handler(request, reply) {
async handler(req, reply) {
try {
const { type, phone, password } = request.body;
// ✅ Step 1: Find the team member in `Deparments`
const department = await Deparments.findOne({
"team_member.team_member.phone": phone
});
const { type, phone, password } = req.body;
// Find department with this team member phone
const department = await Deparments.findOne({ "team_member.team_member.phone": phone }).lean();
if (!department) {
return reply.status(401).send({
simplydata: {
error: true,
message: "Invalid phone number",
},
});
return reply.code(401).send({ message: "Invalid phone number" });
}
// ✅ Step 2: Find the specific team member
const teamMember = department.team_member.team_member.find(
(member) => member.phone === phone
);
// Find the actual team member
const teamMember = department.team_member.team_member.find(m => m.phone === phone);
if (!teamMember) {
return reply.status(401).send({
simplydata: {
error: true,
message: "Invalid phone number",
},
});
return reply.code(401).send({ message: "Invalid phone number" });
}
// ✅ Step 3: Verify password
const isPasswordValid = await bcrypt.compare(password, teamMember.password);
if (!isPasswordValid) {
return reply.status(401).send({
simplydata: {
error: true,
message: "Invalid phone number or password",
},
});
// Validate password
const isMatch = await bcrypt.compare(password, teamMember.password);
if (!isMatch) {
return reply.code(401).send({ message: "Invalid credentials" });
}
console.log("Team Member First Name:", teamMember.firstName); // ✅ Debugging
// ✅ Step 4: Check if this team member already exists in `Install`
let installation = await Install.findOne({
installationId: department.departmentId
});
// Find install document
const installation = await Install.findOne({ installationId: department.departmentId });
if (!installation) {
return reply.status(404).send({
simplydata: {
error: true,
message: "Installation not found",
},
});
return reply.code(404).send({ message: "Installation not found" });
}
// Check if team member already exists in Install schema
const existingTeamMember = installation.team_member.team_member.find(
(member) => member.phone === phone
);
if (!existingTeamMember) {
// ✅ Step 5: Add team member details to `Install` schema
// Add team member to install if missing
const alreadyExists = installation.team_member?.team_member?.some(m => m.phone === phone);
if (!alreadyExists) {
installation.team_member.team_member.push({
teamMemberId: teamMember.teamMemberId,
firstName: teamMember.firstName,
phone: teamMember.phone,
email: teamMember.email,
alternativePhone: teamMember.alternativePhone,
installationTeamMemId: installation.installationId,
password: teamMember.password, // Store hashed password
password: teamMember.password,
status: teamMember.status || "active",
type: type, // Store login type
email: teamMember.email,
alternativePhone: teamMember.alternativePhone,
type
});
await installation.save();
}
// ✅ Step 6: Generate JWT token
// Generate JWT
const token = fastify.jwt.sign(
{ phone: teamMember.phone, role: type, installationId: installation.installationId },
"JWT_SECRET",
{ phone, role: type, installationId: installation.installationId },
"your_secret_key", // replace with config
{ expiresIn: "1h" }
);
return reply.send({
simplydata: {
error: false,
message: "Login successful",
success: true,
message: "Login successful",
data: {
access_token: token,
phone: teamMember.phone,
firstName: teamMember.firstName || null, // ✅ Now included
firstName: teamMember.firstName,
teamMemberId: teamMember.teamMemberId,
alternativePhone: teamMember.alternativePhone || null,
email: teamMember.email || null,
alternativePhone: teamMember.alternativePhone,
email: teamMember.email,
status: teamMember.status || "active",
type: teamMember.type,
type,
installationId: installation.installationId
},
}
});
} catch (err) {
console.error("Error logging in:", err);
reply.status(500).send({
simplydata: {
error: true,
message: "Internal server error",
},
});
console.error("teamMemberLogin error:", err);
reply.code(500).send({ message: "Internal server error" });
}
},
}
});

@ -24,75 +24,145 @@ const generateinstallationId = async () => {
return result.seq;
};
const installationschema = new mongoose.Schema({
// name: { type: String },
phone: { type: String, unique: true, trim: true },
address: String,
installationId: { type: String },
phoneVerified: { type: Boolean, default: false },
phoneVerificationCode: { type: Number, default: 11111 },
passwordResetCode: { type: Number},
oneTimePasswordSetFlag: { type: Boolean, default: false },
emails: [{ email: String, verified: { type: Boolean, default: false } }],
services: { password: { bcrypt: String } },
alternativeNumber: { type: String, default: null },
firstName: { type: String, default: null },
lastName: { type: String, default: null },
address1: { type: String, default: null },
address2: { type: String, default: null },
city: { type: String, default: null },
designation: { type: String, default: null },
reportingManager: { type: String, default: null },
departmentName: { type: String, default: null },
zone: { type: String, default: null },
type: { type: String },
// const installationschema = new mongoose.Schema({
// // name: { type: String },
// phone: { type: String, unique: true, trim: true },
// address: String,
// installationId: { type: String },
// phoneVerified: { type: Boolean, default: false },
// phoneVerificationCode: { type: Number, default: 11111 },
// passwordResetCode: { type: Number},
// oneTimePasswordSetFlag: { type: Boolean, default: false },
// emails: [{ email: String, verified: { type: Boolean, default: false } }],
// services: { password: { bcrypt: String } },
// alternativeNumber: { type: String, default: null },
// firstName: { type: String, default: null },
// lastName: { type: String, default: null },
// address1: { type: String, default: null },
// address2: { type: String, default: null },
// city: { type: String, default: null },
// designation: { type: String, default: null },
// reportingManager: { type: String, default: null },
// departmentName: { type: String, default: null },
// zone: { type: String, default: null },
// type: { type: String },
// profile: {
// state: { type: String, default: null },
// country: { type: String, default: null },
// },
// team : { type: String, default: null},
// manager : { type: String, default: null},
// team_member: {
// team_member: [
// {
// teamMemberId: { type: String },
// firstName: { type: String },
// phone: { type: String },
// installationTeamMemId: { type: String },
// password: { type: String, default: null },
// status: { type: String, default: "active" },
// email: { type: String },
// alternativePhone: { type: String },
// }
// ],
// },
// longitude: { type : Number,default: 0.0},
// latitude: {type: Number,default: 0.0},
// fcmId: { type: String, default: null },
// createdAt: {
// type: Date,
// default: function () {
// return Date.now();
// },
// },
// createdBy: ObjectId,
// updatedAt: {
// type: Date,
// default: function () {
// return Date.now();
// },
// },
// updatedBy: ObjectId,
// });
profile: {
state: { type: String, default: null },
country: { type: String, default: null },
const installationschema = new mongoose.Schema({
phone: { type: String, unique: true, trim: true },
address: { type: String, default: null },
installationId: { type: String },
phoneVerified: { type: Boolean, default: false },
phoneVerificationCode: { type: Number, default: 11111 },
passwordResetCode: { type: Number, default: null },
oneTimePasswordSetFlag: { type: Boolean, default: false },
emails: [
{
email: { type: String },
verified: { type: Boolean, default: false },
},
team : { type: String, default: null},
manager : { type: String, default: null},
team_member: {
],
services: {
password: { bcrypt: { type: String, default: null } },
},
alternativeNumber: { type: String, default: null },
firstName: { type: String, default: null },
lastName: { type: String, default: null },
address1: { type: String, default: null },
address2: { type: String, default: null },
city: { type: String, default: null },
designation: { type: String, default: null },
reportingManager: { type: String, default: null },
departmentName: { type: String, default: null },
zone: { type: String, default: null },
// Store main user type (e.g., Installation_Manager, Installation_TeamMember)
type: { type: String, default: null },
profile: {
state: { type: String, default: null },
country: { type: String, default: null },
role: { type: String, default: null }, // <-- good to keep as per your login flow
},
team: { type: String, default: null },
manager: { type: String, default: null },
team_member: {
team_member: [
{
teamMemberId: { type: String },
firstName: { type: String },
firstName: { type: String, default: null },
phone: { type: String },
installationTeamMemId: { type: String },
password: { type: String, default: null },
status: { type: String, default: "active" },
email: { type: String },
alternativePhone: { type: String },
}
email: { type: String, default: null },
alternativePhone: { type: String, default: null },
type: { type: String, default: "Installation_TeamMember" }, // good to keep for clarity
},
],
},
longitude: { type : Number,default: 0.0},
latitude: {type: Number,default: 0.0},
longitude: { type: Number, default: 0.0 },
latitude: { type: Number, default: 0.0 },
fcmId: { type: String, default: null },
createdAt: {
type: Date,
default: function () {
return Date.now();
},
},
createdBy: ObjectId,
updatedAt: {
type: Date,
default: function () {
return Date.now();
},
},
updatedBy: ObjectId,
fcmId: { type: String, default: null },
});
createdAt: { type: Date, default: Date.now },
createdBy: { type: ObjectId, default: null },
updatedAt: { type: Date, default: Date.now },
updatedBy: { type: ObjectId, default: null },
});
const surveyschema = new mongoose.Schema({

Loading…
Cancel
Save