Allow Users Without Delete Privilege on Activity to End Recurring Appointment Series or Convert Single Appointment to Recurring One

This post will explain how you can implement a plug-in that will allow the normal users without prvDeleteActivity (Delete privilege for the Activity table) to

  • end a recurring appointment series, update recurrence information, or
  • convert an existing appointment to a recurring appointment.

In most of the Dynamics 365/Power Apps + Dataverse implementations, it is a common practice not to give the Delete privilege to the normal user security role to prevent users from accidentally deleting data. Leaving the Delete privilege empty for all tables works fine for most of the actions, but some out-of-the-box actions require the Delete privilege to be successfully performed.

Problem Statement

If the user wants to end a recurring appointment series before the original end date specified during the creation of the series, the user can click on the "End Series" button on the recurring appointment form.  That action will call the DeleteOpenInstancesRequest which deletes all the “open” and “scheduled” future instances of the specified series from the date specified in the series end date. If the user does not have the prvDeleteActivity, the user will get the following Insufficient Permissions error.

You do not have {0} permission to access {1} records. Contact your Microsoft Dynamics 365 administrator for help.
If you decipher the error message by opening the Network tab in the browser Developer Tools, you will see that the error is due to the current user missing prvDeleteActivity privilege.

The same error happens when the user tries to convert an existing appointment to a recurring appointment by clicking on the "Recurrence" button on the appointment form. That action will call the AddRecurrenceRequest which creates a recurring appointment series and deletes the existing single   Appointment. That is why the user will require the prvDeleteActivity to delete the existing single Appointment.

Solution

In order to let the user perform those actions without giving prvDeleteActivity in the user's security role, you can implement a plug-in to delete the Appointments with an elevated user account or temporarily assign a security role with prvDeleteActivity while performing the action.


Solution for Ending a Recurring Appointment Series

The solution for this scenario is simple. The plug-in just needs to retrieve the appointments with the same SeriesId which are starting on or after the SeriesEndDate parameter and delete those appointments with SYSTEM user before the system does. If there is no future appointment after SeriesEndDate, the system will not try to delete in the current user's context and it will not show any error due to the lack of prvDeleteActivity privilege.


The plug-in will only run for RecurringAppointmentMaster table and the DeleteOpenInstances message. Since the future appointments need to be deleted before the actual operation, the plug-in will be registered in the Pre-operation (stage 20). Two main important parameters are the GUID of the target recurring appointment and the series end date parameter entered by the user.


DeleteFutureAppointments method will query the appointments with SeriesId same as the recurring appointment GUID and the ScheduledStart on or after the SeriesEndDate parameter. Then, it will loop through each appointment and delete as the SYSTEM user.

Solution for Updating Recurrence Information of the Recurring Appointment

The plug-in for this scenario is also similar to the previous one. The plug-in needs to be registered for the Update message instead and delete all the future instances of the original series before the actual operation.

Solution for Ending a Recurring Appointment Series

The solution for this scenario is a bit more complex than the previous ones. When the user tries to convert an existing appointment to a recurring appointment, AddRecurrenceRequest will delete the original appointment by GUID, so that even if the plug-in delete the appointment in the Pre-operation with SYSTEM user, the system will throw the following error because the appointment has already deleted when the main operation tried to delete the appointment by GUID.
The requested record was not found or you do not have sufficient permissions to view it.

The workaround solution is to share the Delete permission for the Appointment with the user. However, sharing the permission does not work if the user has no privilege at any level for the particular action. It will only work if the user has minimum User level Delete privilege for the Activity table. So the second step is to temporarily assign the security role with User level Delete privilege before the main operation and remove it afterwards.


The plug-in will run for RecurringAppointmentMaster table as well and for the AddRecurrence message. The user will be assigned an elevated security role in the Pre-validation (stage 10) because making changes to the security roles of the user after validation in Pre-operation (stage 20) will not make any changes and the system will throw the same Insufficient Permissions error. In Post-operation (stage 40), the security role assigned in the previous step will be removed.


In the ElevateDeleteAppointmentPermission method, the delete permission for that particular row is granted to the user first.


Then, check if the user has the delete privilege to the activity at all and if the user does not any enough privilege, temporarily assign the role with DeleteActivityRoleName (security role which has User level Delete privilege for Activity table) in the same Business Unit as the user.


After the main operation, the plug-in step in Post-operation (stage 40) will check if the user has a role with DeleteActivityRoleName (which may be assigned to the user in Pre-validation step) and remove the role from the user if there any.


Summary

Some of the actions related to the recurring appointment will require the Delete privilege for the Activity table but if there is a business requirement not to grant the Delete privilege to the normal users, it can still be achieved by implementing the plug-in as above.

In my opinion, such OOB request action as deleting the future appointments in ending a recurring appointment series or deleting the original appointment in conversion to recurring appointment should automatically be handled by the elevated SYSTEM account instead of deleting with the initiating user's context. If you agree with me, please vote on my ideas in Dynamics 365 Application Ideas or Power Apps Ideas (or both).

You can download the above sample code snippet from my GitHub repository via this link.

Comments

Popular Posts