Monday, October 3, 2016

Create Many to Many Records in CRM using c#

I have written an article of how this can be done in 2011. The class that was used to do this has been deprecated, so putting down below how the new class would work.


The code is taken from the below link from Microsoft. It contains the both associate as well as disassociates functionalities.


Although this has been done for account and contact, the below code can be used for any entities which are having many to many relationship. There are 3 accounts being associated with one contact record. It can be a single account record and the code would still work.

// Associate the accounts to the contact record.

// Create a collection of the entities that will be
// associated to the contact.
EntityReferenceCollection relatedEntities = new EntityReferenceCollection();
relatedEntities.Add(new EntityReference(Account.EntityLogicalName, _account1Id));
relatedEntities.Add(new EntityReference(Account.EntityLogicalName, _account2Id));
relatedEntities.Add(new EntityReference(Account.EntityLogicalName, _account3Id));

// Create an object that defines the relationship between the contact and account.
Relationship relationship = new Relationship("account_primary_contact");


//Associate the contact with the 3 accounts.
_service.Associate(Contact.EntityLogicalName, _contactId, relationship,
    relatedEntities);

Console.WriteLine("The entities have been associated.");

//Disassociate the records.
_service.Disassociate(Contact.EntityLogicalName, _contactId, relationship,
    relatedEntities);


 Also the below code works fine as well. Again this was taken form a Microsoft link.


AssociateRequest teamToProfile = new AssociateRequest
{
    Target = new EntityReference(FieldSecurityProfile.EntityLogicalName, _profileId),
    RelatedEntities = new EntityReferenceCollection
    {
        new EntityReference(Team.EntityLogicalName, _teamId)
    },
    Relationship = new Relationship("teamprofiles_association")
};
 
// Execute the request.
_serviceProxy.Execute(teamToProfile);


Hiding a pane from the social pane

With CRM 2013, we have got a social pane in which we get posts, activities and notes for all the entities that have been marked for activities and notes. You can disregard the whole pane by removing it from the entity.

However, most of the users would love to see this pane. They would want to remove one tab sometime. This is possible using javascripts. There is a good article on how to do this below.



For case, we get 4 tabs. This includes the KB articles as well. This can be removed as well. However, for this you don’t have to write javascript. It is just a click on the properties of the pane. We need to un tick the knowledge base search control check box.



Also you can decide which tab to load when the form is loaded. This can be done by selecting the tab name from the default tab section. 

Tuesday, September 27, 2016

Lead Qualify as opportunity and duplicate detection

In the sales process normally, you would create a lead and then promote that lead to an opportunity by clicking on the qualify button. When this happens, the CRM creates an opportunity and a contact record.

If there are duplicate detection rules created for the contact record, when you try to qualify a lead it would first bring a small dialog box stating that there could be potential duplicates (Displays both account and contact lookups) and to select one from the list.

One thing is that this appears even if there are no duplicate records as well. If you unpublish the duplicate rules for contact, then this dialog box doesn’t come up. If the rules might be needed we cannot unpublish them.

Some clients don’t like this at all as it doesn’t give a user friendly box with potential duplicates are being marked. Also even though there are no duplicates this might pop up.
Luckily we can turn this off by writing a plugin.

The plugin has to be using the “Lead Qualify” message and have to write for the pre validation stage of lead.

In the C# code you need to write the below twice.

localContext.PluginExecutionContext.InputParameters[“SurpressDuplicateDetection”] = true;
localContext.PluginExecutionContext.InputParameters[“SurpressDuplicateDetection”] = true;

This would prevent from displaying the dialog box completely.


If you want to show the dialog box, if there are duplicates then you can write code to check for duplicates based on the criteria you have been given. Then only if there is a duplicate, you can display the dialog by putting the below 2 statements in an if else condition.

Duplicate Detection Rules

In CRM, we do have an OOTB functionality which lets you check for duplicates. This would however, would not stop one from saving the record but letting know the operator that there is a duplicate. This is in a way good as it, lets the operator decide whether to use the existing record or to continue with using a new record.

There are some good features of this as well as there are some limitations.
Main limitations are
  • You can have only 5 published duplicate detection rules per entity
  • The combination of the match code cannot exceed 450.
These probably have been given to stop one from having performance issues.
If you want a new rule and the entity has exceeded the rule limitation, then you would have to unpublish one rule and get this created. For on premise CRM instances you can change this, but it is unsupported. For Online instances, the unsupported cannot be done.

For Match code though you have alternatives. However, this might not always work, but would be good to know them as well.

For an instance when you create a record for contact and if you want to check for duplicates using first name, last name and street 1, the match code length becomes 352. Now it would be difficult for you to add couple more fields as you only have spare 98 length left from 450.

Most of the time street1 length would not exceed for a live record more than 50(Depends on the requirement). If this is the case then what we can do is instead of having the criteria as “Exact Match”, we can have the filter as “Same First Characters” and give a character length of 50. By doing this we can reduce the match code from 352 to 152, which allows us to add more fields if required.

Apart from that, you do have the operator “Same Last Characters” and can give the character length too.

Also one good thing about this is you can check against another different entity as well. If you need to check when creating a lead record, whether there are contact records with a matching criteria this is also possible.
Apart from that you can check for the following as well.

  • Case sensitiveness of characters
  • Include/Exclude inactive records
  • Ignore blank records

Tuesday, May 3, 2016

Setting the state of a sales order to Completed

Normally when we want to update the state we use the following lines of code to do which is more generic.

SetStateRequest setStateRequest = new SetStateRequest();
setStateRequest.EntityMoniker = new EntityReference(entityName, id);
setStateRequest.State = new OptionSetValue(State);
setStateRequest.Status = new OptionSetValue(Status);
db.Execute(setStateRequest);

Though this is generic this cannot be used with Sales Order as it has another method which has been given OOTB for this. If we use the above for it we would get an error. SO if you want to update the state to complete, please use the following lines of code.

var request = new FulfillSalesOrderRequest
            {
                OrderClose = new OrderClose()
                {
                    SalesOrderId = new EntityReference(SalesOrder.EntityLogicalName, id)

                },
                Status = new OptionSetValue(Status)
            };


db.Execute(request);

As mentioned before, you can use the first set of code to update the state and status of the other entities.

Convert a Sales Order to an Invoice directly using C# code

In the sales process a sales order would be converted to an invoice. Most of the fields in both entities are the same.

So it would be easy for us to create an invoice from a sales order directly by assigning each sales order field to an invoice field.  This is fine, but would be a tedious task as for some projects you wouldn’t all the fields in the sales order filled in. Is there an easy way for us to achieve this?

Yes, there is. There is an OOTB functionality which has been given, in which a sales order can be converted to an invoice with few lines of code. The code is given below.

  ConvertSalesOrderToInvoiceRequest convertOrderRequest =
                    new ConvertSalesOrderToInvoiceRequest()
                    {
                        SalesOrderId = Sales Order Id,
                        ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet(true)
                    };
                ConvertSalesOrderToInvoiceResponse convertOrderResponse = (ConvertSalesOrderToInvoiceResponse)db.Execute(convertOrderRequest);
                Invoice invoice = (Invoice)convertOrderResponse.Entity;


Adding MVC 6 Controllers to a Project

When we are working with MVC projects we tend to rely on the intellisense. When creating a controller most of the time we expect the view and the code to be generated if we are using MVC.

However, sometimes we do not get this when we are creating a controller. It only creates a controller, not the view and the code. How to sort this issue out? Can we get these options to sort them?

The answer is yes, we can. This can be achieved by adding the following packages to the project.json file

    "Microsoft.ApplicationInsights.AspNet": "1.0.0-rc1",
    "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
    "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",

    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final"

Wednesday, March 9, 2016

Outlook CRM Plugin and Email Sending

When we are sending emails from outlook which has the CRM plugin installed in how do you think the email is being attached the to the correct record. The reason is when we are sending an email from outlook not like in CRM interface, you just specify the email address and not an actual record. However the record seems to be attached to the right record in CRM. Does that mean that before the record is attached CRM is going to check all accounts, contacts, leads, system users, queues for the correct record. If this is the case it would take some time as to find the right record.

Fortunately, CRM they are is a table which is called email search base that is being used to do this. Whenever an account, contact..etc is created it creates a record in the above table. It contacts the object type code (to indicate which entity it is), Guid ( primary key value of the entity) and the email address itself.


So when someone is sending an email from outlook it will search in this table and will attach to the correct record.

Retrieving Calendar of a Bookable Resource in Dynamics

There are occasions where we need to retrieve working days and working times of a resource in Dynamics grammatically. This is quite possible...