diff --git a/openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json b/openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json index c4629f2..2f5f462 100644 --- a/openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json +++ b/openfn-cd92dd57-9a3c-4318-bdcb-f57a386cf811-state.json @@ -3,7 +3,7 @@ "name": "msf-lime-iraq", "description": null, "inserted_at": "2024-09-05T06:59:05Z", - "updated_at": "2024-09-30T08:22:58Z", + "updated_at": "2024-10-01T07:13:00Z", "scheduled_deletion": null, "project_credentials": { "mtuchi@openfn.org-OpenMRS-Demo": { @@ -190,7 +190,7 @@ }, "concurrency": null, "inserted_at": "2024-09-10T16:34:04Z", - "updated_at": "2024-09-25T07:56:14Z", + "updated_at": "2024-10-01T07:13:00Z", "jobs": { "Get-Teis": { "id": "be724c80-92c8-4fa9-8c3a-d28c5a298fd5", @@ -209,7 +209,7 @@ "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 = locations.options.find(\n // o => o.code === lonlat\n // )?.displayName;\n\n // const [countyDistrict, remainder] = location?.split(' (');\n // const [cityVillage] = remainder?.split(')');\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 create(\n 'patient',\n state => {\n const { patientNumber, ...patient } = state.data;\n console.log(\n 'Creating 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.body.uuid,\n });\n return state;\n }\n )\n);\n\n// Clean up state\nfn(({ data, references, ...state }) => state);\n", + "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" }, @@ -222,7 +222,7 @@ } }, "deleted_at": null, - "lock_version": 40, + "lock_version": 41, "triggers": { "cron": { "enabled": false,