GSoC'20: Add support for FHIR Narratives

great we got to see the pr @iamsr

1 Like

I see that this build is failing due to difference in timezone of the expected narrative and the one which is being generated.

It’s happening in the dispenseRequest.validityPeriod element of MedicationRequest which is of type Period. The thing is that its narrative is provided by HAPI itself. The diff is as follows:

>>>
Thu Jan 15 00:00:00 IST 2015 - Fri Jan 15 00:00:00 IST
----
Thu Jan 15 00:00:00 UTC 2015 - Fri Jan 15 00:00:00 UTC
<<<

Any suggestions for fixing it? One approach might be to define a new narrative for Period, but then we won’t be using the HAPI version of it.

cc: @ibacher @herbert24 @suthagar23

1 Like

Just change the timezone values in the expected result from IST to UTC. This will probably work consistently.

1 Like

I guess it is taking the local timezone, because making manual changes in timezone (IST to UTC) in the expected narrative makes the tests fail for me locally.

@ibacher Thanks a lot for this suggestion! It works now.

For the Location resource, all the examples here just mention a brief location summary (kind of a general address) in the narratives, even if the resource object carries more detailed information with it. This example displayed the maximum info in its narrative, among the other examples, which is still a subset of all the info carried by the object.

So how should we create our narrative for the Location resource? Should we mention each element in the narrative? Or should we rather keep it minimal, the way it is in the examples?

cc: @ibacher @herbert24 @suthagar23

This PR is now ready for review. PTAL!

cc @ibacher @herbert24 @suthagar23

Hi there. Please find the draft PR for narratives of resources Encounter, Observation and Location here. It also contains the commit associated with PR#198, which should be merged before this PR. Changes specific to this PR are in this commit.

For now, I’ve kept the narrative of Location Resource minimal (referring to this post).

cc: @ibacher @herbert24 @suthagar23

I guess I’ll be adding the default narrative for PractionerRole resource too, considering the scope for its support in the future.

Please find the draft PR for narratives of resources Person, Practitioner and ServiceRequest here. It also contains the commits related to PR#198 and PR#207. Please refer to this commit for the changes specifically intended for this PR.

cc: @ibacher @herbert24 @suthagar23

Please find the link to PR for narratives of resources Task, RelatedPerson and PractitionerRole below.

cc @ibacher @herbert24 @suthagar23

1 Like

PR for FM2-249:

cc @ibacher @herbert24 @suthagar23

1 Like

looked through this and also requested other people to look through added a comment on the pr thanks

1 Like

Now that all the tasks for Coding Phase-1 have been wrapped up with this PR, these are the initial objectives for Coding Phase-2.

Overall Objective: Developing a framework to support user defined custom narratives.

Initial Approach:

  • The framework would be implemented as a class in FHIR module’s OMOD.
  • There would be a separate custom narratives properties file for the custom narratives template assignment.
  • The framework would handle setting up of the custom narrative template for the resource in the custom narratives properties file, using helper methods.
  • There would be a check for custom narratives in the initialize() method of FhirRestServlet and the properties file will be provided to the narrative generator accordingly.
  • Apart from this, there will be tests to check for errors in the user defined templates.

Looking forward to feedback/suggestions.

cc: @ibacher @herbert24 @suthagar23

Hi! I’ve come up with something like this for updating the customNarratives.properties file. It gives a rough idea of the approach I’m following:

public void addToPropertiesFile(String resourceName, String templateLocation) throws IOException {
	Properties customProperties = new Properties();
	try {
		customProperties.load(new FileInputStream(getCustomNarrativesPropFile()));
	}
	finally {
		Map<String, String> propertiesMap = getProperties(resourceName, templateLocation);
		propertiesMap.forEach(customProperties::put);
		customProperties.store(new FileOutputStream(getCustomNarrativesPropFile()), null);
	}
}

protected File getCustomNarrativesPropFile() {
	return new File(OpenmrsUtil.getDirectoryInApplicationDataDirectory(FhirConstants.CUSTOM_NARRATIVES_FOLDER_NAME),
	        FhirConstants.CUSTOM_NARRATIVES_PROPERTY_FILE_NAME);
}
	
protected Map<String, String> getProperties(String resourceClass, String templateResourceClasspath {
	Map<String, String> propertiesMap = new HashMap<String, String>();
	propertiesMap.put(String.join(".", resourceClass.toLowerCase(), "resourceType"), resourceClass);
	propertiesMap.put(String.join(".", resourceClass.toLowerCase(), "narrative"), templateResourceClasspath);
	return propertiesMap;
}
  • If a properties file is not present, it creates one in the subdirectory customNarratives of OpenMRS Application Data Directory.
  • The addToPropertiesFile() method takes in the resource class and template location and assigns the template for the resource narrative.
  • In case there already is an entry for that resource, it will automatically update it with the new resource narrative template.
  • Also, I’m thinking of adding a method to remove the listing of a custom narrative for some resource.

Does it look fine? @ibacher @herbert24 @suthagar23

Also, since this is something that the implementer would do on choice and not every time when the FHIR module is used, should it be in a separate module?

Does any other mentor have a different approach than this cc @ibacher @suthagar23

1 Like

Updated Objectives for Coding Phase-2:

  1. Add support for custom narratives.
  2. Support relative paths prefixed with openmrs: for location of narratives and properties file. For example, the relative path openmrs:configuration/Patient.html would point to the location <OPENMRS_APPLICATION_DATA_DIRECTORY>/configuration/Patient.html .

Approach to be followed:

Support for custom narratives could be provided by giving the implementer an option to specify a properties file containing the location of narrative templates which he/she wants to override. The FHIR Module would give a higher priority to these overrides to serve the intended purpose. In order to support relative paths prefixed with openmrs: , we would need to implement our own narrative generator with the required changes in order to support openmrs: prefixed relative paths.

Please find the link for draft PR for FM2-252 below. It contains a basic working version of the modified narrative generator. If this looks fine, I’ll be working on simplification of the implementation.

cc @ibacher @herbert24 @suthagar23

Hi there!

Since we are autowiring messageSource in our message resolver, on running tests, messageSource remains null. For that, we might use @Mock annotation for the messageSource but then the messages won’t be populated in the narrative templates. So what could be done for that? Any suggestions?


Also, if I try to do something like this:

OpenMRSMessageResolver resolver = new OpenMRSMessageResolver(null);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(resolver.getClass());
OpenMRSMessageResolver app = context.getBean(resolver.getClass());
log.info(app.getMessageSource().getMessage("fhir2.title", new Object[] {}, Locale.getDefault()));

I get the following error, even if the property exists in the messages.properties file:

org.springframework.context.NoSuchMessageException: No message found under code 'fhir2.title' for locale 'en_GB'.

So where did I go wrong here?


cc @ibacher @herbert24 @suthagar23

Are you picking from message_en_GB.properties ?