Skip to content

Commit

Permalink
Latest changes from staging (#11)
Browse files Browse the repository at this point in the history
* [skip actions] Configure OpenFn

* Update second workflow (#5)

* add program

* code format

* wip: update mappings for create encounter

* cereate-events

* Update workflow file path

* remove ocl mapping

* Changes accepted by Lightning; updated current project state

* Update 4-get-options-map.js

add missing mapping

* Changes accepted by Lightning; updated current project state

* dataValue mapping- return option code not option uid

* Changes accepted by Lightning; updated current project state

* add identifier mappings

* add draft mappings for other TEAs for wf2

* updating identifier mapping, draft mappings for other TEAs

* cleaning up comments

* mapping fixes per testing

* update gist url

* update mhpss mappings with question names

* update transformation logic

Ref #2 improvements

* Update 4-get-options-map.js

* Update 4-get-options-map.js

* Update 4-get-options-map.js

* user [email protected] initiated a sync from Lightning

* add back config.json file

* Changes accepted by Lightning; updated current project state

* user [email protected] initiated a sync from Lightning

---------

Co-authored-by: mtuchi <[email protected]>
Co-authored-by: Aleksa Krolls <[email protected]>
Co-authored-by: aleksa-krolls <[email protected]>
Co-authored-by: aleksa-krolls <[email protected]>
Co-authored-by: openfn[bot] <openfn[bot]@users.noreply.github.com>
  • Loading branch information
6 people authored Sep 11, 2024
1 parent 2e69404 commit 739077a
Show file tree
Hide file tree
Showing 14 changed files with 947 additions and 254 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
on:
push:
branches:
- staging

concurrency:
group: openfn-deployment
cancel-in-progress: false

jobs:
deploy-to-lightning:
runs-on: ubuntu-latest
name: A job to deploy to Lightning
permissions:
contents: write
steps:
- name: openfn deploy
uses: openfn/[email protected]
with:
secret_input: ${{ secrets.OPENFN_cd92dd57_9a3c_4318_bdcb_f57a386cf811_API_KEY }}
config_path_input: 'openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-config.json'
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
jsconfig.json
# temp
tmp

Expand Down
5 changes: 5 additions & 0 deletions openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"endpoint": "https://app.openfn.org",
"specPath": "openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-spec.yaml",
"statePath": "openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json"
}
571 changes: 541 additions & 30 deletions openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-spec.yaml

Large diffs are not rendered by default.

114 changes: 99 additions & 15 deletions openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions workflows/wf2/1-get-patients.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ fn(state => {
return state;
});

searchPatient({ q: 'Patient', v: 'full', limit: '100' });
searchPatient({ q: 'Aisha', v: 'full', limit: '3' });
// searchPatient({ q: 'Patient', v: 'full', limit: '100' });
//Query all patients (q=all) not supported on demo OpenMRS; needs to be configured
//...so we query all Patients with name "Patient" instead

fn(state => {
const { results } = state.data;

const getPatientByUuid = uuid => {
return results.find(patient => patient.uuid === uuid);
};
// console.log('dateCreated for patient uuid ...2c6dbfc5acc8',getPatientByUuid("31b4d9c8-f7cc-4c26-ae61-2c6dbfc5acc8").auditInfo.dateCreated)
const getPatientByUuid = uuid =>
results.find(patient => patient.uuid === uuid).auditInfo.dateCreated;

// console.log('dateCreated for patient uuid ...2c6dbfc5acc8',getPatientByUuid("31b4d9c8-f7cc-4c26-ae61-2c6dbfc5acc8"))
//console.log(JSON.stringify(state.data, null, 2));

console.log('Filtering patients to only sync most recent records...');
Expand Down
103 changes: 84 additions & 19 deletions workflows/wf2/2-upsert-teis.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,36 @@ fn(state => {
O: 'prefer_not_to_answer',
};

const DHIS2_PATIENT_NUMBER = '8d79403a-c2cc-11de-8d13-0010c6dffd0f';
const OPENMRS_AUTO_ID = '05a29f94-c0ed-11e2-94be-8c13b969e334';
const DHIS2_PATIENT_NUMBER = '8d79403a-c2cc-11de-8d13-0010c6dffd0f'; //DHIS2 ID or DHIS2 Patient Number
const OPENMRS_AUTO_ID = '05a29f94-c0ed-11e2-94be-8c13b969e334'; //MSF ID or OpenMRS Patient Number
const patientsUpsert = [];

const buildPatientsUpsert = (patient, isNewPatient) => {
const dateCreated = patient.auditInfo.dateCreated.substring(0, 10);

const { identifier } =
patient.identifiers.find(
i => i.identifierType.uuid === DHIS2_PATIENT_NUMBER
) ||
patient.identifiers.find(i => i.identifierType.uuid === OPENMRS_AUTO_ID);
function findIdentifierByUuid(identifiers, targetUuid) {
// Use the `find` method to locate the matching identifier
const matchingIdentifier = identifiers.find(
identifier => identifier.identifierType.uuid === targetUuid
);

// Return the `identifier` value if a match is found; otherwise, return null
return matchingIdentifier ? matchingIdentifier.identifier : undefined;
}

const calculateDOB = age => {
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const birthYear = currentYear - age;

const birthday = new Date(
birthYear,
currentDate.getMonth(),
currentDate.getDay()
);

return birthday.toISOString().replace(/\.\d+Z$/, '+0000');
};

const enrollments = [
{
Expand All @@ -31,33 +49,83 @@ fn(state => {
const payload = {
query: {
ou: 'OPjuJMZFLop',
filter: [`AYbfTPYMNJH:Eq:${patient.uuid}`],
program: 'w9MSPn5oSqp',
filter: [`AYbfTPYMNJH:Eq:${patient.uuid}`], //upsert on omrs.patient.uid
},
data: {
program: 'w9MSPn5oSqp',
orgUnit: 'OPjuJMZFLop',
trackedEntityType: 'cHlzCA2MuEF',
attributes: [
{
attribute: 'P4wdYGkldeG',
value: identifier,
attribute: 'fa7uwpCKIwa',
value: patient.person.names[0].givenName,
},
{
attribute: 'Jt9BhFZkvP2',
value: patient.person.names[0].familyName,
},
{
attribute: 'AYbfTPYMNJH',
attribute: 'P4wdYGkldeG', //DHIS2 ID ==> "Patient Number"
value: findIdentifierByUuid(
patient.identifiers,
DHIS2_PATIENT_NUMBER
),
},
{
attribute: 'ZBoxuExmxcZ', //MSF ID ==> "OpenMRS Patient Number"
value: findIdentifierByUuid(patient.identifiers, OPENMRS_AUTO_ID),
},
{
attribute: 'AYbfTPYMNJH', //"OpenMRS Patient UID"
value: patient.uuid,
},
{
attribute: 'qptKDiv9uPl',
value: genderOptions[patient.person.gender],
},
{
attribute: 'T1iX2NuPyqS',
attribute: 'Rv8WM2mTuS5',
value: patient.person.age,
},
{
attribute: 'WDp4nVor9Z7',
value: patient.person.birthdate,
},
// {
// attribute: 'rBtrjV1Mqkz', //Place of living
// value: patient.person.address,
// },
// {
// attribute: 'Xvzc9e0JJmp', //nationality
// value: patient.person.attributes[x].value, //input.attributeType = "24d1fa23-9778-4a8e-9f7b-93f694fc25e2"
// },
// {
// attribute: 'YUIQIA2ClN6', //current status
// value: patient.person.attributes[x].value, //input.attributeType = "e0b6ed99-72c4-4847-a442-e9929eac4a0f"
// },
// {
// attribute: 'Qq6xQ2s6LO8', //legal status
// value: patient.person.attributes[x].value, //input.attributeType = "a9b2c642-097f-43f8-b96b-4d2f50ffd9b1"
// },
// {
// attribute: 'FpuGAOu6itZ', //marital status
// value: patient.person.attributes[x].value, //input.attributeType = "3884dc76-c271-4bcb-8df8-81c6fb897f53"
// },
// {
// attribute: 'v7k4OcXrWR8', //employment status
// value: patient.person.attributes[x].value, //input.attributeType = "dd1f7f0f-ccea-4228-9aa8-a8c3b0ea4c3e"
// },
// {
// attribute: 'SVoT2cVLd5O', //employment status
// value: patient.person.attributes[x].value, //input.attributeType = "e363161a-9d5c-4331-8463-238938f018ed"
// },
],
},
};

console.log('mapped dhis2 payloads:: ', JSON.stringify(payload, null, 2));

if (isNewPatient) {
console.log('create enrollment');
payload.data.enrollments = enrollments;
Expand All @@ -83,7 +151,8 @@ fn(async state => {
'trackedEntityInstances',
{
ou: 'OPjuJMZFLop',
filter: [`jGNhqEeXy2L:Eq:${patient.uuid}`],
filter: [`AYbfTPYMNJH:Eq:${patient.uuid}`],
program: 'w9MSPn5oSqp',
},
{},
state => {
Expand All @@ -106,12 +175,8 @@ fn(async state => {
// Upsert TEIs to DHIS2
each(
'patientsUpsert[*]',
upsert(
'trackedEntityInstances',
state => state.data.query,
state => state.data.data
)
upsert('trackedEntityInstances', $.data.query, $.data.data)
);

// Clean up state
fn(state => ({ ...state, data: {} }));
fn(({ data, ...state }) => state);
20 changes: 13 additions & 7 deletions workflows/wf2/3-get-encounters.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
// Fetch encounters from the date of cursor
// OpenMRS demo instance does not support querying ALL records (q=all)
getEncounters({ q: 'Patient', v: 'full', limit: 100 });
// getEncounters({ q: 'Patient', v: 'full', limit: 100 });
getEncounters({
q: 'Aisha',
v: 'full',
limit: 1,
encounterType: '95d68645-1b72-4290-be0b-ec1fb64bc067',
});

// Update cursor and return encounters
fn(state => {
const { cursor, data } = state;
console.log("cursor datetime::", cursor);
console.log('cursor datetime::', cursor);

console.log('Filtering encounters to only get recent records...');
console.log(
'Encounters returned before we filter for most recent ::',
JSON.stringify(data, null, 2)
);
const encounters = data.body.results.filter(
// console.log(
// 'Encounters returned before we filter for most recent ::',
// JSON.stringify(data, null, 2)
// );
const encounters = data.results.filter(
encounter => encounter.encounterDatetime >= cursor
);
console.log('# of new encounters to sync to dhis2 ::', encounters.length);
Expand Down
65 changes: 0 additions & 65 deletions workflows/wf2/4-get-oclmap.js

This file was deleted.

60 changes: 60 additions & 0 deletions workflows/wf2/4-get-options-map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
get(
'https://gist.githubusercontent.com/aleksa-krolls/b22987f7569bc069e963973401832349/raw/94ae98714c85a6e871fd2fb292c9bff5e324d3a1/msf_mhBaseline_optionsMap.json'
);

fn(state => {
state.optsMap = state.data;
// console.log(JSON.stringify(state.optsMap, null, 2), 'Options Map');
delete state.data;
delete state.references;
delete state.response;
return state;
});

fn(state => {
state.mhpssMap = {
dfdv3SkeXKe: 'a6c5188c-29f0-4d3d-8cf5-7852998df86f', //Has the patient attempted suicide or tried to kill themselves?
hWMBCCA2yy1: 'abede172-ba87-4ebe-8054-3afadb181ea3', //Is the patient currently at risk of hurting himself/herself or attempting suicide?
TWuCY5r2wx7: 'ccc4f06c-b76a-440d-9b7e-c48ba2c4a0ab', //Is the patient currently at risk of hurting others?
QHrIUMhjZlO: 'd516de07-979b-411c-b7e4-bd09cf7d9d91', //Does the patient regularly use alcohol / substances to become intoxicated?
H1fMCaOzr8F: '3e97c2d0-15c1-4cfd-884f-7a4721079217', //Has the patient experienced an act of aggression or violence?
yCwuZ0htrlH: '5f6e245c-83fc-421b-8d46-061ac773ae71', //Follow up session required?
RiiH9A53rvG: '6d3876be-0a27-466d-ad58-92edcc8c31fb', //Referral done
OZViJk8FPVd: 'c2664992-8a5a-4a6d-9238-5df591307d55', //Has the patient had thoughts of death or suicide?
qgfKPlIHjcD: 'd8c84af2-bd9b-4bf3-a815-81652cb0b0bc', //Patient experienced an act of aggression or violence - What type(s) of violence?
rSIazMFEBjD: '4dae5b12-070f-4153-b1ca-fbec906106e1', //Admission type
KSBMR1BDGwx: '1a8bf24f-4f36-4971-aad9-ae77f3525738', //Type of consultation
WDY6MkQWyHb: '722dd83a-c1cf-48ad-ac99-45ac131ccc96', //Consultation done by
AuDPJg6gZE7: '82978311-bef9-46f9-9a9a-cc62254b00a6', //Location of intervention
KeyiEPc4pII: '82978311-bef9-46f9-9a9a-cc62254b00a6', //Type of intervention
qfYPXP76j8g: 'c3c86c1b-07be-4506-ab25-8f35f4389b19', //Patient referred by
PCGI7EnvCQS: '45b39cbf-0fb2-4682-8544-8aaf3e07a744', //Current symptoms or complaints 1
RnbiVrrSFdm: 'ee1b7973-e931-494e-a9cb-22b814b4d8ed', //Current symptoms or complaints 2
CUdI1BJ5W8G: '92a92f62-3ff6-4944-9ea9-a7af23949bad', //Current symptoms or complaints 3
YfcNA5bvkxT: '9a8204ca-d908-4157-9285-7c970dbb5287', //Main category of symptoms
vC3bg9NwJ78: '3edcfddb-7988-4ce5-97a0-d4c46b267a04', //Duration of the main symptom
RqsvaPH9vHt: '22809b19-54ca-4d88-8d26-9577637c184e', //Clinical diagnosis
qacGXlyyQOS: 'a1a75011-0fef-460a-b666-dda2d171f39b', //CGI-S score
S22iy8o0iLg: 'aae000c3-5242-4e3c-bd1f-7e922a6d3d34', //Patient experienced an act of aggression or violence - Time between violence event and consultation
v0qFX0qv1tX: 'd5e3d927-f7ce-4fdd-ac4e-6ad0b510b608', //Main past or precipitating events - 1
SsQqwDBGxjh: '54a9b20e-bce5-4d4a-8c9c-e0248a182586', //Main past or precipitating events - 2
FLIlRjAwn4G: 'e0d4e006-85b5-41cb-8a21-e013b1978b8b', //Main past or precipitating events - 3
JUabDHhT1wJ: 'c1a3ed2d-6d9a-453d-9d93-749164a76413', //Main category of precipitating event
DlqJSA5VApl: '8fb3bb7d-c935-4b57-8444-1b953470e109', //Type of referral
DMaLm9u4GCq: 'b87a93ff-a4a1-4601-b35d-1e42bfa7e194', //Total number of beneficiaries in family consultation
CLGnlnFqqnk: '0a0c70d2-2ba5-4cb3-941f-b4a9a4a7ec6d', //Location of intervention - If Health Facility, specify
f64XCwzJW02: '41e68dee-a2a3-4e6c-9d96-53def5caff52', //Location of intervention - If MSF Health Facility, specify
YeaUNruqmca: '08cd4b4a-4b0b-4391-987b-b5b3d770d30f', //Location of intervention - If Mobile Clinic, specify
KjgDauY9v4J: 'e08d532b-e56c-43dc-b831-af705654d2dc', //Location of intervention - If other, specify
pj5hIE6iyAR: 'e08d532b-e56c-43dc-b831-af705654d2dc', //Current symptoms or complaints - If other, specify
pj5hIE6iyAR: 'e08d532b-e56c-43dc-b831-af705654d2dc', //Current symptoms or complaints - If other, specify
W7cPAi8iXLZ: '819f79e7-b9af-4afd-85d4-2ab677223113', //Clinical diagnosis - If other, specify
MF3RML0HLbP: 'b2c5b6e0-66f0-4b9d-8576-b6f48e0a06df', //MHOS score
m8qis4iUOTo: '790b41ce-e1e7-11e8-b02f-0242ac130002', //Past / Precipitating Events - If other, specify
//pN4iQH4AEzk: '722dd83a-c1cf-48ad-ac99-45ac131ccc96', //Consultation done by //TODO: Return BOOLEAN
//qptKDiv9uPl: 'ec42d68d-3e23-43de-b8c5-a03bb538e7c7', //Sex //TODO: Remove TEA?
//tsFOVnlc6lz: '5f3d618e-5c89-43bd-8c79-07e4e98c2f23', //PHQ9 Score //TODO: ass logic
};

return state;
});
Loading

0 comments on commit 739077a

Please sign in to comment.