Skip to content

TRUNK-6354: Add Provider Roles Service and Dao layer #5073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

mherman22
Copy link
Member

@mherman22 mherman22 commented Jun 12, 2025

Description of what I changed

Issue I worked on

see https://issues.openmrs.org/browse/TRUNK-6354

Checklist: I completed these to help reviewers :)

  • My IDE is configured to follow the code style of this project.

    No? Unsure? -> configure your IDE, format the code and add the changes with git add . && git commit --amend

  • I have added tests to cover my changes. (If you refactored
    existing code that was well tested you do not have to add tests)

    No? -> write tests and add them to this commit git add . && git commit --amend

  • I ran mvn clean package right before creating this pull request and
    added all formatting changes to my commit.

    No? -> execute above command

  • All new and existing tests passed.

    No? -> figure out why and add the fix to your commit. It is your responsibility to make sure your code works.

  • My pull request is based on the latest changes of the master branch.

    No? Unsure? -> execute command git pull --rebase upstream master

@mherman22 mherman22 force-pushed the TRUNK-6354-servicelayer branch from fd576d0 to fcc38f6 Compare June 12, 2025 15:06
@dkayiwa
Copy link
Member

dkayiwa commented Jun 12, 2025

I thought we had agreed adding these methods to the existing ProviderService? I do not see why we should create a new and separate service just for the roles.

@mherman22
Copy link
Member Author

I thought we had agreed adding these methods to the existing ProviderService? I do not see why we should create a new and separate service just for the roles.

Skipped my mind i guess, let me amend that

import org.openmrs.annotation.Authorized;
import org.openmrs.annotation.Handler;
import org.openmrs.util.PrivilegeConstants;

import static org.openmrs.util.PrivilegeConstants.PROVIDER_ROLE_API_PRIVILEGE;
import static org.openmrs.util.PrivilegeConstants.PROVIDER_ROLE_API_READ_ONLY_PRIVILEGE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how we have been importing privileges in other services?

* @since 2.8.0
*/
@Authorized(value = {PROVIDER_ROLE_API_PRIVILEGE, PROVIDER_ROLE_API_READ_ONLY_PRIVILEGE}, requireAll = false)
public List<ProviderRole> getAllProviderRoles(boolean includeRetired);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to deviate from our conventions. Can we use the same privilege pattern as for the rest of the services?

* Thrown when user attempts to delete a provider role that is currently linked to a provider
*/
public class ProviderRoleInUseException extends Exception {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a dedicated class for this when we already have CannotUpdateObjectInUseException?

* Gets all Provider Roles in the database
*
* @param includeRetired whether or not to include retired providers
* @return list of al provider roles in the system
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not need to duplicate this. We can use the @see annotation.

public ProviderRole getProviderRoleByUuid(String uuid) {
Session session = sessionFactory.getCurrentSession();
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<ProviderRole> cq = cb.createQuery(ProviderRole.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use something like HibernateUtil.getUniqueEntityByUUID(sessionFactory, clazz, uuid);

@Transactional
public void purgeProviderRole(ProviderRole role) throws ProviderRoleInUseException {
try {
dao.deleteProviderRole(role);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the same pattern as for the rest of the purge methods?

@@ -158,6 +158,10 @@ private PrivilegeConstants() {

@AddOnStartup(description = "Able to get Provider")
public static final String GET_PROVIDERS = "Get Providers";

public static final String PROVIDER_ROLE_API_PRIVILEGE = "Provider Role API";

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These privileges do not match with our convention.

@Test
public void getProviderRole_shouldGetProviderRole() {
ProviderRole role = service.getProviderRole(1002);
assertEquals(new Integer(1002), role.getId());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why instantiate a new Integer?

* @see ProviderService#getProvider(Integer)
*/
@Test
public void getProvider_shouldGetProviderRoleGivenProviderId() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basing to your method name, we do not fetch provider roles by provider id.

@Test
public void getProviderRoleByUuid_shouldGetProviderRoleByUuid() {
ProviderRole role = service.getProviderRoleByUuid("db7f523f-27ce-4bb2-86d6-6d1d05312bd5");
assertEquals(new Integer(1003), role.getId());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like instantiating the new integer.

}

@Test
public void getProviderRoleByUuid_shouldReturnNUllIfNoProviderForUuid() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Null instead of NUll

}

@Test
public void saveProviderRole_shouldSaveBasicProviderRole() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What value is added by Basic?

ProviderRole role = new ProviderRole();
role.setName("Some provider role");
Context.getService(ProviderService.class).saveProviderRole(role);
assertEquals(13, service.getAllProviderRoles(true).size());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Within this method, how do we tell that the new provider role has been added?

public void deleteProviderRole_shouldDeleteProviderRole() throws Exception {
ProviderRole role = service.getProviderRole(1012);
service.purgeProviderRole(role);
assertEquals(11, service.getAllProviderRoles(true).size());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From this method, how do we confirm that a provider role was deleted?

public void retireProviderRole_shouldRetireProviderRole() {
ProviderRole role = service.getProviderRole(1002);
service.retireProviderRole(role, "test");
assertEquals(10, service.getAllProviderRoles(false).size());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as for the above.

public void unretireProviderRole_shouldUnretireProviderRole() {
ProviderRole role = service.getProviderRole(1002);
service.retireProviderRole(role, "test");
assertEquals(10, service.getAllProviderRoles(false).size());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as for the above.

@Override
@Transactional
public void retireProviderRole(ProviderRole role, String reason) {
// BaseRetireHandler handles retiring the object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we going to be putting these comments in every service method where we retire or unretire objects?

@@ -512,6 +515,11 @@ private PrivilegeConstants() {

@AddOnStartup(description = "Able to edit Provider")
public static final String MANAGE_PROVIDERS = "Manage Providers";

@AddOnStartup(description = "Able to edit Provider Role")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only edit?

*/
@Test
public void purgeProvider_shouldDeleteProviderWithAProviderRole() {
Provider provider = service.getProvider(1009);
Copy link
Member

@dkayiwa dkayiwa Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test about deleting a provider or a provider role?

*/
@Test
public void saveProvider_shouldSaveAProviderWithProviderRole() {
Provider provider = new Provider();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how existing tests confirm that an entity was persisted to the database?

int roleCount = roles.size();
assertEquals(12, roleCount);

roles = service.getAllProviderRoles(true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this duplication about?

@Test
public void getAllProviderRoles_shouldGetAllProviderRolesExcludingRetired() {
List<ProviderRole> roles = service.getAllProviderRoles(false);
int roleCount = roles.size();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case we do not need the roleCount variable.

}

@Test
public void getProviderRoleByUuid_shouldReturnNullIfNoProviderForUuid() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no provider or no provider role?

assertNotNull(saved.getProviderRoleId());
assertEquals("Some provider role", saved.getName());

ProviderRole fetched = service.getProviderRole(saved.getProviderRoleId());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if this was already in the database even before you started saving?
Have you look at how other service methods test for saving?

assertTrue(retiredRole.getRetired());
assertEquals("test reason", retiredRole.getRetireReason());

List<ProviderRole> activeRoles = service.getAllProviderRoles(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary after the above. But you want to keep it, then you need to assert that it originally contained it.

assertFalse(role.getRetired());
assertNull(role.getRetireReason());

List<ProviderRole> activeRoles = service.getAllProviderRoles(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

@Test
public void unretireProviderRole_shouldUnretireProviderRole() {
ProviderRole role = service.getProviderRole(1002);
service.retireProviderRole(role, "testing retire");
Copy link
Member

@dkayiwa dkayiwa Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better done by retrieving an already retired provider role.

@mseaton
Copy link
Member

mseaton commented Jun 13, 2025

One additional thing I would hope / expect to see in this commit are service / DAO methods and/or changes that would allow getting all providers that have a particular role, and / or adding role to the list of search parameters that can be used to retrieve providers (and any other particularly useful service methods that are currently in the providermanagement module related to provider roles).

@mherman22 mherman22 force-pushed the TRUNK-6354-servicelayer branch from 1c297f8 to 08c8416 Compare June 16, 2025 12:31
mherman22 referenced this pull request Jun 17, 2025
* TRUNK-6354: Add the ProviderRole domain object to core

* add liquibase changesets for provider role

* Update Liquibase changesets to use int instead of int(11)

* Add fix as requested in reviews

* remove the module prefix

* use a more meaningful name for the foreign key

* remove defaultvaluenumeric=0 from creator column
@mherman22 mherman22 force-pushed the TRUNK-6354-servicelayer branch from 94e1314 to 8946b97 Compare June 18, 2025 15:14
@mherman22 mherman22 force-pushed the TRUNK-6354-servicelayer branch 2 times, most recently from dd6f3ac to 775c52f Compare July 1, 2025 22:00
@mherman22 mherman22 force-pushed the TRUNK-6354-servicelayer branch from 775c52f to 8d23519 Compare July 2, 2025 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants