Formsubmissions Breakdown

This is the process of converting form submissions to Event and Client models.

Prerequisites

  • Forms OpenMRS concept mappings
  • Forms relationships mapping
  • Forms .json download from Ona


Client Model

FieldTypeopenmrs_entityNotes
_idjava.lang.String
Auto generated value by couchdb
_revjava.lang.String
Auto generated by couchdb
attributes
java.util.Map<String, Object>person_attributeSet of key/value person attributes e.g EPI Card Number, GOB_HHID
deathDateApprox



baseEntityId
java.lang.String
This is the client unique identifier equivalent to id in relational databases. Equivalent to formSubmission.entityId() value
gender
java.lang.StringpersonEither of 'F' or 'M'
birthDateApprox



adresses
List<org.ei.opensrp.clientandeventmodel.Address>
person_address

This is a list of client's location details e.g

Addresses Object
 "adresses": [
       {
           "addressFields": {
               "address5": ""
           },
           "addressType": "usual_residence",
           "cityVillage": ,
           "country": ,
           "countyDistrict": ,
           "endDate": ,
           "geopoint": ,
           "latitude": ,
           "longitude": ,
           "postalCode": ,
           "startDate": ,
           "stateProvince": ,
           "subDistrict": ,
           "subTown": ,
           "town": ,
           "active": true
       }
   ]
firstName
java.lang.StringpersonClient's first name as entered in the forms
dateCreated
java.util.Date
Current date in the format: yyyyMMddTHHmmssSSSZ
identifiers
Map<String, String>
person_identifier

A set of unique key/value person identifiers e.g National ID no,Birth Registration ID

"identifiers": {
       "NID": "1234567890123"
   }
relationships
java.util.Map<String, List<String>>person_relationship

This is only present in client's that have a person relationship with another client. e.g a child client document will have a relationship to the mother e.g

"relationships": {
       "mother": [
           "58b63969-8f58-4533-a08a-a238861713ec"
       ]
   }
birthDate
java.util.DatepersonDate format: yyyyMMddTHHmmssSSSZ
lastName
java.lang.StringpersonClient's last name
deathDate



type
java.lang.String
This is the document type. Should be 'Client'

Event Model

FieldTypeopenmrs_entityNotes
_idjava.lang.String
Auto generated by couchdb
_revjava.lang.String
Auto generated by couchdb
eventTypejava.lang.String
Equivalent to encounter_type value in model.xml
baseEntityIdjava.lang.String

This is the client unique identifier equivalent to id in relational databases. Equivalent to formSubmission.entityId() value.

Only a single client should exist with a similar base_entity_id value

entityTypejava.lang.String
This is equivalent to the bind_type value in the form_definition
dateCreatedjava.util.Date

Current date in the format: yyyyMMddTHHmmssSSSZ

This is the date when the event is created on the server

providerIdjava.lang.String
Logged in user username
formSubmissionIdjava.lang.String
FormsubmissionId of the form submission currently being converted to EC
locationIdjava.lang.String
Location id of the logged in user as returned by OpenMRS authentication process during login
versionjava.lang.Long

Current timestamp long value. Most of the server side repeating jobs use this value to get the last updated or created events

This timestamp indicates when an event was created on the device

eventDatejava.util.Date

This is the encounter date

This is the date when the encounter happened. In most instances this indicates the date the event was created. However if an encounter happened in the past e.g immunization was done in the past, the eventDate this is changed to reflect that.

typejava.lang.String
Document type. Should be Event
obsList<org.ei.opensrp.clientandeventmodel.Obs>concept

Each field of type concept is an Obs object as show below

Sample Observation
{
           "comments": null,
           "fieldCode": "160600AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
           "fieldDataType": "select one",
           "fieldType": "concept",
           "formSubmissionField": "FWCWOMSTRMEN",
           "humanReadableValues": [
               "1"
           ],
           "parentCode": null,
           "values": [
               "1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
           ],
           "value": "1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
       }
The humanReadableValues key stores a human readable version of the concept value for easier processing in the client app
which doesn't maintain a concept dictionary


status



statusHistory



priority



episodeOfCare



referrals



category



duration



reason



Relationship Mapping

Given Clients/Events data, it’s hard to deduce some vital relationships between some entities e.g given a child’s data inform of a client document, it’s hard to tell who the mother is or given a woman’s client data, it’s also hard to tell which household they belong to. To tackle this, a new person_relationship field is to be added to the xlsforms that have subforms e.g. for new household registration form, there will be a new field "<household_head_entity_id openmrs_entity="person_relationship" openmrs_entity_id="household_head"/>” under new woman registration. This field will be populated dynamically with the household entityId value so that each woman's client document indicates which household they belong to. This approach also will be applied for example to the birth notification form to hook up the child client model with the mother's id "<mother_entity_id openmrs_entity="person_relationship" openmrs_entity_id="mother"/>". The relationship fields should also be defined in the form definition.

Further, person relationships might differ in different sites and to be able to add relationships dynamically, there is ec_client_relationships.json file where the person_relationship type and the field that holds the relation_id are defined .

ec_client_relationships.json
[
  {
    "client_relationship": "householdHead",
    "field": "household_head_entity_id",
    "comment": "this field is the name as it appears in the form_definition.json file"
  },
  {
    "client_relationship": "mother",
    "field": "mother_entity_id",
    "comment": "this field is the name as it appears in the form_definition.json file"
  }
]

With the above ec_client_relationships.json or an equivalent, when populating the field values for a subform in the FormUtils.getFieldValuesForSubFormDefinition() method call FormUtils.populateRelationField() method,  check if the client has any of the fields in the relationship JSON document and if a field is present  set its value with the parent base_entity_id and when creating a client model, the logic should check if the client has any of the relationships fields and if so populate its relationship map with the “client_relationship”  value as the relationship type and the value of e.g “household_head_entity_id/mother_entity_id” field as the entityId in FormEntityConverter.addRelationship() method.

Form Submission Breakdown to EC



  1. The FormUtils.generateFormSubmisionFromXMLString() is called in the activities saveFormSubmission() method and converts the XML data received from enketo to a JSONObject and  loads the form_definition.json for the current formsubmission to get the form and the subforms from the xml data in the enketo data creating an instance of org.ei.opensrp.domain.form.FormSubmission .
  2. With the FormSubmission instance, call FormUtils.generateClientAndEventModelsForFormSubmission() method in the above method to retrived EC data from the form submission
  3. In the FormUtils.generateClientAndEventModelsForFormSubmission() method, formEntityConverter.getClientFromFormSubmission() method is called to generate clients and formEntityConverter.getEventFromFormSubmission() to generate events. The method formEntityConverter.getDependentClientsFromFormSubmission () is called to retrieve other clients/events in case the form had subforms and return them in a java.util.Map.

  4. CloudantDataHandler.createEventDocument() and CloudantDataHandler.createClientDocument() are called to create Cloudant event and client models respectively.