365 Overloads and Business Rules – code and config collide
This article is not about 365 items. It is about 2 styles of tech work, where code (overloading) and config (business rules) collide. This collision manifested via 2 surprises I had using business rules in D365 online v22.214.171.1248. To be completely accurate, there was only one surprise, the second one is just a confirmation of the fact that business rules cannot resolve correctly multi-entity lookups.
The concept of “overload”, both as an adjective and as a verb, has been in use in programming as one of the pillars of object-oriented coding patterns. At its core, it meant using the same name for multiple functions, and the only difference would be in each function implementation and number of parameters passed to it. There are some variations of this concept, however all have in common the idea that under a name there is some behavior that is different in some way.
In Dynamics 365, since the CRM days, we inherited a special overloading process for relationships, where under one relationship name we have more than one entity that could be referenced in the relationship. This is an example of “static” overloading, in the sense that the name, the relationships and their related entities are fixed in the application and can only be changed if we had access to the source code of the application. We have “Customer” that can be either an account record or a contact record
Business Rules have been introduced as an end-user tool, to implement data validation or simple page logic rules, without having to resort to writing code (developers, do not hope, you are not out of a job yet!). The benefit is immediate if the business rules are simple and more importantly, do not interfere with complex code logic that may have been implemented in the page. Moreover, the responsibility of the business process stays with the business users that made the decision for the rule logic and the logic can be easily reverse or changed if needed. Through these mechanisms, the business users become citizen-developers, which means that they could implement special logic without coding knowledge. However, since the Microsoft developers are human after all (or at least for the time being), it is naturally that they may have overlooked, forgotten or ignored the correct reference of an overloaded relationship. Citizen-developers work around the developer-developers’ misses and the journey continues.
Here is My Journey
During a training session, I set out to demonstrate how easy it is to change the owner of a record depending on the value selected in a drop-down. Everything worked as expected when selecting the new owner to be a user, and the rule could not be published as soon as I changed the owner to a team record.
Step 1: (beginner) - How to create a Business Rule that assigns an account record to a different owner depending on the choice of the Relationship Type field
- In your favorite solution, add the account entity if it is not already there.
- Expand the account, click on Business Rules and click on New to add a new rule.
- Add a condition “If Relationship Type = “Press” and a step “Set field value” as Owner = “User X”.
- Validate the rule to make sure that everything is in place, then Activate it.
- Open an account record, change the Relationship Type to “Press”, save and refresh the page.
Step 2 (still beginner) - How to create a Business Rule that assigns an account record to a different owning team depending on the choice of the Relationship Type field
- Deactivate the business rule created above.
- Click on the green step and change the owner field to point to a team record instead of a user.
- Save, Validate and Activate.
- During activate the following error is thrown:
System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=126.96.36.199, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> Microsoft.Crm.CrmException: The selected workflow has errors and cannot be published. Please open the workflow, remove the errors and try again.
.... I will spare you the remaining details...
Step 3 (very advanced) – Reproduce the error above by using the customer field within a case business rule
- Identify an option set on the case, e.g. case origin, that will be used for the business rule condition.
- Create a business rule in the case entity, to set the customer to either a contact or an account record, for 2 different values of the case origin field.
- Validate and activate the rule.
Step 4 (very advanced) - How to make sense of where the error is coming from
- Learn a bit of French or use the visual cues to understand the screenshots above. I guarantee that the English and French version work identically.
- Configure a D365 on-premise environment using v8.2.
- Recreate the business rule above and test both step 1 and step 2, just to make sure it happens the same way.
- Trace the calls to the org service and hope that there will be more details in the trace.
Why did it happen
My intuition said that the error is generated from the fact that under the hood, the owner field is an overloaded lookup (meaning a lookup that two entities – user and team, and the selection of the target entity drives the selection of the new owner record – user id or team id). Additionally, a lookup is an EntityReference class with 3 critical attributes: logical name, name and id. For details, see this D365 SDK article.
My Own Opinion
For any software component built from the ground up, the developer has full responsibility over the way the component is behaving. Any potential errors are usually self-inflicted, not necessarily system related (as hardware becomes more and more reliable and even notifies us in advance when it is on its way out).
With the introduction of the concept citizen-developer, the responsibility of solid code is now divided between the developer-developer and the citizen-developer. The developer-developer needs to ensure that the code is complete with references to the proper objects/enumerations, and the citizen-developer needs to identify where the developer-developer inflicts errors through poorly-understood metadata.
D365 has been making huge strides on the citizen developer journey, bringing more and more very-intuitive, visual configurators to the business audience. It turns out that with every enhancement and every tool, we still need a thorough understanding of the structure / metadata / “under the hood dangerous liaisons” that exist amongst the intelligent objects and the tools that use them as building blocks in the system.