Limit access to forms based on Health District ID

Hello @binod
How do I limit access to forms based on Health District ID?
Thanks,
Job

Hi @Job_Isabai,

Welcome to the CHT Forum! It is great to have you here.

I have moved the post to new topic since the earlier question was about restricting to user types and was marked as solved. thanks.

Hi @Job_Isabai, welcome to the forum and thanks for tagging me.

Depending on where your patient and district are in the hierarchy, you might be able to limit the access to forms using context.expression in your {form_name}.properties.json file.

Example:

{
"title": "Screening", 
"context": {
  "place": false,
  "person": true,
  "expression": "contact.parent.parent.parent._id === 'uuid_of_district'"
  }
}

The above examples assumes:

  • Your district is 3 steps above the patient (District → Town → Household → Patient)
  • You want to limit your form to the patients in only one district that has the UUID: uuid_of_district

You can also specify the UUID relative from the logged in user, if that is easier:

"expression": "user.parent.parent._id === 'uuid_of_district'"

If there are multiple districts, then it can get difficult to specify them in the JSON file. In that case, you can consider adding context information in the contact-summary and accessing it from the form context.

Here is a working example form the default configuration:

  1. In contact-summary-templated, we set the context variable as show_pregnancy_form:
  1. Now the above context variable is consumed in pregnancy.properties.json as summary.show_pregnancy_form:

The function used above: isReadyForNewPregnancy is defined here, but you can define your own function that suits your purpose i.e. returning true for certain districts.

In the contact-summary, we have two variabes available that can hold the parent information: contact and lineage.

Variable Description
contact The currently selected contact. This has minimal stubs for the contact.parent, so if you want to refer to a property on the parent use lineage below.
lineage An array of the contact’s parents (2.13+), eg lineage[0] is the parent, lineage[1] is the grandparent, etc. Each lineage entry has full information for the contact, so you can use lineage[1].contact.phone. lineage will include only those contacts which are visible to the logged in profile

If you want to make the form available to only certain districts based on their UUIDs, then you can use the contact variable:

const UUIDS = ['uuid_1', 'uuid_2'];
return UUIDS.includes(contact.parent.parent.parent._id);

If you have any specific field in the district document that can decide the form availability, then you can go for lineage which provides access to more fields.

return lineage[2].show_form === 'yes';

However, in order to use the lineage information about the district, your logged in user should also be able to see the district contact. If it is an offline user at some level below the district level, then the user might not be able to see the district. You can check that in the People/Contacts tab whether you can see the district or not.

Plese let us know how it goes.

6 Likes

@binod thank you very much. It works perfectly.

4 Likes

A post was split to a new topic: Showing or hiding the log-out button depending on conditioin