Child pages
  • Module to Allow Attribute Value to Be Latest obs of a Specified Concept
Skip to end of metadata
Go to start of metadata


This is a module that will allow you to have an attribute write it's value to an observation


  1. Allow you to specify the attribute you want and connect it with any concept in the dictionary
  2. Allow for any number of attribute/concept pairs
  3. Whenever an attribute is changed, should create an obs for the concept with the datetime of creation and user when the attribute is modified
  4. In the Manage Person Attribute Types page, it should create a new Format called coded-obs-generating. Then in Foreign Key, the concept id (not uuid) should be entered
  5. Extends the restrictions for the concept answers to the attribute. If the concept is coded, it makes the response options for the attribute the concepts the concepts which are the answers.## If the concept is numeric, only numeric values are allowed and the absolute low and high are implemented

User Interface


  1. The tribe module is a good way of showing how an attribute can have a pull down menu of options, for the case that the concept is coded
  2. This is in shortpatient.jsp, use Concept FieldGen web-inf/view/fieldgen.jsp
    <spring:bind path="value">
    <openmrs:fieldGen type="${personAttribute.attributeType.format}" formFieldName="${status.expression}" 
    val="${personAttribute.hydratedObject}" parameters="optionHeader=\[blank\]\|showAnswers=${personAttribute.attributeType.foreignKey}\|isNullable=false" /> 
    <%-\- isNullable=false so booleans don't have 'unknown' radiobox --%></spring:bind>



Next Phases of Development

  1. Be able to enter an obs and have that update the attribute
  • No labels


  1. I wouldn't look at this as "an attribute that displays the most recent obs value"; rather, I would approach this as an obs-generating person attribute.  Meaning, that each time the person attribute is created or updated, the new value is written to the obs table as well.  While this wouldn't handle the case of someone generating the observations independently, I wouldn't try to cover that use case -- if you are willing to always search for the latest observation, then there's no need for the person attribute.  If you only update the value through the person attribute, then an obs-generating attribute will give you a history trail in obs while remaining a simple (and quick) lookup.

    A future version could allow for a timestamp ("time observed") along with the value, allowing obs to be created with an obs_datetime different from the current time (if timestamp was earlier than a current timestamp in the person attribute, then an obs would be created without changing the person attribute value).

  2. From a UI perspective it seems like it would be better to incorporate this into the existing Manage Person Attribute Types page (I don't know how feasible this is given the current setup of that page.)

    Ideally you'd expose "coded-obs-generating" as one of the datatypes on the existing page. And somehow (maybe with the fk property) you'd point to the concept that defines the codes.

  3. So, to do this you need to create a module. In that module, write a class CodedObsGeneratingPersonAttribute implements Attributable<Concept>. You can copy a lot of the implementation of the Attributable methods from org.openmrs.Concept (which also implements it)

    Unfortunately I can't think of where in the lifecycle you should actually create the obs. Because as far as I can tell, there's no way for an attribute to distinguish between the scenario where the patient demographics form is successfully updated, versus where a correct value is submitted for that attribute, but something breaks later in the submission. (Still mulling over that now, but it seems like a core change would be required.)

    1. Ideally, the obs would be created any time the person attribute is successfully added/updated in the database (i.e., persisted).

      1. Yes, I agree, though I'm not totally sure how to do this.

        One possibility is that instead of making any core changes, the module could also add AOP advice after PatientService.savePatient that would create the obs if necessary. (I think this would have the right lifecycle.)

  4. We ended up solving this using the groovy module, so that whenever an attribute was updated, it was entered into an obs.