
Microsoft Dynamics CRM: How to remove company from group of companies
Step 0 – What we want to do:
We have a group of companies in ‘CompanyXYZ’. A total of 4 companies belong to this group (Company A, Company B, Company C and Company D). Now, as a user with a special user (security) role (in this case ‘A’), I want to be able to select one or more records, and thus remove those companies from the composite map:
We can zoom in on the yellow icon to get this view:
And with my button “BAAAAM”, I want to get the marked companies out of this group:
The user should confirm, that he is sure about what he does (confirm dialog):
Step 1: Our Action
Go to your Main Solution and add a new process:
It should look like this with two arguments:
and you need the workflow itself:
The workflow checks the actual user. If the user is not a member of Security Role ‘A’, he isn’t allowed to go on. If he is, then there’s a check, if it’s a group of companies. If no, the workflow is canceled. If yes, it checks if the group of companies contains at least one company. If the workflow could be proceeded, then the field Verbund-ID (which is like a blocknumber for all Companies in a group) on the form is deleted.
Step 2: Javascript for Action
So now, we need a Javascript which does three things for us:
- Show us the Confirm Dialog
- Give us an array of GUID-IDs containing the selected companies
- Trigger our action
Add a webresource for a Javascript and enter the code there. Should look like this:
if (typeof (JScript_Entities) == "undefined") { JScript_Entities = { __namespace: true }; } JScript_Entities.accountribbon = { ButtonClick: function (selectedItem,grid) { var itemsCount = SelectedItem.length; var itemsProcessed = 0; Xrm.Utility.confirmDialog("Do you really want to move company out of this group?",yes,no); function no(){ return; } function yes(){ var organizationUrl = Xrm.Page.context.getClientUrl(); for (var i = 0; i < selectedItem.length; i++) { selectedItem[i] = selectedItem[i].replace("{", ""); selectedItem[i] = selectedItem[i].replace("}", ""); selectedItem[i] = selectedItem[i].replace("%7b", ""); selectedItem[i] = selectedItem[i].replace("%7d", ""); var data = { "ReferenceID": selectedItem[i], }; var query = "accounts(" + selectedItem[i] + ")/Microsoft.Dynamics.CRM.abc_VerbundzuordnungAufheben1"; var req = new XMLHttpRequest(); req.open("POST", organizationUrl + "/api/data/v8.0/" + query, true); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4) { itemsProcessed += 1; console.log(itemsProcessed + " of " itemsCount); if (itemsProcessed == itemsCount) { grid.refresh(); } } }; req.send(window.JSON.stringify(data)); }} } }
There’s the confirm dialog which branches in two functions (function yes and function no). If the user cancels, function ‘no’ will be triggered and the code stops (return). If the user wants to go on, the funcion ‘yes’ is executed and per request, the selectedItems are saved into an array (selectedItem), and our Process-action is called (Microsoft.Dynamics.CRM.abc_VerbundzuordnungAufheben1 – see Step 1).
Step 3: Visibility of our Button
In our example, we want to show the Button only if these 3 conditions are true:
- User must have SecurityRole ‘A’
- It has to be the form label “Verbund”
- it has to be a group of companies (not only one single company)
So for that, we need to write a Javascript. Once again, add a new webresource for Javascript:
if (typeof (JScript_Entities) == "undefined") { JScript_Entities = { __namespace: true }; } JScript_Entities.account = { MyfunctionVisible: function () { if (JScript_Entities.account.MyfunctionBtnFunctionExcecuted) { return JScript_Entities.account.MyfunctionBtnVisible; } else { var systemuserid = Xrm.Page.context.getUserId().slice(1, -1); var currForm = Xrm.Page.ui.formSelector.getCurrentItem(); formLabel = currForm.getLabel(); var req = new XMLHttpRequest(); req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/systemusers(" + systemuserid + ")/systemuserroles_association?$select=name,roleid", true); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("Prefer", "odata.include-annotations=\"*\""); req.onreadystatechange = function () { if (this.readyState === 4) { req.onreadystatechange = null; if (this.status === 200) { var results = JSON.parse(this.response); JScript_Entities.account.MyfunctionBtnVisible = false; for (var i = 0; i < results.value.length; i++) { var securityRoleName = results.value[i]["name"]; if (securityRoleName == JScript_Entities.account.SecurityRoleA || securityRoleName == "Systemadministrator") { if (formLabel == "Übersicht Verbund") { JScript_Entities.account.MyfunctionBtnVisible = true; JScript_Entities.account. MyfunctionBtnFunctionExcecuted = true; Xrm.Page.ui.refreshRibbon(); } } } } else { Xrm.Utility.alertDialog(this.statusText); } } }; req.send(); } }, errorHandler: function (error) { Xrm.Utility.alertDialog(error.message); }, MicroStrategyBaseUrl: null, MicroStrategyAvailable: false, FormVerbund: "fa5564af-a540-497b-adc3-04dc82bb4077", FormA: "2d6aaf5b-5882-4d60-b39a-f128ae179f16", FormB: "aca667c1-885e-4047-8893-a3151bc1307b", FormC: "24745821-9c21-426c-a4dd-350ccf893a4f", AccountCategoryVerbund: 2, AccountCategoryKonzernVerbund: 3, AccountCategoryKusa: 1, SecurityRoleB: "B", SecurityRoleA: "A", SecurityRoleC: "C", MyfunctionBtnVisible: false, MyfunctionBtnFunctionExcecuted: false, __namespace: true };
Don’t forget to add the command for refreshRibbon (Page Refresh after workflow Action has finished). I forgot about it and had the following problem then: My button of the Ribbon workbench did exactly what I expected, but the page wasn’t refreshed after my action, so that I didn’t see that it worked and I had to refresh the page manually.
Step 4: Ribbon Workbench
You need to have the Ribbon Workbench and add our button ‘BAAAAM’:
You need to click on the button to customize it. For the images of this Button, you can simply check this homepage which makes it easy to create a matching icon: FlatIcons
So now, we need the command, which you have to write into the marked field after having created it in Step 5.
Step 5: Command
The Command is the thing that should be done by clicking the Button. For the Command, you need to use your JavaScript (see Step 2) and put it into the Custom Javascript Action together with the two CRM Parameters
- SelectedControlSelectedItemIds
- SelectedControl
The first Parameter is needed so that the Javascript knows which elements are selected, Javascript gets all GUID-IDs (of the selected companies) in form of an array. The second parameter is needed to execute the Javascript itself I think, to be honest I don’t really know.
There are two Enable-Rules needed:
- Mscrm.SelectionCountAtLeastOne
- An own Enable-Rule we have to create first (Myfunction – Step 6)
The Mscrm.SelectionCountAtLeastOne is needed so that the Button only is executable when at least one item is selected. The second (our own rule) is for the visibility depending on different security-roles and different form labels.
Step 6: Enable-Rule
Last, we do need an Enable-Rule so that CRM knows when to show our button or not:
Enter the Javascript-Library and the function and set CRM Parameter to Command Properties.
Don’t forget to publish Ribbon Workbench.
Step 7: Try
Hope this could help you.
[…] My button ‘VERBANLTEST’ does not yet know what to do. That’s why we enter a command. My command itself is written in a Javascript, the one out of Step 3. So I entered a Custom Javascript Action and inserted my function out of Step 3. In addition to that, I entered an Enable Rule. I used exactly the same Enable Rule as I used when I removed a company out of a group of companies. […]
LikeLike