# UgandaEMR: Use cases for the Data Filter module

**URL:** <https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191>\
**Category:** Implementing\
**Tags:** ugandaemr\
**Created:** [April 27, 2020, 2:52pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191 "2020-04-27T14:52:51Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![ibacher](https://talk.openmrs.org/user_avatar/talk.openmrs.org/ibacher/32/19751_2.png) [@ibacher](https://talk.openmrs.org/u/ibacher)\
**Post date:** [July 8, 2024, 1:57pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/21 "2024-07-08T13:57:53Z")

</div>

When you say “didn’t quite work”, could you spell that out a bit more? I’ve used it successfully in the past…

---

<div class="post-metadata">

**Author:** ![jnsereko](https://talk.openmrs.org/user_avatar/talk.openmrs.org/jnsereko/32/14978_2.png) [@jnsereko](https://talk.openmrs.org/u/jnsereko)\
**Post date:** [July 8, 2024, 2:17pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/22 "2024-07-08T14:17:41Z")

</div>

> [@aojwang](#):
>
> @jnsereko which approach have you tried so far?

@aojwang From [my draft](https://github.com/MSF-OCG/LIME-EMR/pull/21) i am basing this logic around the initializer

Basically;

- I have a role called **`Mosul: Sensitive Appointments`** that has a privilege, **`Manage Sensitive Appointments`**
- I have an Appointment Service definition **`Mental Health`** that i map to an appointment Service type **`Mental Health Service Type`**

Inside my `datafiltermappings/mappings.csv` file i grant access to the `Privilege` on the basis of the `Appointment Service Type`

> [@ibacher](#):
>
> Disabling filters is covered in the [module documentation](https://openmrs.atlassian.net/wiki/spaces/docs/pages/25476994/Data+Filter).

i had not seen Bypassing a single filter. Seen it now. Thanks

---

<div class="post-metadata">

**Author:** ![aojwang](https://talk.openmrs.org/letter_avatar/aojwang/32/5_5575768a8748004e209b776fc1b2916d.png) [@aojwang](https://talk.openmrs.org/u/aojwang)\
**Post date:** [July 8, 2024, 2:27pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/23 "2024-07-08T14:27:17Z")

</div>

I added the below global properties but we couldn’t pass even the login page on o3. Unless I needed to do anything extra to have the filters disabled. I can give it another try and share feedback.

```auto
	<globalProperty>
		<property>datafilter_locationBasedUserFilter.disabled</property>
		<defaultValue>true</defaultValue>
		<description>
			Location based user filter. To enable, set value to false
		</description>
	</globalProperty>

	<globalProperty>
		<property>datafilter_locationBasedPatientFilter.disabled</property>
		<defaultValue>true</defaultValue>
		<description>
			Location based patient filter. To enable, set value to false
		</description>
	</globalProperty>

```

---

<div class="post-metadata">

**Author:** ![ibacher](https://talk.openmrs.org/user_avatar/talk.openmrs.org/ibacher/32/19751_2.png) [@ibacher](https://talk.openmrs.org/u/ibacher)\
**Post date:** [July 8, 2024, 2:36pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/24 "2024-07-08T14:36:48Z")

</div>

Oh! There are way more than just those two filters in DataFilter by default and you likely need to disable all of them… (Basically, everything listed in any JSON file [here](https://github.com/openmrs/openmrs-module-datafilter/tree/master/api/src/main/resources/filters/hibernate); at a glance you were still hitting the [datafilter\_locationFilter](https://github.com/openmrs/openmrs-module-datafilter/blob/4108bb9784b8f34d75b2c79498c3c4cfb30a1dd0/api/src/main/resources/filters/hibernate/location.json#L104C18-L104C43), which filters locations to those a user is assigned; if user’s haven’t been assigned a location, then no locations would appear).

---

<div class="post-metadata">

**Author:** ![aojwang](https://talk.openmrs.org/letter_avatar/aojwang/32/5_5575768a8748004e209b776fc1b2916d.png) [@aojwang](https://talk.openmrs.org/u/aojwang)\
**Post date:** [July 8, 2024, 2:40pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/25 "2024-07-08T14:40:04Z")

</div>

I see. Thanks, @ibacher. I will try it out again and share feedback.

---

<div class="post-metadata">

**Author:** ![jnsereko](https://talk.openmrs.org/user_avatar/talk.openmrs.org/jnsereko/32/14978_2.png) [@jnsereko](https://talk.openmrs.org/u/jnsereko)\
**Post date:** [July 10, 2024, 6:08am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/26 "2024-07-10T06:08:52Z")

</div>

> [@jnsereko](#):
>
> @aojwang From [my draft](https://github.com/MSF-OCG/LIME-EMR/pull/21) i am basing this logic around the initializer
> 
> Basically;
> 
> - I have a role called **`Mosul: Sensitive Appointments`** that has a privilege, **`Manage Sensitive Appointments`**
> - I have an Appointment Service definition **`Mental Health`** that i map to an appointment Service type **`Mental Health Service Type`**

@aojwang @ibacher @dkayiwa How can i load a filter from a .json file using a custom module

---

<div class="post-metadata">

**Author:** ![jnsereko](https://talk.openmrs.org/user_avatar/talk.openmrs.org/jnsereko/32/14978_2.png) [@jnsereko](https://talk.openmrs.org/u/jnsereko)\
**Post date:** [July 10, 2024, 6:49am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/27 "2024-07-10T06:49:30Z")

</div>

i have a filter on appointments that i believe should check for the corresponding privilege. I want to load this via a custom module, but however, also testing this with the datafilter module throws an error `parameter roles is not specified`

```auto
[
    {
        "name" : "datafilter_encTypePrivBasedAppointmentUserFilter",
        "targetClasses" : [
            "org.openmrs.module.appointments.model.Appointment"
        ],
        "condition" : "patient_appointment_id IN (SELECT DISTINCT pa.patient_appointment_id FROM patient_appointment pa INNER JOIN appointment_service apts ON pa.appointment_service_id = apts.appointment_service_id WHERE apts.name = 'Mental Health' AND 'Manage Sensitive Appointments' IN (SELECT rp.privilege FROM role_privilege rp WHERE rp.role IN (:roles)))",
        "parameters" : [
            {
                "name" : "roles",
                "type" : "string"
            }
        ]
    }
]

```

cc @michaelbontyes @pirupius

---

<div class="post-metadata">

**Author:** ![mksd](https://talk.openmrs.org/user_avatar/talk.openmrs.org/mksd/32/11729_2.png) [@mksd](https://talk.openmrs.org/u/mksd)\
**Post date:** [July 10, 2024, 7:26am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/28 "2024-07-10T07:26:50Z")

</div>

@wyclif will tell but I wonder if your custom module doesn’t need to provide its override of `DataFilterListener` in order for [`supports(String)`](https://github.com/openmrs/openmrs-module-datafilter/blob/4108bb9784b8f34d75b2c79498c3c4cfb30a1dd0/api/src/main/java/org/openmrs/module/datafilter/impl/ImplDataFilterListener.java#L32-L35) to return `true` for your implementation-specific filters?

The default implementation will only be truthy for the filters that are baked in ([here](https://github.com/openmrs/openmrs-module-datafilter/blob/4108bb9784b8f34d75b2c79498c3c4cfb30a1dd0/api/src/main/java/org/openmrs/module/datafilter/impl/ImplConstants.java#L89-L91)).

If I’m right then typically this area of the code should be enhanced to allow Data Filter to be configurable. Would be great if your group could help do that through a next major!

At the very least it would be great if your group could document in the wiki the process, under the current architecture of the module, to bring in own filters through a custom module → [https://openmrs.atlassian.net/wiki/spaces/docs/pages/25476994/Data+Filter](https://openmrs.atlassian.net/wiki/spaces/docs/pages/25476994/Data+Filter)

---

<div class="post-metadata">

**Author:** ![jnsereko](https://talk.openmrs.org/user_avatar/talk.openmrs.org/jnsereko/32/14978_2.png) [@jnsereko](https://talk.openmrs.org/u/jnsereko)\
**Post date:** [July 10, 2024, 9:46am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/29 "2024-07-10T09:46:17Z")

</div>

> [@mksd](#):
>
> The default implementation will only be truthy for the filters that are baked in ([here](https://github.com/openmrs/openmrs-module-datafilter/blob/4108bb9784b8f34d75b2c79498c3c4cfb30a1dd0/api/src/main/java/org/openmrs/module/datafilter/impl/ImplConstants.java#L89-L91)).

Thank you @mksd

> [@jnsereko](#):
>
> How can i load a filter from a .json file using a custom module

I have decided to extend `org.openmrs.module.patientgrid.filter.DataFilterBeanFactoryPostProcessor` like bellow:

```auto
@Component
public class CustomDataFilterBeanFactoryPostProcessor extends DataFilterBeanFactoryPostProcessor {
    @Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        super.postProcessBeanFactory(beanFactory);
    }
}

```

but it seams hibernate files are not loading correctly from my resource files so i get `java.lang.IllegalArgumentException: InputStream cannot be null` error caused from [this point](https://github.com/openmrs/openmrs-module-datafilter/blob/master/api/src/main/java/org/openmrs/module/datafilter/Util.java#L543)

See full log [here](https://pastebin.com/t9HPMmJn)

However, i have the [add-entity-filter-xslt-template.xml](https://github.com/openmrs/openmrs-module-datafilter/blob/master/api/src/main/resources/add-entity-filter-xslt-template.xml) and [update-mapping-loc-xslt-template.xm](https://github.com/openmrs/openmrs-module-datafilter/blob/master/api/src/main/resources/update-mapping-loc-xslt-template.xml)

```auto
├── src
   ├──── resources
           ├──── filter
                  ├────hibername
                  └── appointment_privilege.json
           └── add-entity-filter-xslt-template.xml
           └── update-mapping-loc-xslt-template.xm

```

Could you know what I am missing?

---

<div class="post-metadata">

**Author:** ![wyclif](https://talk.openmrs.org/user_avatar/talk.openmrs.org/wyclif/32/19607_2.png) [@wyclif](https://talk.openmrs.org/u/wyclif)\
**Post date:** [July 10, 2024, 10:43am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/30 "2024-07-10T10:43:31Z")

</div>

I don’t think you should go down the invasive route of creating a `DataFilterBeanFactoryPostProcessor`.

Instead, like @mksd mentioned, you have to register a spring bean that implements [`DataFilterListener`](https://github.com/openmrs/openmrs-module-datafilter/blob/master/api/src/main/java/org/openmrs/module/datafilter/DataFilterListener.java), it has the `onEnableFilter` callback method where you’re expected to set values for any parameters defined in your filter’s definition file, so you’re supposed to set the `roles` parameter in your listener.

Datafilter comes with a single implementation for its core filters that you can find [here](https://github.com/openmrs/openmrs-module-datafilter/blob/master/api/src/main/java/org/openmrs/module/datafilter/impl/ImplDataFilterListener.java) where you can borrow some reusable logic, @mksd in the future we might want to add a base class for this listener that comes with some of this reusable logic that concrete classes can extend.

---

<div class="post-metadata">

**Author:** ![wyclif](https://talk.openmrs.org/user_avatar/talk.openmrs.org/wyclif/32/19607_2.png) [@wyclif](https://talk.openmrs.org/u/wyclif)\
**Post date:** [July 10, 2024, 11:12am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/31 "2024-07-10T11:12:21Z")

</div>

You don’t need to add xslt files, filter definition files are loaded from the classpath, just make sure that in your custom module, you place your filter definition files in `src/main/resources/filters/hibernate`, if your persistent classes are indexed using hibernate search then you also need to add filters for them in `src/main/resources/filters/fulltext` along with another DataFilterListener implementation and impl class for full text queries to set any parameters, you can find examples in the datafilter module.

We definitely need to document this process.

---

<div class="post-metadata">

**Author:** ![mksd](https://talk.openmrs.org/user_avatar/talk.openmrs.org/mksd/32/11729_2.png) [@mksd](https://talk.openmrs.org/u/mksd)\
**Post date:** [July 10, 2024, 11:20am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/32 "2024-07-10T11:20:17Z")

</div>

> [@wyclif](#):
>
> We definitely need to document this process.

➕ 1

@jnsereko can you guys take care of doing so in the wiki when all the steps have been identified?

---

<div class="post-metadata">

**Author:** ![jnsereko](https://talk.openmrs.org/user_avatar/talk.openmrs.org/jnsereko/32/14978_2.png) [@jnsereko](https://talk.openmrs.org/u/jnsereko)\
**Post date:** [July 10, 2024, 12:22pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/33 "2024-07-10T12:22:31Z")

</div>

> [@mksd](#):
>
> @jnsereko can you guys take care of doing so in the wiki when all the steps have been identified?

Am willing to help after running it successfully in my custom module.

> [@wyclif](#):
>
> just make sure that in your custom module, you place your filter definition files in `src/main/resources/filters/hibernate`,

I thought adding the following to my custom module and having `/src/resources/filters/hibernate/appointment_privilege.json` had to do it @wyclifIt still seams that the filter is not loaded

```auto
@Component
public class MosulAppointmentsDataFilterListener implements DataFilterListener {

    @Override
    public boolean onEnableFilter(DataFilterContext filterContext) {
        if (filterContext.getFilterName().startsWith("datafilter_encTypePrivBasedAppointment")) {
			Collection<String> roles = new HashSet<>();
			if (Context.isAuthenticated()) {
				Collection<String> allRoles = Context.getAuthenticatedUser().getAllRoles().stream().map(Role::getName)
				        .collect(Collectors.toSet());
				roles.addAll(allRoles);
			}
			
			filterContext.setParameter(ImplConstants.PARAM_NAME_ROLES, roles);
			
		}
        return false;
    }

    @Override
    public boolean supports(String filterName) {
		return true;
    }
}

```

Note that i was able to successfully load it in the datafilter module after adding my filter name to the baked in ([here](https://github.com/openmrs/openmrs-module-datafilter/blob/4108bb9784b8f34d75b2c79498c3c4cfb30a1dd0/api/src/main/java/org/openmrs/module/datafilter/impl/ImplConstants.java#L89-L91)) following @mksd’s suggestion.

---

<div class="post-metadata">

**Author:** ![ibacher](https://talk.openmrs.org/user_avatar/talk.openmrs.org/ibacher/32/19751_2.png) [@ibacher](https://talk.openmrs.org/u/ibacher)\
**Post date:** [July 10, 2024, 12:37pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/34 "2024-07-10T12:37:09Z")

</div>

Can you link to the code you tried this in? You shouldn’t need to modify _anything_ in the data filter module itself. (I would also not recommend writing `supports()` such that it just returns `true`; by doing that you are opting-in to handling all filter. Instead, your `supports()` function should:

```java
return filterName.startsWith("datafilter_encTypePrivBasedAppointment")

```

As long as your `DataFilterListener` is a Spring bean, your filters are in `src/main/resources/filters/hibernate` or `src/main/resources/filters/fulltext` and your module is configured to depend on the data filter module, everything else should be automatically picked up.

Also, if you’re going to use an OpenMRS security primitive to control access to something, please use privileges instead of roles. This will make maintenance easier (if you hard-code roles, then if a new role needs access to sensitive appointments, you need to modify your module, rebuild and ship it; if you use privileges, you can just assign the privilege to a role, no code changes required).

---

<div class="post-metadata">

**Author:** ![wyclif](https://talk.openmrs.org/user_avatar/talk.openmrs.org/wyclif/32/19607_2.png) [@wyclif](https://talk.openmrs.org/u/wyclif)\
**Post date:** [July 10, 2024, 4:11pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/35 "2024-07-10T16:11:42Z")

</div>

> [@jnsereko](#):
>
> I thought adding the following to my custom module and having `/src/resources/filters/hibernate/appointment_privilege.json` had to do it @wyclif It still seams that the filter is not loaded

The location I mentioned is `src/main/resources/filters/hibernate` ( **PLEASE READ CAREFULLY** 😀), do you see the difference?

---

<div class="post-metadata">

**Author:** ![wyclif](https://talk.openmrs.org/user_avatar/talk.openmrs.org/wyclif/32/19607_2.png) [@wyclif](https://talk.openmrs.org/u/wyclif)\
**Post date:** [July 10, 2024, 4:37pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/36 "2024-07-10T16:37:46Z")

</div>

+1 to @ibacher’s comment about how to implement `supports()`.

@ibacher for the core listener and filters we intentionally used roles and not privileges and I think @jnsereko tried to follow the same approach, we wanted avoid a very long `IN` clause for the privileges in the query since the privilege graph in OpenMRS can get wild as compared to the roles graph, maybe it’s not a big deal.

@jnsereko I would recommend that you borrow some checks in the core `DataFilterListener`, you probably don’t want to apply filters for Daemon and Super user.

---

<div class="post-metadata">

**Author:** ![jnsereko](https://talk.openmrs.org/user_avatar/talk.openmrs.org/jnsereko/32/14978_2.png) [@jnsereko](https://talk.openmrs.org/u/jnsereko)\
**Post date:** [July 11, 2024, 11:38am UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/37 "2024-07-11T11:38:17Z")

</div>

@aojwang @ibacher, could you know why a filter like `datafilter_encTypePrivBasedAppointmentUserFilter` shown above or the one shown below prevents a non-admin user from searching a patient but can access the details in chart? Refer to attachments below

 ![Screenshot 2024-07-11 at 14.27.30](https://talk.openmrs.org/uploads/default/original/3X/c/0/c0712701a79054b77706067990635e0e9321caec.png) ![Screenshot 2024-07-11 at 14.27.55](https://talk.openmrs.org/uploads/default/original/3X/3/a/3ae48c5d4d0b0d0c7ec3fe0fbe792cfa1bc4fbff.png)

Filter

```json
[
    {
        "name" : "datafilter_appointmentPrivBasedAppointmentServiceUserFilter",
        "targetClasses" : [
            "org.openmrs.module.appointments.model.Appointment"
        ],
        "condition" : "patient_appointment_id IN (
            SELECT pa.patient_appointment_id FROM patient_appointment pa 
            INNER JOIN appointment_service apts ON pa.appointment_service_id = apts.appointment_service_id 
            WHERE 'Manage Sensitive Appointments' IN (:privileges) OR apts.name NOT LIKE '%Mental Health%')",
        "parameters" : [
            {
                "name" : "privileges",
                "type" : "string"
            }
        ]
    }
]

```

@ibacher, i am sharing the code in a few

---

<div class="post-metadata">

**Author:** ![wyclif](https://talk.openmrs.org/user_avatar/talk.openmrs.org/wyclif/32/19607_2.png) [@wyclif](https://talk.openmrs.org/u/wyclif)\
**Post date:** [July 11, 2024, 1:18pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/38 "2024-07-11T13:18:46Z")

</div>

@jnsereko I see the filter is named `datafilter_appointmentPrivBasedAppointmentServiceUserFilter` I would expect filters provided by other modules not to have a `datafilter` prefix, it should be your module Id instead. This name seems not intuitive to me too, it suggests that it filters users when actually it filters appointments.

---

<div class="post-metadata">

**Author:** ![jnsereko](https://talk.openmrs.org/user_avatar/talk.openmrs.org/jnsereko/32/14978_2.png) [@jnsereko](https://talk.openmrs.org/u/jnsereko)\
**Post date:** [July 12, 2024, 12:51pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/39 "2024-07-12T12:51:09Z")

</div>

@wyclif I renamed it to `patientidentifiergenerator_appointmentServicePrivBasedAppointmentFilter` but still i am not able to search for patients on non-admin users.  
Could you know any other possible cause?

---

<div class="post-metadata">

**Author:** ![wyclif](https://talk.openmrs.org/user_avatar/talk.openmrs.org/wyclif/32/19607_2.png) [@wyclif](https://talk.openmrs.org/u/wyclif)\
**Post date:** [July 12, 2024, 1:31pm UTC](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191/40 "2024-07-12T13:31:24Z")

</div>

Renaming the filter was just a by the way, it was not meant to fix why you can’t search for patients.

As to why you’re unable to search for patients for non admin users, I guess it may be caused by other filters, please make sure all are disabled.

[Previous page](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191.md?page=1)

[Next page](https://talk.openmrs.org/t/ugandaemr-use-cases-for-the-data-filter-module/28191.md?page=3)
