Mapping ContactPoints to OpenMRS

So one of the things that has come up in our on-going efforts to implement the FHIR module for OpenMRS is how we deal with the ContactPoints FHIR data type. ContactPoints in FHIR represent a means of contacting an individual, for example, a phone, fax, email, pager, etc. In OpenMRS, we think these data are usually stored as Attributes (PersonAttributes, LocationAttributes, ProviderAttributes). That’s all well and good. The problem is in determining the relative priority of the different values (what FHIR calls their “rank”). I.e., if a person has multiple phone numbers, which phone number should we prefer using?

There are two ways to address this that we’ve come up with (thanks to @corneliouzbett and @jecihjoy):

  1. Add a preferred flag to the appropriate *Attribute classes, similar to what is done for PersonName, PersonIdentifier, etc. Alternatively, we could add a “ranking” value similar to the rank in the FHIR data model.

  2. Setup a different *AttributeType to indicate preferred phone number, etc.

The first of these involves making a change to the platform data model, but is otherwise relatively clean. The second of these does not involve changes to the core data model but may involve changes to implementations to, e.g., implement a “Preferred Phone Number” PersonAttributeType.

We thought it would be best to reach out to the OpenMRS community to see if there were any options we hadn’t considered or any preferences one way or the other.

My preferred option is 2

The reason why i do not like adding a preferred field to person attribute types is, unlike PersonName, PersonAddress, or PatientIdentifier, which are a specific type or category of something, person attribute types are too generic that there are many uses of them where the preferred flag does not apply.


I have been thinking of the best way to map ContactPoint to Openmrs. My vision is to have a Person or Location or Provider contact details represented in Fhir as follows:

         "id": "f425e0cc-d793-4d4e-9536-5d9609d681f2",
        "id": "f425e0cc-d793-4d4e-9536-5d9609d681f7",
         "id": "f425e0cc-d793-4d4e-9536-5d9609d681f5",

Using the above as an example been extracted from a person resource, the person has three contact points 2 phone numbers and 1 email address. ContactPoint with rank 1 is the preferred phone number since rank specify preferred order of use (1 being the highest). the system is mapped to fhir value-set (

How to achieve this, isn’t straight forward. First, you need to create a person attribute type for PHONE and EMAIL, then you can insert value to the person attribute with person attribute type phone, with this you can’t have multiple values for phone numbers.

So the only way I could think of for having multiple phone numbers is to append rank at the end when creating attribute type i.e PHONE-1, PHONE-2 - meaning the person attribute value with PersonAttributeType PHONE-2 is the preferred phone number for that person. It might work but it’s not the right way. It’s hackish, can’t imagine how the code will look like.

is there any other better way to do this?

On the second thought PersonAttributeType table has column format and foreign_key. So what if I create a new table contact_points (FHIR2 module specific). Then add as a new person attribute type with format (org.openmrs.ContactPoint).

Why not just have a setting for the preferred phone number person attribute type?

The other option that i can think of is, introduce a new PersonContactPoint object, just like we have PersonName, PersonAddress, and PatientIdentifier

But PersonContactPoint will be specific to the person only, what of Location and Provider does it mean you will have another object ProviderContactPoint e.t.c

Yes it would be specific to the person. Just like we have PersonAttribute, LocationAttribute, and ProviderAttribute, where each is specific to person, location, and provider.

We could easily make those all descend from an abstract ContactPoint class, but if we’re going to have a semantic linkage to the right “owner” than we do need one type that belongs to Person, one type that belongs to location, etc.