Skip Ribbon Commands
Skip to main content
brite global home

Post

Nov 10
Retrieving All Record owned by other Team Members – Part II

In a recent post we showed how to retrieve all the team members of a particular record. This was different then using the default My Team Comments view, and we showed the relationship that is needed.

In this post we will show how to implement that same query using C# code. This can be used from within a plugin or a custom application that uses the CRM SDK. 

        
      internal EntityCollection RetrieveMyTeamComments(Guid userId)
        {
            ColumnSet commentsColumns = 
      new ColumnSet("bgx_commentid", 
      " bgx_autonumber", 
      " bgx_categoryid", 
      " bgx_comment", 
      " bgx_response", 
      "ownerid", 
      "owninguser", 
      " bgx_submissionid");

            EntityCollection rc = 
      new EntityCollection();
            QueryExpression query = 
      new QueryExpression()
            {
                EntityName = 
      " bgx_comment",
                ColumnSet = commentsColumns,
                Distinct = 
      true,
                Criteria =
                {
                    Conditions = 
                    {
                        
      new ConditionExpression("statecode", ConditionOperator.Equal, 0)
                    }
                },
                LinkEntities = 
                {
                   
      new LinkEntity()
                   {
                       LinkToEntityName = 
      "systemuser",
                       LinkToAttributeName = 
      "systemuserid",
                       LinkFromEntityName = 
      "scag_comment",
                       LinkFromAttributeName = 
      "owninguser",
                       JoinOperator = Microsoft.Xrm.Sdk.Query.JoinOperator.Inner,
                       EntityAlias = 
      "user",
                       LinkEntities = 
                       {
                           
      new LinkEntity()
                           {
                               LinkToEntityName="teammembership",
                               LinkToAttributeName="systemuserid",
                               LinkFromEntityName = 
      "systemuser",
                               LinkFromAttributeName="systemuserid",
                               JoinOperator = Microsoft.Xrm.Sdk.Query.JoinOperator.Inner,
                               EntityAlias= 
      "teammembership1",
                               LinkEntities = 
                               {
                                   
      new LinkEntity()
                                   {
                                       LinkToEntityName="team",
                                       LinkToAttributeName="teamid",
                                       LinkFromEntityName = 
      "teammembership",
                                       LinkFromAttributeName="teamid",
                                       JoinOperator = Microsoft.Xrm.Sdk.Query.JoinOperator.Inner,
                                       EntityAlias= 
      "team",
                                       LinkEntities = 
                                       {
                                           
      new LinkEntity()
                                           {
                                               LinkToEntityName="teammembership",
                                               LinkToAttributeName="teamid",
                                               LinkFromEntityName = 
      "team",
                                               LinkFromAttributeName="teamid",
                                               JoinOperator = Microsoft.Xrm.Sdk.Query.JoinOperator.Inner,
                                               EntityAlias= 
      "teammembership2",
                                               LinkEntities = 
                                               {
                                                   
      new LinkEntity()
                                                   {
                                                       LinkToEntityName = 
      "systemuser",
                                                       LinkToAttributeName = 
      "systemuserid",
                                                       LinkFromEntityName = 
      "teammembership",
                                                       LinkFromAttributeName = 
      "systemuserid",
                                                       JoinOperator = Microsoft.Xrm.Sdk.Query.JoinOperator.Inner,
                                                       EntityAlias = 
      "systemuser",
                                                       LinkCriteria = 
      new FilterExpression
                                                       {
                                                           FilterOperator = LogicalOperator.And,
                                                           Conditions = 
                                                           {
                                                               
      new ConditionExpression("systemuserid", ConditionOperator.Equal, userId)
                                                           }
                                                        }
                                                   }
                                               }
                                           }
                                       }
                                   }
                               }
                           }
                       }
                   }
                }
            };

            EntityCollection results = 
      new EntityCollection();
            
      try
            {
                results = service.RetrieveMultiple(query);
            }
            
      catch (FaultException<OrganizationServiceFault> ex)
            {
                Console.WriteLine(ex.Message);
            }

            
      return results;

        }

You will notice the difference between the code and the advanced find from the previous view is that in the view there is only three levels of relationships, while in the code there are 5.
The reason for this is that in the advanced find view, we do not need to create the relationship with the teammembership entity.

Nov 10
Creating an Approval Process

We recently had a requirement to add an approval process to an entity in CRM. This was a custom entity (Comment), where most of the fields were prepopulated from the web, but had a response field that had to go through multiple layers of approval/review. The review process was once the comment was received it would be assigned to a responder, which would then go through manager, legal and director approvals.

We first created a field in CRM called Review Stage that would hold the value of the review stage.

Added Submit for Approval, Approve and Lock/Unlock buttons using Ribbon Workbench. Thank you Scott DuBrow.

Ribbon Workbench Comment Command Bar 

The next step is that we needed to provide custom privileges for the users. Some users would have multiple roles and particular rights that had to be validated before a particular action would need to be performed. Although this could have been done via Security Roles, the restrictions had to be per user, so we added certain security rights to the User Entity. We also considered doing this in custom entity, but since there were not that many specials privileges, we ended up adding the fields to the user entity.

User Entity Comment Privileges 

The different roles of the users required particular rights, such as which users could assign or reassign a record to another user, which users could submit for approval (mark complete), and who can approve. The main reasoning behind this, is that users could perform multiple actions (such as being a responder and a manager, or being a manager and a director).

 

There were three main Actions (or custom messages) that would be called from the Comment record.
These would be Assign, Submit for Approval and Approve. Each of these functions would call the Action Process via JavaScript and would then execute the Plugin Message code.

The following is an example of the Approve Comment Action that is being called via JavaScript.

Approval Process Action 

Once the Action is called, it will execute the Plugin code, which would validate whether the user has the proper privileges, and whether the user is the proper user in the chain of approvals.

Action Source Code 

When the plugin code finished executing, the form would refresh, and show the user that the process has advances to the next stage. We did this by creating a custom wizard web resource (looks similar to the Business Process Flow, but without all the bells and whistles). This would also allow us to lock down records once it reached certain stages of the approval process.

 

Since Directors are not really used to going through hundreds of records in CRM, we created an Export Process for them, that will allow them to export their comments to Excel. We restricted the user of the out-of-the-box Export to Excel feature, since we needed the Excel workbook to be protected/restricted to only certain columns. We created a process Console application called by a Task scheduler running on a separate application server. This process would check for requests from users for Excel exports and would generate the files and send them to the users via email. The process was implemented using the Infragistics Excel framework (an easier way to generate Excel files then using the Excel object model). The files would be locked for editing with the exception of the columns/rows that we needed.

We then created an SSIS import package using the SSIS Integration Toolkit for Microsoft Dynamics CRM (by Kingswaysoft) that allowed us to validate and upload the changes from the high level approvers that wanted to go over the responses in back into CRM.

 

Nov 05
Retrieving All Records owned by other Team Members

We recently got into a situation where a client wanted to have a view that will display all the records of all the users that belong to the same team as the logged in user. Originally we thought it would be easy, but it happens to be slightly more complex.

The first thought of course is to modify the "My Active Comments" view to include both Owner Equals Current User and Owner Equals Current User's Teams, but that of course will only retrieve the records that are owned by the logged in user or the actual team, not the team members.

The next option was of course creating a view with various levels of linked entities and set the IsDefault of the team entity to No, so that not all team members will be retrieved.
Since this was a comments system and the application had a lot of teams for different Roles and Categories, so setting the IsDefault attribute to No would not solve our problem because we would still get the Role based users.

What we ended up doing is excluding from the view all of the Teams that are "Role based", which included Users spanning across different categories. by doing so, we were able to retrieve the expected results.

Team Members View 

When looking at the view, we will be able to see all the records that are assigned to other members of your team.

Oct 19
CRM Exchange Sync 3.0 Released

Our CRM Exchange Sync tool has just been released, now with additional functionality and support for additional environments.

The CRM Exchange Sync application adds the capability of synchronizing between Microsoft Dynamics CRM Marketing Lists and Contacts with Exchange Distribution Groups, Mail Contacts and Mail User records. The application retrieves the data from Microsoft Dynamics CRM Marketing Lists (both static or dynamic), and adds the members of the lists to Microsoft Exchange. If the members already exist in Exchange, the application can update them.

From the Microsoft Dynamics CRM side, the application supports CRM 2011, CRM 2013, CRM 2015 and Microsoft Dynamics CRM Online. On the Exchange Server side, the application support Microsoft Exchange 2010 and Microsoft Exchange 2013, as well as Microsoft Exchange Online (via an Office 365 subscription). Microsoft Exchange 2007 (and the use of Powershell 1.0) has been deprecated.

The application support features such as Automatic Synchronization, Field Mapping and Custom entity relationships.

It is available for a 30-day trial.

Aug 20
Checking if a solution exists and upload it to CRM using the SDK

​Many times we encounter an external application that requires a solution to be installed in your CRM environment, but it might not be there or we might require to upgrade an existing solution.

The first thing that we want to check is if the solution that we are looking for already exists in CRM. The following function checks for that exactly.

public EntityCollection RetrieveSolutions(string solutionName)

{

QueryExpression query = new QueryExpression

{

EntityName = "solution",

ColumnSet = new ColumnSet(true),

Criteria =

{

Conditions =

{

new ConditionExpression("uniquename", ConditionOperator.Equal, solutionName)

},

}

};

RetrieveMultipleRequest request = new RetrieveMultipleRequest();

request.Query = query;

try

{

RetrieveMultipleResponse response = (RetrieveMultipleResponse)CRMHelper.xrm5.Execute(request);

EntityCollection results = response.EntityCollection;

return results;

}

catch (System.Exception ex)

{

return null;

}

}

 

Just pass the name of the solution to the function, and it will return all solutions that match that solution name. Should be either 0 or 1 values returned. I can use the following code to check for additional information about the solution (such as version number):

 

if (solutions.Entities.Count > 0)

{

string friendlyName = solutions.Entities[0].Attributes["friendlyname"].ToString();

string versionNumber = solutions.Entities[0].Attributes["version"].ToString();

}

The next phase is to import the solution if none exists, or if you had a newer version that you would like to import, the same codeset will work. We can call the following function, and pass the full path of the solution file (zip file):

public static bool ImportSolution(string fileName)

{

byte[] fileBytes = File.ReadAllBytes(fileName);

ImportSolutionRequest request = new ImportSolutionRequest()

{

CustomizationFile = fileBytes

};

try

{

ImportSolutionResponse response = (ImportSolutionResponse)context.Execute(request);

return true;

}

catch (FaultException<OrganizationServiceFault> ex)

{

throw ex;

}

}

That is basically the entire process. If the import fails, you will receive a Fault Exception and can check the data returned in the catch block.

Jul 29
Windows 10 is here. Is CRM ready?
Windows 10 has been released, and Microsoft offered a free upgrade to licensed Windows 7 and Windows 8 users. Windows 10 ships with a new browser called Microsoft Edge, which introduces some great new features and let go of some older capabilities of Internet Explorer. These changes will require CRM to be updated.

What does this mean for your CRM? The Microsoft Dynamics CRM team has been working with the Microsoft Edge team to make sure that Microsoft Dynamics CRM works with Microsoft Edge, which will require CRM to make some updates in order to support the new browser.
The first wave of these update was introduced in CRM Online 2015 Update 1. At this time the following releases of Microsoft Dynamics CRM will provide support for Windows 10, Windows Edge and Microsoft Office 2016:

  • Microsoft Dynamics CRM 2013, Service Pack 1, Update Rollup 4 (version 6.1.4)
  • Microsoft Dynamics CRM Update 0.2 (version 7.0.2)
  • Microsoft Dynamics CRM Online, 2015 Update 1.1 (version 7.1.1)

The above releases are still in development, and we believe a release date is coming out shortly. 

Jul 29
Windows 10. Available Today. Upgrade for Free

​Today, Microsoft release Windows 10 in 190 countries. The launch of Windows 10 is being deployed to millions of people and organzations around the world.

As Windows 10 starts being rolled oup, Microsoft is empowering their customers to do great things in four key ways:

1. Windows 10 is fast and familiar, and includes the familiar Start Menu, Taskbar and Desktop that we are all familiar with, and the addition of Live Tiles which provide streaming updates from what matters most to us instantly.

2. Windows 10 is the most secure Windows ever offering enhanced protection with Windows Defender and Smart Screen. Windows Hello provides a fast and secure password-free way to log in.

3. Windows 10 is more personal and productive with Voice, Pen and Gesture input methods to interact with the PC. Cortana makes it easy to find the right information at the right time, you can easily switch between apps and stay organized with Snap and Task View, and Continuum optimizes your apps and experience across touch and desktop modes.

4. Windows 10 Offers innovatives experiences and new devices with the introduction of the new Microsoft Edge browser, integrated XBox App, Companion Phone app and additional built in apps that come with it.

Apr 04
Permission accessing SSRS Report Server/Manager
Recently we have encountered an issue where a domain admin (and local admin) account was trying to access the SSRS Report Manager and Report Server web sites and was getting the following error:
User DOMAIN\UserAccount does not have the required permissions. Verify that the permissions have been grated and Windows User Account Control (UAC) have been addressed.

The easiest solution to the problem is to disable UAC on that machine (a restart will be required).
After that you should be able to access to SSRS Report Manager and Report Server web sites.

If you need to keep UAC running, the following KB article details the configuration required for the installation to both install and run SSRS:
http://support.microsoft.com/kb/934164

Jan 20
CRM 2013 Notes Control Form Presentation

CRM 2013 has a new feature that allows displaying Posts, Notes and Activities within a single control (using the Updated Forms). We can easily add this new control to the form by clicking on the Notes ribbon icon on the Insert Tab of the Form Customization.

It seems that the behavior of adding the Notes control is not always the same, as sometimes the control might display only Notes and sometimes it will display the Posts, Notes and Activities.

The solution as to what the control will display can be modified, by exporting the entity, and modifying the FormXml section of the Entity within the customizations.xml file. Within the FormXml section, under forms type = "main"/systemform there is an element called FormPresentation.

The value of FormPresentation can be either 0 or 1. If the value is 0, only the Notes section will appear (classic). If the value is 1, the Posts, Notes and Activities sections will appear (updated). Make the required changes, re-import your entity/solution and publish your customizations and your form will display the Notes control in the proper way.

Dec 26
Using Multiple User Principal Name Suffixes

​​When configuring ADFS in your own local the default login of any user authenticating into the environment would be user@domain.local or something of that sort. At many times, especially when working with multiple applications, we would like the user to authenticate using different login credentials such as user@mynewdomain.com. In order to implement this, we can add suffixes that gives us the ability to user a friendly logon name that is not the same as the domain or parent's domain name.

In order to add a domain suffix to a forest, we need to follow the instructions below:

  • Log on to the domain controller, or a computer that has the different Active Directory Management Tools, and open Active Directory Domains and Trusts.
  • When the application opens, right-click on the Active Directory Domain and Trusts in the Tree window pane, and select Properties from the pop-up menu.
  • On the UPN Suffixes tab, type the new User Principal Name suffix that you would like to add to the existing forest.
  • Click Add and click OK

After the domain suffixes have been added, new users that are added to the domain can select the UPN suffix to use.

1 - 10Next

 

Connect

Like us on Facebook, add us to your LinkedIn network, view our videos on YouTube or subscribe to our blog. Facebook Linked In You Tube Blog and RSS
Powered By SharePoint Online