An error occurred while loading the file. Please try again.
-
Reshmi authored19df1bdb
import axios from "axios";
import async from "async";
const targetURL = process.env.TARGET_URL || "https://hasura.upsmfac.org";
const notificationURL = process.env.REACT_APP_API_URL || "https://uphrh.in/api/api";
const emailAuthToken = process.env.REACT_APP_AUTH_TOKEN;
const getBulkUploadAssessorSchedule = '/api/rest/getBulkUploadAssessorSchedule';
const filterAssessments = '/api/rest/filterAssessments';
const getUsersForSchedulingAssessment = '/api/rest/getUsersForSchedulingAssessment';
const addAssessmentSchedule = '/api/rest/addAssessmentSchedule';
const addInstituteCourse = '/api/rest/addInstituteCourse';
const addEvents = '/api/rest/addEvents';
const updateForm = '/api/rest/updateForm';
const getApplicantDeviceId = '/api/rest/getApplicantDeviceId';
const notify = '/email/notify';
const getFormSubmissionsByFormIds = '/api/rest/getFormSubmissionsByFormIds';
const updateStatusToBulkUpload = '/api/rest/updateStatusToBulkUpload';
const getAllAssessorsAPI = '/api/rest/getAllAssessors';
const getAdminDetailsById = '/api/rest/getRegulator';
// Creating an Axios instance with custom headers
const axiosInstance = axios.create({
baseURL: targetURL,
headers: {
"x-hasura-admin-secret": "myadminsecretkey",
"Hasura-Client-Name": "hasura-console"
// Add any other headers you need
},
});
const getBulkUpload = (processStr) => {
return new Promise(async(resolve) => {
try {
//console.log(processStr);
const response = await axiosInstance.post(targetURL + getBulkUploadAssessorSchedule, processStr);
//console.log(response.data);
resolve(response.data.assessor_schedule_bulk_upload);
} catch (error) {
console.error('Error getBulkUpload:', error.message);
throw error;
}
});
};
const getAllAssessors = () => {
return new Promise(async(resolve) => {
try {
const processStr = {"offsetNo":0,"limit": 100000}
//console.log(processStr);
const response = await axiosInstance.post(targetURL + getAllAssessorsAPI, processStr);
//console.log(response.data.assessors);
const assessors = response.data.assessors;
const users = assessors.filter(obj => obj["workingstatus"] == "Valid");
resolve(users);
} catch (error) {
console.error('Error getUsersForScheduling:', error.message);
throw error;
}
});
};
const addAssessmentScheduleToDB = (scheduleStr) => {
return new Promise(async(resolve) => {
try {
//console.log(scheduleStr);
const response = await axiosInstance.post(targetURL + addAssessmentSchedule, scheduleStr);
//console.log(response.data);
resolve(response.data);
} catch (error) {
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
console.error('Error addAssessmentScheduleToDB:', error.message);
throw error;
}
});
};
const addInstituteCourseToDB = (instituteStr) => {
return new Promise(async(resolve) => {
try {
//console.log(instituteStr);
const response = await axiosInstance.post(targetURL + addInstituteCourse, instituteStr);
//console.log(response.data);
resolve(response.data);
} catch (error) {
console.error('Error addInstituteCourse:', error.message);
throw error;
}
});
};
const addEventsToDB = (eventsStr) => {
return new Promise(async(resolve) => {
try {
// console.log(eventsStr);
const response = await axiosInstance.post(targetURL + addEvents, eventsStr);
//console.log(response.data);
resolve(response.data);
} catch (error) {
console.error('Error addEvents:', error.message);
throw error;
}
});
};
const updateFormToDB = (formStr) => {
return new Promise(async(resolve) => {
try {
//console.log(formStr);
const response = await axiosInstance.put(targetURL + updateForm, formStr);
//console.log(response.data);
resolve(response.data);
} catch (error) {
console.error('Error updateForm:', error.message);
throw error;
}
});
};
const getAdminDetails = async (adminId) => {
try {
const postData = {"user_id":adminId};
console.log(postData);
const res = await axiosInstance.post(targetURL + getAdminDetailsById , postData);
//console.log(res);
return res.data.regulator;
} catch (error) {
console.error('Error getAdminDetails:', error.message);
throw error;
}
};
const sendEmailNotification = async (postData) => {
return new Promise(async(resolve) => {
const res = await axiosInstance.post(
notificationURL + notify,
postData,
{
headers: {
"Content-Type": "application/json",
Authorization: emailAuthToken,
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
},
}
);
resolve( res);
});
};
const getFormSubmissionsByFormId = (arr) => {
return new Promise(async(resolve) => {
try {
const reqData = {"params": arr};
const response = await axiosInstance.post(targetURL+getFormSubmissionsByFormIds, reqData);
resolve(response.data.form_submissions);
} catch (error) {
console.error('Error getFormSubmissionsByFormId:', error.message);
throw error;
}
});
};
const updateStatusToBulkUploadData = (obj) => {
return new Promise(async(resolve) => {
try {
const response = await axiosInstance.post(targetURL + updateStatusToBulkUpload, obj);
resolve(response.data);
} catch (error) {
console.error('Error updateStatusToBulkUploadData :', error.message);
throw error;
}
});
};
function findDuplicateRecords(array, attribute1, attribute2) {
const duplicates = array.filter((item, index, self) => {
return (
index !== self.findIndex(
(innerItem) =>
innerItem[attribute1] === item[attribute1] &&
innerItem[attribute2] === item[attribute2]
)
);
});
return duplicates;
}
function getDatesFromTodayTo90Days() {
const currentDate = new Date();
const datesArray = [];
for (let i = 1; i < 90; i++) {
const nextDate = new Date(currentDate);
nextDate.setDate(currentDate.getDate() + i);
datesArray.push(nextDate.toISOString().split('T')[0]);
}
// Sort the filtered dates in ascending order
datesArray.sort((a, b) => new Date(a) - new Date(b));
return datesArray;
}
function createEmailTable(emailTableRows, id, process_id, application_id, form_title,
application_type, course_type, assessor_id, uploaded_date, updateStatus, updateRemarks){
if(emailTableRows.length()===1){
emailTableRows.append("<tr><td>Id</td><td>Process_Id</td><td>Form_Id</td><td>Form_Title</td><td>Application_Type</td><td>Course_Type</td><td>Assessor_Id</td><td>Uploaded_Date</td><td>Status</td><td>Remarks</td></tr>");
}
emailTableRows.append("<tr><td>"+id);
emailTableRows.append("</td> <td>" + process_id );
emailTableRows.append("</td> <td>" + application_id);
emailTableRows.append("</td> <td>" + form_title );
emailTableRows.append("</td> <td>" + application_type);
emailTableRows.append("</td> <td>" + course_type );
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
emailTableRows.append("</td> <td>" + assessor_id );
emailTableRows.append("</td> <td>" + uploaded_date );
emailTableRows.append("</td> <td>" + updateStatus );
emailTableRows.append("</td> <td>" + updateRemarks +"</td></tr>");
return emailTableRows;
}
class StringBuffer {
constructor() {
this.buffer = [];
}
append(str) {
this.buffer.push(str);
return this; // Returning the instance for method chaining
}
toString() {
return this.buffer.join('');
}
length() {
return this.buffer.length;
}
}
const getSchedule = async(processStr, callback) => {
//return new Promise(async(resolve) => {
try {
const response = await axiosInstance.post(targetURL + filterAssessments, processStr);
// console.log(response.data.assessment_schedule);
var formSchedules = response.data.assessment_schedule;
//resolve (formSchedules);
callback(null,formSchedules);
} catch (error) {
console.error('Error getSchedule:', error.message);
throw error;
}
// });
};
const getScheduless = async(processStr, callback) => {
//return new Promise(async(resolve) => {
try {
const response = await axiosInstance.post(targetURL + filterAssessments, processStr);
// console.log(response.data.assessment_schedule);
var formSchedules = response.data.assessment_schedule;
//resolve (formSchedules);
callback(null,formSchedules);
} catch (error) {
console.error('Error getSchedules:', error.message);
throw error;
}
// });
};
const addAssessorSchedule = (formSubmissionObj, element, assessorObj, callback)=>{
try {
//get existing assessor schedules
var datesNotInArray = [];
const scheduleCriteria = {"offsetNo":0,"limit": 100000,"condition": {"assessor_code": {"_eq": element.assessor_id+""}}};
getScheduless(scheduleCriteria,(error,schedules)=> {
if(error){
console.error(`Error getScheduless ${element.id}:`, error);
throw error;
}else{
const dateRange = getDatesFromTodayTo90Days();
//if no existing schedules, pick the nearest one
if(schedules.length == 0){
datesNotInArray = dateRange;
}else{
const scheduledDates = schedules.filter(obj => obj.hasOwnProperty("date")).map(obj => obj["date"]);
datesNotInArray = dateRange.filter(date => !scheduledDates.includes(date));
const nearestUpcomingFreeDate = datesNotInArray[0];
async.waterfall([
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
function addSchedul(callback1){
//assign new schedule
const scheduleStr ={"assessment_schedule":[{
"assessor_code":assessorObj[0].code,
"date":nearestUpcomingFreeDate,
"institute_id":formSubmissionObj[0].institute.id,
"applicant_form_id":formSubmissionObj[0].form_id}]};
const addedRec = addAssessmentScheduleToDB(scheduleStr);
console.log("added schedule");
callback1(null,addedRec);
},
function addinst(addedRec, callback2){
const instituteStr ={"institute_course":[{
"institute_id":formSubmissionObj[0].institute.id,
"institute_type":"[{\"courseType\":\""+formSubmissionObj[0].course_type+"\",\"courseLevel\":\""+formSubmissionObj[0].course_level+"\"}]"}],
"institute_form":[{"course_id":formSubmissionObj[0].course_id,"applicant_form_id":formSubmissionObj[0].form_id,"institute_id":formSubmissionObj[0].institute.id,"assessment_date":nearestUpcomingFreeDate}]};
const addInstRec = addInstituteCourseToDB(instituteStr);
console.log("added Institute");
callback2(null,addInstRec);
},
function addEve(addInstRec, callback3){
const eventsStr = {"events":[{
"created_date":new Date().toLocaleString(),
"entity_id":formSubmissionObj[0].form_id+"",
"entity_type":"form",
"event_name":"Inspection Scheduled",
"remarks":"Round 1 inspection scheduled"}]};
const addeventsRec = addEventsToDB(eventsStr);
console.log("Added event");
callback3(null,addeventsRec);
},
function updateFormSub(addeventsRec,callback4){
const formStr = {"form_id":formSubmissionObj[0].form_id,"form_status":"Inspection Scheduled"};
const addFormRec = updateFormToDB(formStr);
console.log("Updated From Sub");
callback4(null,addFormRec);
},
function sendMail(addFormRec, callback5){
var email = emailTemplate.replace("${applicantName}",formSubmissionObj[0].institute.name);
const emailData = {
"recipientEmail":[formSubmissionObj[0].institute.email],
"emailSubject":"Inspection scheduled for "+formSubmissionObj[0].institute.name,
"emailBody":email
};
sendEmailNotification(emailData);
console.log('Applicant notification sent');
callback5(null,"Success");
},
function returningCallback(status){
callback(null, true, status, "Updated Successfully.");
}
], (error, finalResult) => {
if (error) {
console.error(`Error for element ${element.id}:`, error);
} else {
console.log(`Final Result for element ${element.id}:`, finalResult);
}
});
}
}
}
);
} catch (error) {
console.error('Error addAssessorSchedule:', error.message);
throw error;
}
}
const executeBulkUpload = (bulkUploadData, emailTableRows, adminId, formSubData, activeAssessors, callback1) => {
var updateStatus = "";
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
var updateRemarks = "";
console.log("step 5.1 - "+bulkUploadData.length +" adminId "+adminId);
var itemsProcessed = 0;
var assessorObj;
if(bulkUploadData.length === 0){
callback1(null,"success",emailTableRows, adminId);
}else{
bulkUploadData.forEach((element) => {
async.waterfall([
function checkAssessor(callback2){
var isUpdate = false;
assessorObj = activeAssessors.filter(assessor => assessor["code"] === (element.assessor_id)+"");
if(assessorObj.length === 0){
updateRemarks = "Assessor code is not existing in system.";
updateStatus = "Failed";
callback2(null, true, updateStatus, updateRemarks);
}else{
callback2(null, false, "", "");
}
},
function getSchedul(isUpdate, updateStatus, updateRemarks, callback3) {
if(!isUpdate){
//get existing form application schedule
const scheduleCriteria1 = {"offsetNo":0,"limit": 100000,"condition": {"applicant_form_id": {"_eq": element.application_id}}};
getSchedule(scheduleCriteria1, (error,formSchedules)=> {
if(error){
console.error(`Error getSchedule ${element.id}:`, error);
throw error;
}else{
if(formSchedules.length === 0){
callback3(null, false, "", "");
}else{
updateRemarks = "Form Schedule Already Exists.";
updateStatus = "Failed";
callback3(null, true, updateStatus, updateRemarks);
}
}});
}else{
callback3(null, isUpdate, updateStatus, updateRemarks);
}
},
function addRecords(isUpdate, updateStatus, updateRemarks, callback41){
if(!isUpdate){
var formSubmissionObj = formSubData.filter(obj => obj["form_id"] === element.application_id);
addAssessorSchedule(formSubmissionObj, element, assessorObj,(error,isUpdate, updateStatus,updateRemarks)=>{
if(error){
console.error(`Error addAssessorSchedule ${element.id}:`, error);
throw error;
}else{
callback41(null, isUpdate, updateStatus, updateRemarks);
}
});
}else{
callback41(null, isUpdate, updateStatus, updateRemarks);
}
},
function updateDB1(isUpdate, updateStatus, updateRemarks){
const updateData = updateStatusToBulkUploadData({id:element.id,status:updateStatus,remarks:updateRemarks});
emailTableRows.append(createEmailTable(emailTableRows, element.id, element.process_id, element.application_id, element.form_title,
element.application_type, element.course_type, element.assessor_id, element.uploaded_date, updateStatus, updateRemarks));
console.log("Updated id :" + element.id);
adminId = element.uploaded_by;
itemsProcessed++;
if(itemsProcessed === bulkUploadData.length){
callback1(null,"success",emailTableRows, adminId);
}
}
], (error, finalResult) => {
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
if (error) {
console.error(`Error for element ${element.id}:`, error);
} else {
console.log(`Final Result for element ${element.id}:`, finalResult);
}
});
});
}
};
const findMissingRecords = (object1, object2, key1,key2) => {
const set1 = new Set(object1.map(item1 => item1[key1]));
const missingRecords = object2.filter(item2 => !set1.has(item2[key2]));
return missingRecords;
};
const removeDuplicatesFromBulkUpload = (bulkUploadData, emailTableRows, callback) =>{
// Find duplicates based on the "application_id" attribute
const duplicates = findDuplicateRecords(bulkUploadData, 'application_id','process_id');
var itemsProcessed = 0;
var adminId = "";
console.log("duplicates "+ duplicates.length+" : "+bulkUploadData.length);
if(duplicates.length === 0){
callback(null,"success",bulkUploadData,emailTableRows,adminId);
}else{
duplicates.forEach(element => {
async.waterfall([
function updatedbrec(callback1){
var updateStatus = "Failed";
var updateRemarks = "Duplicate Record";
const updateData = updateStatusToBulkUploadData({id:element.id,status:updateStatus,remarks:updateRemarks});
callback1(null, updateStatus, updateRemarks);
},
function removDup( updateStatus, updateRemarks){
emailTableRows.append(createEmailTable(emailTableRows, element.id, element.process_id, element.application_id, element.form_title,
element.application_type, element.course_type, element.assessor_id, element.uploaded_date, updateStatus, updateRemarks));
bulkUploadData = bulkUploadData.filter(obj => (obj["id"] !== element.id));
adminId = element.uploaded_by;
itemsProcessed++;
if(itemsProcessed === duplicates.length) {
callback(null,"success",bulkUploadData,emailTableRows,adminId);
}
}]);
});
}
};
const removeInvalidFormSubmissionIds = async (bulkUploadData, emailTableRows, adminId, formSubData, callback) =>{
var itemsProcessed = 0;
const missingRecords = findMissingRecords( formSubData, bulkUploadData,"form_id", "application_id");
console.log("missingRecords "+ missingRecords.length+" : "+bulkUploadData.length+":"+formSubData.length);
if(missingRecords.length === 0){
callback(null,"success",bulkUploadData,emailTableRows,adminId);
} else {
missingRecords.forEach(async (element) => {
async.waterfall([
function updatedbrec(callback1){
var updateRemarks = "Form Application id is not existing in system or payment is not complete.";
var updateStatus = "Failed";
const updateData = updateStatusToBulkUploadData({id:element.id,status:updateStatus,remarks:updateRemarks});
callback1(null, updateStatus, updateRemarks);
},
function removDup( updateStatus, updateRemarks){
emailTableRows.append(createEmailTable(emailTableRows, element.id, element.process_id, element.application_id, element.form_title,
element.application_type, element.course_type, element.assessor_id, element.uploaded_date, updateStatus, updateRemarks));
bulkUploadData = bulkUploadData.filter(obj => ( obj["id"]!==element.id));
adminId = element.uploaded_by;
itemsProcessed++;
if(itemsProcessed === missingRecords.length) {
callback(null,"success",bulkUploadData,emailTableRows,adminId);
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
}
}]);
});
}
};
var emailTemplate = "<!DOCTYPE html><html><head><meta charset=\'utf-8\'><title>Your Email Title</title><link href=\'https://fonts.googleapis.com/css2?family=Mulish:wght@400;600&display=swap\' rel=\'stylesheet\'></head>"+
"<body style=\'font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0;\'>"+
"<table width=\'100%\' bgcolor=\'#ffffff\' cellpadding=\'0\' cellspacing=\'0\' border=\'0\'>"+
"<tr><td style=\'padding: 20px; text-align: center; background-color: #F5F5F5;\'><img src=\'https://regulator.upsmfac.org/images/upsmf.png\' alt=\'Logo\' style=\'max-width: 360px;\'></td></tr></table>"+
"<table width=\'100%\' bgcolor=\'#ffffff\' cellpadding=\'0\' cellspacing=\'0\' border=\'0\'><tr><td style=\'padding: 36px;\'><p style=\'color: #555555; font-size: 18px; font-family: \'Mulish\', Arial, sans-serif;\'>Dear ${applicantName},</p>"+
"<p style=\'color: #555555; font-size: 18px; line-height: 1.6; font-family: \'Mulish\', Arial, sans-serif;\'>We hope this email finds you well. We are glad to inform you that your application has been processed and was found fit for our next step which is on-ground assessment. "+
"On-ground assessment for your application have been scheduled. Please expect us to visit your institute very soon.</p><p style=\'color: #555555; font-size: 18px; line-height: 1.6; font-family: \'Mulish\', Arial, sans-serif;\'>Following information will help you prepare for the scheduled on-ground assessment:\\n "+
"<br/>1. A team of assessors will visit your institute for on-ground assessment. To make this process fair and transparent, institutes are not supposed to know the date of on-ground assessment and assessors are not supposed to know the institute they will be assessing till the day of assessment.\\n "+
"<br/>2. We expect your institute open and accessible to our on-ground assessment team on any working day.\\n "+
"<br/>3. Once on-ground assessment team prove their identity, they should be allowed to enter the institute and given full cooperation to carry out the on-ground assessment.</p>"+
"<p style=\'color: #555555; font-size: 18px; line-height: 1.6; font-family: \'Mulish\', Arial, sans-serif;\'>If you have any questions or need further clarification regarding the resubmission process, "+
"please do not hesitate to reach out to our support executives at <Contact Details>. We are here to assist you and provide any necessary guidance.</p>"+
"<p style=\'color: #555555; font-size: 18px; line-height: 1.6; font-family: \'Mulish\', Arial, sans-serif;\'>Thank you for your time and continued interest in getting affiliated from our organization.</p></td></tr></table></body></html>";
var adminEmailTemplate = "<!DOCTYPE html><html><head><meta charset=\'utf-8\'><title>Your Email Title</title><link href=\'https://fonts.googleapis.com/css2?family=Mulish:wght@400;600&display=swap\' rel=\'stylesheet\'></head>"+
"<body style=\'font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0;\'>"+
"<table width=\'100%\' bgcolor=\'#ffffff\' cellpadding=\'0\' cellspacing=\'0\' border=\'0\'>"+
"<tr><td style=\'padding: 20px; text-align: center; background-color: #F5F5F5;\'><img src=\'https://regulator.upsmfac.org/images/upsmf.png\' alt=\'Logo\' style=\'max-width: 360px;\'></td></tr></table>"+
"<table width=\'100%\' bgcolor=\'#ffffff\' cellpadding=\'0\' cellspacing=\'0\' border=\'0\'><tr><td style=\'padding: 36px;\'><p style=\'color: #555555; font-size: 18px; font-family: \'Mulish\', Arial, sans-serif;\'>Dear ${adminName},</p>"+
"<p style=\'color: #555555; font-size: 18px; line-height: 1.6; font-family: \'Mulish\', Arial, sans-serif;\'>Please find the assessor upload status below: "+
"<table width=\'100%\' bgcolor=\'#ffffff\' cellpadding=\'5\' border=\'1\'>${emailTableRows}</table>"+
"</p></td></tr></table></body></html>";
const performBackgroundTask = async () => {
try {
const emailTableRows = new StringBuffer();
emailTableRows.append("")
const activeAssessors = await getAllAssessors();
var bulkUploadData = await getBulkUpload({"where" : {"status": {"_eq": "Pending"}}});
removeDuplicatesFromBulkUpload(bulkUploadData, emailTableRows, async (error,result,bulkUploadData,emailTableRows,adminId)=>{
if(error){
console.error('Error removeDuplicatesFromBulkUpload:', error.message);
throw error;
}else{
const formIdArr = bulkUploadData.filter(obj => obj.hasOwnProperty("application_id")).map(obj => obj["application_id"]);
const formSubData = await getFormSubmissionsByFormId(formIdArr);
await removeInvalidFormSubmissionIds(bulkUploadData, emailTableRows, adminId, formSubData,(error,result,bulkUploadData,emailTableRows,adminId)=>{
if(error){
console.error('Error removeInvalidFormSubmissionIds:', error.message);
throw error;
}else{
executeBulkUpload(bulkUploadData, emailTableRows,adminId, formSubData, activeAssessors, async (error,result,emailTableRows,adminId) => {
if(error){
console.error('Error executeBulkUpload:', error.message);
throw error;
}else{
if(adminId !==""){
const adminDetails = await getAdminDetails(adminId);
var adminEmail = adminEmailTemplate.replace("${adminName}", adminDetails[0].full_name);
adminEmail = adminEmail.replace("${emailTableRows}", emailTableRows.toString());
const adminEmailData = {
"recipientEmail":[adminDetails[0].email,"reshmi.nair@tarento.com"],
"emailSubject":"Assessor Upload Status",
"emailBody":adminEmail
};
sendEmailNotification(adminEmailData);
console.log('Admin notification sent..');
}
}
});
}
});
}
561562563564565566567568569570571
});
// Process the API response
} catch (error) {
console.error('Error making API call:', error.message);
throw error;
}
}
// Perform the background task
performBackgroundTask();