diff --git a/app/reporting-framework/json-reports/clinical-reminder-report.json b/app/reporting-framework/json-reports/clinical-reminder-report.json index af46abd99..5b738f5f1 100644 --- a/app/reporting-framework/json-reports/clinical-reminder-report.json +++ b/app/reporting-framework/json-reports/clinical-reminder-report.json @@ -79,6 +79,14 @@ "joinCondition": "mwl.person_id = t1.person_id" } }, + { + "table": "etl.pre_appointment_summary", + "alias": "pre_s", + "join": { + "type": "left", + "joinCondition": "mwl.person_id = pre_s.person_id " + } + }, { "table": "amrs.relationship", "alias": "t6", @@ -222,13 +230,43 @@ { "type": "simple_column", "alias": "last_encounter_date", - "column": "ls.encounter_datetime" + "column": "t1.encounter_datetime" }, { "type": "simple_column", "alias": "latest_CD4_Date", "column": "ls.cd4_1_date" }, + { + "type": "simple_column", + "alias": "ipt_start_date", + "column": "ls.ipt_start_date" + }, + { + "type": "simple_column", + "alias": "ipt_stop_date", + "column": "ls.ipt_stop_date" + }, + { + "type": "simple_column", + "alias": "on_ipt", + "column": "ls.on_ipt" + }, + { + "type": "simple_column", + "alias": "ipt_completion_date", + "column": "ls.ipt_completion_date" + }, + { + "type": "simple_column", + "alias": "tb_tx_start_date", + "column": "ls.tb_tx_start_date" + }, + { + "type": "simple_column", + "alias": "tb_tx_end_date", + "column": "ls.tb_tx_end_date" + }, { "type": "simple_column", "alias": "on_tb_tx", @@ -305,6 +343,16 @@ "alias": "prediction_generated_date", "column": "mwl.prediction_generated_date" }, + { + "type": "simple_column", + "alias": "reschedule_appointment", + "column": "pre_s.reschedule_appointment" + }, + { + "type": "simple_column", + "alias": "rescheduled_date", + "column": "pre_s.rescheduled_date" + }, { "type": "simple_column", "alias": "test_date", diff --git a/app/reporting-framework/json-reports/ml-predictions/ml-weekly-predictions-base.json b/app/reporting-framework/json-reports/ml-predictions/ml-weekly-predictions-base.json index f2fa4b3a7..39d5293e8 100644 --- a/app/reporting-framework/json-reports/ml-predictions/ml-weekly-predictions-base.json +++ b/app/reporting-framework/json-reports/ml-predictions/ml-weekly-predictions-base.json @@ -46,7 +46,23 @@ "alias": "pre", "join": { "type": "LEFT", - "joinCondition": "pre.person_id = ml.person_id" + "joinCondition": "pre.person_id = ml.person_id and(DATEDIFF(ml.start_date, pre.encounter_datetime) <= 7)" + } + }, + { + "table": "( select max(is_successful_phone_follow_up) as latest_phone_follow_up, person_id, follow_up_type from etl.pre_appointment_summary group by person_id )", + "alias": "s", + "join": { + "type": "LEFT", + "joinCondition": "pre.person_id = s.person_id" + } + }, + { + "table": "(SELECT et.person_id, SUM(CASE WHEN et.is_successful_phone_follow_up = 'YES' THEN 0 WHEN et.is_successful_phone_follow_up = 'NO' THEN 1 ELSE 0 END) AS counter FROM etl.pre_appointment_summary et left join predictions.ml_weekly_predictions mwl on et.person_id = mwl.person_id WHERE et.encounter_datetime BETWEEN mwl.prediction_generated_date AND DATE_ADD(mwl.prediction_generated_date, INTERVAL 14 DAY) GROUP BY et.person_id)", + "alias": "etc", + "join": { + "type": "LEFT", + "joinCondition": "ml.person_id = etc.person_id" } } ], @@ -156,9 +172,14 @@ "alias": "was_follow_up_successful", "expressionType": "simple_expression", "expressionOptions": { - "expression": "if((pre.is_successful_phone_follow_up = 'YES' OR (pre.attempted_home_visit = 'YES' AND pre.was_client_found = 'YES')), 1, 0)" + "expression": "if((latest_phone_follow_up = 'YES' OR (pre.attempted_home_visit = 'YES' AND pre.was_client_found = 'YES')), 1, 0)" } }, + { + "type": "simple_column", + "alias": "number_of_failed_phone_attempts", + "column": "etc.counter" + }, { "type": "simple_column", "alias": "comments", @@ -180,12 +201,12 @@ }, { "filterType": "tableColumns", - "conditionExpression": "(if((pre.is_successful_phone_follow_up = 'YES' OR (pre.attempted_home_visit = 'YES' AND pre.was_client_found = 'YES')), 1, 0)) = ?", + "conditionExpression": "(if((latest_phone_follow_up = 'YES' OR (pre.attempted_home_visit = 'YES' AND pre.was_client_found = 'YES')), 1, 0)) = ?", "parameterName": "successfulOutcome" }, { "filterType": "tableColumns", - "conditionExpression": "(if((pre.is_successful_phone_follow_up = 'NO' OR (pre.attempted_home_visit = 'YES' AND pre.was_client_found = 'NO')), 1, 0)) = ?", + "conditionExpression": "(if((latest_phone_follow_up = 'NO' OR (pre.attempted_home_visit = 'YES' AND pre.was_client_found = 'NO')), 1, 0)) = ?", "parameterName": "failedOutcome" }, { diff --git a/app/reporting-framework/json-reports/patient-list-with-contacts-template.json b/app/reporting-framework/json-reports/patient-list-with-contacts-template.json index f7ac08f90..0dc61d894 100755 --- a/app/reporting-framework/json-reports/patient-list-with-contacts-template.json +++ b/app/reporting-framework/json-reports/patient-list-with-contacts-template.json @@ -103,6 +103,14 @@ "type": "LEFT", "joinCondition": "delivery_report.person_id = t1.person_id and DATE_FORMAT(delivery_report.date_created, '%Y-%m-%d')='{startDate}'" } + }, + { + "table": "etl.flat_prep_summary_v1_1", + "alias": "fps", + "join": { + "type": "LEFT", + "joinCondition": "t1.person_id = fps.person_id AND fps.next_encounter_datetime IS NULL AND fps.encounter_type NOT IN (99999)" + } } ], "columns": [ @@ -142,6 +150,112 @@ "expression": "extract(year from (from_days(datediff(now(),t1.birthdate))))" } }, + { + "type": "simple_column", + "alias": "prev_rtc_date", + "column": "date_format(fps.prev_rtc_date, '%Y-%m-%d')" + }, + { + "type": "simple_column", + "alias": "cur_prep_meds_names", + "column": "fps.cur_prep_meds_names" + }, + { + "type": "simple_column", + "alias": "rapid_test_date", + "column": "date_format(fps.hiv_rapid_test_date, '%Y-%m-%d')" + }, + { + "type": "derived_column", + "alias": "hiv_rapid_test", + "expressionType": "case_statement", + "expressionOptions": { + "caseOptions": [ + { + "condition": "fps.hiv_rapid_test_result = 703", + "value": "Positive" + }, + { + "condition": "fps.hiv_rapid_test_result = 664", + "value": "Negative" + }, + { + "condition": "fps.hiv_rapid_test_result = 1138", + "value": "Indeterminate" + }, + { + "condition": "fps.hiv_rapid_test_result = 1304", + "value": "Poor sample quality" + }, + { + "condition": "fps.hiv_rapid_test_result = 1067", + "value": "Unknown" + } + ] + } + }, + { + "type": "derived_column", + "alias": "population_type_category", + "expressionType": "case_statement", + "expressionOptions": { + "caseOptions": [ + { + "condition": "fps.sub_population_type = 1", + "value": "MSM" + }, + { + "condition": "fps.sub_population_type = 2", + "value": "MSW" + }, + { + "condition": "fps.sub_population_type = 3", + "value": "FSW" + }, + { + "condition": "fps.sub_population_type = 4", + "value": "IDU" + }, + { + "condition": "fps.sub_population_type = 5", + "value": "TRANS WOMAN" + }, + { + "condition": "fps.sub_population_type = 6", + "value": "TRANS MAN" + }, + { + "condition": "fps.sub_population_type = 7", + "value": "FISHER FOLK" + }, + { + "condition": "fps.sub_population_type = 8", + "value": "CSW" + }, + { + "condition": "fps.sub_population_type = 9", + "value": "DISPLACED PERSONS" + }, + { + "condition": "fps.sub_population_type = 10", + "value": "Military and other" + }, + { + "condition": "fps.sub_population_type = 12", + "value": "TRUCK/LORRY DRIVER" + }, + { + "condition": "fps.sub_population_type = 13", + "value": "NIDU" + } + ] + } + }, + { + "type": "simple_column", + "alias": "enrollment_date", + "column": "date_format(fps.enrollment_date, '%Y-%m-%d')" + }, { "type": "derived_column", "alias": "person_name", diff --git a/app/reporting-framework/json-reports/prep-monthly/disaggregations/new/new-for-prep-base.json b/app/reporting-framework/json-reports/prep-monthly/disaggregations/new/new-for-prep-base.json index b0880c767..aa31e79ce 100644 --- a/app/reporting-framework/json-reports/prep-monthly/disaggregations/new/new-for-prep-base.json +++ b/app/reporting-framework/json-reports/prep-monthly/disaggregations/new/new-for-prep-base.json @@ -43,7 +43,7 @@ { "type": "simple_column", "alias": "ccc_number", - "column": "fi.ccc" + "column": "IFNULL(fi.ccc, 'No CCC')" }, { "type": "simple_column", @@ -60,6 +60,11 @@ "alias": "age", "column": "pd.age" }, + { + "type": "simple_column", + "alias": "latest_rtc_date", + "column": "date_format(pd.rtc_date, '%Y-%m-%d')" + }, { "type": "simple_column", "alias": "location_id", @@ -76,9 +81,29 @@ "column": "l.uuid" }, { - "type": "simple_column", + "type": "derived_column", "alias": "population_type", - "column": "pd.population_type" + "expressionType": "case_statement", + "expressionOptions": { + "caseOptions": [ + { + "condition": "pd.population_type = 1", + "value": "discordant" + }, + { + "condition": "pd.population_type = 2", + "value": "priority" + }, + { + "condition": "pd.population_type = 3 or pd.population_type is null", + "value": "general" + }, + { + "condition": "pd.population_type = 4", + "value": "key" + } + ] + } }, { "type": "derived_column", diff --git a/programs/patient-program-config.json b/programs/patient-program-config.json index 49deeab16..0a04af3f0 100755 --- a/programs/patient-program-config.json +++ b/programs/patient-program-config.json @@ -125,6 +125,10 @@ { "uuid": "37770eca-8a2f-48d6-b3c8-54af0fa989c2", "display": "MENTALHEALTHSCREENING" + }, + { + "uuid": "61ad56ae-a2c3-4ddb-a351-8c8ae253378c", + "display": "ADULTARTPREPARATION" } ] }, @@ -319,6 +323,10 @@ { "uuid": "37770eca-8a2f-48d6-b3c8-54af0fa989c2", "display": "MENTALHEALTHSCREENING" + }, + { + "uuid": "bda00ff3-c811-4223-a602-3eb31c96d1f2", + "display": "PEDARTPREPARATION" } ] }, @@ -498,6 +506,10 @@ { "uuid": "37770eca-8a2f-48d6-b3c8-54af0fa989c2", "display": "MENTALHEALTHSCREENING" + }, + { + "uuid": "a400ea27-7052-4745-b51f-d9370aaef4dc", + "display": "YOUTHARTPREPARATION" } ] }, @@ -4444,7 +4456,7 @@ { "uuid": "8d5b2be0-c2cc-11de-8d13-0010c6dffd0f", "display": "ADULTRETURN", - "allowedIf": "!isViremicHighVL && age > 24", + "allowedIf": "age > 24", "errors": { "viremiaError": "To access clinical forms kindly fill Enhanced Adherence Encounter Form" } @@ -4452,7 +4464,7 @@ { "uuid": "4e7553b4-373d-452f-bc89-3f4ad9a01ce7", "display": "YOUTHRETURN", - "allowedIf": "!isViremicHighVL && age >= 10 && age <= 24", + "allowedIf": "age >= 10 && age <= 24", "errors": { "viremiaError": "To access clinical forms kindly fill Enhanced Adherence Encounter Form" } @@ -4460,7 +4472,7 @@ { "uuid": "8d5b3108-c2cc-11de-8d13-0010c6dffd0f", "display": "PEDSRETURN", - "allowedIf": "!isViremicHighVL && age <= 14", + "allowedIf": "age <= 14", "errors": { "viremiaError": "To access clinical forms kindly fill Enhanced Adherence Encounter Form" } diff --git a/programs/scope-builder.service.js b/programs/scope-builder.service.js index c9e8f4dfb..60e7c3101 100755 --- a/programs/scope-builder.service.js +++ b/programs/scope-builder.service.js @@ -29,7 +29,13 @@ function buildScope(dataDictionary) { 'db2bdd7c-5fe6-4ea3-adc1-d2d8dfb3d658', '17c97881-90e5-43c8-b8a3-cc0322f89a89', 'e9f515c2-7c48-4099-ac76-41db9977f96f', - 'f7aabb83-7915-4c24-88b2-bcde8b3a9977' + 'f7aabb83-7915-4c24-88b2-bcde8b3a9977', + '08feae7c-1352-11df-a1f1-0026b9348838', + '1ce5034b-f05d-46b6-910f-fc959e091641', + '29124daf-6422-4896-b70e-daad3b252c9d', + '08fec42a-1352-11df-a1f1-0026b9348838', + 'a36c86bb-7ca3-4319-8674-28c66ba14deb', + '345514ae-8f37-42fc-9bbe-993828c2910d' ].includes(dataDictionary.intendedVisitLocationUuid); if (dataDictionary.patient) { buildPatientScopeMembers(scope, dataDictionary.patient); @@ -93,7 +99,13 @@ function buildScope(dataDictionary) { 'db2bdd7c-5fe6-4ea3-adc1-d2d8dfb3d658', '17c97881-90e5-43c8-b8a3-cc0322f89a89', 'e9f515c2-7c48-4099-ac76-41db9977f96f', - 'f7aabb83-7915-4c24-88b2-bcde8b3a9977' + 'f7aabb83-7915-4c24-88b2-bcde8b3a9977', + '08feae7c-1352-11df-a1f1-0026b9348838', + '1ce5034b-f05d-46b6-910f-fc959e091641', + '29124daf-6422-4896-b70e-daad3b252c9d', + '08fec42a-1352-11df-a1f1-0026b9348838', + 'a36c86bb-7ca3-4319-8674-28c66ba14deb', + '345514ae-8f37-42fc-9bbe-993828c2910d' ].includes(dataDictionary.intendedVisitLocationUuid); } diff --git a/service/eid/eid-facility-mappings.json b/service/eid/eid-facility-mappings.json index 5c46b9a0b..719daf228 100755 --- a/service/eid/eid-facility-mappings.json +++ b/service/eid/eid-facility-mappings.json @@ -2834,6 +2834,33 @@ "cityVillage": "", "eidDisplay": "" }, + "0cc1e6c8-69a5-4b78-932d-6170fcfb98fe": { + "mrsId": 496, + "mrsDisplay": "Bravo Module-Turbo", + "description": "Bravo Module-Turbo", + "mflCode": "15753", + "county": "Uasin Gishu County", + "cityVillage": "", + "eidDisplay": "" + }, + "a844aa95-e9a6-416b-942b-ac07c1ef84fe": { + "mrsId": 497, + "mrsDisplay": "Maisha Module-Turbo", + "description": "Maisha Module-Turbo", + "mflCode": "15753", + "county": "Uasin Gishu County", + "cityVillage": "", + "eidDisplay": "" + }, + "c22318da-d854-43fa-bd1e-8cb7d1d16ebf": { + "mrsId": 498, + "mrsDisplay": "Victor's Module-Turbo", + "description": "Victor's Module-Turbo", + "mflCode": "15753", + "county": "Uasin Gishu County", + "cityVillage": "", + "eidDisplay": "" + }, "469bb74e-18a4-4d74-872e-55fcebe12dc7": { "mrsId": 328, "mrsDisplay": "Soy MCH", diff --git a/service/patient-reminder.service.js b/service/patient-reminder.service.js index f52fd9f7b..06932baeb 100755 --- a/service/patient-reminder.service.js +++ b/service/patient-reminder.service.js @@ -424,6 +424,12 @@ function TPTReminders(data) { data.inh_treatment_days_remaining < 150 ) { showReminder = true; + } else if ( + data.is_on_inh_treatment && + data.inh_treatment_days_remaining <= 30 && + data.inh_treatment_days_remaining > 0 + ) { + showReminder = true; } // INH Treatment Reminder - last month try { @@ -432,7 +438,7 @@ function TPTReminders(data) { message: 'Patient started ' + months + - ' months' + + ' months ' + treatment + ' treatment on (' + Moment(data.ipt_start_date).format('DD-MM-YYYY') + @@ -442,7 +448,7 @@ function TPTReminders(data) { '). ' + data.inh_treatment_days_remaining + ' days remaining.', - title: 'INH Treatment Reminder', + title: 'TPT Treatment Reminder', type: 'danger', display: { banner: true, @@ -453,37 +459,12 @@ function TPTReminders(data) { } catch (e) { console.log(e); } - // INH Treatment Reminder - last month - if ( - data.is_on_inh_treatment && - data.inh_treatment_days_remaining <= 30 && - data.inh_treatment_days_remaining > 0 - ) { - reminders.push({ - message: - 'Patient started ' + - months + - ' month ' + - treatment + - 'treatment since (' + - Moment(data.ipt_start_date).format('DD-MM-YYYY') + - '). Expected to end on (' + - Moment(data.ipt_completion_date).format('DD-MM-YYYY') + - ') ', - title: 'INH Treatment Reminder', - type: 'danger', - display: { - banner: true, - toast: true - } - }); - } - // TPT Reminders if ( calculateAge(data.birth_date) >= 1 && !data.ipt_start_date && - !data.on_tb_tx + !data.on_tb_tx && + !(data.tb_tx_start_date && !data.tb_tx_end_date) ) { reminders.push({ message: @@ -761,11 +742,11 @@ function getIptCompletionReminder(data) { message: 'Patient started ' + months + - ' month IPT on ' + + ' month TPT on ' + Moment(data.ipt_start_date).format('DD-MM-YYYY') + ' and was supposed to be completed on ' + Moment(data.ipt_start_date).add(months, 'months').format('DD-MM-YYYY'), - title: 'IPT Completion Reminder', + title: 'TPT Completion Reminder', type: 'danger', display: { banner: true, @@ -773,7 +754,7 @@ function getIptCompletionReminder(data) { } }); } else { - console.info.call('No IPT Completion Reminder For Selected Patient'); + console.info.call('No TPT Completion Reminder For Selected Patient'); } return reminders; @@ -964,7 +945,10 @@ function getFPExpiryDate(data) { function generateAppointmentNoShowUpRiskReminder(data) { let reminders = []; const predicted_score = (data.predicted_prob_disengage * 100).toFixed(2); - if (data.predicted_risk) { + if ( + data.predicted_risk && + data.last_encounter_date < data.prediction_generated_date + ) { if (data.predicted_risk === 'Medium Risk') { reminders.push({ message: @@ -1001,8 +985,27 @@ function generateAppointmentNoShowUpRiskReminder(data) { return reminders; } +function generateAppointmentRescheduledReminder(data) { + let reminders = []; + if (data.reschedule_appointment && data.reschedule_appointment === 'YES') { + if (data.last_encounter_date < data.prediction_generated_date) { + reminders.push({ + message: + 'Promised to come date is ' + + Moment(data.rescheduled_date).format('DD-MM-YYYY'), + title: 'Appointment reschedule request', + type: 'ml', + display: { + banner: true, + toast: true + } + }); + } + } + return reminders; +} + async function generateReminders(etlResults, eidResults) { - // console.log('REMINDERS generateReminders'); let reminders = []; let patientReminder; if (etlResults && etlResults.length > 0) { @@ -1044,6 +1047,9 @@ async function generateReminders(etlResults, eidResults) { let appointmentNoShowUpRiskReminder = generateAppointmentNoShowUpRiskReminder( data ); + let appointmentRescheduledRiskReminder = generateAppointmentRescheduledReminder( + data + ); let currentReminder = []; if (pending_vl_lab_result.length > 0) { @@ -1072,8 +1078,11 @@ async function generateReminders(etlResults, eidResults) { reminders = reminders.concat(currentReminder); - // Add appointment no show up risk reminder - reminders = reminders.concat(appointmentNoShowUpRiskReminder); + // Add appointment no show up risk reminder and + reminders = reminders.concat( + appointmentNoShowUpRiskReminder, + appointmentRescheduledRiskReminder + ); patientReminder.reminders = reminders; return patientReminder;