diff --git a/app/otz/cohort-module.service.js b/app/otz/cohort-module.service.js new file mode 100644 index 000000000..5e7c14f14 --- /dev/null +++ b/app/otz/cohort-module.service.js @@ -0,0 +1,52 @@ +var db = require('../../etl-db'); + +export class CohortModuleService { + getCohortSummary = (cohortUuids) => { + const uuids = cohortUuids + .split(',') + .map((s) => { + return `"${s}"`; + }) + .join(','); + return new Promise((resolve, reject) => { + let queryParts = {}; + const sql = `SELECT + c.uuid, + COUNT(DISTINCT cm.patient_id) AS total_patients, + IFNULL(SUM(CASE + WHEN fl.hiv_viral_load < 200 THEN 1 + ELSE 0 + END) / NULLIF(COUNT(DISTINCT cm.patient_id), 0) * 100, + 0) AS suppression_rate_percentage + FROM + amrs.cohort c + INNER JOIN + amrs.cohort_member cm ON c.cohort_id = cm.cohort_id + LEFT JOIN + (SELECT + person_id, MAX(test_datetime) AS latest_test_datetime + FROM + etl.flat_labs_and_imaging + WHERE + hiv_viral_load IS NOT NULL + GROUP BY person_id) AS latest_tests ON cm.patient_id = latest_tests.person_id + LEFT JOIN + etl.flat_labs_and_imaging fl ON latest_tests.person_id = fl.person_id + AND latest_tests.latest_test_datetime = fl.test_datetime + WHERE + c.uuid in (${uuids}) + GROUP BY c.cohort_id; + + `; + + queryParts = { + sql: sql + }; + + return db.queryServer(queryParts, function (result) { + result.sql = sql; + resolve(result); + }); + }); + }; +} diff --git a/dao/patient/etl-patient-dao.js b/dao/patient/etl-patient-dao.js index ea647f6a0..39a632892 100755 --- a/dao/patient/etl-patient-dao.js +++ b/dao/patient/etl-patient-dao.js @@ -718,6 +718,39 @@ module.exports = (function () { }); } + function getPatientsLatestHivSummmary(request, callback) { + return new Promise(function (resolve, reject) { + const uuid = request.query.uuid ? request.query.uuid.split(',') : []; + + const whereClause = [ + 't1.uuid in ? and t1.next_encounter_datetime_hiv is null', + uuid + ]; + const queryParts = { + columns: + request.query.fields || + ' t1.vl_1 as latest_vl, t1.vl_1_date as latest_vl_date, t2.rtc_date, t1.cur_arv_adherence as adherence, t1.encounter_datetime as latest_appointment, t1.uuid', + table: 'etl.flat_hiv_summary_v15b', + where: whereClause, + leftOuterJoins: [ + [ + 'etl.flat_hiv_summary_v15b', + 't2', + 't1.person_id = t2.person_id and t2.next_clinical_datetime_hiv is null and t2.is_clinical_encounter = 1' + ] + ] + }; + + db.queryDb(queryParts) + .then(function (data) { + resolve(data.result); + }) + .catch((error) => { + reject(error); + }); + }); + } + return { getPatientHivSummary: getPatientHivSummary, getPatientOncologySummary: getPatientOncologySummary, @@ -728,6 +761,7 @@ module.exports = (function () { getHivPatientClinicalSummary: getHivPatientClinicalSummary, getPatientCountGroupedByLocation: getPatientCountGroupedByLocation, getPatientDetailsGroupedByLocation: getPatientDetailsGroupedByLocation, - getHivNegativesPatientSummary: getHivNegativesPatientSummary + getHivNegativesPatientSummary: getHivNegativesPatientSummary, + getPatientsLatestHivSummmary: getPatientsLatestHivSummmary }; })(); diff --git a/departments/department-programs-config.json b/departments/department-programs-config.json index 295306e43..69e171fa4 100755 --- a/departments/department-programs-config.json +++ b/departments/department-programs-config.json @@ -69,6 +69,10 @@ { "uuid": "03552f68-8233-4793-8353-3db1847bb617", "name": "NUTRITION PROGRAM" + }, + { + "uuid": "203571d6-a4f2-4953-9e8b-e1105e2340f5", + "name": "OTZ PROGRAM" } ] }, diff --git a/etl-routes.js b/etl-routes.js index feffa7dab..5afebd42c 100755 --- a/etl-routes.js +++ b/etl-routes.js @@ -81,6 +81,7 @@ import { getPatientCovidVaccinationStatus } from './service/covid-19/covid-19-va import { Covid19MonthlyReport } from './service/covid-19/covid-19-monthly-report'; import { MlWeeklyPredictionsService } from './service/ml-weekly-predictions.service'; import { getPatientPredictedScore } from './service/predictions/ml-prediction-service'; +import { CohortModuleService } from './app/otz/cohort-module.service'; module.exports = (function () { var routes = [ @@ -6291,6 +6292,45 @@ module.exports = (function () { notes: 'Returns the patients predictions data.', tags: ['api'] } + }, + { + method: 'GET', + path: '/etl/hiv-latest-summaries', + config: { + auth: 'simple', + plugins: {}, + handler: function (request, reply) { + dao.getPatientsLatestHivSummmary(request).then((summary) => { + reply(summary); + }); + }, + description: 'Get cohort hiv summaries', + notes: 'Api endpoint that returns cohort hiv summaries', + tags: ['api'] + } + }, + { + method: 'GET', + path: '/etl/viral-load-suppression-rate', + config: { + auth: 'simple', + plugins: {}, + handler: function (request, reply) { + const { uuid } = request.query; + const cohortService = new CohortModuleService(); + cohortService + .getCohortSummary(uuid) + .then(function (cohortUsers) { + reply(cohortUsers); + }) + .catch(function (error) { + reply(new Boom(500, 'Internal server error.', '', '', error)); + }); + }, + description: 'Get cohort viral load suppression rate', + notes: 'Api endpoint that returns cohort viral load suppression rate', + tags: ['api'] + } } ]; diff --git a/programs/patient-program-config.json b/programs/patient-program-config.json index 0a04af3f0..dd34d9eba 100755 --- a/programs/patient-program-config.json +++ b/programs/patient-program-config.json @@ -2090,6 +2090,51 @@ } ] }, + "203571d6-a4f2-4953-9e8b-e1105e2340f5": { + "name": "OTZ PROGRAM", + "enrollmentOptions": { + "requiredProgramQuestions": [], + "allowMultipleEnrollment": false, + "stateChangeEncounterTypes": { + "enrollment": [], + "transfer": [ + { + "uuid": "cbe2d31d-2201-44ce-b52e-fbd5dc7cff33", + "name": "AMPATH POC Transfer Out Form v0.01", + "required": true + } + ], + "discharge": [ + { + "uuid": "c2380050-5e55-4d93-9f4f-cc4cd9d59dc0", + "name": "AMPATH POC OTZ Exit Form V1.0", + "required": true + } + ] + } + }, + "dataDependencies": [ + "patient", + "enrollment", + "hivLastTenClinicalEncounters" + ], + "incompatibleWith": [], + "visitTypes": [ + { + "uuid": "d3d5fd4a-508c-4610-97b7-5197a0bdb88d", + "name": "OTZ Visit ", + "groupVisit": true, + "allowedIf": "age > 9 && age <= 24", + "message": "Patient has to be between the age of 10 and 24", + "encounterTypes": [ + { + "uuid": "76680613-2974-4d89-9b85-6b0a4bf56267", + "display": "OTZACTIVITY" + } + ] + } + ] + }, "781d8768-1359-11df-a1f1-0026b9348837": { "name": "DERMATOLOGY PROGRAM", "enrollmentOptions": {