Giter Club home page Giter Club logo

language-dhis2's Introduction

⚠️ MOVED TO OpenFn/adaptors! ⚠️

N.B.: New versions are available at: https://github.com/OpenFn/adaptors/tree/main/packages/dhis2

Language DHIS2 (Archived)

An OpenFn language Pack for building expressions and operations for working with the DHIS2 API. Used most commonly via OpenFn.org or by hand with OpenFn/core from the root of this repo:

core execute \
 -l ../language-dhis2 \
 -e ./tmp/expression.js \
 -s ./tmp/state.json \
 -o ./tmp/output.json

Documentation

View the docs site for full technical documentation.

There are lots of examples for how to use the various helper functions on the main Adaptor docs page.

Sample State

{
  "configuration": {
    "username": "admin",
    "password": "district",
    "hostUrl": "https://play.dhis2.org/2.36.6"
  },
  "data": { "a": 1, "b": 2 }
}

Development

Clone the repo and run npm install.

Run tests using npm run test or npm run test:watch. (NB: that this repo also contain integration tests which can be run with npm run integration-test.)

⚠️ NB: Make changes to the files in src/ and then use npm run build to generate output files in lib/.

The documentation is autogenerated, so please rebuild the docs after making changes by running ./node_modules/.bin/jsdoc --readme ./README.md ./lib -d docs

Unit Tests

Unit tests allows to test the functionalities of the adaptor helper functions such as:

Does create('events', payload) perform a post request to the correct DHIS2 API?

To run unit tests execute npm run test (they're the default tests).

Anytime a new functionality is added to the helper functions, more unit tests needs to be added.

End-to-end integration tests

Integration tests allow us to test the end-to-end behavior of the helper functions and also to test the examples we provide via inline documentation.

For example with integration tests we answer the following question:

Does create('events', eventPayload) actually create a new event in a live DHIS2 system?

To run integration tests, execute npm run integration-test. These tests use network I/O and a public connection to a DHIS2 "play" server so their timing and performance is unpredictable. Consider adding an increased timeout, and modifying the orgUnit, program, etc., IDs set in globalState.

Troubleshooting the tests

  • Depending on your internet strength please consider changing the global timeout in the test/mocha.opts file to avoid faillures related to network timeouts.

  • The behavior of the tests in test/integration.js is very unpredictable; they depend on the configuration of a target DHIS2 instance. Currently you need to have at least one organisation unit with one program, one trackedEntityInstance and one programStage in it. These components need to be well configured for the integration tests to work. For example: the trackedEntityInstance need to be enrolled to the program, which should be created in that organisation unit and contains at least that programStage. If the tests fail, you must adjust these attributes in the before hook:

before(done => {
  fixture.initialState = {
    configuration: {
      username: 'admin',
      password: 'district',
      hostUrl: 'https://play.dhis2.org/2.36.6',
    },
    program: 'IpHINAT79UW',
    orgUnit: 'DiszpKrYNg8',
    trackedEntityInstance: 'uhubxsfLanV',
    programStage: 'eaDHS084uMp',
  };
  done();
});
  • Make sure the update and upsert integration tests don't affect those initial organisation units, programs, programStage and trackedEntityInstance required. Otherwise the create integration tests would be broken again; and that's an endless faillure loop :(

Anytime a new example is added in the documentation of a helper function, a new integration test should be built.

language-dhis2's People

Contributors

chaiwa-berian avatar dependabot[bot] avatar elias-ba avatar mtuchi avatar santiagogak avatar stuartc avatar taylordowns2000 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

language-dhis2's Issues

Message Filtering and Triggering not working

Hi @taylordowns2000 ,
Would you kindly help me understand why the filters are not matching any of the messages CommCare is sending?

Ideally, I would like to be able to match specific forms based on their form names and/or ids, and sometimes based on the case type. I have tried configuring the trigger as "@name": "Waterpoint Registration Form"
But no matching is taking place. Would you guide navigating the JSON tree of the message for the trigger configurations?

The message looks like below:

{
  "version": "34",
  "uiversion": "1",
  "type": "data",
  "server_modified_on": "2018-01-07T10:34:30.952072Z",
  "resource_uri": "",
  "received_on": "2018-01-07T10:34:30.425740Z",
  "problem": null,
  "metadata": {
    "username": "test",
    "userID": "9231768348d64a5aa8e2df401c6ca7fd",
    "timeStart": "2018-01-07T10:33:46.188000Z",
    "timeEnd": "2018-01-07T10:34:28.902000Z",
    "location": null,
    "instanceID": "d82c1d6a-a991-4213-944b-a6dc32b93bfd",
    "geo_point": null,
    "deviceID": "357950075597380",
    "commcare_version": "2.40.1",
    "app_build_version": 34,
    "appVersion": "CommCare Android, version \"2.40.1\"(444156). App v34. CommCare Version 2.40. Build 444156, built on: 2017-11-20"
  },
  "is_phone_submission": true,
  "initial_processing_complete": true,
  "id": "d82c1d6a-a991-4213-944b-a6dc32b93bfd",
  "form": {
    "waterpoint_id": "2533884",
    "name": "Kamuzule",
    "meta": {
      "username": "test",
      "userID": "9231768348d64a5aa8e2df401c6ca7fd",
      "timeStart": "2018-01-07T10:33:46.188000Z",
      "timeEnd": "2018-01-07T10:34:28.902000Z",
      "instanceID": "d82c1d6a-a991-4213-944b-a6dc32b93bfd",
      "geo_point": null,
      "deviceID": "357950075597380",
      "commcare_version": "2.40.1",
      "app_build_version": 34,
      "appVersion": "CommCare Android, version \"2.40.1\"(444156). App v34. CommCare Version 2.40. Build 444156, built on: 2017-11-20",
      "@xmlns": "http://openrosa.org/jr/xforms"
    },
    "longitude": "32.6390061",
    "lattitude": "-13.6426553",
    "gps_coordinates": "-13.6426553 32.6390061 0.0 20.0",
    "case": {
      "create": {
        "owner_id": "69ca667a1fd4bd822f3766e95f91df9c",
        "case_type": "water_point",
        "case_name": "Kamuzule"
      },
      "@xmlns": "http://commcarehq.org/case/transaction/v2",
      "@user_id": "9231768348d64a5aa8e2df401c6ca7fd",
      "@date_modified": "2018-01-07T10:34:28.902000Z",
      "@case_id": "4850cd93-f657-4887-99bc-515943ea61b7"
    },
    "@xmlns": "http://openrosa.org/formdesigner/C3478C08-ABB3-47FC-ADF1-A7788E28D565",
    "@version": "34",
    "@uiVersion": "1",
    "@name": "Waterpoint Registration Form",
    "#type": "data"
  },
  "edited_on": null,
  "edited_by_user_id": null,
  "domain": "mawa-wash",
  "build_id": "1750b5c4626c4038a51b0fdc4217acd8",
  "attachments": {
    "form.xml": {
      "url": "https://www.commcarehq.org/a/mawa-wash/api/form/attachment/d82c1d6a-a991-4213-944b-a6dc32b93bfd/form.xml",
      "length": 1322,
      "content_type": "text/xml"
    }
  },
  "archived": false,
  "app_id": "3ebb1ab0124313650b86d7668645f556",
  "__query_params": {
    "app_id": "3ebb1ab0124313650b86d7668645f556"
  }
}

Thanks and kind regards.

Job Failing to Run: Challenges getting the CommCare-DHIS2 Setup on a Local DHIS2 Instance

Hi @taylordowns2000 ,
I have had hard time setting up the configs and the job so I am able to create a new tracked entity in DHIS2 which is an equivalent of a case in CommCare. I would like, OpenFn, to be able to authenticate into and query my local DHIS2 instance(for testing purposes), but I am not too sure on how to correcctly complete that setup as my job keeps failing to run. I have granted access to OpenFn.org Support so you can have a look at my project setup. The name of my project space is Mawa WASH!

Please see the error below and advise on how I can go about fixing this:

Posting tracked entity instance data:

{ 'trackedEntity,VENu24Hqrg5': undefined,
  'orgUnit,qCaJ3CY1rgw': undefined,
  'attributes,function (state){ //Set Tracked Entity Attributes
     return [{
          "attribute": "Exn9iU61K5S", //waterpoint_name
               "value": dataValue("form.name")(state) },
         {  "attribute": "TFk7uLjDrB7", //GPS Coordinates
            "value:": dataValue("form.gps_coordinates")(state) }
         { "attribute": "hA9s4T7EC7x", //Latitude
          "value:": dataValue("form.lattitude")(state)},
         { "attribute": "HgQVDJTn5p6", //Longitude
         "value:": dataValue("form.longitude")(state) },
         { "attribute": "dyuCklbsDXs", //Waterpoint_id
          "value:": dataValue("form.waterpoint_id")(state)}]
          }': undefined }
{ Error: connect ETIMEDOUT 192.168.43.44:8082
    at Object.exports._errnoException (util.js:1018:11)
    at exports._exceptionWithHostPort (util.js:1041:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)
  code: 'ETIMEDOUT',
  errno: 'ETIMEDOUT',
  syscall: 'connect',
  address: '192.168.43.44',
  port: 8082,
  response: undefined }

The functions fields() and field() in createTEI() not working

Can someone help me understand why Version 1 of the code below is able to create a new Tracked Entity Instance in DHIS2 while Version 2 is not? @taylordowns2000 , @stuartc , @santiagogak
Version 1

createTEI( {
    "trackedEntity": "VENu24Hqrg5",
    "orgUnit": "qCaJ3CY1rgw",
    "attributes": [
      {
      "attribute": "Exn9iU61K5S",
      "value": dataValue("form.name")(state)
      },
      {
        "attribute": "TFk7uLjDrB7",
        "value": dataValue("form.gps_coordinates")(state)
      },
      {
        "attribute": "hA9s4T7EC7x",
        "value": dataValue("form.lattitude")(state)
      },
      {
        "attribute": "HgQVDJTn5p6",
        "value": dataValue("form.longitude")(state)
      },
      {
        "attribute": "dyuCklbsDXs",
        "value": dataValue("form.waterpoint_id")(state)
      }]
  }   )

Version 2

createTEI(
   fields(
     field("trackedEntity","VENu24Hqrg5"),
     field("orgUnit", "qCaJ3CY1rgw"),
     field("attributes", function(state){ 
       return [
         {
         "attribute": "Exn9iU61K5S",
         "value": dataValue("form.name")(state)
         },
         {
           "attribute": "TFk7uLjDrB7",
           "value": dataValue("form.gps_coordinates")(state)
         },
         {
           "attribute": "hA9s4T7EC7x",
           "value": dataValue("form.lattitude")(state)
         },
         {
           "attribute": "HgQVDJTn5p6",
           "value": dataValue("form.longitude")(state)
         },
         {
           "attribute": "dyuCklbsDXs",
           "value": dataValue("form.waterpoint_id")(state)
         }
         ]
     })))

Update tests for a subset of new operations

@chaiwa-berian , after reviewing the existing tests which pass on master, can you implement a basic set of tests for the key operations in your new version?

Open to pushback here, but my guess is that it's most important to start by testing getData, create and upsert rather than createTEI and upsertTEI as those tests will provide some coverage for the other operations that use them. Time-boxed to 8 hours for now.

As for specific case tests for our high-traffic opertaions, i'd envision:

+describe('upsertTEI', function () {
+  it('should deep merge attributes when partial data is provided', function () {
+    let state = {
+      configuration: {
+        username: 'admin',
+        password: 'district',
+        hostUrl: 'https://play.dhis2.org/2.35.0',
+        apiVersion: 35,
+      },
+      data: {
+        // something...
+      },
+    };
+
+    return execute(
+      upsertTEI('someUniqueAttributeId', {
+        // some attributes
+      })
+    )(state).then(state => {
+      const instances = state.data.trackedEntityInstances;
+
+      const newTEI = getTEI('the ID from before');
+      expect(newTEI.attributes).to.eq({
+        // some expected new set of attributes which SHOWCASES the face that the
+        // deep merge succeeded.
+      });
+    });
+  }).timeout(10 * 1000);
+
+  it('should fail upsert when unique is set to false');
+});

TypeError: Cannot read property 'orgUnit' of undefined: /language-dhis2/lib/Adaptor.js:309:16

Hello,

I am using the core programmatically , I have :
upsertTEI((state) => {
/*
.some config
/
return {"uniqueAttributeId": trackedEntityAttribute.case_name ,
"data": {
"orgUnit": rootOrgUnit,
"trackedEntityType": trackedEntityType,
"attributes": [
{
"attribute": trackedEntityAttribute.case_name,
"value": state.data.properties.case_name,
},
{
"attribute": trackedEntityAttribute.p_gender,
"value": state.data.properties.p_gender,
},
],
"enrollments": [{
"orgUnit": state.data.properties.user_location_uid,
"program": programUid,
"enrollmentDate": state.data.date_closed.substring(0, 10),
"incidentDate": state.data.properties.date_opened.substring(0, 10),
"events": [{
"program": programUid,
"orgUnit": curOrgUnit,
"eventDate": state.data.date_closed.substring(0, 10),
"programStage" : programStage,
"status": "COMPLETED",
"storedBy": "mediator",
"dataValues": function(state){
/

some code to construct the data element
*/
}
}]
}]
}
};

});
and I am getting

TypeError: Cannot read property 'orgUnit' of undefined: /language-dhis2/lib/Adaptor.js:309:16

I did the same config on the openFN server and have exactly the same issue

https://www.openfn.org/projects/pdej65/runs/rg5r7j8z

is it a bug or a misuse ? (I cannot see what is wrong, I also tried without the quote around the "keys" like orgUnit with the same result)

Update inline docs for platform usage

The jsDocs for version 2.0.0 are extensive, going well beyond those provided in v1.4.0. This is great 🥳 but we've got to ensure that they still can be used to generate inline documentation for folks who are using this adaptor on the openfn.org platform.

Please update the inline docs here so that an ast can be generated from this adaptor before we build and link a new tarball to the 2.0.0 release.

You can check for a valid ast (as would be done during the build process for OpenFn.org) with this command, executed in the simple-ast root directory: node ./lib/generate.js --adaptor ~/devtools/adaptors/language-dhis2/lib/Adaptor.js --output ./tmp/ast.json

N.B., If you feel that the current documentation is accurate and should be producing a valid AST, please feel free to propose changes to https://github.com/OpenFn/simple-ast/blob/master/lib/generate.js so that it handles this new style of documentation as well as the older method in use across the adaptors. generate.js is, admittedly, very brittle because we'd always done inline documentation for adaptors in a very particular way.

Rename functions with singular names rather than plural names

Do these functions actually take an array or and object? If not, they should probably be renamed:

  1. createPrograms should be createProgram
  2. createEvents should be createEvent
  3. ...more?

If so, can we add some explanation in the docs which shows that these functions take objects or arrays? ( To consider, @chaiwa-berian , I know that there was some issue around how JsDoc parses these optional args.)

Address TEI test failures

Hey @chaiwa-berian , these TEI tests are still failing so I'm guessing it's less to do with a change to the play instance and more to do with a change to the adaptor. Could you take a look and get these back to passing?

Code for Job converting to all lowercase causing the "Function not found" error

For some reason, sometimes after editing the job and clicking on "Save" the code snippet gets converted to "lowercase" leading to the error below when I attempt to run the job:

Line 2: createtei(
        ^^^^
Function not available.
Line 9:          "value": datavalue("form.name")(state)
                          ^^^^^^^^^^^^^^^^^^^^^^
Function not available.
Line 13:          "value:": datavalue("form.gps_coordinates")(state)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Function not available.
Line 17:          "value:": datavalue("form.lattitude")(state)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Function not available.
Line 21:          "value:": datavalue("form.longitude")(state)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Function not available.
Line 25:          "value:": datavalue("form.waterpoint_id")(state)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Function not available.
Error: Compilation failed.
    at Promise.all.readFile.then (/home/production/repo/node_modules/core/lib/cli.js:186:35)

Kindly advise.
Thanks.

Data Value Sets Fetch API Support for Start and End Date Query Parameters

I am wondering whether the use of startDate and endDate query parameters are being supported by the fetchData API. I tried the below configuration and I am only getting an empty({}) response:

fetchData({
  fields: {
    dataSet: 'MVccvKD4o8Q',
    orgUnit: 'Gmn6FKMQQ13',
    startDate: '2017-01-01',
    endDate: '2018-01-01'
  },
  postUrl: "https://www.openfn.org/inbox/id_for_my_inbox"
})

Provide a guide to the integration tests

We should have 2-3 sentences that explain how to get the integration tests to pass. My current understanding is that orgUnits, programs, and one or two other things occasionally need to be updated. Can we add this to the README?

Fix inline docs for operations, release new version

Please fix failing tests by pre-configuring the dhis2 play instance before tests tun:

describe('live adaptor testing', () => {
  // before ALL tests run, we must re-configure the dhis2 environment
  before(() => {
    // PUT https://play.dhis2.org/2.35.1/api/users/xE7jOejl9FI // set user
    // PUT https://play.dhis2.org/2.35.1/api/userRoles/Ufph3mGRmMo // set user roles
    // PUT https://play.dhis2.org/2.35.1/api/29/trackedEntityTypes/nEenWmSyUEp?mergeMode=REPLACE // ensure trackedEntity types are set
    // PUT add Programs... // ??
  })

Then, the inline docs are not generating properly for v2.0.0. For this issue, please:

  1. fix inline docs so they're generating properly with simple-ast @lakhassane , your help will be needed here! Make sure you've got the most recent version of simple-ast, of devtools, etc., etc.
  2. create a new release on github and publish it on npm
  3. submit a PR to platform-app to use this new version with the working inline docs.

Note the failing docs here. It's possible that some are fixed by the pull request on simple-ast (OpenFn/simple-ast#4)

Parsing /home/taylor/devtools/adaptors/language-dhis2/lib/Adaptor.js
├─ Warning: Invalid documentation for ownKeys ✗ Stated params are 'No docs.', but detected params are '["object","enumerableOnly"]'.
├─ configMigrationHelper is properly documented ✓
├─ getTEIs is properly documented ✓
├─ upsertTEI is properly documented ✓
├─ createTEI is properly documented ✓
├─ updateTEI is properly documented ✓
├─ getEvents is properly documented ✓
├─ createEvents is properly documented ✓
├─ updateEvents is properly documented ✓
├─ getPrograms is properly documented ✓
├─ createPrograms is properly documented ✓
├─ updatePrograms is properly documented ✓
├─ getEnrollments is properly documented ✓
├─ enrollTEI is properly documented ✓
├─ updateEnrollments is properly documented ✓
├─ cancelEnrollment is properly documented ✓
├─ completeEnrollment is properly documented ✓
├─ getRelationships is properly documented ✓
├─ getDataValues is properly documented ✓
├─ createDataValues is properly documented ✓
├─ generateDhis2UID is properly documented ✓
├─ discover is properly documented ✓
├─ getAnalytics is properly documented ✓
├─ getResources is properly documented ✓
├─ getSchema is properly documented ✓
├─ getData is properly documented ✓
├─ getMetadata is properly documented ✓
├─ create is properly documented ✓
├─ update is properly documented ✓
├─ patch is properly documented ✓
├─ del is properly documented ✓
└─ upsert is properly documented ✓
Parsing /home/taylor/devtools/adaptors/language-dhis2/lib/Utils.js
Gathering documentation for language-common
├─ Warning: Invalid documentation for recursivelyExpandReferences ✗ Stated params are 'No docs.', but detected params are '["thing"]'.
├─ Warning: Invalid documentation for composeSuccessMessage ✗ Stated params are 'No docs.', but detected params are '["operation"]'.
├─ Warning: Invalid documentation for warnExpectLargeResult ✗ Stated params are 'No docs.', but detected params are '["paramOrResourceType","endpointUrl"]'.
├─ Warning: Invalid documentation for logWaitingForServer ✗ Stated params are 'No docs.', but detected params are '["url","params"]'.
├─ Warning: Invalid documentation for logApiVersion ✗ Stated params are 'No docs.', but detected params are '["apiVersion"]'.
├─ Warning: Invalid documentation for logOperation ✗ Stated params are 'No docs.', but detected params are '["operation"]'.
├─ Warning: Invalid documentation for buildUrl ✗ Stated params are 'No docs.', but detected params are '["path","hostUrl","apiVersion"]'.
├─ Warning: Invalid documentation for attribute ✗ Stated params are 'No docs.', but detected params are '["attributeId","attributeValue"]'.
├─ Warning: Invalid documentation for requestHttpHead ✗ Stated params are 'No docs.', but detected params are '["endpointUrl","_ref"]'.
├─ Warning: Invalid documentation for validateMetadataPayload ✗ Stated params are 'No docs.', but detected params are '["payload","resourceType"]'.
├─ Warning: Invalid documentation for handleResponse ✗ Stated params are 'No docs.', but detected params are '["result","state","callback"]'.
├─ Warning: Invalid documentation for prettyJson ✗ Stated params are 'No docs.', but detected params are '["data"]'.
├─ Warning: Invalid documentation for getIndicesOf ✗ Stated params are 'No docs.', but detected params are '["string","regex"]'.
├─ Warning: Invalid documentation for isLike ✗ Stated params are 'No docs.', but detected params are '["string","words"]'.
├─ Warning: Invalid documentation for applyFilter ✗ Stated params are 'No docs.', but detected params are '["arrObject","targetProperty","operator","valueToCompareWith"]'.
└─ Warning: Invalid documentation for parseFilter ✗ Stated params are 'No docs.', but detected params are '["filterExpression"]'.
├─ Warning: Invalid documentation for ESCAPE ✗ Stated params are 'No docs.', but detected params are '{}'.
├─ Warning: Invalid documentation for COLORS ✗ Stated params are 'No docs.', but detected params are '{}'.
├─ Warning: Invalid documentation for Log ✗ Stated params are 'No docs.', but detected params are '{}'.
├─ Warning: Invalid documentation for dhis2OperatorMap ✗ Stated params are 'No docs.', but detected params are '{}'.
└─ Warning: Invalid documentation for CONTENT_TYPES ✗ Stated params are 'No docs.', but detected params are '{}'.
Documented the following exports from language-common: [
  "alterState",
  "sourceValue",
  "dataPath",
  "dataValue",
  "lastReferenceValue",
  "each",
  "field",
  "fields",
  "merge"
]
The AST has been written.

Cleaner logs

Currently, the dhis2 logs are too verbose and make use of non-standard color coding. This is fine for most OSs, but makes display on platform pretty bleak. Note the undefined (line 5,6) outputs and the color handling:
image
I'd say:

  1. pluck out the error message and display it at the top if there's a standard way dhis2's api responds.
  2. fall back to the whole error
  3. don't use color coding if we can't also display it in platform, as 95% of usage right now is on platform.

Test coverage for new functions

In addition to the existing tests, please extend the tests on @elias-ba 's branch to cover:

create

  • create makes a POST
  • the proper URL gets built from the 'entity' string and the config
  • when an array is passed it gets nested inside that "entity" key
  • when an object is passed it doesn't get nested
  • when an object, an array, OR a function, it gets properly "expanded" with expandReferences
  • the proper authentication gets built

update

  • update makes a PUT
  • the proper URL gets built from the 'entity' string and the config
  • when an array is passed it gets nested inside that "entity" key
  • when an object is passed it doesn't get nested
  • when an object, an array, OR a function, it gets properly "expanded" with expandReferences
  • the proper authentication gets built

and keep your eyes sharp for "features" of the helper functions that are not yet in this list.

Does upsertTEI(...) work as specified?

Test this upsertTEI(...) helper on any DHIS2 instance, and I don't think this will work. Please try with the DHIS2 Play instance to verify... but I've never been able to get the CREATE_AND_UPDATE strategy to work.

* Create or update one or many new Tracked Entity Instances
* @public
* @example
* upsertTEI(data)
* @constructor
* @param {object} data - Payload data for new/updated tracked entity instance(s)
* @returns {Operation}
*/
export function upsertTEI(data) {
return state => {
const body = expandReferences(data)(state);
const { username, password, apiUrl } = state.configuration;
const url = resolveUrl(
apiUrl + '/',
'api/trackedEntityInstances?strategy=CREATE_AND_UPDATE'
);
console.log(
`Upserting tracked entity instance of type '${
body.trackedEntityType
}' to org unit '${body.orgUnit}' with ${
body.attributes && body.attributes.length
} attributes and ${
body.enrollments && body.enrollments.length
} enrollments.`
);
return post({
username,
password,
body,
url,
}).then(result => {
console.log('Success:', result);
return { ...state, references: [result, ...state.references] };
});
};
}

Also...

  1. don't we need to specify the TEI Id somewhere in order to upsert?
  2. Please update the readme docs to reflect all available helper functions

In past DHIS2 projects we've had to implement a pattern where we first GET a TrackedEntity, and then PUT or POST to upsert depending on the GET search results - see here: https://github.com/OpenFn/logical-outcomes/blob/master/tnc/CSVtoDHIS2__http.js

Upsert or "import strategy: create and update"

It's not clear to me whether importStrategy: 'CREATE_AND_UPDATE' is available for common resourceTypes like trackedEntityInstances. I see it mentioned here and in a few more places, but does DHIS2 actually support upserts?

If not, I'd like to see a composed upsert that either attempts to create and then updates on conflict, or attempts to get and then either creates or updates depending on whether the get succeeds.

While we've used the get then post or put method for other adaptors, given that the required parameters can change between get and create for dhis2 (ou to orgUnit seemingly) I'm starting to think we should attempt to create and catch the error, updating if we get a conflict. We just need to make sure that we get back the canonical ID when the create fails due to a conflicting external ID.

If I try to create a TEI twice with the same data:

create('trackedEntityInstances', {
  orgUnit: 'DiszpKrYNg8',
  trackedEntityType: 'Zy2SEgA61ys',
  attributes: [
    {
      attribute: 'flGbXLXCrEo', // system case ID
      value: '123',
    },
  ],
});

The first attempt succeeds and then I get this 409 on the second. Could we use that to then send an update? Doubtful, as it lacks the TEI id:

✗ Error at Tue Dec 21 2021 22:22:20 GMT-0700 (Mountain Standard Time):
 Request failed with status code 409
{
  "responseType": "ImportSummaries",
  "status": "ERROR",
  "imported": 0,
  "updated": 0,
  "deleted": 0,
  "ignored": 1,
  "importOptions": {
    "idSchemes": {},
    "dryRun": false,
    "async": false,
    "importStrategy": "CREATE_AND_UPDATE",
    "mergeMode": "REPLACE",
    "reportMode": "FULL",
    "skipExistingCheck": false,
    "sharing": false,
    "skipNotifications": false,
    "skipAudit": false,
    "datasetAllowsPeriods": false,
    "strictPeriods": false,
    "strictDataElements": false,
    "strictCategoryOptionCombos": false,
    "strictAttributeOptionCombos": false,
    "strictOrganisationUnits": false,
    "requireCategoryOptionCombo": false,
    "requireAttributeOptionCombo": false,
    "skipPatternValidation": false,
    "ignoreEmptyCollection": false,
    "force": false,
    "firstRowIsHeader": true,
    "skipLastUpdated": true,
    "mergeDataValues": false,
    "skipCache": false
  },
  "importSummaries": [
    {
      "responseType": "ImportSummary",
      "status": "ERROR",
      "importOptions": {
        ...blah
        "importStrategy": "CREATE_AND_UPDATE",
        "mergeMode": "REPLACE",
        ...blah
      },
      "importCount": {
        "imported": 0,
        "updated": 0,
        "ignored": 1,
        "deleted": 0
      },
      "conflicts": [
        {
          "object": "Attribute.value",
          "value": "Non-unique attribute value 'ZRP792320' for attribute flGbXLXCrEo"
        }
      ],
      "enrollments": {
        "responseType": "ImportSummaries",
        "status": "SUCCESS",
        "imported": 0,
        "updated": 0,
        "deleted": 0,
        "ignored": 0,
        "importSummaries": [],
        "total": 0
      }
    }
  ],
  "total": 1
}

But maybe we could then perform a get which looks for just TEIs with that attribute/value combination, grab the ID, and then update? Using the following I can snag the dhis2 id:

get('trackedEntityInstances', {
  ou: 'DiszpKrYNg8',
  filters: ['flGbXLXCrEo:Eq:123'],
});

ReferenceError: responseType is not defined

Hello,

I am trying to use getEvents but I am getting this error

ReferenceError: responseType is not defined

when I look at the code it seems to be a issue (response type is never extracted from option and get data don't have this param)

return getData('events', params, responseType, options, callback)(state);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.