Attachments Module Tries to load Complex Obs for All Encounter Observations

I have installed the attachment module 2.0.0-SNAPSHOT, however when I go to view existing encounters, the module tries to download complex obs for all encounters, although the uploads on the encounter are okay as per the image below


First of all, customizing the encounter template had been nightmarish to say the least. This visits/encounters dashboard is a horror show.

This is what configures the custom encounter template to be used:

  "id": "attachments.encounterTemplate",
  "extensionPointId": "org.openmrs.referenceapplication.encounterTemplate",
  "type": "fragment",
  "extensionParams": {
    "templateId": "complexObsEncounterTemplate",
    "templateFragmentProviderName": "attachments",
    "templateFragmentId": "complexObsEncounterTemplate",
    "supportedEncounterTypes": {
      "5021b1a1-e7f6-44b4-ba02-da2f2bcf8718": {
        "icon": "icon-paper-clip",
        "deletable": "false"

As you can see, only on encounter type is supposedly supported… You may have to dig in to understand why this is not applied as expected.

The toast message error popups are unrelated, it would be interesting to know why Attachments cannot figure out how to fallback on the complex obs handler that was used for those obs (because it is supposed to actually.). Would you be in a position to investigate this?

It most likely relates to this thread: ‘Visit Documents Module does not display images saved as complex obs from another module’. I was hoping back then that @ivange94 could dig further and raise a ticket.

Or if you are in a position to provide detailed steps as to how to reproduce the ‘core bug’ so to say, that’d be helpful.

@mksd I will dig in further over the weekend to locate the errors. We customized the encounter template so that may also be cause but at least I have a starting point

I think it’s time to rebuild that encounters/visits dashboard from scratch with a proper design @darius @mogoodrich any pointers on how to break down a design for this page?


I must say that rather spending time troubleshooting what doesn’t work with this dashboard I would also 100% second reworking it, as an OWA for instance :wink:

Seriously, it’s time.

Sorry about that. Was assigned to something else and couldn’t find the time to proceed with this.

@mksd Where can I find the code that actually does this outside the app?

UPDATE: Looks like the check for the Attachment encounter type does not really work, so all encounters are hijacked so that is where the root cause can be found.

On further digging I think I have found the problem, which is based off this code here

What is happening is that I find this for my encounter type (in generated JS)

encounterTemplates.setTemplate('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'ugandaEMREncounterTemplate');
encounterTemplates.setParameter('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'icon', 'icon-file-alt');
encounterTemplates.setTemplate('8d5b27bc-c2cc-11de-8d13-0010c6dffd0f', 'ugandaEMREncounterTemplate');

encounterTemplates.setTemplate('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'complexObsEncounterTemplate');
encounterTemplates.setParameter('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'editable', 'true');
encounterTemplates.setParameter('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'icon', 'icon-file-alt');

encounterTemplates.setTemplate('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'defaultEncounterTemplate');
encounterTemplates.setParameter('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'editable', 'true');
encounterTemplates.setParameter('8d5b2be0-c2cc-11de-8d13-0010c6dffd0f', 'icon', 'icon-file-alt');

What does this mean, that the code for mapping a template to supportedEncounterTypes in the org.openmrs.referenceapplication.encounterTemplate actually does not work. It generates template mappings for all encounter types here

This explains why the complexObsEncounterTemplate seems to take over the mapping for all template types and not be restricted to just the defined encountertype uuid it is meant to work with

Thanks for investigating this @ssmusoke!

When you look at this part of the GSP script, which is in fact one inlined JavaScript instruction in the middle of it:

  .setTemplate('${encounterType.key}', '${extension.extensionParams.templateId}');

The second argument is correctly resolved so that’s fine. But the first argument seems to be stuck on presumably the first encounterType.key ever found when doing the second nested loop on supportedEncounterTypes.

It doesn’t look like antything wrong happens to the model parameter encounterTemplateExtensions before being passed to the view’s GSP script. Look it’s here and it only relies on AppFramework’s getExtensionsForCurrentUser(..).

Did you do some Groovy printout of encounterTemplateExtensions just to be sure that the above double loop is performed with the expected input at hand?

@mksd That is actually where the problem lies. My expectation would be that the complexObsEncounterTemplate for example would only appear once in the output, but it appears for each encounter type, rather than just the one defined in supportedTypes. I just have no idea where to look for that

Maybe @darius can help a little here

  1. The supportedEncounterTypes in the custom encounter template seems not to filter the list of encounter types applied to a template that is defined

  2. Looking in the the only time supportedEncounterTypes variable is used is in getPrimaryEncounterRoleForEncounter()

So some guidance:

  • Where is the definition of the supportedEncounterTypes property?
  • Where can one test whether its actually working or not?
  • How can one test the configuration of a custom param on an extension point?

@darius @mksd ping

@ssmusoke did you try this:

Did you do some Groovy printout of encounterTemplateExtensions just to be sure that the above double loop is performed with the expected input at hand?

My bottom line at this point is that the Groovy script itself looks correct. So the fact that an incorrect piece of JavaScript is generated by it makes me wonder if somehow the model parameter encounterTemplateExtensions has been transformed unexpectedly somewhere?

If yes, then the Java stack needs to be looked at to understand where/how this is happening, and that could be in ParseEncounterToJson as you hinted. However a quick look at the code shows that the model param. is coming right out of AppFramework’s getExtensionsForCurrentUser(..) (but that’s just me looking at the code on GitHub).

P.S. @darius is on leave right now.

As a follow up, looks like the issue is here

This method loads all encounterTemplateExtensions but does not filter out those by supported types which I think should work as follows:

  1. All encounter types which have supported types should have only one entry

  2. Any encounter types without supported types should use the defaultEncounterTemplate as a catch all