forked from OpenFn/openfn-lime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopenfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json
328 lines (328 loc) · 63.7 KB
/
openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
{
"id": "cd92dd57-9a3c-4318-bdcb-f57a386cf811",
"name": "msf-lime-iraq-main",
"description": null,
"inserted_at": "2024-09-05T06:59:05Z",
"updated_at": "2024-12-17T07:58:27Z",
"project_credentials": {
"[email protected]": {
"id": "3141d874-5456-4168-9680-ce04efb1089c",
"name": "OpenMRS Demo",
"owner": "[email protected]"
},
"[email protected]": {
"id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d",
"name": "MSF DHIS2 UAT",
"owner": "[email protected]"
},
"[email protected]": {
"id": "2eace4af-4e52-484c-82b0-ffb1717c259d",
"name": "AK Sharepoint",
"owner": "[email protected]"
},
"[email protected]": {
"id": "6533e534-6ad8-4651-b27d-245b8cbb69d8",
"name": "mtuchi-github-token",
"owner": "[email protected]"
},
"[email protected]": {
"id": "3dd044bb-6a0e-4f16-a80d-836a39f95b40",
"name": "OpenFnSharepoint",
"owner": "[email protected]"
},
"[email protected](HTTP)": {
"id": "62cab5d8-939f-46f3-b635-cb79a1e1dc5d",
"name": "OpenMRS Demo (HTTP)",
"owner": "[email protected]"
}
},
"scheduled_deletion": null,
"history_retention_period": 365,
"dataclip_retention_period": null,
"retention_policy": "retain_all",
"workflows": {
"wf2-omrs-dhis2": {
"id": "0f8ec062-1a2d-4f13-a8c5-b8298004512c",
"name": "wf2-omrs-dhis2",
"edges": {
"cron->Get-Patients": {
"enabled": true,
"id": "7d239f46-635e-4b7f-8706-6a3d08d473db",
"source_trigger_id": "51283b68-c07a-4d85-854c-c2e6e93af041",
"condition_type": "always",
"target_job_id": "ab326112-9cdd-4449-8611-b5abc659d4ca"
},
"Upsert-TEIs->Get-Encounters": {
"enabled": true,
"id": "79ca3ec3-641f-4167-8fe3-a96c40cc9954",
"source_job_id": "6973c510-b36d-4c42-82f5-b26d8cd36a57",
"condition_expression": "state.patientUuids.length > 0 && !state.errors\n",
"condition_type": "js_expression",
"condition_label": "has-patient-uuids",
"target_job_id": "8fb577e5-d068-4d47-8172-81f08153ced9"
},
"Get-TEIs-and-Map-Answers->Create-Events": {
"enabled": true,
"id": "32b04529-a796-461c-8a0a-a5e543ef535e",
"source_job_id": "99e52cef-d4f2-4c5e-8718-e240bb3deab3",
"condition_expression": "state.TEIs && !state.errors\n",
"condition_type": "js_expression",
"condition_label": "has-teis",
"target_job_id": "932645d8-ddb8-4d00-841e-7fe7af214837"
},
"Mappings->Upsert-TEIs": {
"enabled": true,
"id": "5619b87c-685d-45b7-b2b6-ef598018d360",
"source_job_id": "79b58ab5-cb0a-44a5-b230-776b4016464a",
"condition_type": "on_job_success",
"target_job_id": "6973c510-b36d-4c42-82f5-b26d8cd36a57"
},
"Get-Patients->Mappings": {
"enabled": true,
"id": "65613153-275c-4897-a6ad-256ad818358c",
"source_job_id": "ab326112-9cdd-4449-8611-b5abc659d4ca",
"condition_expression": "state.patients.length > 0 && !state.errors\n",
"condition_type": "js_expression",
"condition_label": "has-patients",
"target_job_id": "79b58ab5-cb0a-44a5-b230-776b4016464a"
},
"Create-Events->Update-TEIs": {
"enabled": true,
"id": "456bc7f5-04cf-4d3c-91a1-9ecbfee0c986",
"source_job_id": "932645d8-ddb8-4d00-841e-7fe7af214837",
"condition_expression": "state.genderUpdated.length > 0 && !state.errors\n",
"condition_type": "js_expression",
"condition_label": "has-gender-updated",
"target_job_id": "b30b4200-d2f8-4c7a-827a-bec10c64fbc3"
},
"Get-Encounters->Get-TEIs-and-Map-Answers": {
"enabled": true,
"id": "3a099da2-12de-42ae-889e-2b11946e974a",
"source_job_id": "8fb577e5-d068-4d47-8172-81f08153ced9",
"condition_type": "on_job_success",
"target_job_id": "99e52cef-d4f2-4c5e-8718-e240bb3deab3"
}
},
"concurrency": null,
"inserted_at": "2024-09-06T11:58:48Z",
"updated_at": "2024-12-17T07:58:27Z",
"jobs": {
"Get-Patients": {
"id": "ab326112-9cdd-4449-8611-b5abc659d4ca",
"name": "Get Patients",
"body": "cursor($.lastRunDateTime || $.manualCursor || '2023-05-20T06:01:24.000+0000');\n\ncursor('today', {\n key: 'lastRunDateTime',\n format: c => dateFns.format(new Date(c), \"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'\"),\n});\n\nsearchPatient({ q: 'IQ', v: 'full', limit: '100' });\n\nfn(state => {\n const { cursor, data, lastRunDateTime } = state;\n console.log('Filtering patients since cursor:', cursor);\n\n const patients = data.results.filter(({ auditInfo }) => {\n const lastModified = auditInfo?.dateChanged || auditInfo?.dateCreated;\n return lastModified > cursor;\n });\n console.log('# of patients to sync to dhis2 ::', patients.length);\n console.log(\n 'uuids of patients to sync to dhis2 ::',\n patients.map(p => p.uuid)\n );\n\n return { cursor, lastRunDateTime, patients };\n});\n",
"adaptor": "@openfn/language-openmrs@latest",
"project_credential_id": "3141d874-5456-4168-9680-ce04efb1089c"
},
"Upsert-TEIs": {
"id": "6973c510-b36d-4c42-82f5-b26d8cd36a57",
"name": "Upsert TEIs",
"body": "const buildPatientsUpsert = (state, patient, isNewPatient) => {\n const { placeOflivingMap, genderOptions } = state;\n const dateCreated = patient.auditInfo.dateCreated.substring(0, 10);\n const findIdentifierByUuid = (identifiers, targetUuid) =>\n identifiers.find(i => i.identifierType.uuid === targetUuid)?.identifier;\n\n const enrollments = [\n {\n orgUnit: state.orgUnit,\n program: state.program,\n programStage: state.patientProgramStage, //'MdTtRixaC1B',\n enrollmentDate: dateCreated,\n },\n ];\n\n const findOptsUuid = uuid =>\n patient.person.attributes.find(a => a.attributeType.uuid === uuid)?.value\n ?.uuid ||\n patient.person.attributes.find(a => a.attributeType.uuid === uuid)?.value;\n\n const findOptCode = optUuid =>\n state.optsMap.find(o => o['value.uuid - External ID'] === optUuid)?.[\n 'DHIS2 Option Code'\n ];\n\n const patientMap = state.formMaps.patient.dataValueMap;\n const statusAttrMaps = Object.keys(patientMap).map(d => {\n const optUid = findOptsUuid(patientMap[d]);\n return {\n attribute: d,\n value: findOptCode(optUid) || optUid,\n };\n });\n\n const payload = {\n query: {\n ou: state.orgUnit,\n program: state.program,\n filter: [`AYbfTPYMNJH:Eq:${patient.uuid}`], //upsert on omrs.patient.uid\n },\n data: {\n program: state.program,\n orgUnit: state.orgUnit,\n trackedEntityType: 'cHlzCA2MuEF',\n attributes: [\n {\n attribute: 'fa7uwpCKIwa',\n value: patient.person?.names[0]?.givenName,\n },\n {\n attribute: 'Jt9BhFZkvP2',\n value: patient.person?.names[0]?.familyName,\n },\n {\n attribute: 'P4wdYGkldeG', //DHIS2 ID ==> \"Patient Number\"\n value:\n findIdentifierByUuid(\n patient.identifiers,\n state.dhis2PatientNumber\n ) || findIdentifierByUuid(patient.identifiers, state.openmrsAutoId), //map OMRS ID if no DHIS2 id\n },\n {\n attribute: 'ZBoxuExmxcZ', //MSF ID ==> \"OpenMRS Patient Number\"\n value: findIdentifierByUuid(patient.identifiers, state.openmrsAutoId),\n },\n {\n attribute: 'AYbfTPYMNJH', //\"OpenMRS Patient UID\"\n value: patient.uuid,\n },\n {\n attribute: 'qptKDiv9uPl',\n value: genderOptions[patient.person.gender],\n },\n {\n attribute: 'T1iX2NuPyqS',\n value: patient.person.age,\n },\n {\n attribute: 'WDp4nVor9Z7',\n value: patient.person.birthdate.slice(0, 10),\n },\n {\n attribute: 'rBtrjV1Mqkz', //Place of living\n value: placeOflivingMap[patient.person?.addresses[0]?.cityVillage],\n },\n ...statusAttrMaps,\n ],\n },\n };\n\n console.log('mapped dhis2 payloads:: ', JSON.stringify(payload, null, 2));\n\n if (isNewPatient) {\n console.log('create enrollment');\n payload.data.enrollments = enrollments;\n }\n\n return payload;\n};\n\nconst delay = ms => new Promise(resolve => setTimeout(resolve, ms));\n\neach(\n $.patients,\n get(\n 'tracker/trackedEntities',\n {\n orgUnit: $.orgUnit,\n filter: [`AYbfTPYMNJH:Eq:${$.data?.uuid}`],\n program: $.program,\n },\n {},\n async state => {\n const patient = state.references.at(-1);\n console.log(patient.uuid, 'patient uuid');\n\n const isNewPatient = state.data.instances.length === 0;\n\n state.patientsUpsert ??= [];\n state.patientsUpsert.push(\n buildPatientsUpsert(state, patient, isNewPatient)\n );\n await delay(2000);\n return state;\n }\n )\n);\n\n// Upsert TEIs to DHIS2\neach(\n $.patientsUpsert,\n upsert('trackedEntityInstances', $.data.query, $.data.data)\n);\nfn(state => {\n const {\n data,\n response,\n references,\n patients,\n patientsUpsert,\n placeOflivingMap,\n genderOptions,\n identifiers,\n ...next\n } = state;\n\n next.patientUuids = patients.map(p => p.uuid);\n return next;\n});",
"adaptor": "@openfn/[email protected]",
"project_credential_id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d"
},
"Get-Encounters": {
"id": "8fb577e5-d068-4d47-8172-81f08153ced9",
"name": "Get Encounters",
"body": "// Fetch all encounters\nget(\n '/ws/fhir2/R4/Encounter',\n { query: { _count: 100, _lastUpdated: `ge${$.cursor}` }, parseAs: 'json' },\n state => {\n const { link, total } = state.data;\n state.nextUrl = link\n .find(l => l.relation === 'next')\n ?.url.replace(/(_count=)\\d+/, `$1${total}`);\n\n state.allResponse = state.data;\n return state;\n }\n);\n\nfnIf(\n $.nextUrl,\n get($.nextUrl, { parseAs: 'json' }, state => {\n delete state.allResponse.link;\n state.allResponse.entry.push(...state.data.entry);\n console.log(state.allResponse.entry.length);\n return state;\n })\n);\n\nfn(state => {\n state.encounterUuids = state.allResponse.entry.map(p => p.resource.id);\n state.patientUuids = [\n ...new Set(\n state.allResponse.entry.map(p =>\n p.resource.subject.reference.replace('Patient/', '')\n )\n ),\n ];\n\n return state;\n});\n\n// Fetch patient encounters\neach(\n $.patientUuids,\n get(\n '/ws/rest/v1/encounter/',\n { query: { patient: $.data, v: 'full' }, parseAs: 'json' },\n state => {\n const patientUuid = state.references.at(-1);\n const filteredEncounters = state.formUuids.map(formUuid =>\n state.data.results.filter(\n e => e.encounterDatetime >= state.cursor && e?.form?.uuid === formUuid\n )\n );\n\n const encounters = filteredEncounters.map(e => e[0]).filter(e => e);\n state.encounters ??= [];\n state.encounters.push(...encounters);\n\n console.log(\n encounters.length,\n `# of filtered encounters found in OMRS for ${patientUuid}`\n );\n\n return state;\n }\n )\n);\n\nfn(state => {\n const {\n data,\n index,\n response,\n references,\n allResponse,\n patientUuids,\n ...next\n } = state;\n console.log(next.encounters.length, '# of new encounters to sync to dhis2');\n\n return next;\n});",
"adaptor": "@openfn/language-http@latest",
"project_credential_id": "62cab5d8-939f-46f3-b635-cb79a1e1dc5d"
},
"Get-TEIs-and-Map-Answers": {
"id": "99e52cef-d4f2-4c5e-8718-e240bb3deab3",
"name": "Get TEIs and Map Answers",
"body": "const delay = ms => new Promise(resolve => setTimeout(resolve, ms));\n\neach(\n $.encounters,\n get(\n 'tracker/trackedEntities',\n {\n orgUnit: $.orgUnit,\n program: $.program,\n filter: [`AYbfTPYMNJH:Eq:${$.data.patient.uuid}`],\n fields: '*,enrollments[*],enrollments[events[*]]',\n },\n {},\n async state => {\n const encounter = state.references.at(-1);\n console.log(encounter.patient.uuid, 'Encounter patient uuid');\n\n const { trackedEntity, enrollments } = state.data?.instances?.[0] || {};\n if (trackedEntity && enrollments) {\n state.TEIs ??= {};\n state.TEIs[encounter.patient.uuid] = {\n trackedEntity,\n events: enrollments[0]?.events,\n enrollment: enrollments[0]?.enrollment,\n };\n }\n\n await delay(2000);\n return state;\n }\n )\n);\n\nconst processAnswer = (\n answer,\n conceptUuid,\n dataElement,\n optsMap,\n optionSetKey\n) => {\n return typeof answer.value === 'object'\n ? processObjectAnswer(\n answer,\n conceptUuid,\n dataElement,\n optsMap,\n optionSetKey\n )\n : processOtherAnswer(answer, conceptUuid, dataElement);\n};\n\nconst processObjectAnswer = (\n answer,\n conceptUuid,\n dataElement,\n optsMap,\n optionSetKey\n) => {\n if (isDiagnosisByPsychologist(conceptUuid, dataElement)) {\n console.log('Yes done by psychologist..');\n return '' + answer.value.uuid === '278401ee-3d6f-4c65-9455-f1c16d0a7a98';\n }\n\n if (isTrueOnlyQuestion(conceptUuid, dataElement)) {\n console.log('True only question detected..', dataElement);\n return answer.value.uuid === '681cf0bc-5213-492a-8470-0a0b3cc324dd'\n ? 'true'\n : undefined;\n }\n\n return findMatchingOption(answer, optsMap, optionSetKey);\n};\n\nconst processOtherAnswer = (answer, conceptUuid, dataElement) => {\n if (isPhq9Score(answer.value, conceptUuid, dataElement)) {\n console.log('isPhq9Score', isPhq9Score);\n return getRangePhq(answer.value);\n }\n return answer.value;\n};\n\nconst processNoAnswer = (data, conceptUuid, dataElement) => {\n if (isEncounterDate(conceptUuid, dataElement)) {\n return data.encounterDatetime.replace('+0000', '');\n }\n return '';\n};\n\nconst findMatchingOption = (answer, optsMap, optionSetKey) => {\n const optionKey = `${answer.formUuid}-${answer.concept.uuid}`;\n\n const matchingOptionSet = optionSetKey[optionKey];\n console.log('optionKey', optionKey);\n console.log('conceptUid', answer.concept.uuid);\n console.log('value uid', answer.value.uuid);\n console.log('value display', answer.value.display);\n console.log('matchingOptionSet', matchingOptionSet);\n\n const matchingOption =\n optsMap.find(\n o =>\n o['value.uuid - External ID'] === answer.value.uuid &&\n o['DHIS2 Option Set UID'] === matchingOptionSet\n )?.['DHIS2 Option Code'] || answer.value.display; //TODO: revisit this logic if optionSet not found\n\n console.log('matchingOption value', matchingOption);\n\n if (matchingOption === 'FALSE') {\n return 'false';\n }\n if (matchingOption === 'TRUE') {\n return 'true';\n }\n\n return matchingOption || '';\n};\n\nconst isEncounterDate = (conceptUuid, dataElement) => {\n return (\n conceptUuid === 'encounter-date' &&\n ['CXS4qAJH2qD', 'I7phgLmRWQq', 'yUT7HyjWurN'].includes(dataElement)\n );\n};\n\nconst isTrueOnlyQuestion = (conceptUuid, dataElement) =>\n conceptUuid === '54e8c1b6-6397-4822-89a4-cf81fbc68ce9' &&\n dataElement === 'G0hLyxqgcO7';\n\nconst isDiagnosisByPsychologist = (conceptUuid, dataElement) =>\n conceptUuid === '722dd83a-c1cf-48ad-ac99-45ac131ccc96' &&\n dataElement === 'pN4iQH4AEzk';\n\nconst isPhq9Score = (value, conceptUuid, dataElement) =>\n typeof value === 'number' &&\n (conceptUuid === '5f3d618e-5c89-43bd-8c79-07e4e98c2f23' ||\n conceptUuid === '6545b874-f44d-4d18-9ab1-7a8bb21c0a15');\n\nconst getRangePhq = input => {\n if (input >= 20) return '>20';\n if (input >= 15) return '15_19';\n if (input >= 10) return '10_14';\n if (input >= 5) return '5_9';\n return '0_4';\n};\n\nconst dataValuesMapping = (data, dataValueMap, optsMap, optionSetKey) => {\n return Object.keys(dataValueMap)\n .map(dataElement => {\n const conceptUuid = dataValueMap[dataElement];\n const obsAnswer = data.obs.find(o => o.concept.uuid === conceptUuid);\n const answer = {\n ...obsAnswer,\n formUuid: data.form.uuid,\n };\n const value = answer\n ? processAnswer(answer, conceptUuid, dataElement, optsMap, optionSetKey)\n : processNoAnswer(data, conceptUuid, dataElement);\n\n return { dataElement, value };\n })\n .filter(d => d);\n};\n\n// Prepare DHIS2 data model for create events\nfn(state => {\n const handleMissingRecord = (data, state) => {\n const { uuid, display } = data.patient;\n\n console.log(uuid, 'Patient is missing trackedEntity && enrollment');\n\n state.missingRecords ??= {};\n state.missingRecords[uuid] ??= {\n encounters: [],\n patient: display,\n };\n\n state.missingRecords[uuid].encounters.push(data.uuid);\n };\n\n const processEncounter = (data, state) => {\n const form = state.formMaps[data.form.uuid];\n if (!form?.dataValueMap) {\n return null;\n }\n const { trackedEntity, enrollment, events } =\n state.TEIs[data.patient.uuid] || {};\n\n if (!trackedEntity || !enrollment) {\n handleMissingRecord(data, state);\n return null;\n }\n\n return {\n event: events.find(e => e.programStage === form.programStage)?.event,\n program: state.program,\n orgUnit: state.orgUnit,\n trackedEntity,\n enrollment,\n occurredAt: data.encounterDatetime.replace('+0000', ''),\n programStage: form.programStage,\n dataValues: dataValuesMapping(\n data,\n form.dataValueMap,\n state.optsMap,\n state.optionSetKey\n ),\n };\n };\n\n state.encountersMapping = state.encounters\n .map(data => processEncounter(data, state))\n .filter(Boolean);\n\n return state;\n});",
"adaptor": "@openfn/[email protected]",
"project_credential_id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d"
},
"Create-Events": {
"id": "932645d8-ddb8-4d00-841e-7fe7af214837",
"name": "Create Events",
"body": "// Create or update events for each encounter\ncreate(\n 'tracker',\n {\n events: state => {\n console.log(\n 'Creating events for: ',\n JSON.stringify(state.encountersMapping, null, 2)\n );\n return state.encountersMapping;\n },\n },\n {\n params: {\n async: false,\n dataElementIdScheme: 'UID',\n importStrategy: 'CREATE_AND_UPDATE',\n },\n }\n);\n\nfn(state => {\n const latestGenderUpdate = state.encounters.reduce((acc, e) => {\n const answer = e.obs.find(\n o => o.concept.uuid === 'ec42d68d-3e23-43de-b8c5-a03bb538e7c7'\n );\n if (answer) {\n const personUuid = answer.person.uuid;\n if (\n !acc[personUuid] ||\n new Date(answer.obsDatetime) > new Date(acc[personUuid].obsDatetime)\n ) {\n acc[personUuid] = answer;\n }\n }\n return acc;\n }, {});\n\n state.genderUpdated = Object.values(latestGenderUpdate);\n\n return state;\n});\n\nfnIf(\n state => state.genderUpdated.length === 0,\n ({ lastRunDateTime }) => ({ lastRunDateTime })\n);",
"adaptor": "@openfn/[email protected]",
"project_credential_id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d"
},
"Mappings": {
"id": "79b58ab5-cb0a-44a5-b230-776b4016464a",
"name": "Mappings",
"body": "fn(state => {\n state.placeOflivingMap = {\n 'Al Ayadya': 'lon42.423409_lat36.481517',\n 'Al Bosaif': 'lon43.159987_lat36.27218',\n 'Al Jazaer': 'lon43.164382_lat36.354178',\n 'Al Karama': 'lon43.203229_lat36.341201',\n 'Al Mothana': 'lon43.171821_lat36.37478',\n 'Al Nabi Younis': 'lon43.165939_lat36.348147',\n 'Al Qawsyat': 'lon43.103793_lat36.440127',\n 'Al Rashedia': 'lon43.092499_lat36.405267',\n 'Al Sahaji': 'lon42.94467_lat36.280869',\n 'Al Salamya': 'lon43.314713_lat36.142365',\n 'Al Shora': 'lon43.223899_lat35.994031',\n 'Al Sokar': 'lon43.169151_lat36.389263',\n 'Al Zahra': 'lon43.209061_lat36.384103',\n 'Al-Abar': 'lon43.097359_lat36.337313',\n 'Al-Adba': 'lon43.107228_lat36.228804',\n Alamel: 'lon43.095958_lat36.324676',\n 'Al-Araby': 'lon43.116613_lat36.405873',\n Alathba: 'lon43.107062_lat36.228771',\n 'Al-Auraiby': 'lon43.092403_lat36.35815',\n 'Al-Baaj': 'lon41.715935_lat36.04154',\n 'Al-Bakeer': 'lon43.2005_lat36.372429',\n 'Al-Dandan': 'lon43.146081_lat36.33257',\n 'Al-Ekhaa': 'lon43.216323_lat36.353175',\n 'Al-Ektasadeen': 'lon43.086044_lat36.361673',\n 'Al-Entesar': 'lon43.213825_lat36.326253',\n Aleslaah: 'lon43.082506_lat36.350517',\n 'Al-Faroak': 'lon43.128901_lat36.337586',\n Alflah: 'lon43.183338_lat36.394155',\n Algosq: 'lon43.150265_lat36.327732',\n Algzlany: 'lon43.137129_lat36.320443',\n 'Al-Hadbaa': 'lon43.15051_lat36.394474',\n Alhrmat: 'lon43.072674_lat36.362245',\n 'Al-Humaidat': 'lon42.978138_lat36.403105',\n Aljazeera: 'lon42.268108_lat35.764664',\n 'Al-Kadasia': 'lon43.200525_lat36.380719',\n 'Al-Kuba': 'lon43.072704_lat36.410733',\n 'Al-Ma`Mun': 'lon43.10664_lat36.310099',\n 'Al-Maghrab': 'lon43.079798_lat36.334318',\n Almalayeen: 'lon43.103821_lat36.424167',\n 'Al-Masarf': 'lon43.179613_lat36.38814',\n 'Al-Matahen': 'lon43.09246_lat36.338635',\n Almnsoor: 'lon43.11188_lat36.318691',\n Almoaly: 'lon42.838777_lat36.324391',\n Almohalabya: 'lon42.703975_lat36.265162',\n Almshahda: 'lon43.120709_lat36.343216',\n 'Al-Mualamin': 'lon42.923458_lat36.31039',\n Almuhandseen: 'lon43.137239_lat36.367498',\n Alngar: 'lon43.100449_lat36.357173',\n Alnuor: 'lon43.187796_lat36.365769',\n Alobor: 'lon43.059863_lat36.313292',\n Alquds: 'lon43.22851_lat36.344222',\n 'Al-Qyaraa': 'lon43.29582_lat35.798215',\n Alresala: 'lon43.090091_lat36.322804',\n 'Al-Rifa`I': 'lon43.102846_lat36.360217',\n 'Al-Saaha': 'lon43.097854_lat36.34371',\n 'Al-Sahaji': 'lon42.94396_lat36.280114',\n 'Al-Samah': 'lon43.212253_lat36.35825',\n 'Al-Sekak': 'lon43.100669_lat36.339441',\n 'Al-Shefaa': 'lon43.121928_lat36.352',\n Alshohadaa: 'lon43.101322_lat36.318532',\n Alshykhan: 'lon43.350052_lat36.691541',\n 'Alsinaa Alkadema': 'lon43.071956_lat36.347428',\n Alsmood: 'lon43.111796_lat36.320265',\n 'Al-Tahrer': 'lon43.201287_lat36.390342',\n 'Al-Taiaran': 'lon43.140315_lat36.325341',\n Altank: 'lon43.069844_lat36.334344',\n Althoraa: 'lon43.110259_lat36.343145',\n 'Al-Wahdaa': 'lon43.184839_lat36.331538',\n 'Al-Warshan': 'lon43.097102_lat36.350075',\n Alyrmoq: 'lon43.082273_lat36.336458',\n Alzngly: 'lon43.109626_lat36.353944',\n 'Aski Mousl': 'lon42.73514_lat36.513471',\n Auenat: 'lon42.399071_lat36.67976',\n 'Bab Al-Bead': 'lon43.127605_lat36.334953',\n Badush: 'lon42.967959_lat36.41445',\n Bartella: 'lon43.380304_lat36.349597',\n Basheeka: 'lon43.342171_lat36.451798',\n Dohok: 'lon42.9842_lat36.859369',\n Gogjali: 'lon43.246833_lat36.353981',\n 'Hamaam Alaleel': 'lon43.260379_lat36.160157',\n 'Hawi Al-Kanisa': 'lon43.085152_lat36.381247',\n 'Mosul Algdida': 'lon43.104377_lat36.331809',\n 'Mosul Al-Kadema': 'lon43.126541_lat36.342823',\n Msherfa: 'lon43.179668_lat36.387648',\n Nablus: 'lon43.084701_lat36.328359',\n Rabeaa: 'lon42.08276_lat36.808678',\n 'Ragm Hadid': 'lon43.076396_lat36.326236',\n Sadam: 'lon43.208775_lat36.383105',\n Sanjar: 'lon41.864538_lat36.316244',\n Somer: 'lon43.200918_lat36.301028',\n Sumeel: 'lon42.847606_lat36.857084',\n 'Tal Abta': 'lon42.563028_lat35.94226',\n 'Tal Afer': 'lon42.450003_lat36.374589',\n 'Tal Alroman': 'lon43.089466_lat36.316493',\n 'Tal Keef': 'lon43.120284_lat36.489935',\n 'Tal Zalt': 'lon42.829782_lat36.282837',\n Tmooz: 'lon43.084933_lat36.365008',\n 'Twim & Mjarin': 'lon42.692998_lat36.363335',\n 'Wady Alaen': 'lon43.103452_lat36.325881',\n 'Wady Hagr': 'lon43.126976_lat36.320946',\n Zakho: 'lon42.688446_lat37.146393',\n Zumar: 'lon42.603252_lat36.655901',\n Other: 'lon0.0_lat0.0',\n };\n return state;\n});\nfn(state => {\n state.nationalityMap = {\n '84066564-253e-43d8-b141-76730cffa878': 'afghanistan',\n 'db21f4f9-faf2-4358-8297-0ae76627b3b8': 'albania',\n '5f6c017f-074c-46b3-92d0-d055e2094366': 'algeria',\n '8a2e5a03-8a74-41ae-9a98-2310f9ce400d': 'angola',\n 'c911af8a-171c-4ee9-b1ff-934373e8a819': 'anguilla',\n 'b83d24e8-34d8-4920-83c0-8ba014467ff4': 'argentina',\n '39f1652a-f2b7-4b65-a7e1-7097ac6cdef0': 'armenia',\n 'f3f1cba1-7c1e-4234-86a2-f27bb5964fee': 'aruba',\n '29750013-0e35-47ca-8f77-9192a923fb07': 'azerbaijan',\n 'a99de53c-ce76-4b1e-91b2-461094baf79e': 'bangladesh',\n '664baba4-c552-47b9-97c0-ff67dafd27d6': 'belarus',\n 'cf863e31-bb38-48ed-90dd-f3dedcac304c': 'benin',\n 'd45a57c9-994f-4deb-8845-9b785860a2ec': 'bhutan',\n 'd8800d10-862b-42f1-8e22-cac1ce1bbcae': 'bolivia',\n '05d8f4ef-45eb-463d-b2f3-8a5a613ee6b9': 'bosnia_and_herzegovina',\n '1304a0de-5b70-4d36-a873-e72a82963316': 'botswana',\n '353ff388-64e6-434c-b78f-ca9636390389': 'brazil',\n 'b02c6d20-83a2-4947-8a7d-91d1f9c4d8a2': 'british_virgin_islands',\n '91c85a62-2b02-483a-aefd-e29d368565fe': 'bulgaria',\n '6c90c1ae-17a4-4e94-a267-4fba4c94efd8': 'burkina_faso',\n '8a2ed0db-eaad-44bc-bf06-5cb1b2a3db0b': 'burundi',\n '4fd14df8-8279-4dfa-bdd3-e1ab26bc0264': 'cambodia',\n '873552ac-9850-4cc1-ae09-17eb0fccf405': 'cameroon',\n 'cfbc220a-1d6c-4469-bb6d-a8e3deb4f7e7': 'cape_verde',\n '61a4c4a4-25c2-4459-a874-ec1d24f8323a': 'central_african_republic',\n '9e41e71c-f5d5-456c-a6f9-2129b8055bfc': 'chad',\n '05333883-44e9-4f57-836a-041391803007': 'chile',\n '15016874-3e20-484a-baa8-9b94e1a3d358': 'china',\n 'a008dff8-ce96-4662-bf8a-372e43d424f0': 'colombia',\n '9d8738c8-40c2-4c66-aabb-ef176a20ffe8': 'comoros',\n 'fb52f8c9-40ec-4dc4-92a4-d465612de2ff': 'costa_rica',\n '513cb36a-3f67-46ea-a789-fcdaca0e26f5': 'cote_divoire',\n '147c2434-5d7e-420c-8053-ba623301f3f5': 'cuba',\n 'cf5b334f-1c0f-41fc-ab54-53ff1e942830': 'djibouti',\n 'f70e51e5-b76c-4c38-9bf2-ef8e1f308ce1': 'dominica',\n 'ce72fc9b-619b-4c32-b865-600e888ad814': 'dominican_republic',\n '8f6d3d2a-e09f-473b-99c9-e539f97ceab6': 'drc_congo',\n '854f2f66-40e1-4a6a-9dee-09c832a52289': 'east_timor',\n 'f9810f9a-78a7-42a2-99e6-19c629642386': 'ecuador',\n 'cc7343f8-9243-4d09-b378-58363850d624': 'egypt',\n '9a34935e-5a8a-45be-8ccd-cb23192e420f': 'el_salvador',\n '7e591605-d723-4398-982a-8737af63a2dc': 'equatorial_guinea',\n 'c61f03c2-0d1f-444f-a974-0a61063aff71': 'eritrea',\n '7478d375-014e-410e-a355-090143e88f5b': 'ethiopia',\n '9f46ae06-114a-47fa-8f8d-e9749f04da25': 'gabon',\n '5ec7ddd7-14a5-48ec-9e7c-8896d1010655': 'gambia',\n 'bc71788f-db69-4b6f-8d1c-57a74395bdd2': 'georgia',\n '2eb4ff46-d908-4148-9b0d-40ccfc1a655a': 'ghana',\n 'b75d6bcc-fadf-4141-8d0f-2463154b89f7': 'greece',\n '51fa502b-98a3-4c42-b5fd-7b4d64489bb9': 'guam',\n '3725a4d2-b28f-466b-905a-bafeaeb75855': 'guatemala',\n 'eeaff39c-8afd-43f7-b9a0-53729f5df1d8': 'guinea',\n '14e90203-9197-42ea-9222-acafd2fd6984': 'guinea_bissau',\n 'ba4dfa7e-f3cd-4e94-8ca7-6b96a93378a8': 'guyana',\n 'f76f7dcb-f82e-4257-a627-1685ff3f3586': 'haiti',\n 'cdd1336e-495b-4868-aace-57a84442d6fd': 'honduras',\n '378d0107-eb43-485d-930c-0704b4e5aa11': 'india',\n '1cbe17e6-adc2-4680-bee0-54d94af75ebf': 'indonesia',\n 'b422270e-d8af-4a32-b523-742545a17a3f': 'iran',\n '03aa7d6e-7656-48e4-8dc0-5e27706722c0': 'iraq',\n '842f963c-f84d-4076-a8db-337295fd9b91': 'jordan',\n '6f6d0e78-2c81-411d-8d13-367e250dc110': 'kazakhstan',\n 'ad351a33-8846-4cad-8195-b07b6041d4a5': 'kenya',\n '4aee7a88-cda9-454e-9f25-4a6420270417': 'kuwait',\n 'ace3b851-042b-46a6-8fea-68aae042d614': 'kyrgyzstan',\n 'dfb01b39-c224-459e-b045-dd9461b9a1e5': 'laos',\n '7de78f22-f53e-48d2-923f-ae1e4d814f46': 'lebanon',\n 'b35b29c5-9bb7-4b40-ad33-29eecd28a9e6': 'lesotho',\n 'a5fd61b4-fd27-433d-8428-7e88a7f27921': 'liberia',\n '600c6af4-b767-423c-b942-7f06ca467258': 'libya',\n '5837cc40-9ab5-4088-91c8-ca6e4b57e903': 'macedonia',\n '3782bf3c-380e-4b60-b21a-38199073f112': 'madagascar',\n 'e8b5f188-6a5c-43ae-b4a5-200abb13153e': 'malawi',\n '3facca11-fbaa-4c40-8fac-4751d45c3f1b': 'malaysia',\n '3e844a47-526a-46f9-afea-1af9ff8690aa': 'mali',\n '051ce04e-05e8-4430-8b75-3e499bbffbc8': 'martinique',\n '8acb006b-8596-4a98-8177-acb4cb575956': 'mauritania',\n '17ced083-eb2a-4046-a713-26cabc7af95d': 'mauritius',\n '1af148fe-2698-4b89-bf7f-87e5c48b6848': 'mayotte',\n '8381208f-01ca-4ed3-8f2c-f73ed1c316e3': 'mexico',\n 'f0e9c8b5-69b5-48df-8cb9-2d089ba04e46': 'moldova',\n '9f341cb1-dcb5-4f6c-bd21-b57db01b4193': 'mongolia',\n 'ef467a17-91e8-4124-a136-7ed8ff7c7d15': 'morocco',\n '0916133b-4d93-4d60-9c20-e7ee3936f391': 'mozambique',\n 'e81ba700-f9fc-4ed0-b248-578a25717cdb': 'myanmar',\n '0cb123dc-8810-4840-b6ab-6a527c5a79ef': 'namibia',\n '3386fe63-2158-4040-a502-9f65fd2079d3': 'nauru',\n 'fb01b01a-6775-423c-8012-7d43f587cb6c': 'nepal',\n 'e67c072b-7707-491f-8c2e-13c914216b61': 'new_caledonia',\n 'f6a9521c-596b-49f9-b914-67138e8c17e6': 'nicaragua',\n '7561db90-a866-4443-93f4-95cac1d47e9c': 'niger',\n '4134651a-7f53-45fb-8bc6-7fed9cf36f51': 'nigeria',\n '4d3079e4-8568-48e6-9342-665896875a38': 'north_korea',\n '9b0af037-99d1-43b8-ac06-82137ec4b06d': 'oman',\n Other: 'other',\n 'f45d93c3-c9b0-4333-a5e6-299b7c425812': 'pakistan',\n 'e2a19948-49aa-44c0-98ef-67ae1160ef43': 'palestine',\n '1ef5a828-9d0d-4336-91ab-880d5dc0151c': 'panama',\n 'e1e6b451-d7fe-4954-b225-99b2de82a4c0': 'papua_new_guinea',\n 'd8412016-82f5-4801-a026-1bdc429850b7': 'paraguay',\n 'e74fa87f-8469-46b0-975f-6cb37c394564': 'peru',\n 'bdbd5c9f-1f28-4f4d-a254-4a84f8bb2c8f': 'philippines',\n '39fca1d0-d2e7-4b13-82bd-626fbec71252': 'puerto_rico',\n '5db9afa5-b57e-4f45-8b1c-af766f14fc58': 'republic_of_congo',\n '1dae4b2d-50c9-4bf1-b25a-7063600a5e74': 'reunion',\n '457e745e-ae97-463d-95a9-8d5689d3ca2b': 'romania',\n '6bc925a1-7699-496a-85b0-c290699381db': 'rwanda',\n 'e03b381b-a7f4-40eb-964f-51571dc3c48c': 'samoa',\n 'f66bbb42-684f-42d7-bfcd-95d586eb7dc9': 'sao_tome_and_principe',\n 'fdf495a4-e60c-46f7-a8a2-61a216849086': 'saudi_arabia',\n 'ad948f1b-0733-4f8d-b049-d64289b43a10': 'senegal',\n 'd2e69cef-3bff-4220-ba91-a6a678fb606b': 'serbia',\n 'ffba9caf-b6aa-4078-845e-578f7a7fd566': 'sierra_leone',\n '99c8dccc-4dfa-4d30-86be-42a309ab431f': 'somalia',\n '75882d62-1c55-480d-b411-8ca40c3307df': 'south_africa',\n '0603d6b9-334f-4443-ab60-7c5d457b95fc': 'south_korea',\n 'f113e24e-2ea9-49a2-9b28-59241b9adb21': 'south_sudan',\n 'b0031c01-d242-4410-b98b-cc1511590b85': 'sri_lanka',\n '2f03a932-2b75-4e8b-9f44-0fcd83c75dc4': 'sudan',\n 'c65d3329-98d4-4dd7-89d3-141b70d00eb2': 'suriname',\n '06a2703b-af17-4e44-83f5-6cc9a8a75320': 'swaziland',\n 'dcdcdc70-a006-4b0a-bac2-7de89b022b65': 'switzerland',\n '1e34ee55-ef9f-4386-bae6-6995555ded75': 'syria',\n '34836c60-5449-48d6-b3c9-c0b3361b9f2c': 'tajikistan',\n '050a8eb1-0d77-4f65-a2da-776a13bcd2a4': 'tanzania',\n '289ac5bd-6434-4837-86bf-b54d22970ac8': 'thailand',\n '6a583e64-869d-477d-a1c1-746320d45fc4': 'togo',\n 'd381f06d-2365-4f40-948b-cfe90d8cb532': 'tonga',\n '56be7864-fde6-4db3-8fa5-b9dd42cd9c53': 'tunisia',\n '7429c779-1d3a-4aec-8256-d0b1637e1bd1': 'turkey',\n '3ef17df5-299b-4385-9ea6-572df4b6f9ca': 'turkmenistan',\n 'be3d11d3-446d-440c-a582-d01c7cbb0eda': 'uganda',\n '38c99c8d-2b93-4848-a537-b1865a260bb2': 'ukraine',\n Unknown: 'unknown',\n 'c2e45baf-748b-4d7b-a391-ed6b802b6f94': 'uruguay',\n '60512350-d79b-41aa-aff0-1b28ca4aa5f1': 'uzbekistan',\n '557cea4a-0049-4b7a-b373-ed63f294a2a0': 'venezuela',\n '49509c5f-e533-48a8-bf06-86935e3376b2': 'vietnam',\n '4086dfd2-f4f5-4107-93e8-07bee235af8f': 'western_sahara',\n '6a3214e0-f94b-414c-8148-968e24386671': 'yemen',\n '3ec0432d-ea37-4159-a658-29d6f07fe21a': 'zambia',\n 'ce1b0d8d-0a2d-4f93-a6ed-64aca2fd0f45': 'zimbabwe',\n };\n\n state.statusMap = {\n '18692c24-4d33-4cdc-a92c-bf4138da5d6d': 'unknown', //Inconnu\n 'f921ffdd-72ca-4d58-a89b-1fa2e959d110': 'asylum_seeker',\n '2bacead2-f280-457c-9d28-e80e106f7d25': 'no_status',\n 'MSF-AAAAAA000000000000001929': 'refugee',\n '1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 'unknown',\n '20b8524e-4c26-4fa0-81f0-fa23ebacc54d': 'single',\n 'MSF-AAAAAA000000000000001863': 'married',\n 'MSF-AAAAAA000000000000001864': 'widowed',\n 'MSF-AAAAAA000000000000001865': 'divorced_separated',\n '1060AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 'concubine',\n 'MSF-AAAAAA000000000000001823': 'not_applicable',\n '1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 'unknown',\n 'MSF-AAAAAA000000000000001871': 'student',\n '4a18a820-f3a1-4bb7-9138-558a9ecc81da': 'fixed_employee',\n '2cb73bee-7f94-4695-89c7-c81187dbc90c': 'occasional_employee',\n 'MSF-AAAAAA000000000000001870': 'unemployed',\n '9b14b4d4-b749-4acf-acfe-79c480f3c4b3': 'housewife',\n 'MSF-AAAAAA000000000000001823': 'not_applicable',\n 'MSF-AAAAAA000000000000001329': 'unknown',\n '1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 'unknown',\n 'MSF-AAAAAA000000000000001930': 'idp',\n '515c5abe-4172-4d0c-a991-0de2888228d7': 'internationally_displaced',\n 'bbdb287c-4ba1-4944-bd87-eb126c5f9d92': 'non_displaced',\n 'fc49acaa-ece2-4365-9dfb-70c2105de8b1': 'returnee',\n '1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 'unknown',\n };\n\n state.genderOptions = {\n M: 'male',\n F: 'female',\n U: 'unknown',\n O: 'prefer_not_to_answer',\n };\n\n return state;\n});\n",
"adaptor": "@openfn/[email protected]",
"project_credential_id": null
},
"Update-TEIs": {
"id": "b30b4200-d2f8-4c7a-827a-bec10c64fbc3",
"name": "Update TEIs",
"body": "fn(state => {\n const { optionSets, genderUpdated, TEIs } = state;\n const genderMap = optionSets\n .filter(o => o['DHIS2 DE UID'] === 'qptKDiv9uPl')\n .reduce((acc, obj) => {\n acc[obj['value.display - Answers']] = obj['DHIS2 Option Code'];\n return acc;\n }, {});\n\n state.teisToUpdate = genderUpdated.map(answer => {\n const { trackedEntity } = TEIs[answer.person.uuid];\n return {\n trackedEntity,\n program: 'w9MSPn5oSqp',\n orgUnit: 'OPjuJMZFLop',\n trackedEntityType: 'cHlzCA2MuEF',\n attributes: [\n {\n attribute: 'qptKDiv9uPl', //gender\n value: genderMap[answer.value.display],\n },\n {\n attribute: 'AYbfTPYMNJH', //OpenMRS Patient UID to use to upsert TEI\n value: answer.person.uuid,\n },\n ],\n };\n });\n return state;\n});\n\n// Update TEIs\ncreate(\n 'tracker',\n { trackedEntities: $.teisToUpdate },\n { params: { async: false, importStrategy: 'UPDATE' } }\n);\n// Return only lastRunDateTime\nfn(({ lastRunDateTime }) => ({ lastRunDateTime }));\n",
"adaptor": "@openfn/[email protected]",
"project_credential_id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d"
}
},
"deleted_at": null,
"lock_version": 191,
"triggers": {
"cron": {
"enabled": false,
"id": "51283b68-c07a-4d85-854c-c2e6e93af041",
"type": "cron",
"cron_expression": "0 0 * * *"
}
}
},
"wf1-dhis2-omrs-migration": {
"id": "94e04fb5-d5ae-45ad-be31-98b902f36861",
"name": "wf1-dhis2-omrs-migration",
"edges": {
"cron->Fetch-Metadata": {
"enabled": true,
"id": "f54f198a-5fa1-4ee0-803f-35316e32ab92",
"source_trigger_id": "0e7d525f-c24a-4969-8131-397cc94a6065",
"condition_type": "always",
"target_job_id": "be724c80-92c8-4fa9-8c3a-d28c5a298fd5"
},
"Get-Locations->Create-Patients": {
"enabled": true,
"id": "e80f8963-3c31-48cc-8df4-6b6dd89fd616",
"source_job_id": "2c1dc59e-c8c0-409d-813f-d0eb3f812a07",
"condition_expression": "state.teis.length > 0 && !state.errors\n",
"condition_type": "js_expression",
"condition_label": "has-teis",
"target_job_id": "fd21a322-aca4-404f-8b5c-93f5f23336fc"
},
"Create-Patients->Update-Teis": {
"enabled": true,
"id": "eb140757-c73f-4f9f-83d6-0ac0c76cf4da",
"source_job_id": "fd21a322-aca4-404f-8b5c-93f5f23336fc",
"condition_type": "on_job_success",
"target_job_id": "eed2a687-7ef3-4a38-819e-d50319874d03"
},
"Fetch-Metadata->Get-Teis-and-Locations": {
"enabled": true,
"id": "29589705-ad94-4515-82f5-a2e1af59ced4",
"source_job_id": "be724c80-92c8-4fa9-8c3a-d28c5a298fd5",
"condition_type": "on_job_success",
"target_job_id": "982099f9-3e69-4684-8935-be5a98636fd2"
},
"Get-Teis-and-Locations->Get-Locations": {
"enabled": true,
"id": "a3da4581-ce0f-444d-8c56-2f67611dc554",
"source_job_id": "982099f9-3e69-4684-8935-be5a98636fd2",
"condition_type": "on_job_success",
"target_job_id": "2c1dc59e-c8c0-409d-813f-d0eb3f812a07"
}
},
"concurrency": null,
"inserted_at": "2024-09-10T16:34:04Z",
"updated_at": "2024-12-17T07:58:27Z",
"jobs": {
"Fetch-Metadata": {
"id": "be724c80-92c8-4fa9-8c3a-d28c5a298fd5",
"name": "Fetch Metadata",
"body": "fn(state => {\n // const manualCursor = '2023-06-20T17:00:00.00';\n state.cursor = state.manualCursor || state.lastRunDateTime;\n console.log('Date cursor to filter TEI extract ::', state.cursor);\n\n return state;\n});\n\n// Get trackedEntityInstances that are \"active\" in the target program\nget(\n 'tracker/trackedEntities',\n {\n orgUnit: 'OPjuJMZFLop',\n program: 'w9MSPn5oSqp',\n programStatus: 'ACTIVE',\n },\n {},\n state => {\n const trackedEntityInstances = state.data.instances\n .filter(tei => tei.updatedAt >= state.cursor) //for testing\n //.filter(tei => tei.createdAt > state.cursor) //for prod\n //.slice(0, 1); //to limit 1 for testing\n const offset = 2; // GMT+2 (Geneva time)\n const currentDateTime = new Date();\n currentDateTime.setHours(currentDateTime.getHours() + offset);\n\n const lastRunDateTime = currentDateTime.toISOString().replace('Z', '');\n //console.log('TEI payload found before filter ::', JSON.stringify(state.data.instances, null, 2));\n console.log('# of TEIs found before filter ::', state.data.instances.length);\n //console.log('lastUpdated of TEI eWXRNHtmHB0 :: ', JSON.stringify(state.data.instances.filter(tei => tei.trackedEntity == 'eWXRNHtmHB0'), null, 2)); \n console.log('# of TEIs to migrate to OMRS ::', trackedEntityInstances.length);\n // console.log(\n // 'trackedEntityInstance IDs ::',\n // trackedEntityInstances.map(tei => tei.trackedEntityInstance)\n // );\n\n console.log('Next sync start date:', lastRunDateTime);\n return {\n ...state,\n // data: {},\n references: [],\n trackedEntityInstances,\n lastRunDateTime,\n };\n }\n);\n",
"adaptor": "@openfn/[email protected]",
"project_credential_id": null
},
"Get-Locations": {
"id": "2c1dc59e-c8c0-409d-813f-d0eb3f812a07",
"name": "Get Locations",
"body": "get('optionGroups/kdef7pUey9f', {\n fields: 'id,displayName,options[id,displayName,code]',\n});\n\nfn(({ data, ...state }) => {\n state.locations = data;\n return state;\n});\n\nfn(state => {\n state.nationalityMap = {\n afghanistan: '84066564-253e-43d8-b141-76730cffa878',\n albania: 'db21f4f9-faf2-4358-8297-0ae76627b3b8',\n algeria: '5f6c017f-074c-46b3-92d0-d055e2094366',\n angola: '8a2e5a03-8a74-41ae-9a98-2310f9ce400d',\n anguilla: 'c911af8a-171c-4ee9-b1ff-934373e8a819',\n argentina: 'b83d24e8-34d8-4920-83c0-8ba014467ff4',\n armenia: '39f1652a-f2b7-4b65-a7e1-7097ac6cdef0',\n aruba: 'f3f1cba1-7c1e-4234-86a2-f27bb5964fee',\n azerbaijan: '29750013-0e35-47ca-8f77-9192a923fb07',\n bangladesh: 'a99de53c-ce76-4b1e-91b2-461094baf79e',\n belarus: '664baba4-c552-47b9-97c0-ff67dafd27d6',\n benin: 'cf863e31-bb38-48ed-90dd-f3dedcac304c',\n bhutan: 'd45a57c9-994f-4deb-8845-9b785860a2ec',\n bolivia: 'd8800d10-862b-42f1-8e22-cac1ce1bbcae',\n bosnia_and_herzegovina: '05d8f4ef-45eb-463d-b2f3-8a5a613ee6b9',\n botswana: '1304a0de-5b70-4d36-a873-e72a82963316',\n brazil: '353ff388-64e6-434c-b78f-ca9636390389',\n british_virgin_islands: 'b02c6d20-83a2-4947-8a7d-91d1f9c4d8a2',\n bulgaria: '91c85a62-2b02-483a-aefd-e29d368565fe',\n burkina_faso: '6c90c1ae-17a4-4e94-a267-4fba4c94efd8',\n burundi: '8a2ed0db-eaad-44bc-bf06-5cb1b2a3db0b',\n cambodia: '4fd14df8-8279-4dfa-bdd3-e1ab26bc0264',\n cameroon: '873552ac-9850-4cc1-ae09-17eb0fccf405',\n cape_verde: 'cfbc220a-1d6c-4469-bb6d-a8e3deb4f7e7',\n central_african_republic: '61a4c4a4-25c2-4459-a874-ec1d24f8323a',\n chad: '9e41e71c-f5d5-456c-a6f9-2129b8055bfc',\n chile: '05333883-44e9-4f57-836a-041391803007',\n china: '15016874-3e20-484a-baa8-9b94e1a3d358',\n colombia: 'a008dff8-ce96-4662-bf8a-372e43d424f0',\n comoros: '9d8738c8-40c2-4c66-aabb-ef176a20ffe8',\n costa_rica: 'fb52f8c9-40ec-4dc4-92a4-d465612de2ff',\n cote_divoire: '513cb36a-3f67-46ea-a789-fcdaca0e26f5',\n cuba: '147c2434-5d7e-420c-8053-ba623301f3f5',\n djibouti: 'cf5b334f-1c0f-41fc-ab54-53ff1e942830',\n dominica: 'f70e51e5-b76c-4c38-9bf2-ef8e1f308ce1',\n dominican_republic: 'ce72fc9b-619b-4c32-b865-600e888ad814',\n drc_congo: '8f6d3d2a-e09f-473b-99c9-e539f97ceab6',\n east_timor: '854f2f66-40e1-4a6a-9dee-09c832a52289',\n ecuador: 'f9810f9a-78a7-42a2-99e6-19c629642386',\n egypt: 'cc7343f8-9243-4d09-b378-58363850d624',\n el_salvador: '9a34935e-5a8a-45be-8ccd-cb23192e420f',\n equatorial_guinea: '7e591605-d723-4398-982a-8737af63a2dc',\n eritrea: 'c61f03c2-0d1f-444f-a974-0a61063aff71',\n ethiopia: '7478d375-014e-410e-a355-090143e88f5b',\n gabon: '9f46ae06-114a-47fa-8f8d-e9749f04da25',\n gambia: '5ec7ddd7-14a5-48ec-9e7c-8896d1010655',\n georgia: 'bc71788f-db69-4b6f-8d1c-57a74395bdd2',\n ghana: '2eb4ff46-d908-4148-9b0d-40ccfc1a655a',\n greece: 'b75d6bcc-fadf-4141-8d0f-2463154b89f7',\n guam: '51fa502b-98a3-4c42-b5fd-7b4d64489bb9',\n guatemala: '3725a4d2-b28f-466b-905a-bafeaeb75855',\n guinea: 'eeaff39c-8afd-43f7-b9a0-53729f5df1d8',\n guinea_bissau: '14e90203-9197-42ea-9222-acafd2fd6984',\n guyana: 'ba4dfa7e-f3cd-4e94-8ca7-6b96a93378a8',\n haiti: 'f76f7dcb-f82e-4257-a627-1685ff3f3586',\n honduras: 'cdd1336e-495b-4868-aace-57a84442d6fd',\n india: '378d0107-eb43-485d-930c-0704b4e5aa11',\n indonesia: '1cbe17e6-adc2-4680-bee0-54d94af75ebf',\n iran: 'b422270e-d8af-4a32-b523-742545a17a3f',\n iraq: '03aa7d6e-7656-48e4-8dc0-5e27706722c0',\n jordan: '842f963c-f84d-4076-a8db-337295fd9b91',\n kazakhstan: '6f6d0e78-2c81-411d-8d13-367e250dc110',\n kenya: 'ad351a33-8846-4cad-8195-b07b6041d4a5',\n kuwait: '4aee7a88-cda9-454e-9f25-4a6420270417',\n kyrgyzstan: 'ace3b851-042b-46a6-8fea-68aae042d614',\n laos: 'dfb01b39-c224-459e-b045-dd9461b9a1e5',\n lebanon: '7de78f22-f53e-48d2-923f-ae1e4d814f46',\n lesotho: 'b35b29c5-9bb7-4b40-ad33-29eecd28a9e6',\n liberia: 'a5fd61b4-fd27-433d-8428-7e88a7f27921',\n libya: '600c6af4-b767-423c-b942-7f06ca467258',\n macedonia: '5837cc40-9ab5-4088-91c8-ca6e4b57e903',\n madagascar: '3782bf3c-380e-4b60-b21a-38199073f112',\n malawi: 'e8b5f188-6a5c-43ae-b4a5-200abb13153e',\n malaysia: '3facca11-fbaa-4c40-8fac-4751d45c3f1b',\n mali: '3e844a47-526a-46f9-afea-1af9ff8690aa',\n martinique: '051ce04e-05e8-4430-8b75-3e499bbffbc8',\n mauritania: '8acb006b-8596-4a98-8177-acb4cb575956',\n mauritius: '17ced083-eb2a-4046-a713-26cabc7af95d',\n mayotte: '1af148fe-2698-4b89-bf7f-87e5c48b6848',\n mexico: '8381208f-01ca-4ed3-8f2c-f73ed1c316e3',\n moldova: 'f0e9c8b5-69b5-48df-8cb9-2d089ba04e46',\n mongolia: '9f341cb1-dcb5-4f6c-bd21-b57db01b4193',\n morocco: 'ef467a17-91e8-4124-a136-7ed8ff7c7d15',\n mozambique: '0916133b-4d93-4d60-9c20-e7ee3936f391',\n myanmar: 'e81ba700-f9fc-4ed0-b248-578a25717cdb',\n namibia: '0cb123dc-8810-4840-b6ab-6a527c5a79ef',\n nauru: '3386fe63-2158-4040-a502-9f65fd2079d3',\n nepal: 'fb01b01a-6775-423c-8012-7d43f587cb6c',\n new_caledonia: 'e67c072b-7707-491f-8c2e-13c914216b61',\n nicaragua: 'f6a9521c-596b-49f9-b914-67138e8c17e6',\n niger: '7561db90-a866-4443-93f4-95cac1d47e9c',\n nigeria: '4134651a-7f53-45fb-8bc6-7fed9cf36f51',\n north_korea: '4d3079e4-8568-48e6-9342-665896875a38',\n oman: '9b0af037-99d1-43b8-ac06-82137ec4b06d',\n other: 'Other',\n pakistan: 'f45d93c3-c9b0-4333-a5e6-299b7c425812',\n palestine: 'e2a19948-49aa-44c0-98ef-67ae1160ef43',\n panama: '1ef5a828-9d0d-4336-91ab-880d5dc0151c',\n papua_new_guinea: 'e1e6b451-d7fe-4954-b225-99b2de82a4c0',\n paraguay: 'd8412016-82f5-4801-a026-1bdc429850b7',\n peru: 'e74fa87f-8469-46b0-975f-6cb37c394564',\n philippines: 'bdbd5c9f-1f28-4f4d-a254-4a84f8bb2c8f',\n puerto_rico: '39fca1d0-d2e7-4b13-82bd-626fbec71252',\n republic_of_congo: '5db9afa5-b57e-4f45-8b1c-af766f14fc58',\n reunion: '1dae4b2d-50c9-4bf1-b25a-7063600a5e74',\n romania: '457e745e-ae97-463d-95a9-8d5689d3ca2b',\n rwanda: '6bc925a1-7699-496a-85b0-c290699381db',\n samoa: 'e03b381b-a7f4-40eb-964f-51571dc3c48c',\n sao_tome_and_principe: 'f66bbb42-684f-42d7-bfcd-95d586eb7dc9',\n saudi_arabia: 'fdf495a4-e60c-46f7-a8a2-61a216849086',\n senegal: 'ad948f1b-0733-4f8d-b049-d64289b43a10',\n serbia: 'd2e69cef-3bff-4220-ba91-a6a678fb606b',\n sierra_leone: 'ffba9caf-b6aa-4078-845e-578f7a7fd566',\n somalia: '99c8dccc-4dfa-4d30-86be-42a309ab431f',\n south_africa: '75882d62-1c55-480d-b411-8ca40c3307df',\n south_korea: '0603d6b9-334f-4443-ab60-7c5d457b95fc',\n south_sudan: 'f113e24e-2ea9-49a2-9b28-59241b9adb21',\n sri_lanka: 'b0031c01-d242-4410-b98b-cc1511590b85',\n sudan: '2f03a932-2b75-4e8b-9f44-0fcd83c75dc4',\n suriname: 'c65d3329-98d4-4dd7-89d3-141b70d00eb2',\n swaziland: '06a2703b-af17-4e44-83f5-6cc9a8a75320',\n switzerland: 'dcdcdc70-a006-4b0a-bac2-7de89b022b65',\n syria: '1e34ee55-ef9f-4386-bae6-6995555ded75',\n tajikistan: '34836c60-5449-48d6-b3c9-c0b3361b9f2c',\n tanzania: '050a8eb1-0d77-4f65-a2da-776a13bcd2a4',\n thailand: '289ac5bd-6434-4837-86bf-b54d22970ac8',\n togo: '6a583e64-869d-477d-a1c1-746320d45fc4',\n tonga: 'd381f06d-2365-4f40-948b-cfe90d8cb532',\n tunisia: '56be7864-fde6-4db3-8fa5-b9dd42cd9c53',\n turkey: '7429c779-1d3a-4aec-8256-d0b1637e1bd1',\n turkmenistan: '3ef17df5-299b-4385-9ea6-572df4b6f9ca',\n uganda: 'be3d11d3-446d-440c-a582-d01c7cbb0eda',\n ukraine: '38c99c8d-2b93-4848-a537-b1865a260bb2',\n unknown: 'Unknown',\n uruguay: 'c2e45baf-748b-4d7b-a391-ed6b802b6f94',\n uzbekistan: '60512350-d79b-41aa-aff0-1b28ca4aa5f1',\n venezuela: '557cea4a-0049-4b7a-b373-ed63f294a2a0',\n vietnam: '49509c5f-e533-48a8-bf06-86935e3376b2',\n western_sahara: '4086dfd2-f4f5-4107-93e8-07bee235af8f',\n yemen: '6a3214e0-f94b-414c-8148-968e24386671',\n zambia: '3ec0432d-ea37-4159-a658-29d6f07fe21a',\n zimbabwe: 'ce1b0d8d-0a2d-4f93-a6ed-64aca2fd0f45',\n };\n state.statusMap = {\n asylum_seeker: 'f921ffdd-72ca-4d58-a89b-1fa2e959d110',\n no_status: '2bacead2-f280-457c-9d28-e80e106f7d25',\n refugee: 'MSF-AAAAAA000000000000001929',\n single: '20b8524e-4c26-4fa0-81f0-fa23ebacc54d',\n married: 'MSF-AAAAAA000000000000001863',\n widowed: 'MSF-AAAAAA000000000000001864',\n divorced_separated: 'MSF-AAAAAA000000000000001865',\n concubine: '1060AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n not_applicable: 'MSF-AAAAAA000000000000001823',\n student: 'MSF-AAAAAA000000000000001871',\n permanent_employee: '4a18a820-f3a1-4bb7-9138-558a9ecc81da',\n occasional_employee: '2cb73bee-7f94-4695-89c7-c81187dbc90c',\n unemployed: 'MSF-AAAAAA000000000000001870',\n housewife: '9b14b4d4-b749-4acf-acfe-79c480f3c4b3',\n other: 'MSF-AAAAAA000000000000001329',\n unknown: '1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n idp: 'MSF-AAAAAA000000000000001930',\n internationally_displaced: '515c5abe-4172-4d0c-a991-0de2888228d7',\n non_displaced: 'bbdb287c-4ba1-4944-bd87-eb126c5f9d92',\n returnee: 'fc49acaa-ece2-4365-9dfb-70c2105de8b1',\n };\n return state;\n});\n",
"adaptor": "@openfn/language-dhis2@latest",
"project_credential_id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d"
},
"Create-Patients": {
"id": "fd21a322-aca4-404f-8b5c-93f5f23336fc",
"name": "Create Patients",
"body": "//Define gender options and prepare newPatientUuid and identifiers\nfn(state => {\n const genderOptions = {\n male: 'M',\n female: 'F',\n unknown: 'U',\n transgender_female: 'O',\n transgender_male: 'O',\n prefer_not_to_answer: 'O',\n gender_variant_non_conforming: 'O',\n };\n\n const identifiers = [];\n const newPatientUuid = [];\n\n const { trackedEntityInstances } = state;\n if (trackedEntityInstances.length > 0)\n console.log(\n '# of TEIs to send to OpenMRS: ',\n trackedEntityInstances.length\n );\n if (trackedEntityInstances.length === 0)\n console.log('No data fetched in step prior to sync.');\n\n return {\n ...state,\n genderOptions,\n newPatientUuid,\n identifiers,\n };\n});\n\n//First we generate a unique OpenMRS ID for each patient\neach(\n 'trackedEntityInstances[*]',\n post(\n 'idgen/identifiersource/8549f706-7e85-4c1d-9424-217d50a2988b/identifier',\n {}\n ).then(state => {\n state.identifiers.push(state.data.identifier);\n return state;\n })\n);\n\n// Then we map trackedEntityInstances to openMRS data model\nfn(state => {\n const {\n trackedEntityInstances,\n identifiers,\n genderOptions,\n nationalityMap,\n statusMap,\n locations,\n } = state;\n\n const getValueForCode = (attributes, code) => {\n const result = attributes.find(attribute => attribute.code === code);\n return result ? result.value : undefined;\n };\n\n const calculateDOB = age => {\n const currentDate = new Date();\n const currentYear = currentDate.getFullYear();\n const birthYear = currentYear - age;\n\n const birthday = new Date(\n birthYear,\n currentDate.getMonth(),\n currentDate.getDay()\n );\n\n return birthday.toISOString().replace(/\\.\\d+Z$/, '+0000');\n };\n\n state.patients = trackedEntityInstances.map((d, i) => {\n const patientNumber = getValueForCode(d.attributes, 'patient_number'); // Add random number for testing + Math.random()\n\n const nationality =\n nationalityMap[getValueForCode(d.attributes, 'origin_nationality')];\n const currentStatus =\n statusMap[getValueForCode(d.attributes, 'current_status')];\n const legalStatus =\n getValueForCode(d.attributes, 'legal_status') &&\n statusMap[getValueForCode(d.attributes, 'legal_status')];\n const maritalStatus =\n statusMap[getValueForCode(d.attributes, 'marital_status')];\n const employmentStatus =\n statusMap[getValueForCode(d.attributes, 'occupation')];\n\n const noOfChildren = d.attributes.find(\n a => a.attribute === 'SVoT2cVLd5O'\n )?.value;\n\n const lonlat = d.attributes.find(a => a.attribute === 'rBtrjV1Mqkz')?.value;\n const location = lonlat\n ? locations.options.find(o => o.code === lonlat)?.displayName\n : undefined;\n\n let countyDistrict, cityVillage;\n\n if (location) {\n const match = location.match(/^(.*?)\\s*\\((.*?)\\)/);\n if (match) {\n [, countyDistrict, cityVillage] = match;\n cityVillage = cityVillage.split('-')[0].trim(); // Remove country code and trim\n }\n }\n\n return {\n patientNumber,\n person: {\n age: getValueForCode(d.attributes, 'age'),\n gender: genderOptions[getValueForCode(d.attributes, 'sex')],\n birthdate:\n d.attributes.find(a => a.attribute === 'WDp4nVor9Z7')?.value ??\n calculateDOB(getValueForCode(d.attributes, 'age')),\n birthdateEstimated: d.attributes.find(\n a => a.attribute === 'WDp4nVor9Z7'\n )\n ? true\n : false,\n names: [\n {\n familyName:\n d.attributes.find(a => a.attribute === 'fa7uwpCKIwa')?.value ??\n 'unknown',\n givenName:\n d.attributes.find(a => a.attribute === 'Jt9BhFZkvP2')?.value ??\n 'unknown',\n },\n ],\n addresses: [\n {\n country: 'Iraq',\n stateProvince: 'Ninewa',\n countyDistrict,\n cityVillage,\n },\n ],\n attributes: [\n {\n attributeType: '24d1fa23-9778-4a8e-9f7b-93f694fc25e2',\n value: nationality,\n },\n {\n attributeType: 'e0b6ed99-72c4-4847-a442-e9929eac4a0f',\n value: currentStatus,\n },\n legalStatus && {\n attributeType: 'a9b2c642-097f-43f8-b96b-4d2f50ffd9b1',\n value: legalStatus,\n },\n {\n attributeType: '3884dc76-c271-4bcb-8df8-81c6fb897f53',\n value: maritalStatus,\n },\n employmentStatus && {\n attributeType: 'dd1f7f0f-ccea-4228-9aa8-a8c3b0ea4c3e',\n value: employmentStatus,\n },\n noOfChildren && {\n attributeType: 'e363161a-9d5c-4331-8463-238938f018ed',\n value: noOfChildren,\n },\n ].filter(i => i),\n },\n\n identifiers: [\n {\n identifier: identifiers[i], //map ID value from DHIS2 attribute\n identifierType: '05a29f94-c0ed-11e2-94be-8c13b969e334',\n location: 'cf6fa7d4-1f19-4c85-ac50-ff824805c51c', //default location old:44c3efb0-2583-4c80-a79e-1f756a03c0a1\n preferred: true,\n },\n {\n uuid: d.trackedEntity,\n identifier: patientNumber,\n identifierType: '8d79403a-c2cc-11de-8d13-0010c6dffd0f', //Old Identification number\n location: 'cf6fa7d4-1f19-4c85-ac50-ff824805c51c', //default location\n preferred: false, //default value for this identifiertype\n },\n ],\n };\n });\n\n return state;\n});\n\n// Creating patients in openMRS\neach(\n '$.patients[*]',\n upsert(\n 'patient',\n state => {\n return { q: state.data.patientNumber };\n },\n state => {\n const { patientNumber, ...patient } = state.data;\n console.log(\n 'Upserting patient record\\n',\n JSON.stringify(patient, null, 2)\n );\n return patient;\n },\n state => {\n state.newPatientUuid.push({\n patient_number: state.references.at(-1)?.patientNumber,\n uuid: state.data.uuid,\n });\n return state;\n }\n )\n);\n\n// Clean up state\nfn(({ data, references, ...state }) => state);\n",
"adaptor": "@openfn/language-openmrs@latest",
"project_credential_id": "3141d874-5456-4168-9680-ce04efb1089c"
},
"Update-Teis": {
"id": "eed2a687-7ef3-4a38-819e-d50319874d03",
"name": "Update Teis",
"body": "fn(state => {\n if (state.newPatientUuid.length === 0) {\n console.log('No data fetched in step prior to sync.');\n }\n\n console.log(\n 'newPatientUuid ::',\n JSON.stringify(state.newPatientUuid, null, 2)\n );\n return state;\n});\n\n// Update TEI on DHIS2\neach(\n 'newPatientUuid[*]',\n upsert(\n 'trackedEntityInstances',\n state => ({\n ou: 'OPjuJMZFLop',\n program: 'w9MSPn5oSqp',\n filter: [`P4wdYGkldeG:Eq:${state.data.patient_number}`],\n }),\n {\n orgUnit: 'OPjuJMZFLop',\n program: 'w9MSPn5oSqp',\n trackedEntityType: 'cHlzCA2MuEF',\n attributes: [\n { attribute: 'P4wdYGkldeG', value: `${$.data.patient_number}` }, //DHIS2 patient number to use as lookup key\n { attribute: 'AYbfTPYMNJH', value: `${$.data.patient.uuid}` }, //OMRS patient uuid\n {\n attribute: 'ZBoxuExmxcZ',\n value: `${$.data.patient.identifier[0].identifier}`,\n }, //id generated in wf1-2 e.g., \"IQ146-24-000-027\"\n ],\n }\n )\n);\n",
"adaptor": "@openfn/[email protected]",
"project_credential_id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d"
},
"Get-Teis-and-Locations": {
"id": "982099f9-3e69-4684-8935-be5a98636fd2",
"name": "Get Teis and Locations",
"body": "\n// Check out the Job Writing Guide for help getting started:\n// https://docs.openfn.org/documentation/jobs/job-writing-guide\n",
"adaptor": "@openfn/language-dhis2@latest",
"project_credential_id": "8a5ead9b-5f9e-49b1-9e9a-9dc3c4ccf72d"
}
},
"deleted_at": null,
"lock_version": 48,
"triggers": {
"cron": {
"enabled": false,
"id": "0e7d525f-c24a-4969-8131-397cc94a6065",
"type": "cron",
"cron_expression": "0 0 * * *"
}
}
},
"fetch-metadata-and-generate-opts-json": {
"id": "57a7ef39-d396-4959-a725-85c4bef08c6a",
"name": "fetch-metadata-and-generate-opts-json",
"edges": {
"webhook->Get-metadata-file-from-Sharepoint": {
"enabled": true,
"id": "a1a8243d-dfe8-48ff-88ab-793f4176e2ce",
"source_trigger_id": "e86ca050-ad88-4936-8c14-6eac23922017",
"condition_type": "always",
"target_job_id": "c9712182-a389-4664-8e10-f275f87fb478"
},
"Map-metadata-file-to-option-set-Json-format->Save-option-set-json-to-github": {
"enabled": true,
"id": "3342bdc4-487d-49d2-839c-3c6d7835af8f",
"source_job_id": "bbc012b5-4811-4354-888c-f10b0294901d",
"condition_type": "on_job_success",
"target_job_id": "56f67a06-cf99-42b5-81c5-49c058b5126c"
},
"Get-metadata-file-from-Sharepoint->Map-metadata-file-to-option-set-Json-format": {
"enabled": true,
"id": "22252bb8-2e4c-422e-8aa3-667b04d67400",
"source_job_id": "c9712182-a389-4664-8e10-f275f87fb478",
"condition_type": "on_job_success",
"target_job_id": "bbc012b5-4811-4354-888c-f10b0294901d"
}
},
"concurrency": null,
"inserted_at": "2024-10-11T18:16:12Z",
"updated_at": "2024-10-28T08:26:44Z",
"jobs": {
"Get-metadata-file-from-Sharepoint": {
"id": "c9712182-a389-4664-8e10-f275f87fb478",
"name": "Get metadata file from Sharepoint",
"body": "const toCamelCase = text => {\n return text\n .toLowerCase()\n .replace(/[^a-zA-Z0-9]+(.)/g, (match, chr) => chr.toUpperCase());\n};\n\nconst sheets = [\n 'OptionSets',\n 'F01-MHPSS Baseline',\n 'F02-MHPSS Follow-up',\n 'F03-mhGAP Baseline',\n 'F04-mhGAP Follow-up',\n 'F05-MHPSS Closure',\n];\n\nfn(state => {\n state.siteId =\n 'openfnorg.sharepoint.com,4724a499-afbc-4ded-a371-34ae40bf5d8d,1d20a7d4-a6f1-407c-aa77-76bd47bb0f32';\n return state;\n});\n\ngetDrive(\n {\n id: $.siteId,\n owner: 'sites',\n },\n 'default'\n);\n\ngetFile('/msf-metadata/LIME EMR - Iraq Metadata - Release 1.xlsx', {\n metadata: true,\n});\n\nfn(state => {\n const itemId = state.data.id;\n const driveId = state.drives.default.id;\n state.workbookBase = `sites/${state.siteId}/drives/${driveId}/items/${itemId}/workbook`;\n return state;\n});\n\neach(\n sheets,\n get(`${$.workbookBase}/worksheets('${$.data}')/usedRange`, {}, state => {\n const sheetName = toCamelCase(state.references.at(-1));\n console.log('Fetched sheet: ', sheetName);\n state[sheetName] = state.data.values;\n return state;\n })\n);\n\nfn(state => {\n delete state.data;\n delete state.response;\n delete state.references;\n return state;\n});\n",
"adaptor": "@openfn/language-msgraph@latest",
"project_credential_id": "3dd044bb-6a0e-4f16-a80d-836a39f95b40"
},
"Map-metadata-file-to-option-set-Json-format": {
"id": "bbc012b5-4811-4354-888c-f10b0294901d",
"name": "Map metadata file to option-set Json format",
"body": "const isValidValue = value => value !== '' && value !== 'NA';\n\nconst mapArrayToObject = (item, keys) => {\n return item.reduce((acc, value, idx) => {\n acc[keys[idx]] = value;\n return acc;\n }, {});\n};\nfn(state => {\n const { optionsets } = state;\n const keys = optionsets[1];\n\n const optsMap = optionsets.slice(2).map(item => mapArrayToObject(item, keys));\n\n state.optionSets = optsMap\n .filter(\n o =>\n isValidValue(o['External ID']) && isValidValue(o['DHIS2 DE full name'])\n )\n .map(o => {\n return {\n 'value.display - Answers': o['Answers'],\n 'value.uuid - External ID': o['External ID'],\n 'DHIS2 DE full name': o['DHIS2 DE full name'],\n 'DHIS2 DE UID': o['DHIS2 DE UID'],\n 'OptionSet name': o['OptionSet name'],\n 'DHIS2 Option Set UID': o['DHIS2 Option Set name'],\n 'DHIS2 Option name': o['DHIS2 Option name'],\n 'DHIS2 Option UID': o['DHIS2 Option UID'],\n 'DHIS2 Option Code': o['DHIS2 Option code'],\n };\n });\n\n return state;\n});\n\nconst safeKeyValuePairs = arr => {\n if (arr === null || arr === undefined) {\n return arr;\n }\n const mappedArr = arr.slice(2).map(item => mapArrayToObject(item, arr[1]));\n try {\n return mappedArr\n .filter(\n o => isValidValue(o['External ID']) && isValidValue(o['DHIS2 DE UID'])\n )\n .reduce((acc, value) => {\n acc[value['DHIS2 DE UID']] = value['External ID'];\n return acc;\n }, {});\n } catch (error) {\n console.error(`Error processing ${arr}:`, error);\n return arr; // Return original value if processing fails\n }\n};\n\nfn(\n ({\n optionSets,\n f01MhpssBaseline,\n f02MhpssFollowUp,\n f03MhgapBaseline,\n f04MhgapFollowUp,\n f05MhpssClosure,\n }) => {\n const processedState = Object.fromEntries(\n Object.entries({\n f01MhpssBaseline,\n f02MhpssFollowUp,\n f03MhgapBaseline,\n f04MhgapFollowUp,\n f05MhpssClosure,\n }).map(([key, value]) => [key, safeKeyValuePairs(value)])\n );\n\n return {\n optionSets,\n ...processedState,\n };\n }\n);\n",
"adaptor": "@openfn/language-common@latest",
"project_credential_id": null
},
"Save-option-set-json-to-github": {
"id": "56f67a06-cf99-42b5-81c5-49c058b5126c",
"name": "Save option-set json to github",
"body": "const metadataPath =\n 'repos/OpenFn/openfn-lime-pilot/contents/metadata/metadata_mapping.json';\n\nget(metadataPath, {\n headers: {\n 'user-agent': 'OpenFn',\n },\n});\n\nfn(state => {\n const {\n optionSets,\n f01MhpssBaseline,\n f02MhpssFollowUp,\n f03MhgapBaseline,\n f04MhgapFollowUp,\n f05MhpssClosure,\n data,\n } = state;\n\n state.body = {\n message: 'Update metadata content',\n committer: {\n name: 'Emmanuel Evance',\n email: '[email protected]',\n },\n content: util.encode(\n JSON.stringify({\n optionSets,\n f01MhpssBaseline,\n f02MhpssFollowUp,\n f03MhgapBaseline,\n f04MhgapFollowUp,\n f05MhpssClosure,\n })\n ),\n sha: data.sha,\n };\n\n return state;\n});\n\nput(metadataPath, {\n body: $.body,\n headers: {\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'user-agent': 'OpenFn',\n },\n});\n",
"adaptor": "@openfn/language-http@latest",
"project_credential_id": "6533e534-6ad8-4651-b27d-245b8cbb69d8"
}
},
"deleted_at": null,
"lock_version": 12,
"triggers": {
"webhook": {
"enabled": true,
"id": "e86ca050-ad88-4936-8c14-6eac23922017",
"type": "webhook"
}
}
}
},
"requires_mfa": false
}