UNPKG

@ionaai/rtnapi

Version:

common api collection for RTN

1,306 lines (1,160 loc) 69.8 kB
'use strict'; var _ = require("underscore"); var lodash = require("lodash-node"); var moment = require('moment'); var path = require('path') var Cache = require('memory-cache'); var request = require('request'); var DBModel = require('@ionaai/rtndbmodel'); var SMSLog = DBModel.smsLog; var LifeCycle = DBModel.applicationLifeCycle; var MailLog = DBModel.mailLog; var User = DBModel.user; var fs = require('fs'); var Interviews = DBModel.interviews; var Job = DBModel.job; var AppliedJobData = DBModel.appliedJobData; var mongoose = require("mongoose"); var ejs = require('ejs'); var stageDetail = require("./stageDetails.json"); var stageFunnelMap = require("./stageFunnelMap.json"); var exotel = require('./exotel'); var Match = require('./match'); var PrepServices = require('./prepservices'); function generateUUID() { var d = new Date().getTime(); var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); }); return uuid; } var count = function (ary, classifier) { return ary.reduce(function (counter, item) { var p = (classifier || String)(item); counter[p] = counter.hasOwnProperty(p) ? counter[p] + 1 : 1; return counter; }, {}) } var searchJobsByUser = function (Job, params, colString, next) { Date.prototype.toLocaleDateString = function (d) { var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" ]; return (d.getDate() + "-" + monthNames[d.getMonth()] + "-" + (d.getYear() - 100)); }; var query = Job.find(); if (params.industry) { query.in('industry', params.industry); } if (params.sector) { query.in('sector', params.sector); } if (params.function) { query.in('function', params.function); } Job.find(query).exec(function (err, jobs) { if (!err) { var data = _.map(jobs, function (item) { return { id: item.id, name: item.name, cutOffText: item.cutOffText, eligibility: item.eligibility, eligibilityTags: item.eligibilityTags, salaryRange: item.salaryRange, minSalary: item.minSalary, excitingStuff: item.excitingStuff, employer: item.employer, workLocation: _.pluck(item.workLocation, "area").join(" ,"), logoUrl: item.logoUrl, urlSlug: item.urlSlug, hotJobFactor: item.hotJobFactor, incentiveAvailable: item.incentiveAvailable, gender: item.gender, badges: item.badges, localCandidateOnly: item.localCandidateOnly }; }); next(null, data); } else { next(err, 'Something went wrong while executing query.'); } }) }; var similarJobsByJobName = function (Job, params, next) { Date.prototype.toLocaleDateString = function (d) { var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" ]; return (d.getDate() + "-" + monthNames[d.getMonth()] + "-" + (d.getYear() - 100)); }; var query = Job.find(); query.ne("_id", params.id); var queryArray = []; if (params.state) { query.elemMatch("workLocation", { state: params.state }); } if (params.function) { queryArray.push({ function: params.function }); } if (params.roleName) { queryArray.push({ roleName: params.roleName }); } if (params.titleName) { queryArray.push({ titleName: params.titleName }); } query.where({ 'isApplicable': true, 'applicationType': 'application' }); query.or(queryArray); Job.find(query).limit(3).exec(function (err, jobs) { console.log("Found Jobs " + (jobs ? jobs.length : 0)); if (!err && jobs) { var data = _.map(jobs, function (item) { return { id: item.id, name: item.name, cutOffText: item.cutOffText, eligibility: item.eligibility, eligibilityTags: item.eligibilityTags, salaryRange: item.salaryRange, minSalary: item.minSalary, excitingStuff: item.excitingStuff, orgDisplayName: item.orgDisplayName, workLocation: _.pluck(item.workLocation, "area").join(" ,"), logoUrl: item.logoUrl, urlSlug: item.urlSlug, hotJobFactor: item.hotJobFactor, incentiveAvailable: item.incentiveAvailable, gender: item.gender, badges: item.badges, localCandidateOnly: item.localCandidateOnly }; }); next(null, data); } else if (!jobs) { next(null, jobs); } else { console.log(err); next(err, 'Something went wrong while executing query.'); } }) }; var searchUsersByJobParams = function (AppliedJobData, params, next) { Date.prototype.toLocaleDateString = function (d) { var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" ]; return (d.getDate() + "-" + monthNames[d.getMonth()] + "-" + (d.getYear() - 100)); }; var query = AppliedJobData.find({ isMasterApplication: true }); if (params.degreeTypes) { query.in('educationInfo.degreeType', params.degreeTypes); } if (params.fresherFlag) { if (params.fresherFlag == "yes") { query.where('isFresher').eq(true); } else { query.where('isFresher').eq(false); } } if (params.notDegreeTypes) { query.nin('educationInfo.degreeType', params.notDegreeTypes); } if (params.degrees) { query.in('educationInfo.degree', params.degrees); } if (params.cities) { var receivedCities = []; for (var i = 0; i < params.cities.length; i++) { if (receivedCities.indexOf(params.cities[i].city) === -1) { receivedCities.push(params.cities[i].city) } } query.in('location.city', receivedCities); } if (params.states) { query.in('location.state', params.states); } if (params.mobiles) { query.in('mobile', params.mobiles); } if (params.emails) { query.in('email', params.emails); } if (params.names) { query.in('seeker_profile.first_name', params.names); } if (params.appliedJobs) { query.in('appliedJobs.jobId', params.appliedJobs); } if (params.assessments) { query.in('assessments.quizTypeName', params.assessments); } if (params.creationDateStart) { var dateString = params.creationDateStart; var cutoff = new Date(dateString); var cutOffNext = cutoff; if (params.creationDateEnd) { dateString = params.creationDateEnd; var cutoff2 = new Date(dateString); cutOffNext = cutoff2; } query.where('creationDate').gt(cutoff).lt(cutOffNext); } AppliedJobData.find(query, 'email isFresher mobile enrolledCourses assessments applicationDate educationInfo userId seeker_profile.first_name seeker_profile.last_name location').exec(function (err, users) { console.log("Found Users " + users.length); if (!err) { var data = _.map(users, function (item) { return { id: item.userId, name: item.seeker_profile.first_name + ' ' + (item.seeker_profile.last_name ? item.seeker_profile.last_name : ''), email: item.email, phone: item.mobile, addressLine1: item.location ? item.location.addressLine1 : '', addressLine2: item.location ? item.location.addressLine2 : '', state: item.location ? item.location.state : '', addressCity: item.location ? item.location.city : '', educationInfo: item.educationInfo ? _.map(item.educationInfo, function (i) { return i.degreeType; }).join(", ") : '', creationDate: item.applicationDate.toLocaleDateString(item.applicationDate), enrolledCourses: item.enrolledCourses ? item.enrolledCourses.length : 0, assessments: item.assessments ? item.assessments.length : 0, isFresher: item.isFresher }; }); next(null, data); } else { next(err, 'Something went wrong while executing query.'); } }) }; //-------START------------ // Creating queue data structure for Breadth First Search of tree var Queue = function () { this.first = null; }; var qNode = function (data) { this.data = data; this.next = null; }; Queue.prototype.enqueue = function (data) { var node = new qNode(data); if (!this.first) { this.first = node; } else { var n = this.first; while (n.next) { n = n.next; } n.next = node; } return node; }; Queue.prototype.dequeue = function () { var temp = this.first; this.first = this.first.next; return temp; }; //-------END------------ //Creating tree data structure function Node(stageName, count) { this.stageName = stageName; this.children = []; } function Tree(stageName) { var node = new Node(stageName); this._root = node; } //returing a node and its children from tree by doing the Depth First Search Tree.prototype.traverseDF = function (node) { var temp = []; (function recurse(currentNode) { lodash.each(currentNode.children, function (value, index) { recurse(currentNode.children[index]); }) temp.push(currentNode.stageName); })(node); return temp; }; //based on a stage returing a node and its children from tree by doing the Depth First Search Tree.prototype.traverseDFStage = function (stage) { var that = this, childStages = null; (function recurse(currentNode) { lodash.each(currentNode.children, function (value, index) { if (currentNode.children[index].stageName != stage) { recurse(currentNode.children[index]); } else { var node = currentNode.children[index]; childStages = that.traverseDF(node); return false; } }) })(this._root); return childStages; } //Now if the stages array parameter is equal to ["Interview Selected","Interview Rejected","Interview Invited","On Hold"] //then the final result should be ["Interview Invited","Interview Selected","Interview Rejected","Not Attended", //"Offer Rejected","Offer Given","Offer Accepted","Joined","On Hold"] //that means extract the stage first from stages array whose children covers the maximum stages from stages array //for example in above example extarct "Interview Invited" first because its children contain most of the other elements //of the stages array like "Interview Selected","Interview Rejected". After this find the children of the left element //of the stages array i.e. "On Hold" //If stages array contains any of the below exceptional stages value then they will always be included in the final result as //they donot fall under funnel mode //exceptionalStages=["Filtered Out","Dormant","Not Qualified","In Queue","Cancelled By User"] Tree.prototype.getStageAndChildren = function (stages) { console.log(stages); var exceptionalStages = ["Filtered Out", "Dormant", "Not Qualified", "In Queue", "Cancelled By User"]; var node = null; var childStages = []; childStages.push(lodash.intersection(stages, exceptionalStages)); stages = lodash.difference(stages, exceptionalStages); if (stages.indexOf(this._root.stageName) >= 0) { childStages.push(this.traverseDFStage(this._root.stageName)); } else { var that = this; var queue = new Queue(); queue.enqueue(this._root); var currentTree = queue.dequeue(); while (currentTree) { for (var i = 0, length = currentTree.data.children.length; i < length; i++) { queue.enqueue(currentTree.data.children[i]); } if (stages.indexOf(currentTree.data.stageName) >= 0) { var childnodes = that.traverseDFStage(currentTree.data.stageName), isarrayOfChildnodesSupersetsetOfStages; stages.splice(stages.indexOf(currentTree.data.stageName), 1); isarrayOfChildnodesSupersetsetOfStages = stages.every(function (val) { return childnodes.indexOf(val) >= 0; }); childStages.push(childnodes); if (isarrayOfChildnodesSupersetsetOfStages) { break; } else { for (var i = 0; i < stages.length; i++) { if (childnodes.indexOf(stages[i]) >= 0) { stages.splice(stages.indexOf(stages[i]), 1); } } currentTree = queue.dequeue(); } } else { if (queue.first) { currentTree = queue.dequeue(); } else { break; } } } } return childStages.join(",").split(","); }; //Saves the stage funnel structure in tree data structure. Then uses the getStageAndChildren(stages) function to get //the stage names of the stages array and their children. var GetStageAndChildren = function (stageNames) { var stageTree = new Tree('Started'); stageTree._root.children.push(new Node('Qualified')); stageTree._root.children[0].children.push(new Node('Recommended')); stageTree._root.children[0].children.push(new Node('RTN Rejected')); stageTree._root.children[0].children.push(new Node('Assessment Invited')); stageTree._root.children[0].children.push(new Node('Assessment Rejected')); stageTree._root.children[0].children.push(new Node('Assessment Not Attended')); stageTree._root.children[0].children[0].children.push(new Node('On Hold')); stageTree._root.children[0].children[0].children.push(new Node('Recommended Rejected')); stageTree._root.children[0].children[0].children.push(new Node('Interview Invited')); stageTree._root.children[0].children[0].children[2].children.push(new Node('Interview Selected')); stageTree._root.children[0].children[0].children[2].children.push(new Node('Interview Rejected')); stageTree._root.children[0].children[0].children[2].children.push(new Node('Not Attended')); stageTree._root.children[0].children[0].children[2].children[0].children.push(new Node('Offer Rejected')); stageTree._root.children[0].children[0].children[2].children[0].children.push(new Node('Offer Given')); stageTree._root.children[0].children[0].children[2].children[0].children.push(new Node('Offer Accepted')); stageTree._root.children[0].children[0].children[2].children[0].children.push(new Node('Joined')); var stageAndChildrenStages = stageTree.getStageAndChildren(stageNames); console.log("stageAndChildren " + stageAndChildrenStages); return stageAndChildrenStages; } var GetStagesInFunnel = function (stages, lifeCycle) { var finalStageList = []; if (stages.constructor === Array) { _.each(stages, function (stage) { console.log("Find Funneled stage of " + stage); var thisStage = _.find(lifeCycle.stages, function (s) { return (s.name == stage); }); console.log(thisStage.funnelStages); finalStageList = [].concat(finalStageList, thisStage.funnelStages); }); finalStageList = _.uniq(finalStageList); console.log(finalStageList); return finalStageList; } else { var finalStageList = _.find(lifeCycle.stages, function (s) { return (s.name == stages); }) console.log(finalStageList); return finalStageList.funnelStages; } } var findApplicants = function (AppliedJobData, params, next) { let skip = params.skip; let limit = params.limit; //Search Query Magicwords parsing if (params.appInterviewDate) { if (params.appInterviewDate === 'TODAY') { params.appInterviewDate = moment().startOf('day').format("DD/MM/YYYY"); } else if (params.appInterviewDate === 'TOMORROW') { params.appInterviewDate = moment().add(1, 'days').startOf('day').format("DD/MM/YYYY"); } else if (params.appInterviewDate === 'TOMORROW+1') { params.appInterviewDate = moment().add(2, 'days').startOf('day').format("DD/MM/YYYY"); } } Date.prototype.toLocaleDateString = function (d) { var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" ]; return (d.getDate() + "-" + monthNames[d.getMonth()] + "-" + (d.getYear() - 100)); }; var query = undefined; if (params.userSearch) { query = AppliedJobData.find({ isMasterApplication: true, isArchived: false }); } else { query = AppliedJobData.find({ isMasterApplication: false, isArchived: false }); } if (params.keyword) { var keyword = params.keyword.replace("@gmail.com", ""); query = query.where({ $text: { $search: keyword }, isMasterApplication: false }); } if (params.appId) { var appId = params.appId; query = query.where({ applicationId: appId }); } if (params.bulkSearchDataType && params.bulkSearchData) { console.log("bulk search for ", params.bulkSearchDataType); var givenString = params.bulkSearchData.replace("[", "").replace("]", ""); var splitStrings = givenString.split(/["\s,;]/); console.log("Split data ", splitStrings.length, " > ", splitStrings); if (params.bulkSearchDataType === 'Mobile Numbers') { query.in('mobile', splitStrings); } else if (params.bulkSearchDataType === 'Email Ids') { query.in('email', splitStrings); } else if (params.bulkSearchDataType === 'External / Oracle Ids') { query.in('client.applicationId', splitStrings); } else if (params.bulkSearchDataType === 'Passport Numbers') { query.in('passport.number', splitStrings); } else if (params.bulkSearchDataType === 'ApplicationId') { query.in('applicationId', splitStrings); } } if (params.agencies && params.agencies.length) { query.elemMatch('agencies', { associatedOrgId: params.orgId, orgId: { $in: params.agencies } }); } if (params.vendorLock) { query.where('vendorLock.status', { $in: ['requested', 'open'] }); } if (params.countryCodes && params.countryCodes.length) { query.where('countryCode', { $in: params.countryCodes }); } if (params.nationalities && params.nationalities.length) { query.where('passport.nationality', { $in: params.nationalities }); } if (params.clients && params.clients.length) { query.where('client.orgId', { $in: params.clients }); } if (params.orgType === 'employer') { query.where('client.orgId', params.orgId); } else if (params.orgIds && params.orgIds.length && (!params.agencies)) { var agencyOption = { orgId: params.orgId } query.elemMatch('agencies', agencyOption); } else if (params.orgId) { var agencyOption = { orgId: params.orgId } query.elemMatch('agencies', agencyOption); } if (params.applicationType) { var applicationType = params.applicationType; query = query.where('applicationType', applicationType); } if (params.isVisited === 'yes') { query.where('isVisited', true); } else if (params.isVisited === 'no') { query.where('isVisited', false); } if (params.abbyStatus) { query.where('abbyStatus', params.abbyStatus); } if (params.tags && params.tags.length) { query.in('tags.title', params.tags); } if (params.gender) { query.in('gender', params.gender); } //sourcingOrgIds will be always overwritten by basicPlutoOrgId if (params.basicPlutoOrgId) { query.in('basicPAOrgId', params.basicPlutoOrgId); } if (params.jobAdvisorByUserId && params.jobAdvisorByUserId === "Not Assigned") { query.where('jobAdvisor', { $exists: false }); } else if (params.jobAdvisorByUserId) { query.in('jobAdvisor.userId', params.jobAdvisorByUserId); } if (params.stages) { if (params.stages.indexOf(",") > 0) { params.stages = params.stages.split(","); } if (!params.isFunnel) { query.in('currentStage', params.stages); } else { var stageAndChildren = GetStagesInFunnel(params.stages, params.lifeCycle); query.in('currentStage', stageAndChildren); } } if (params.jobIds) { query.in('jobId', params.jobIds); } if (params.onlyJobRoles) { query.where({ entityType: 'jobRole' }); } if (params.bulkStageSessionId) { query.in('stageHistory.sessionId', params.bulkStageSessionId); } //Supporting Advanced Search Options var advancedOptions = {}; var isAdvancedSearchTriggered = false; var isAdvancedSearchCvTemplateTriggered = false; //query.elemMatch('stageHistory',{}) if (params.historySelectedStage) { isAdvancedSearchTriggered = true; advancedOptions.nextStage = params.historySelectedStage; } if (params.cvTemplate) { isAdvancedSearchCvTemplateTriggered = true; advancedOptions.urlSlug = params.cvTemplate console.log(params.cvTemplate) } if (params.startDateCvTemplate && params.endDateCvTemplate) { isAdvancedSearchCvTemplateTriggered = true; var from = moment.utc(params.startDateCvTemplate, "DD/MM/YYYY").startOf('day').toDate(); var to = moment.utc(params.endDateCvTemplate, "DD/MM/YYYY").startOf('day').toDate(); console.log("cv template Dates:", from, to); advancedOptions.createdOn = { $gte: from, $lt: to }; } else if (params.startDateCvTemplate) { isAdvancedSearchCvTemplateTriggered = true; var from = moment.utc(params.startDateCvTemplate, "DD/MM/YYYY").startOf('day').toDate(); console.log("cv template Dates (after):", from); advancedOptions.createdOn = { $gte: from }; } else if (params.endDateCvTemplate) { isAdvancedSearchCvTemplateTriggered = true; var to = moment.utc(params.endDateCvTemplate, "DD/MM/YYYY").startOf('day').toDate(); console.log("cv template Dates (before):", to); advancedOptions.createdOn = { $lt: to }; } if (params.stageFromDate && params.stageToDate) { isAdvancedSearchTriggered = true; var from = moment.utc(params.stageFromDate, "DD/MM/YYYY").startOf('day').toDate(); var to = moment.utc(params.stageToDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("stage Dates:", from, to); advancedOptions.stageDate = { $gte: from, $lt: to }; } else if (params.stageFromDate) { isAdvancedSearchTriggered = true; var from = moment.utc(params.stageFromDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("stageFrom Date Dates (after):", from); advancedOptions.stageDate = { $gte: from }; } else if (params.stageToDate) { isAdvancedSearchTriggered = true; var to = moment.utc(params.stageToDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("stageToDate Dates (before):", to); advancedOptions.stageDate = { $lt: to }; } if (params.processingFromDate && params.processingToDate) { isAdvancedSearchTriggered = true; var from = moment.utc(params.processingFromDate, "DD/MM/YYYY").startOf('day').toDate(); var to = moment.utc(params.processingToDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("processing Dates:", from, to); query.gte('processingDate', from); query.lte('processingDate', to); } else if (params.processingFromDate) { isAdvancedSearchTriggered = true; var from = moment.utc(params.processingFromDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("processingFromDate Dates (after):", from); query.gte('processingDate', from); } else if (params.processingToDate) { isAdvancedSearchTriggered = true; var to = moment.utc(params.processingToDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("processingToDate Dates (before):", to); query.lte('processingDate', to); } if (params.historyFromDate && params.historyToDate) { isAdvancedSearchTriggered = true; var from = moment.utc(params.historyFromDate, "DD/MM/YYYY").startOf('day').toDate(); var to = moment.utc(params.historyToDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("history Dates:", from, to); advancedOptions.updatedOn = { $gte: from, $lt: to }; } else if (params.historyFromDate) { isAdvancedSearchTriggered = true; var from = moment.utc(params.historyFromDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("history Dates (after):", from); advancedOptions.updatedOn = { $gte: from }; } else if (params.historyToDate) { isAdvancedSearchTriggered = true; var to = moment.utc(params.historyToDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("history Dates (before):", to); advancedOptions.updatedOn = { $lt: to }; } if (params.updatedByUserId) { isAdvancedSearchTriggered = true; advancedOptions.updatedByUserId = params.updatedByUserId; } if (params.interviewSlotFromDate && params.interviewSlotToDate) { var from = moment.utc(params.interviewSlotFromDate, "DD/MM/YYYY").startOf('day').toDate(); var to = moment.utc(params.interviewSlotToDate, "DD/MM/YYYY").startOf('day').toDate(); query.gte('interviewSlot.date', from) query.lte('interviewSlot.date', to) } else if (params.interviewSlotFromDate) { var from = moment.utc(params.interviewSlotFromDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("interview Dates (after):", from); query.gte('interviewSlot.date', from) } else if (params.interviewSlotToDate) { var to = moment.utc(params.interviewSlotToDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("interview slot Dates (before):", to); query.lte('interviewSlot.date', to) } if (params.appInterviewDate) { var appInterviewDate = moment.utc(params.appInterviewDate, "DD/MM/YYYY").startOf('day').toDate(); console.log("interview slot Date:", appInterviewDate); query.where('interviewSlot.startDate', appInterviewDate) } if (isAdvancedSearchTriggered) { console.log("Advanced Search option (history) : " + JSON.stringify(advancedOptions)); query.elemMatch('stageHistory', advancedOptions); } if (isAdvancedSearchCvTemplateTriggered) { console.log("Advanced Search option (cvTemplate) : " + JSON.stringify(advancedOptions)); query.elemMatch('cvTemplates', advancedOptions); } //must be deprecated soon if (params.jobUrlSlug && params.jobUrlSlug.length) { query.in('jobUrlSlug', params.jobUrlSlug); } if (params.jobRoleUrl && params.jobRoleUrl.length) { query.in('jobRoleUrl', params.jobRoleUrl); } if (params.jobUrlSlugs) { query.in('jobUrlSlug', params.jobUrlSlugs); } if (params.location && params.location.length) { query.in('location.area', params.location); } if (params.assessmentScore && params.assessmentScore >= 0) { query.gte('assessments.report.dataUnit.obtainedPercentage', params.assessmentScore); } if (params.assessmentScore && params.assessmentScore < 0) { query.lt('assessments.report.dataUnit.obtainedPercentage', (params.assessmentScore) * (-1)); } if (params.interviewDate) { var interviewFrom = moment(params.interviewDate).utc().startOf('day').toDate(); var interviewTo = moment(params.interviewDate).utc().add(1, 'days').startOf('day').toDate(); query.gte('interviewSlot.date', interviewFrom) query.lt('interviewSlot.date', interviewTo) console.log(interviewFrom, interviewTo); } if (params.isFresher) { query.where('isFresher', params.isFresher); } if (params.qualification && params.qualification.length) { var processedQualification = [] for (var i = 0; i < params.qualification.length; i++) { var thisQualification = params.qualification[i] if (thisQualification.degreeType && thisQualification.degree && thisQualification.passingYear) { var cookedQualification = { 'educationInfo.degreeType': thisQualification.degreeType, 'educationInfo.degree': thisQualification.degree, 'educationInfo.passingYear': thisQualification.passingYear } } else if (thisQualification.degreeType && thisQualification.degree) { var cookedQualification = { 'educationInfo.degreeType': thisQualification.degreeType, 'educationInfo.degree': thisQualification.degree, } } else if (thisQualification.degreeType && thisQualification.passingYear) { var cookedQualification = { 'educationInfo.degreeType': thisQualification.degreeType, 'educationInfo.passingYear': thisQualification.passingYear } } else { var cookedQualification = { 'educationInfo.degreeType': thisQualification.degreeType, } } processedQualification.push(cookedQualification) if (i === params.qualification.length - 1) { query.or(processedQualification) } } } console.log(query._conditions); AppliedJobData.find(query.sort({ applicationDate: -1 })).skip(skip).limit(limit).exec(function (err, ajds) { var totalApplicants = (ajds ? ajds.length : 0); console.log("Found Applicants " + totalApplicants); if (!err) { ajds = _.first(ajds, 5000); var refinedAjds = _.map(ajds, function (item) { var associatedOrgId = undefined; if (params.orgType !== 'employer') { associatedOrgId = params.orgId; } var thisVendor = _.find(item.agencies, function (a) { if (!associatedOrgId) { return !a.associatedOrgId; } else { return a.associatedOrgId === associatedOrgId; } }); return { id: item.userId, name: item.seeker_profile.first_name + (item.seeker_profile.last_name ? (' ' + item.seeker_profile.last_name) : ''), seeker_profile: item.seeker_profile, FBUserId: item.FBUserId, email: item.email ? item.email : '', jobUrlSlug: item.jobUrlSlug, jobId: item.jobId, jobRoleUrl: item.jobRoleUrl, passport: item.passport, personalAttributes: item.personalAttributes, attachmentsLength: item.attachments ? item.attachments.length : 0, phone: item.mobile, city: item.location ? item.location.city : '', zip: item.location ? item.location.zip : '', state: item.location ? item.location.state : '', authSourceUtm: item.authSourceUtm ? item.authSourceUtm : '', isFresher: item.isFresher ? item.isFresher : '', abbyStatus: item.abbyStatus ? item.abbyStatus : '', localUserId: item.localUserId ? item.localUserId : '', isVisited: item.isVisited ? item.isVisited : '', currentStage: item.currentStage ? item.currentStage : '', educationInfo: item.educationInfo ? _.map(item.educationInfo, function (i) { return i.degreeType; }).join(", ") : '', applicationId: item.applicationId ? item.applicationId : '', applicationDate: item.applicationDate ? item.applicationDate : '', qnaSet: item.qnaSet, displayPic: item.displayPic, vendor: thisVendor ? thisVendor : undefined, client: item.client, vendorLock: item.vendorLock, trainingSlot: item.trainingSlot, interviewSlot: item.interviewSlot, skills: _.filter(item.skills, function (s) { return s.type === 'English'; }), workLocation: _.map(item.workLocation, function (w) { return w.area; }).join(", "), jobName: item.jobName ? item.jobName : '', screeningId: item.screeningId ? item.screeningId : '', tags: item.tags ? item.tags : undefined, qnaSetLength: item.qnaSet ? item.qnaSet.length : 0, interviewDate: item.interviewSlot ? item.interviewSlot.date : '', interviewVenue: item.interviewSlot ? item.interviewSlot.venue : '', jobAdvisor: (item.jobAdvisor) ? (item.jobAdvisor.seeker_profile.first_name + (item.jobAdvisor.seeker_profile.last_name ? (' ' + item.jobAdvisor.seeker_profile.last_name) : '')) : '', stageHistory: params.isStageHistoryNeeded ? item.stageHistory : [], userSourceOrgId: (item.userSource) ? item.userSource.orgId : '', userSourceOrgName: (item.userSource) ? item.userSource.orgName : '', matchScore: (item.matchScore) ? item.matchScore : '', countryCode: (item.countryCode) ? item.countryCode : '', currentPosition: (item.currentPosition) ? item.currentPosition : '', profileSummary: (item.profileSummary) ? item.profileSummary : '', keyskills: (item.keyskills) ? item.keyskills : '' }; }); //post search params - turbo mode var turbo = { }; if (params.turbo) { var stageData = []; var stages = _.pluck(refinedAjds, "currentStage"); stages = count(stages); for (var property in stages) { if (stages.hasOwnProperty(property)) { stageData.push([property, stages[property]]) } }; var jobData = []; var jobs = _.pluck(refinedAjds, "jobName"); jobs = count(jobs); for (var property in jobs) { if (jobs.hasOwnProperty(property)) { jobData.push([property, jobs[property]]) } }; var authSourceData = []; var authSourceUtms = _.pluck(refinedAjds, "authSourceUtm"); authSourceUtms = count(authSourceUtms); for (var property in authSourceUtms) { if (authSourceUtms.hasOwnProperty(property)) { authSourceData.push([property, authSourceUtms[property]]) } }; var vendorData = []; // console.log(refinedAjds); var vendors = _.pluck(refinedAjds, "vendor"); vendors = _.map(vendors, function (i) { if (i) { return i.orgName; } }); vendors = count(vendors); for (var property in vendors) { if (vendors.hasOwnProperty(property)) { vendorData.push([property, vendors[property]]) } }; turbo = { stages: stageData, jobs: jobData, authSourceData: authSourceData, vendorData: vendorData, totalApplicants: totalApplicants } } var payLoad = { applicants: refinedAjds, turbo: turbo, userSearch: params.userSearch }; console.log(refinedAjds.length); next(null, payLoad); } else { next(err, 'Something went wrong while executing query.'); } }) }; var findStageHistoryChangeTrend = function (AppliedJobData, startDate, endDate, next) { //endDate is not included console.log("========================= Changes b/w: ", startDate, " - ", endDate, " ========================="); AppliedJobData.find({ stageHistory: { $elemMatch: { updatedOn: { $gte: startDate, $lt: endDate } } } }).exec(function (err, applications) { console.log("Impacted applications: " + (applications ? applications.length : 0)); if (!err && applications && applications.length) { //Stage History changes var StageHistories = []; _.each(applications, function (item) { var todaySHs = _.filter(item.stageHistory, function (sh) { if ((sh.updatedOn >= startDate) && (sh.updatedOn < endDate) && (sh.updatedByRole !== 'abby')) { return true; } }); var todaySHss = _.map(todaySHs, function (sh) { return { updatedByRole: sh.updatedByRole, updatedByUserId: sh.updatedByUserId, previousStage: sh.previousStage, stageDate: sh.stageDate, nextStage: sh.nextStage, updatedBy: sh.updatedBy, orgId: sh.orgId, orgAccessLifeCycleLabel: sh.orgAccessLifeCycleLabel, updatedOn: sh.updatedOn, mobile: item.mobile } }) StageHistories = StageHistories.concat(todaySHss); }); var PlutoPremiumStageHistories = _.filter(StageHistories, function (sh) { if (sh.updatedByRole === "plutoPremium") { return true; } }); var PlutoPremiumProcessings = _.filter(StageHistories, function (sh) { if (sh.updatedByRole === "plutoPremium" && sh.nextStage === "Processed") { return true; } }); var UniquePlutoPremiumProcessings = _.uniq(PlutoPremiumProcessings, function (item) { return item.mobile; }) var UniquePlutoPremiumProcessingsGrouped = _.groupBy(UniquePlutoPremiumProcessings, function (item) { return item.updatedBy.first_name }) var processingData = _.map(UniquePlutoPremiumProcessingsGrouped, function (group) { return { processings: group.length, jobAdvisor: group[0].updatedBy } }); processingData = _.sortBy(processingData, function (item) { return -1 * item.processings }); console.log(processingData); var ElpisStageHistories = _.filter(StageHistories, function (sh) { if (sh.updatedByRole === "elpis") { return true; } }); var groups = _.groupBy(StageHistories, function (value) { return value.updatedBy + '#' + value.nextStage + '#' + value.previousStage + '#' + value.updatedByRole; }); var data = _.map(groups, function (group) { return { updatedBy: group[0].updatedBy.first_name + ' ' + group[0].updatedBy.last_name, updatedByUserId: group[0].updatedByUserId, orgAccessLifeCycleLabel: group[0].orgAccessLifeCycleLabel, updatedByRole: group[0].updatedByRole, previousStage: group[0].previousStage, nextStage: group[0].nextStage, history: group.length } }); data = _.sortBy(data, function (o) { return o.updatedByRole + '_' + o.updatedBy + '_' + o.previousStage + '_' + o.nextStage; }); var finalSummary = { startDate: startDate.format('DD/MM/YYYY'), endDate: endDate.format('DD/MM/YYYY'), impactedApplicants: applications.length, stageHistories: StageHistories.length, premiumPlutoChanges: PlutoPremiumStageHistories.length, processingData: processingData, UniquePlutoPremiumProcessings: UniquePlutoPremiumProcessings, elpisChanges: ElpisStageHistories.length, history: data }; next(null, finalSummary); } else { next(err, null); } }) }; var findStageHistoryTrendByDate = function (AppliedJobData, startDate, endDate, userId, next) { //endDate is not included console.log("========================= Changes b/w: ", startDate, " - ", endDate, " ========================="); var query; if (userId) { query = { entityType: 'jobRole', stageHistory: { $elemMatch: { updatedOn: { $gte: startDate, $lt: endDate }, nextStage: "Processed" } }, 'jobAdvisor.userId': userId }; } else { query = { entityType: 'jobRole', stageHistory: { $elemMatch: { updatedOn: { $gte: startDate, $lt: endDate }, nextStage: "Processed" } } }; } AppliedJobData.find(query).exec(function (err, applications) { console.log("Impacted applications: " + (applications ? applications.length : 0)); if (!err && applications) { next(null, applications); } else { next(err, null); } }) }; var lifeCycleBuilderApplicantSearch = function (ajd, orgId, next) { var orgId = orgId ? orgId : ajd.client.orgId; var cacheName = 'elpis' + orgId + 'RTNALC'; console.log('cacheName: ' + cacheName); var name = 'Recruiter'; if (Cache.get(cacheName)) { console.log('Got cached ' + cacheName); next(JSON.parse(Cache.get(cacheName))); } else { var query = LifeCycle.findOne({ 'name': name, role: 'elpis' }); if (orgId) { query = LifeCycle.findOne({ 'name': name, role: 'elpis', orgId: orgId }); } query.exec(function (err, lifeCycle) { if (!err && lifeCycle) { console.log('Got lifeCycle:' + lifeCycle.name); Cache.put(cacheName, JSON.stringify(lifeCycle)); next(lifeCycle); } else { console.log(err); next(null, err); } }); } }; var sendStageChangeSMSToUser = function (ajd, interviewSlot, orgId, thisStage, lifeCycleSettings, reqBody) { if (reqBody && reqBody.smsText) { var template = parseKeywordFromMessage(reqBody.smsText, ajd); saveSmsToSmsLog(ajd, template, lifeCycleSettings); } else if (thisStage && thisStage.smsText) { var template = parseKeywordFromMessage(thisStage.smsText, ajd); saveSmsToSmsLog(ajd, template, lifeCycleSettings); } }; var parseKeywordFromMessage = function (body, ajd) { if (body) { var tempBody = body; if (ajd.seeker_profile) { tempBody = body.replace("<name - autofill|30>", (ajd.seeker_profile.first_name + ' ' + ajd.seeker_profile.last_name)); tempBody = tempBody.replace("*USERNAME*", (ajd.seeker_profile.first_name + ' ' + ajd.seeker_profile.last_name)); tempBody = tempBody.replace("*USERFNAME*", ajd.seeker_profile.first_name); tempBody = tempBody.replace("*USERLNAME*", ajd.seeker_profile.last_name); } //*JOBNAME* tempBody = tempBody.replace("*JOBNAME*", ajd.jobName ? ajd.jobName : 'job'); //CLIENTNAME tempBody = tempBody.replace("*CLIENTNAME*", ajd.client ? ajd.client.orgName : 'company'); //JOBBOTLINK tempBody = tempBody.replace("*JOBBOTLINK*", ajd.jobUrlSlug ? ('http://iona.ai/job/' + ajd.jobId) : 'http://iona.ai'); //INTERVIEWVENUE tempBody = tempBody.replace("*INTERVIEWVENUE*", ajd.interviewSlot ? ajd.interviewSlot.venue : ''); tempBody = tempBody.replace("*INTERVIEWDATE*", ajd.interviewSlot ? moment(ajd.interviewSlot.startDate).format("DD/MM/YYYY") : ''); tempBody = tempBody.replace("*INTERVIEWTIME*", (ajd.interviewSlot && ajd.interviewSlot.time) ? ajd.interviewSlot.time : ''); tempBody = tempBody.replace("*INTERVIEWINSTRUCTION*", (ajd.interviewSlot && ajd.interviewSlot.instruction) ? ajd.interviewSlot.instructions : ''); tempBody = tempBody.replace("*INTERVIEWMAPLINK*", (ajd.interviewSlot && ajd.interviewSlot.maplink) ? ajd.interviewSlot.maplink : ''); return tempBody; } else { return body; } }; var saveSmsToSmsLog = function (ajd, template, settings) { var smsLog = new SMSLog({ sid: 'textLocal', txnId: ajd.applicationId, userId: ajd.userId, senderId: settings ? settings.smsSenderId : '', mobile: ajd.mobile, smsBody: template, countryCode: ajd.countryCode, deliveryStatus: "inQueue", isTransactional: true, priority: 0 }); smsLog.save(function (err, saved) { if (!err && saved) { console.log("Queued SMS for service status change : " + ajd.currentStage) } else { console.log(JSON.stringify(err)) } }) }; var sendStageChangeEmailToUser = function (ajd, interviewSlot, orgId, thisStage, lifeCycleSettings, reqBody) { var mailTemplates = path.join(path.dirname(fs.realpathSync(__filename)), './mailTemplates') var templatePath = mailTemplates + '/filler.ejs'; var template = ''; var subject = ''; if (reqBody && reqBody.emailText) { template = parseKeywordFromMessage(reqBody.emailText, ajd); subject = parseKeywordFromMessage(reqBody.emailSubject, ajd); } else if (thisStage && thisStage.emailText) { template = parseKeywordFromMessage(thisStage.emailText, ajd); subject = parseKeywordFromMessage(thisStage.emailSubject, ajd); } if (subject && template) { var mailLog = new MailLog({ _id: mongoose.Types.ObjectId(), txnId: ajd.id, userId: ajd.userId, email: ajd.email, subject: subject, deliveryStatus: "InQueue", isOpened: false, source: lifeCycleSettings ? lifeCycleSettings.sourceEmail : "help@hireira.com", replyToAddresses: lifeCycleSettings ? lifeCycleSettings.sourceEmail : "help@hireira.com", retu