Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Excerpt

Organizations lt you represent the real-world structure of your project and enable CommCareHQ to be smarter about how features, such as case sharing, work. You can create a Organization Structure that represents geographic or organizational elements in your project. For example, you may create a hierarchy of regions, clinics and attached CHWs for your project. Each element in your structure is a Location.  

...

Multiexcerpt include macro
macro_uuid9078ada9-7c16-4fe4-af1c-4ddd91c1ebe9
nameSoftware Plan - Advanced
templateDataeJyLjgUAARUAuQ==
page[Internal] CommCare Public ManagementCommCare Help Site Design Guidance
addpanelfalse

Child pages (Children Display)
depth92
allChildrentrue
styleh2h3
sortAndReverse
excerptTypesimple
first0

The sections below walk through how to use the Organizations Feature in CommCare.

Organizations Overview

Examples of Organization Structures

Example 1: Agricultural Extension Agents

Background

In this project, the primary users are Agricultural Extension Agents who were using an application to monitor farms.

Here is the government/administrative hierarchy where they were working:

  • Province

    • District

      • Administrative Post

The people involved in the project were in the following hierarchy:

...

Worker Type

...

Notes

...

Coverage

...

Provincial Managers (PM)

...

Use a separate PM application in which they should be able to see cases created by any user in the entire province

...

Each PM is responsible for all cases/data collected by all of the district supervisors and extension agents in their province.

...

District Supervisors (DS)

...

Also work as Extension Agents, but should be able to see and update cases of other Extension Agents in their district

...

Each supervisor is responsible for exactly one District, which includes 3-5 Administrative Posts

...

Extension Agents (EA)

...

Collects data using the Extension Agent app

...

Each extension agent is responsible for one or more Administrative Posts

Location Design

...

Notes on each level:

  • Administrative Post - Cases are actually owned by the Administrative Post, so when a mobile worker creates a case it is assigned to a Post. (NOTE: This means if you had multiple workers assigned to one location at this level that they would see each other cases).

  • Extension Agent - a level was created for the Extension Agents; this is the level to which Mobile Workers who are Extension Agents are assigned. This may seem a bit strange because you have to create both a mobile worker account as well as a location, but there advantages to this, as described below.

  • District - this is the level to which District Supervisors are assigned; this allows them to view cases created by any Extension Agents in their district and to create cases for any administrative post in their district.

  • Province - the provincial manager can see all cases below. Mobile workers at the PM level are assigned to locations at this level.

Other notes:

  • This app used the location hierarchy as a Lookup Table as described in Assigning Cases to one of Multiple Groups . Imagine you are an Extension Agent assigned to the Extension Agent level, which has three Administrative Posts under it. When create a case you would see a lookup table question which shows a list of the three Administrative Posts assigned to you. When you choose one and then submit the form that new case is assigned to the post you selected. It is also not necessary to maintain a separate lookup table

  • The application also captures the names of the locations above it in the hierarchy.

  • It is very easy to reassign administrative posts; you can just move the location to a different district in the hierarchy, and once the users sync their data the transfer will be complete

  • One drawback of this approach is that one person can only be assigned to one district; so if there were workers that covered a subset of districts that would need to be another level in the hierarchy

Setting up Organization Levels and Structure

Overview

Note: In order to use this feature, you must have Case Sharing enabled in your app. For more information, please see https://dimagi.atlassian.net/wiki/x/ITLKfw.

Once you've defined a hierarchy, it can be used to simplify managing the project: 

  • Case Sharing can be configured so that cases are assigned to a location. Then higher levels can see cases of lower levels (ex. Mobile workers at a clinic can see the CHWs' cases)

  • Lookup Tables can be assigned to a location allowing all mobile workers at that unit and below it to see that lookup table's data

  • Your organization structure can be displayed inside your forms (ex. Allowing users to choose the village for a given beneficiary from a list).

In the future, "Organizations" will also enable reporting and data exports (allowing you to download data or a view a report for users at and below a particular organization unit).

Set Your Organization Levels

To use Organizations, you first need to define your Organization Levels. These describe the behaviour of different levels of your hierarchy (i.e. whether Clinics, for example, can have cases assigned to them).  

To setup Organization Levels, go to Users tab and choose Organization Levels from the menu.

...

You can use the page to define the levels in your organization hierarchy. Specify the following information for each organization level:

  • Organization Level: The name of the organization level (ex. District or Clinic).

  • Parent Level: The parent level for the organization level (ex. the parent level of Clinic is District). For the top level of your organization hierarchy, set the Parent Type to -top level-.

  • Owns Cases: This controls whether locations of this type are able to have cases created and assigned to them. For example, you may have Health Workers that own cases, but districts do not.  If there are multiple workers assigned to a single location at this level they will share cases if this box is checked. Depending on your use case, you might want to see https://dimagi.atlassian.net/wiki/x/XTPKfw for more information.

  • View Child Data: For an organization level that has child organization levels, this controls whether a location at that level can view cases assigned to child locations.  For example, you may want to have Clinics view cases owned by each child Health Worker.

Here's a simple example of the organization levels for a project:

...

Set Your Organization Structure

Once you've configured your Organization Levels, you can create the the Organization Structure for your project.  The Organization Structure is comprised of locations that can represent a geographical hierarchy (i.e .a state or a district), a real world location (i.e. a Clinic) or just a programmatic point in the hierarchy (i.e. a Supervisor and Health Workers).

Click on the Users tab and choose Organization Structure.  

Click on the "New location at top level" to create your first location.

...

Once you've created a location, you can click New Child Location, or go back to the Locations page to create more locations.

...

When viewing the location tree, you can use the + button to expand a location and view its children.  Once expanded, there will also be a button to create more child locations for that location.

...

You can also edit a location using the Edit button next to it in the tree. When editing a location, you can set the following information:

  1. Name and Organization Level

  2. Coordinates: This is useful for map-based reports if using Organizations in  CommCare Supply project

  3. Parent: Change or move the location to a different parent.  Currently only locations with no children can be moved.

  4. Site Code: A unique identifier for the location that can be used when assigning cases to the location via Excel or assigning lookup table rows to the location

...

Bulk Importing your Organization Structures

Once you've created your Organization Levels, you can also use Excel to create or update the organization structure. Using Excel might be easier when managing larger numbers of locations.

  1. Go to the Organization Structure page (Users tab -> Organization Structure) and then choose Bulk Upload.

...

  1. Download the Excel file - it will list a tab for each organization level. You can add (or edit rows) in this Excel document to create new locations. For each location you're required to provide the following information:

  • Name: The name of the location

  • Site Code: This is a unique identifier for the location and cannot contain any spaces or special characters

  • Parent Site Code: This is the site code of the parent of this location. If the location doesn't have a parent, leave this column blank

  • Latitude and Longitude: Optional columns to set the coordinates of the location.

  1. Once you've created or updated your Excel file, upload the Excel file using the same download page.

Note: You cannot move locations using the bulk upload (changing the parent site code for an existing location will result in an error). 

Assigning Mobile Workers to Location

To use the Organizations feature in your applications, you first need to assign mobile workers to the location.  

There are two ways to assign mobile workers to a location

  1. You can choose the user from the mobile worker list, and then use the Locations tab to choose their location.  Each user can be assigned to more than one location.  Set the Primary Location to represent that user's main working location.  This primary location will then appear in the bulk mobile worker download / upload, and be displayed in the app when accessing the user's information.  

...

Panel
panelIconIdatlassian-info
panelIcon:info:
bgColor#EAE6FF

Orphan case alerts project setting

Depending on your usecase, you might want to consider enabling the Show Orphan Case Alerts on Mobile Worker Page project setting. This will notify the user before accidentally unassigning the last mobile worker from a location that owns cases, thereby orphaning those cases.

  1. Alternatively, you can use the Locations page to edit the location.  Choose Edit on the location from the Locations page, then chose the Users tab to assign mobile workers to that location.   

...

Case Sharing using Organizations

Multiexcerpt include macro
macro_uuid9078ada9-7c16-4fe4-af1c-4ddd91c1ebe9
nameSoftware Plan - Advanced
templateDataeJyLjgUAARUAuQ==
page[Internal] CommCare Public Management
addpanelfalse

The Organization Structure lets you easily configure parent locations to view their child location's data (ex. A supervisor viewing their supervisee's data).   In the example diagram below, users assigned to Fermathe Hospital can view the data for their health workers, and users assigned Grace Children's Hospital can view their health worker's data, but Fermathe Hospital can't view Grace Children's data, and each health worker cannot view each other's data.

...

This works by assigning cases to the child locations (ex. Andrea Fletcher).  Users assigned to parent locations (that have View Child Data turned on) are then allowed to view data for any locations below them.  A case sharing group is automatically created representing each location that can own cases - CommCare will then automatically assign mobile workers to the case sharing groups based on the organization hierarchy and data sharing settings.  

Configuring Case Sharing for an Application

For mobile workers assigned to locations at an organization level that can only "Own Cases", but not "View Child Data", its relatively simple to configure the application.  Turn on the Case Sharing option on the application settings page and newly created cases will automatically be assigned to the location.  

...

For mobile workers assigned to locations at an organization level that can "View Child Data", they can sometimes be in more than one case sharing group.  You'll be required to choose which location the case gets assigned to.  To configure this, follow the instructions on the https://dimagi.atlassian.net/wiki/x/2CTKfw

This works by assigning cases to the child locations (ex. Andrea Fletcher).  Users assigned to parent locations (that have View Child Data turned on) are then allowed to view data for any locations below them.  A case sharing group is automatically created representing each location that can own cases - mobile workers at that location and any parent locations that can view child location data are added to that case sharing group.  

Location-Based Data Access and User Editing Restrictions

IMPORTANT: This feature dramatically limits what pages and reports are available.  In particular, things like app-building, messaging, and admin configurations are disabled for restricted users.  Be sure to log in as a restricted user to see what's available before committing to using this feature.

Organizations allow you to partition your project and restrict which data different users are allowed to view and edit.  You can limit data exports so that a web user can only export data in their assigned location, or limit mobile worker and location editing.  When you have organization-based restrictions turned on, users are only allowed to access the following:

  • Mobile Workers:  The web user can view and edit mobile workers who are also assigned to their location, or assigned to any of their location's child locations.  

  • Cases:  The web user can view cases that are assigned to their location, their child locations or any mobile workers they also have access to

  • Forms: The web user can view forms submitted by mobile workers that they have access to

  • Some Reports: As of this writing, following reports are accessible:

    • Submit History (and associated child pages)

    • Case List (and associated child pages)

    • Aggregate User Status

    • Application Status

    • Submissions By Form

    • Daily Form Activity

    • Form Completion Time

    • Form Completion vs Submission Trends

Restricting Access for a Web User Role

Create or edit a web user role that defines what the web user will be allowed to access.  When configuring the role, make sure you set "Full Organization Access" to false.  For more information about configuring roles see https://dimagi.atlassian.net/wiki/x/BzXKfw.

...

Setting up a Web User

Once you've setting roles, you can assign a web user to that role and their accessible locations. This is done by clicking on the web user from the web user management page. 

...

Restrictions to Routines and Pages on CommCareHQ

Once a user is location restricted, they will be able to access only pages on CommCareHQ that can have their information restricted by location.  These pages include:

  • Data Exports: The user will be able to export form and case data, but they will only be able to filter the data to their assigned location or their child locations.   If no filters are specified, all data from their assigned location (and that location's child locations) will be downloaded. 

  • Mobile Workers: The mobile workers page will only list mobile workers that the user has access to.  When creating a mobile worker, they will need to be assigned to one of the user's available locations

  • Organization Structure: Only locations that the web user has access to will be listed here and editable. 

Adding Custom Location Fields

You may want to add and store additional data about each location. In order to do that, you can add custom location fields to your organization structure.

Step 1

To add a field, go to the Organization Structure page, and click on Edit Location Fields.

...

Step 2

Click on the green "Add a Field" button to add a custom field: 

...

Step 3

Enter in the following information for the field:

  • Location Property: the unique ID you can use to reference this property in the app builder. This field should be concise, and cannot have any spaces.

  • Label: this is the text that users will see when adding or editing a location in CommCare HQ.

  • Required: tick this box if you want the field to be required for all locations.

  • Choices: if you want users to have to choose from a list of dropdowns, click on "add choice" and add as many answer options as you'd like to appear in the dropdown. If you want users to be able to enter in free text, do not add any choices.

See example below where we are adding a field called Facility Type, with three answer options in a dropdown (pharmacy, hospital, and clinic): 

...

 Step 4

Press the blue "Save Fields" button at the bottom of the page, and your location field will be saved.

...

Organization Data Management

Viewing Data Assigned to Locations

You can use the Case List report to view cases that are assigned to each location. In the case list report, you can choose a specific location to view data for - this will show data for all cases assigned to that location and any child locations. You can type and search using the Location name to find a location. Please note that only some of the native reporting supports organizations.

...

Reassign Cases to a Location

Similar to assigning cases between mobile workers, you can use the Reassign Cases report to assign a case to a location.  To go to the Reassign Cases report, choose the Data tab, then choose View All, then choose the Reassign Cases link on the left side.

Use the reassign cases report to search and filter for the cases you care about - then check the cases you want to reassign and choose "Group" and the location you want to reassign the cases to. 

...

Assigning Cases to Locations When Using the Excel Importer

Panel
panelIconIdatlassian-info
panelIcon:info:
bgColor#EAE6FF

Importing Cases from Excel

For more details on importing cases from Excel please see https://dimagi.atlassian.net/wiki/x/TAjKfw.

Using the Owner Name

When importing cases using the bulk uploader, you can assign them to a location using an owner_name column.  In the owner_name column, you can list the name of the location or the site code for the location.  The importer will first check for mobile worker names and groups for matches before trying to match to locations.  

  • If you have location names that conflict in your project, you can also use the site code to ensure the cases are assigned to the correct owner.    

Using Owner ID

You can also directly use the ID of the location when importing cases to assign cases to that location.  You can put the ID in a column called owner_id in your Excel sheet. To find the ID of a location, navigate to the locations page: https://www.commcarehq.org/a/<domain>/settings/locations/import/ and click on "Download Organization Structure". When you download your locations, there will be a "location_id" column, which will contain the location ID against each location.

You can also find the location ID of your location by clicking on "Edit" and looking at the URL in your browser. The last portion of the URL is the location ID. For example:  https://www.commcarehq.org/a/[your_domain]/settings/locations/ddc5de8aedb66637cc96ab25d6fb9e2c/. In this URL, the last part: ddc5de8aedb66637cc96ab25d6fb9e2c is the location ID.

Assigning Cases to One of Multiple Locations

For mobile workers assigned to locations that can "View Child Data", they can sometimes be in more than one case sharing group. The user will be required to choose which location the case gets assigned to. For example, a clinic may be required to register clients and assign them to one of their CHWs.

This will add a multiple choice question in your application that allows you to choose which location a case will be assigned to.  

Step 1: Turn on the Add-On

When a mobile worker is registering a patient, you want to display a list of the case sharing groups so that they can assign the case to the appropriate location.  To do this, you need to turn on an Add-On called "Custom Single and Multiple Answer Questions".  This allows you to display custom choice lists in forms (i.e. a list of case sharing groups) instead of just items from a Lookup Table

Choose the Application Settings (the gear icon next to your application's name near the top left of the screen)

...

Navigate to the Add-Ons tab.

...

Turn on the "Custom Single and Multiple Answer Questions" add-on under "Calculations" and hit Save

...

Step 2: Configure Your Application

In the application, you need to setup your Registration form so that it displays the list of case sharing groups in a single or multiple select question.  

Go to your form that is used to register a new case.  Choose the Choice dropdown and add a new Multiple Choice Lookup Table question. 

...

Set the question ID to owner_id (or whatever makes sense) and the label "What location do you want to assign the user to? (or whatever makes sense)".

...

Choose the "Lookup Table Data" item in the left tree, and then choose the "..." button to configure the list of choices.

...

Set the Query Expression to instance('locations')/locations/location[@type = 'TYPE OF LOCATION'] (note: be sure to change "TYPE OF LOCATION" to the specific type of location in your application. This will display the list of locations that are available to own the case.  Set the Instance ID to locations and the Instance URI to jr://fixture/locations.  Then click on the Save button. 

...

Back on the Lookup Table Data page, set the Value field to @id and the Display Text field to name.  Note that the Lookup Table dropdown should say "Lookup table not found in project".

...

Save your form, and then go to the Case Management section of the form and save the question to the case property called owner_id, which is a special property used to define the owner of the case.

...

Search for Locations

When searching for locations, you can use special symbols to make your search more precise.

You can initiate an exact search by including quotation marks around the name of the location, as pictured above.  CommCare will provide the user suggestions matching the exact text, so for instance, "Cambridgeport" wouldn't appear.

...

 You can use slashes to specify multiple location levels, narrowing your search.  For example, typing "mass" will show you "Massachusetts":

...

Adding a slash afterward will start a new search among the results.

...

You may then type to search in those results.

...

This can be done multiple times.

...

These two techniques can also be combined for maximal precision.

...

Assigning Lookup Table Rows to a Location

Panel
panelIconIdatlassian-info
panelIcon:info:
bgColor#EAE6FF

Lookup Table Documentation

For more details on using Lookup tables, view https://dimagi.atlassian.net/wiki/x/gijKfw.

Lookup table rows can be assigned to a location by editing the excel upload. This will allow all mobile workers assigned to that location and mobile workers at any child locations to view that lookup table data. This makes it easier to assign specific data to a region or group of mobile workers.

To assign a lookup table row to a location, add a column titled location 1 (or location 2, location 3, etc. if you want to assign multiple locations to a row). This column must be added on the Table ID tab of the upload. Likely, the Table ID tab will be second on the spreadsheet if it was originally created using the Download Lookup Tables feature.

...

Next, enter the name of the location or the site code. Since location names can sometimes conflict, the site code will ensure that the lookup table row is correctly assigned.  If you use a location name that results in duplicates, you will get a warning after importing the lookup table.  

Show Orphan Case Alerts on Mobile Worker Edit Page

Locations that owns cases and have a single assigned mobile worker require careful consideration. This is because unassigning that mobile worker from the location would render the cases inaccessible to all mobile workers. On the other hand, unassigning mobile workers from locations with no cases presents no issue, as no new cases can be created in such locations.

While some workflows capitalize on this behavior, other workflows might be impacted differently. Depending on your project's specific worflow, you might want the system to display a warning when this situation is detected.

The warning banner

The display of a warning banner is controlled by a project setting named Show Orphan Case Alerts on Mobile Worker Edit Page.

...

When editing a mobile worker, the warning banner will be displayed on the "Locations" tab if any of the worker's assigned locations fall into the category described above. The banner presents a list of locations where the mobile worker is the sole assigned user, along with the number of cases present in each location. This enables you to quickly identify situations that require attention.

...

Advanced Organization Level Configuration

There are a number of advanced options for organization levels. These are shown when you click on the Advanced checkbox on the Organization Levels page.

Type Code

This is a code that you can use to refer to the type when accessing locations in lookup tables or logic.  For example, if your level is called District Warehouse, the type code might be district_warehouse

Level to Expand From

By default, CommCare will only send each user the list of their assigned locations and those location's ancestors and descendants.  For example, if the organization levels are State -> District -> Block -> Outlet, and the user is assigned to a block,  they will get a list of their state, their district, their block and all that block's outlets.  In some situations, you may want to get a list of locations outside of the ancestors and descendants.  In the example above, if a user is assigned to a block, they may want to see all blocks in their district anyway. This is controlled using the "Expand From" option.  

This option sets the level below which all locations will be synced down.  For example, if the user is assigned to a block but the level to expand from is set to "district", that user will get a list of their state, their district, and all blocks in that district (including their own). 

Level to Expand To

This option should only be changed if you need to improve your application's performance.

This option limits the types of locations that are sent to a given user.   For example, if the organization levels are State -> District -> Block -> Outlet, and the user is assigned to a district, they will get a list of their state, their district and all blocks and all outlets in that block.  If there are too many outlets and the list of outlets is not needed in the application, the level to expand to can be set to "block".  Commcare will then not send any locations below the block level. 

Force Sync

This option allows you to force CommCare to send all locations of a given type, but not any of those locations descendants.  For example, if the organization levels are State -> District -> Block -> Outlet, and the user is assigned to a block,  they will get a list of their state, their district, their block and all that block's outlets.  In some situations, you may want to get a list of states as well (but none of the state's districts, blocks or outlets).  You can achieve this by setting the Force Sync option to "State".  

Translating or Customizing Location Display

Location names are not directly translatable.  This document describes an approach to work around this limitation.  It allows you to arbitrarily customize the display of locations or any other fixture in your app.

Multiple choice or checkbox lookup table questions typically operate on a fixture instance, but you don't have very much control.  The technique described here instead creates a "nodeset" using a repeat group with a model iteration query, and then uses that for the lookup table question.  This way, you can define whatever properties you need in the nodeset for reference in the lookup table question.

Storing Location Translations

The first thing you need for this to work is stored translations.  You can define custom location fields for the name in each supported language, for example:

  • name-en

  • name-hin

  • name-es

Then edit your locations to populate these fields.  This information will now be available to access in your application.

Referencing the current language

This process is described in the page on https://dimagi.atlassian.net/wiki/x/7CTKfw.  If you set up the lang-code question as described there, you should be able to use jr:itext('lang-code-label') to refer to the current language.

Setting up a nodeset

Add a new repeat group, and under the "Advanced" section, set the Model Iteration ID Query to "instance('locations')/locations/location/@id".  This will make one iteration of the repeat group for each location in your project. You can add a filter here if you like, or you can filter the expression later, in your lookup table question.  Set the Instance ID to "locations", and the Instance URI to "jr://fixture/locations" to make sure the instance is available in the form.

Inside this repeat group, add hidden values for whatever you may need to reference.  The location id will be made available by virtue of the Model Iteration ID Query.  Here you can make a translated "name" field - just add a hidden value which selects the appropriate field for the active language:

cond(jr:itext('lang-code-label') = 'es', instance('locations')/locations/location[@id = ../@id]/location_data/name-es,
jr:itext('lang-code-label') = 'en', instance('locations')/locations/location[@id = ../@id]/location_data/name-en,
jr:itext('lang-code-label') = 'hin', instance('locations')/locations/location[@id = ../@id]/location_data/name-hin,
instance('locations')/locations/location[@id = ../@id]/name)

Note that you could do whatever you wanted here to decide how to display the location - you could reference the location's state, or a calculated property elsewhere in the form, for instance.

Setting up the Lookup Table question

Now that you have a suitable nodeset, you can set up a lookup table to reference it.  Add a new lookup table question and edit the lookup table.  Drag the repeat group used to make your nodeset into the "Query Expression" field.  It should look something like "/data/locations/item" (*Note: it must start with "/data/". The #form/ syntax will throw an error.)  Leave the Instance ID and Instance URI fields blank.  Then set the Value Field to "@id", and the Display Text Field to "name", or whatever field in your nodeset you want to display.  That's it!  Your lookup table question should now use the nodeset described above, with translated names.

Referencing the Location/Organization Hierarchy in Applications

Please note the documentation below requires more technical expertise

The documentation below may require knowledge of more technical software management and development topics.

This page discusses how to reference the location hierarchy in various parts of apps.

Enabling Access to Location Hierarchy

All new projects have the location hierarchy.  

Some older projects may be setup to only receive the Old Hierarchical Fixture.  To transition to the flat fixture, go to project settings, then choose Pre-Release Features -> Location Fixture.  You can use this to turn on the new location format (flat fixture).  Once you have done this, new versions of the app will start to use the new location format.  Once all your existing users have transitioned to a new version of the application that uses the new location format, turn off the hierachical fixture.  This process is described in depth at https://dimagi.atlassian.net/wiki/x/cinKfw.

The User's location

To pull the current user's location ID you can use the "commcare_location_id" session variable. To reference this in a form, use the following expression: 

 instance('commcaresession')/session/user/data/commcare_location_id

The Location Hierarchy

To reference the location hierarchy in forms you need edit the source XML by hand and construct complicated xpath expressions. 

Ensure that the Locations Data Source is Available

First, you'll need to make sure that the form has a reference to the Locations data source.

The easiest way to accomplish this is to ensure that your question has at least one select question with locations as choices.

If your form doesn't contain one of those questions you can create a 'dummy' question:

  • Below you'll see instructions for "Making select questions with locations as choices"

  • Follow those instructions to add a locations lookup to the form

  • Set the Display Condition for that question to false()

After those steps you should be able to reference locations elsewhere in the form.

Note: If you are using a Locations driven select question in the form, you won't need to keep around the 'dummy' question as well.

Referencing the properties of the user's location (or location ancestor) in a form

 You can use the following templates to reference the properties of the user's location (or ancestors). These examples assume a hierarchy of state --> district --> block --> outlet. These expressions will need to be customized to your own hierarchy.  To find the code to use for each organization level, on the Organization Level page, click on the Advanced checkbox.  

For example, if my location hierarchy has village →  city → county→ and I'm trying to pull the city's ID for my current village user, I would take this example from below: 

instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@block_id

and modify @block_id to say @city_id  

 instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@city_id

...

I am a...

...

referencing my...

...

syntax in forms

...

outlet

...

own location's name

...

 instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/name

...

outlet

...

own location's type

...

 instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@type

...

outlet

...

own location's site code

...

 instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/site_code

...

outlet

...

own location's custom data

...

 instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/location_data/custom_field_id

...

outlet

...

parent block's id

...

 instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@block_id

...

outlet

...

parent block's name

...

instance('locations')/locations/location[@id =  instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@block_id]/name

...

outlet

...

parent block's name

...

instance('locations')/locations/location[@id =  instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@block_id]/site_code

...

outlet

...

parent district's id

...

instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@district_id

...

outlet

...

parent district's name

...

instance('locations')/locations/location[@id =  instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@district_id]/name

...

block

...

parent district's id

...

instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@district_id

...

block

...

parent district's name

...

instance('locations')/locations/location[@id =  instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@district_id]/name

...

district

...

parent state's id

...

instance('locations')/locations/location[@id = instance('commcaresession')/session/user/data/commcare_location_id]/@state_id

Accessing the location additional information (Location Fields)

Once you have the location's ID you can access it to get other information.

These examples assume your ID is stored in a hidden value called location_id

Referencing...

syntax in forms

The gps of the location

instance('locations')/locations/location[@id = /data/location_id]/latitude

instance('locations')/locations/location[@id = /data/location_id]/longitude

Any custom location fields you may have (ex. admin name)

instance('locations')/locations/location[@id = /data/location_id]/location_data/admin_name

Making select questions with locations as choices

You can use the location hierarchy to make select questions that allow you to choose a location in a form. The process is similar to setting up multiple choice questions with cases as choices.

  1. Go to Application Settings to turn on the Custom Single and Multiple Answer Add-On in the "Calculations" section.

  2. Add a new "multiple choice lookup table" question

  3. In the "lookup table data" choose the 3 dots next to the list of lookup tables

  4. Set the query to: instance('locations')/locations/location[@type = 'TYPE OF LOCATION']  NOTE:  "type of location" is given for each organization level by the "type code." You can see the type code when you click on "Advanced Mode" on the Organization Levels page. 

  5. Set the instance ID to locations

  6. Set the instance URI to jr://fixture/locations

  7. Hit save

  8. Set the value to "@id" and the label to "name"

Tiered Location Selection

You can also add tiered selection (e.g. select state, then district, then block) by adding multiple select questions after each other as described above.  Assuming the example of districts and block:

  1. Setup the district list as described above  (this example assumes the question_id is district)

  2. Add a second multiple choice question, and configure it to display a list of blocks

    1. In the filter section, add a filter with the following: @district_id = /data/district 

Example location fixture structure

Example locations fixture
Code Block
languagexml
<fixture id="locations" indexed="true" user_id="b43e50ca1c3174fe0bbcf36cfd93a1eb">
  <locations>

    <location id="999dc78d9ca84ea8749dc75b44542332"
              type="country"
              country_id="999dc78d9ca84ea8749dc75b44542332"
              state_id=""
              county_id=""
              city_id="">
      <name>USA</name>
      <site_code>usa</site_code>
      <external_id/>
      <latitude/>
      <longitude/>
      <location_type>country</location_type>
      <supply_point_id/>
      <location_data>
        <name-en>USA</name-en>
        <name-es>USA</name-es>
        <is_test/>
      </location_data>
    </location>

    <location id="999dc78d9ca84ea8749dc75b44541bdc"
              type="state"
              country_id="999dc78d9ca84ea8749dc75b44542332"
              state_id="999dc78d9ca84ea8749dc75b44541bdc"
              county_id=""
              city_id="">
      <name>Massachusetts</name>
      <site_code>massachusetts</site_code>
      <external_id/>
      <latitude/>
      <longitude/>
      <location_type>state</location_type>
      <supply_point_id/>
      <location_data>
        <is_test/>
      </location_data>
    </location>

    <location id="999dc78d9ca84ea8749dc75b44540257"
              type="county"
              country_id="999dc78d9ca84ea8749dc75b44542332"
              state_id="999dc78d9ca84ea8749dc75b44541bdc"
              county_id="999dc78d9ca84ea8749dc75b44540257"
              city_id="">
      <name>Middlesex</name>
      <site_code>middlesex</site_code>
      <external_id/>
      <latitude/>
      <longitude/>
      <location_type>county</location_type>
      <supply_point_id/>
      <location_data>
        <name-en>Middlesex</name-en>
        <name-es>Middlesex</name-es>
        <is_test/>
      </location_data>
    </location>

    <location id="999dc78d9ca84ea8749dc75b4453ff5b"
              type="city"
              country_id="999dc78d9ca84ea8749dc75b44542332"
              state_id="999dc78d9ca84ea8749dc75b44541bdc"
              county_id="999dc78d9ca84ea8749dc75b44540257"
              city_id="999dc78d9ca84ea8749dc75b4453ff5b">
      <name>Cambridge</name>
      <site_code>cambridge</site_code>
      <external_id/>
      <latitude/>
      <longitude/>
      <location_type>city</location_type>
      <supply_point_id/>
      <location_data>
        <is_test/>
      </location_data>
    </location>

  </locations>
</fixture>

Syncing more of location hierarchy to users

By default, CommCare will only send each user the list of their assigned locations and those location's ancestors and descendants.  For example, if I'm assigned to a block,  I will get a list of my state, my district, my block and all that blocks outlets.  

In some situations, you may want to get a list of locations outside of the ancestors and descendants.  In the example above, if a user is assigned to a block, they may want to see all districts in that state anyway. This is controlled using the "Expand From" options outlined on https://dimagi.atlassian.net/wiki/x/GW-Kfw.

Migrating your project from the hierarchical location fixture to the flat location fixture.

Why might you want to do this?  The flat fixture is much simpler to use and understand, and it's faster!

I'm making a new domain and want to use the flat fixture

We got you covered, all new domains use the flat fixture by default.

I have an existing domain that I want to upgrade to the flat fixture

Go to "Project Settings" then on the left, under "Pre-Release Features" click "Location Fixture".  If you don't see this link, you're probably already on the flat fixture.  That page lets you configure which version to send to the phone.  If the flat fixture is enabled here, your forms will automatically try to reference the flat fixture in new builds of your app.

We expect that the migration will go something like this:

  1. Starting off, you may have an existing app which references the old fixture, and this app may have active users.  The idea is to be able to migrate your app without disrupting active users.

  2. Go to the aforementioned "Location Fixture" page and check "Sync the flat location fixture".  Do not uncheck the other box yet.

  3. Begin converting your app to use the flat fixture as described on https://dimagi.atlassian.net/wiki/x/DArKfw.  You can make new app versions to a phone and test them out, and your existing users won't be affected (As usual, don't release any new builds until it's working so your users don't accidentally update).

  4. Once you're confident that it's working, star the new app version and get your users to update.

  5. Once none of your users are using the old app version, you can uncheck "Sync the hierarchical location fixture" to reduce the size of the restore payload that must be synced to the phones.

I have an existing domain with multiple apps that I want to upgrade to the flat fixture incrementally

...

Go to "Project Settings" then on the left, under "Pre-Release Features" click "Location Fixture". 

...

Ensure that the option "Sync the hierarchicial location fixture (legacy format)." is already selected. If it is not selected, then you are already on the flat fixture format.

...

On the application that you want to upgrade, go to the applications settings page by selecting the gear in the app builder.

...

Go to the "Advanced Settings" tab. Under the "Advanced" section select "Both Hierarchical and Flat Fixture" from the "App Aware Location Fixture Format" dropdown. This will allow you to reference both the hierarchical fixture and flat fixture in this app.

  1. To reference both fixtures you need to add the instance references in your form appropriately. In your form that references them both you must add:

    1. <instance src="jr://fixture/locations" id="locations" />

    2. <instance src="jr://commtrack:locations" id="locations_old" />

  2. When writing your xpath references, to refer to the new flat file you use "instance('locations')" to refer to the old format you can use "instance('locations_old')"

  3. Note: you can put anything you want in the id= section above. That is how you'll refer to it in your app.

...

Begin converting your app to use the flat fixture as described on https://dimagi.atlassian.net/wiki/x/DArKfw.  You can make new app versions and publish them to a phone and test them out, and your existing users won't be affected (As usual, don't release any new builds until it's working so your users don't accidentally update).

...

Once you're confident that it's working and all location references have been converted to the flat fixture, select the "Only Flat Fixture" from the "App Aware Location Fixture Format" dropdown. This will disallow any references to the hierarchical fixture in this app.

...

Test your application again with this option selected.

...