Skip to content

Commit

Permalink
HIV 237: Add ability to auto-enrol patients to Enhanced Adherence HIV…
Browse files Browse the repository at this point in the history
… program on a nightly basis
  • Loading branch information
kagai committed Jan 23, 2019
1 parent b41fbda commit 10d8a32
Show file tree
Hide file tree
Showing 9 changed files with 380 additions and 4 deletions.
51 changes: 51 additions & 0 deletions dao/enrollment/double-enrollment-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*jshint -W003, -W097, -W117, -W026 */
'use strict';

var Promise = require('bluebird');
var squel = require('squel');
var _ = require('underscore');
var moment = require('moment');
var connection = require('../../dao/connection/mysql-connection-service.js');
var authorizer = require('../../authorization/etl-authorizer');

var double_enrollment_check = {
getDoubleEnrollment : getDoubleEnrollment
};

module.exports = double_enrollment_check;

//check if patient is enrolled to a program before autoenrolling to prevent double enrollment
function getDoubleEnrollment(patientUuid,programUuid) {

return new Promise(function (resolve, reject) {

connection.getServerConnection()
.then(function (conn) {
var query = squel.select()
.field('count(*) as count')
.from('amrs.patient_program', 'pp')
.join('amrs.person','p','pp.patient_id = p.person_id')
.join('amrs.program','pr','pp.program_id = pr.program_id')
.where('p.uuid = ?',patientUuid)
.where('pr.uuid = ?', programUuid)
.where('pp.date_completed IS NULL')
.toString();
conn.query(query, {}, function (err, rows, fields) {
if (err) {
console.log(err);
reject('Error querying server');
}
else {

resolve(rows);
}
conn.release();
});
})
.catch(function (err) {
reject('Error establishing connection to MySql Server');
});
//amrs patient
});

};
48 changes: 48 additions & 0 deletions dao/enrollment/enrollment-patient-program-dao.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*jshint -W003, -W097, -W117, -W026 */
'use strict';

var Promise = require('bluebird');
var squel = require('squel');
var _ = require('underscore');
var moment = require('moment');
var connection = require('../../dao/connection/mysql-connection-service.js');
var authorizer = require('../../authorization/etl-authorizer');

var enrollments = {
getPatientProgramEnrollment : getPatientProgramEnrollment
};

module.exports = enrollments;

function getPatientProgramEnrollment(patientUuid,incompatibleprograms) {

return new Promise(function (resolve, reject) {
connection.getServerConnection()
.then(function (conn) {
var query = squel.select()
.field('pp.uuid')
.from('amrs.patient_program', 'pp')
.join('amrs.person','p','pp.patient_id = p.person_id')
.join('amrs.program','pr','pp.program_id = pr.program_id')
.where('pr.uuid in ?',incompatibleprograms)
.where('p.uuid = ?',patientUuid)
.where('pp.date_completed IS NULL')
.toString();
conn.query(query, {}, function (err, rows, fields) {
if (err) {
reject('Error querying server');
}
else {
// console.log('patient programs Rows', rows);
resolve(rows);
}
conn.release();
});
})
.catch(function (err) {
reject('Error establishing connection to MySql Server');
});
//amrs patient
});

};
18 changes: 18 additions & 0 deletions docker/auto-enroll/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:6
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
cron rsyslog \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN npm install pm2 -g
COPY . /opt/etl
COPY worker/eid-crontab-sample /etc/cron.d/eid-schedule-task
RUN rm -rf /opt/etl/conf
RUN chmod 0644 /etc/cron.d/eid-schedule-task
RUN npm install -g babel-cli
RUN cd /opt/etl && npm install
ENV TZ=Africa/Nairobi
RUN ln -fs /usr/share/zoneinfo/$TZ /etc/localtime && dpkg-reconfigure -f noninteractive tzdata
RUN echo "cron.* /var/log/cron.log" >> /etc/rsyslog.conf
RUN chmod +x /opt/etl/run1.sh
CMD /opt/etl/run1.sh
8 changes: 4 additions & 4 deletions eid-rest-formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = function () {
var hasLessThanSymbol = /</g;
if (_.isEmpty(viralLoadPayload)) return -1;
var viralLoadResult = removeWhiteSpace(viralLoadPayload.FinalResult);


if (_.isEmpty(viralLoadResult)) {
return -1;
Expand Down Expand Up @@ -279,7 +279,7 @@ module.exports = function () {
body.groupMembers.push(AVGCD3percentLymph);

}

}
if ("AVGCD3AbsCnt" in CD4payload) {
var conceptUuId = "a898fcd2-1350-11df-a1f1-0026b9348838";
Expand All @@ -290,7 +290,7 @@ module.exports = function () {
body.groupMembers.push(AVGCD3AbsCnt);

}

}
if ("AVGCD3CD4percentLymph" in CD4payload) {
var conceptUuId = "a8970a26-1350-11df-a1f1-0026b9348838";
Expand Down Expand Up @@ -324,7 +324,7 @@ module.exports = function () {
body.groupMembers.push(CD45AbsCnt);

}

}

if (CD4payload['OrderNo'] && stringNotEmpty(CD4payload['OrderNo'])) {
Expand Down
16 changes: 16 additions & 0 deletions pm2-AUTO-ENROLL.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apps" : [
{
"name" : "eid-sync",
"script" : "/opt/etl/worker/auto-enroll-veremia.js",
"watch" : false,
"exec_interpreter" : "babel-node",
"exec_mode" : "fork"
},{
"name" : "etl-server",
"script" : "/opt/etl/etl-server.js",
"watch" : false,
"exec_interpreter" : "babel-node",
"exec_mode" : "fork"
}]
}
5 changes: 5 additions & 0 deletions run1.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
echo "Setup cron"
service rsyslog start
service cron start
pm2-docker start /opt/etl/pm2-AUTO-ENROLL.json
213 changes: 213 additions & 0 deletions worker/auto-enroll-veremia.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
const
db = require('../etl-db'),
Promise = require('bluebird'),
https = require('http'),
config = require('../conf/config'),
moment = require('moment'),
curl = require('curlrequest'),
_ = require('underscore'),
program_config = require('../programs/patient-program-config'),
patient_programs = require('../dao/enrollment/enrollment-patient-program-dao'),
check_program_enrollment = require('../dao/enrollment/double-enrollment-check');
const cron = require("node-cron");


var App = {

stateTracker: false,

start: function() {
let _this = this;
this.loadQueueData()
.then(function(data) {
if (data.length > 0) {
App.process(data)
.then(function() {
return App.deleteProcessed(data)
}).then(function(deleted) {

}).catch(function(err) {
console.log(err);
})
} else {
console.log('No data in the queue', new Date());
//process.exit(1);
}
});
},
process: function(data) {
let arrayList = [];
let promise = new Promise(function(resolve, reject) {
data.forEach((arrayItem) => {
const key = arrayItem.program_uuid;
const person_uuid = arrayItem.person_uuid;
let list = [];
if (program_config[key].incompatibleWith && program_config[key].incompatibleWith.length > 0) {
list = program_config[key].incompatibleWith;
_.each(list, function(item) {
patient_programs.getPatientProgramEnrollment(person_uuid, list)
.then(function(rows) {
if (rows && rows.length !== 0) {
_.each(rows, function(row) {
App.unEnrollIfIncompatible(row.uuid);
resolve()
})
App.enroll(person_uuid, key);
} else {
App.enroll(person_uuid, key);
resolve()
}
})
})
} else {
App.enroll(person_uuid, key);
resolve()
}
})
});
return promise;
},
loadQueueData: function() {
let limit = 100;

var sql = 'select * from etl.program_registration_queue limit ?';
var qObject = {
query: sql,
sqlParams: [limit]
};
return new Promise(function(resolve, reject) {
db.queryReportServer(qObject, function(data) {
resolve(data.result);
});
});
},
unEnrollIfIncompatible: function(uuid) {

let protocol = config.etl.tls ? 'https' : 'http';

let date = moment().format('YYYY-MM-DD');

let openmrsAppName = config.openmrs.applicationName || 'amrs';
let payload = {
dateCompleted: date,
uuid: uuid
}

var url = protocol + '://' + config.openmrs.host + ':' + config.openmrs.port + '/' + openmrsAppName + '/ws/rest/v1/programenrollment/' +
payload.uuid;

delete payload['uuid'];
payload = JSON.stringify(payload);

var usernamePass = config.eidSyncCredentials.username + ":" + config.eidSyncCredentials.password;
var auth = "Basic " + Buffer.from(usernamePass).toString('base64');

var options = {
url: url,
data: payload,
headers: {
'Content-Type': 'application/json',
'Authorization': auth
},
method: 'POST'
};

return new Promise(function(resolve, reject) {
curl.request(options, function(err, parts) {
if (err || (parts && JSON.parse(parts).error)) {
console.log(parts && JSON.parse(parts).error);
console.log('error unenrolling to program');
reject(err)
//log error to file or db
} else {
console.log('unenrolling to program: ');
resolve('str')
}
});
})
},

enroll: function(person_uuid, program_uuid) {

let dateEnrolled = moment().format('YYYY-MM-DD');

var openmrsAppName = config.openmrs.applicationName || 'amrs';
var payload = {
program: program_uuid,
patient: person_uuid,
dateEnrolled: dateEnrolled

}
var protocol = config.openmrs.https ? 'https' : 'http';
var url = protocol + '://' + config.openmrs.host + ':' + config.openmrs.port + '/' + openmrsAppName + '/ws/rest/v1/programenrollment/';

var usernamePass = config.eidSyncCredentials.username + ":" + config.eidSyncCredentials.password;
var auth = "Basic " + Buffer.from(usernamePass).toString('base64');

payload = JSON.stringify(payload);

var options = {
url: url,
data: payload,
headers: {
'Content-Type': 'application/json',
'Authorization': auth
},
method: 'POST'
};
return new Promise(function(resolve, reject) {

curl.request(options, function(err, parts) {

if (err || (parts && JSON.parse(parts).error)) {
console.log((parts && JSON.parse(parts).error));
console.log('error enrolling patient into program');
//log to file or database
reject('error enrolling patient into viremia')
} else {
console.log('Enrolled Patient Into Standard HIV Treatment');
resolve('Enrolled Patient Into Program');
}

});
})
},
deleteProcessed: function(data) {
let lst = [];
for (var i = 0; i < data.length; i++) {
var row = data[i];
lst.push(row.person_uuid);
}

var sql = 'delete from etl.program_registration_queue where person_uuid in (?)';

var qObject = {
query: sql,
sqlParams: [lst]
}
return new Promise(function(resolve, reject) {
try {
db.queryReportServer(qObject, function(result) {
console.log(result);
resolve(result);
});
} catch (e) {
//TODO - ignoring delete
resolve(e);
}
});
},

init: function() {
cron.schedule('* * * * *',function(){
try {
App.start();
} catch (e) {
console.log(`Error occured when starting app ${e}`);
}
})
}
}
App.init();

//module.exports = App;
Loading

0 comments on commit 10d8a32

Please sign in to comment.