29 Jan 2016

Automatic record creation or update rules in Dynamics CRM 2015 SP1

Microsoft always believes in making life of people simpler using their product. This is what happens with every update of Dynamics CRM.
There was one feature introduced in CRM 2013 to ease the life of CRM users and that feature was Automatic case record creation through email and social monitoring.
This was indeed a very much needed feature. Prior to this update it used to be a manual/automated (through plug-in or workflow) process. As a result this feature came as a boon for a non-developer posse of users.
Albeit it was a boon, it was somewhat restricted in its functionality. We were only allowed to use Email and Social monitoring activities out of all the available activities for case creation and only case creation was possible.
Now, in CRM 2015 SP1, they have enhanced the Automatic Record Creation to another level, the feature is now named as Automatic Record Creation and Update Rules. Name itself is enough for us to understand the advancements.
Lets understand what all things have been implemented in this update.
First and foremost, this rule is now applicable on almost all the available Activities plus Custom activities. Woahh! what a jump.
Below is the list of available activities on which automatic record creation and update rule is applicable:
  • Phone Call
  • Email
  • Appointment
  • Service Activity
  • Task
  • Social Activity
  • Custom Activities
We can select any Activity, Entity, Custom Activity and Custom Entity for creation, previously we were only allowed to Create Case.
Automatic Record Creation or Updation
How to create an Automatic Record Creation or Update rule?
  • Navigate to Settings -> Service Management and then select Automatic Record Creation and Update Rules
    Automatic Record Creation or Updation1
  • Click New, fill in the required details.
  • Click Save.
  • Once, you save the details you can specify the rules for the record creation.
 How to specify rules?
  • Click the "+" button.
    Automatic Record Creation or Updation2
  • Another form would pop-up, here you can specify the conditions and the record to be created.
Specify Conditions:
Automatic Record Creation or Updation3
Specify Entity for which record needs to be Created:
Automatic Record Creation or Updation4
Note: Feedback is a custom activity and Action plan is a custom entity in the above screenshots. 
Once everything is set-up, you need to Activate the Automatic Record Creation or Update Rule, if not activated the rule wont take effect.
How to Activate the rule?
  • Click the Activate button.
    Automatic Record Creation or Updation5



25 Jan 2016

Sample PlugIn to perform CRUD operation- Late Bound


Sample Program to illustrate CRUD operations using Late bond.

Entities:
Department- Parent entity
Employee- Child entity

Task: 
Update Employee count filed in Department entity when a create, update  and delete Employee entity.

Note: Here I used fetchXML to retrieve multiple records(used resource file)

FetchXML query:

 <fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" aggregate="true">  
  <entity name="cit_employee">  
   <attribute name="cit_employeeid" aggregate="count" alias="empCount" />  
   <filter type="and">  
    <condition attribute="cit_department" operator="eq" value="{0}" />  
   </filter>  
  </entity>  
 </fetch>  

coding is

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using System.Runtime.Serialization;  
 using System.Globalization;  
 using System.ServiceModel;  
 using Microsoft.Xrm.Sdk;  
 using Microsoft.Xrm.Sdk.Query;  
 namespace EmployeeCountDepartmentWise  
 {  
   public class EmployeeCount : IPlugin  
   {  
     public void Execute(IServiceProvider _serviceProvider)  
     {  
       IPluginExecutionContext _context = (IPluginExecutionContext)_serviceProvider.GetService(typeof(IPluginExecutionContext));  
       IOrganizationServiceFactory _factory = (IOrganizationServiceFactory)_serviceProvider.GetService(typeof(IOrganizationServiceFactory));  
       IOrganizationService _service = _factory.CreateOrganizationService(_context.UserId);  
       if(_context.InputParameters.Contains("Target"))  
       {  
         if (_context.InputParameters["Target"] is Entity)  
         {  
           Entity _empEntity = (Entity)_context.InputParameters["Target"];  
           if (_empEntity.LogicalName.ToLower() == "cit_employee")  
           {  
             switch (_context.MessageName)  
             {    
               case "Create":  
                 try  
                 {  
                   Guid _deptId = ((EntityReference)_empEntity.Attributes["cit_department"]).Id;  
                   PostEventOperation(_service, _deptId);  
                 }  
                 catch (FaultException<OrganizationServiceFault> ex)  
                 {  
                   throw new InvalidPluginExecutionException("An error occurred in CFR13.DemoPlugin plug-in.", ex);  
                 }  
                 break;  
               case "Update":  
                 try  
                 {  
                   Guid _deptPreImageId = Guid.Empty; Guid _deptPostImageId = Guid.Empty;  
                   if (_context.PreEntityImages.Contains("PreImage"))  
                   {  
                     Entity _preEntityImage = (Entity)_context.PreEntityImages["PreImage"];  
                     if (_preEntityImage.Contains("cit_department"))  
                     {  
                       _deptPreImageId = ((EntityReference)_preEntityImage.Attributes["cit_department"]).Id;  
                     }  
                     if (_empEntity.Attributes.Contains("cit_department"))  
                     {  
                       _deptPostImageId = ((EntityReference)_empEntity.Attributes["cit_department"]).Id;  
                     }  
                     Guid[] ar = new Guid[] { _deptPreImageId, _deptPostImageId };  
                     int i = 0;  
                     while (i < 2)  
                     {  
                       PostEventOperation(_service, ar[i]);  
                       i++;  
                     }  
                   }  
                 }  
                 catch (FaultException<OrganizationServiceFault> ex)  
                 {  
                   throw new InvalidPluginExecutionException("An error occurred in CFR13.DemoPlugin plug-in.", ex);  
                 }  
                 break;  
             }  
           }  
         }  
         else if (_context.InputParameters["Target"] is EntityReference)  
         {  
           EntityReference _empEntity = (EntityReference)_context.InputParameters["Target"];  
           if (_empEntity.LogicalName.ToLower() == "cit_employee")  
           {  
             if (_context.MessageName == "Delete")  
             {  
               try  
               {  
                 if (_context.PreEntityImages.Contains("PreImage"))  
                 {  
                   Entity _preImage = (Entity)_context.PreEntityImages["PreImage"];  
                   if (_preImage.Contains("cit_department"))  
                   {  
                     Guid _deptId = ((EntityReference)_preImage.Attributes["cit_department"]).Id;  
                     PostEventOperation(_service, _deptId);  
                   }  
                 }  
               }  
               catch (FaultException<OrganizationServiceFault> ex)  
               {  
                 throw new InvalidPluginExecutionException("An error occurred in CFR13.DemoPlugin plug-in.", ex);  
               }  
             }  
           }  
         }  
       }  
     }  
     public void PostEventOperation(IOrganizationService _service, Guid depId)  
     {  
       Entity _deptEntity = new Entity("cit_department");  
       _deptEntity["cit_departmentid"] = depId;  
       string _getEmployeeCount = string.Format(CultureInfo.CurrentCulture, FetchXML.getEmployeeCount, depId);  
       EntityCollection _entityCollection = (EntityCollection)_service.RetrieveMultiple(new FetchExpression(_getEmployeeCount));  
       if (_entityCollection.Entities.Count == 1)  
       {  
         int val = (int)((AliasedValue)_entityCollection.Entities[0]["empCount"]).Value;  
         _deptEntity["cit_employeecount"] = Convert.ToString(val);  
         _service.Update(_deptEntity);  
       }  
     }  
   }  
 }  

Expecting Suggestions......

Why did Microsoft partner with Salesforce?

Expect the unExpected

When Microsoft teamed up with Salesforce last year it prompted shock and a few grumbles from the Microsoft Dynamics community.
Microsoft makes money selling non crm services and products
  • Windows
  • Microsoft Office
  • Azure
  • Cloud infrastructure
  • Other products
Microsoft Dynamics CRM resellers were frustrated because one of the key advantages Microsoft Dynamics CRM had over Salesforce was its integration with Microsoft products.
The CRM community questioned if the Salesforce partnership would lose Microsoft CRM deals to competing bids from Salesforce?
The first reaction is often an over reaction and Microsoft CRM resellers didn’t lose bids to their Salesforce counterparts en masse after the partnership (integration will take time from Salesforce).  I doubt the key reasons for choosing Microsoft Dynamics CRM as the technology to deliver a project wasn’t due to it’s integration with Microsoft Office.

Why do companies win bids?

What are the key ingredients to a winning bid?
  • People
  • connecting with the customer and understanding their problems and requirements
  • Vision
  • Experience
  • vertical or industry solutions
Competing bids using different technologies are usually close with different strengths and weaknesses.  The key differentiator is the company, people and how well they connect with the customer.
Consider the most common cause of failure of projects isn’t the technology used but the people and the working relationship.

Conclusion:

Instead of focusing on competing with Saleforces, Microsoft is focusing on improving the applications which can integrate with Microsoft Dynamics CRM and Azure services which can be consumed by CRM.


How to Calculate a work Timestamp based on a calendar

Enhanced Service Level Agreements (SLA’s) are one of the most helpful features that the latest version of Microsoft Dynamics CRM has to offer. This feature can calculate the amount of time spent on a specific case or even the amount of time a case was on hold.  However, SLAs cannot calculate the next work timestamp.
Consider the following scenario of escalating a critical case.
Challenge: You need to calculate the work timestamp that indicates when a critical case can be escalated based on a CSR’s calendar. If a critical case was created on Friday at 4:30pm and your CSR’s don’t work during the weekend, you need to add four hours to when the case is created and come up with a timestamp for when the case should be escalated. The timestamp should fall on a working day for a CSR. It could be on Monday or even Tuesday if it was a holiday weekend.

So how do you calculate a work timestamp based on a calendar in Microsoft Dynamics CRM 2015?

Solution:  We create a custom entity that takes a calendar GUID (string, as CRM does not allow lookups to Calendar entity – CSR calendar), start time (DateTime – case createdon/modifiedon), hours, minutes, and seconds as integers for the amount of time to add to the start time. On the creation of this entity, a plugin is triggered that does the calculation and stores the result in the same record in the work timestamp field. Employing a custom entity gives the benefit of calling create from JavaScript, custom code or even from inside any other plugin.
The following are screenshots of how the entity looks before and after.
Timestamp-Blog-Photo-1 Timestamp-Blog-Photo-2
Above you can see that based on a provided start time, the CSR calendar, and amount of time; the plugin calculates the work timestamp.
 I have bundled this in an unmanaged CRM 2015 solution that you can import. Also available is a complete plugin code in case you would like to use the code separately.

22 Jan 2016

Save Time Entering Data into CRM by Mapping Fields between Records

It’s been said that a database is only as good at the data in it. A good way to insure good data is to reduce the amount of data entry by your users and to insure the correct data is entered. A way to accomplish this is through the mapping of fields from parent records to related, child records.

The key to making the mapping work is that the users need to create the new, child record from the parent record. For example, if you have an Opportunity record open, you would then select Quote from the left navigation and then click the ‘Add New Quote’ button from the ribbon when it changes.
To setup the mapping, do the following:
  1. Get to ‘Customizations’.  One way to do this is to go to ‘Settings’, ‘Customizations’, and then choose ‘Customize the System’.


  2. Select arrow to the left of the parent entity to expose the sub-menu items. In our example, that is the Opportunity.



  3. Once there, go to the Opportunity entity and click on the ‘1:N Relationships’.


  4. Next click on ‘Mappings’ and then the ‘New’ button.



  5. Lastly, choose the source and target fields, click ‘OK’ and you’re done.



  • An important note here is that the field types must be same on both entities if you want to map fields
  • The AttributeMetadata type must match.
  • The length of the target field cannot be shorter than the source field.
  • The format must match.
  • The target field must not be used in another mapping.
  • The will work if only you create child record from parent record, through subgrid or an associated view.
  • The target field must be a field in which a user can enter data.
  • Address ID values cannot be mapped.
  • It wont inherit the fields mapping define before(possible with Plugin)

ASP.NET 5 is dead - Introducing ASP.NET Core 1.0 and .NET Core 1.0

This post originally appeared on Scott Hanselman's blog at:http://www.hanselman.com/blog/ASPNET5IsDeadIntroducingASPNETCore10AndNETCore10.aspx
Naming is hard.
There are only two hard things in Computer Science: cache invalidation and naming things. - Phil Karlton
It's very easy to armchair quarterback and say that "they should have named it Foo and it would be easy" but very often there's many players involved in naming things. ASP.NET is a good 'brand' that's been around for 15 years or so. ASP.NET 4.6 is a supported and released product that you can get and use now from http://get.asp.net.
However, naming the new, completely written from scratch ASP.NET framework "ASP.NET 5" was a bad idea for a one major reasons: 5 > 4.6 makes it seem like ASP.NET 5 is bigger, better, and replaces ASP.NET 4.6. Not so.
So we're changing the name.

Reintroducing ASP.NET Core 1.0 and .NET Core 1.0

  • ASP.NET 5 is now ASP.NET Core 1.0.
  • .NET Core 5 is now .NET Core 1.0.
  • Entity Framework 7 is now Entity Framework Core 1.0 or EF Core 1.0 colloquially.
Why 1.0? Because these are new. The whole .NET Core concept is new. The .NET CLI is very new. Not only that, but .NET Core isn't as complete as the full .NET Framework 4.6. We're still exploring server-side graphics libraries. We're still exploring gaps between ASP.NET 4.6 and ASP.NET Core 1.0.

Which to choose?

To be clear, ASP.NET 4.6 is the more mature platform. It's battle-tested and released and available today. ASP.NET Core 1.0 is a 1.0 release that includes Web API and MVC but doesn't yet have SignalR or Web Pages. It doesn't yet support VB or F#. It will have these subsystems some day but not today.
We don't want anyone to think that ASP.NET Core 1.0 is the finish line. It's a new beginning and a fork in the road, but ASP.NET 4.6 continues on, released and fully supported. There's lots of great stuff coming, stay tuned.

Note: This post is not related to MS Dynamics CRM.

19 Jan 2016

Event Execution Pipeline

Execution Pipeline Stages

The event pipeline is divided into multiple stages, of which 4 are available to register custom developed or 3rd party plug-ins. Multiple plug-ins that are registered in each stage can be further be ordered (ranked) within that stage during plug-in registration.

EventStage nameStage numberDescription
Pre-Event
Pre-validation
10
Stage in the pipeline for plug-ins that are to execute before the main system operation. Plug-ins registered in this stage may execute outside the database transaction.
The pre-validation stage occurs prior to security checks being performed to verify the calling or logged on user has the correct permissions to perform the intended operation.
Pre-Event
Pre-operation
20
Stage in the pipeline for plug-ins that are to execute before the main system operation. Plug-ins registered in this stage are executed within the database transaction.
Platform Core Operation
MainOperation
30
In-transaction main operation of the system, such as create, update, delete, and so on. No custom plug-ins can be registered in this stage. For internal use only.
Post-EventPost-operation
40
Stage in the pipeline for plug-ins which are to execute after the main operation. Plug-ins registered in this stage are executed within the database transaction.
Post-EventPost-operation (Deprecated)
50
Stage in the pipeline for plug-ins which are to execute after the main operation. Plug-ins registered in this stage may execute outside the database transaction. This stage only supports Microsoft Dynamics CRM 4.0 based plug-ins.

12 Jan 2016

Entity Ownership in MS Dynamics CRM

When you create a new entity, you have to set the ownership options, How many ownership options are there?
entity ownership
I’m guessing most of you reading are going to say two.
  • Organization Owned
  • User Or Team
but did you know there are other types? Hidden types that only Microsoft can use/made up
There are several types of entity ownership. Most entities, including custom entities, are owned by the organization, by a user, or a team. There are some business entities that do not have an owner, such as discount type (discount list), where the ownership is defined by its parent entity discount. The type of ownership defines some of the operations that can be performed on a record. Ownership for an entity is defined in the metadata property OwnershipType. The following table lists the ownership properties.
Ownership TypeDescription
Organization OwnedContains data involving something that belongs to or that can be viewed by the whole organization. Organization-owned entities cannot be assigned or shared. For example, products are owned by the organization. These entities have an attribute named organizationid.
Business OwnedEntities that belong to a business unit. These entities have an attribute named owningbusinessunit.
User or Team OwnedAssigned to a user or to a team. These entities contain data that relates to customers, such as accounts or contacts. Security can be defined according to the business unit for the user or team. These entities have attributes named owningteam and owninguser.
NoneThese entities are not owned by another entity.

Business Owned and None!

I will admit I had never thought about the ownership options on the system entities and to think some business entities (new term) which do not have an owner.
I find it intriguing when you see how Microsoft bend the rules when creating system entities and data, so they can create the default functionality in CRM but it’s only when you understand how the entities and ownership works that you can understand how Microsoft have bent these rules and why.

Entity ownership Choice

I find making the choice of entity ownership is always a painful one, it always causes me to spend a few minutes deciding whether it should be organizational or user/team.  I’m always keen to choose organization where possible because it’s neater (when used appropriotly) and doesn’t create those extra fields.

Why is the choice important?

I know most CRM developers choose the default choice of User or team entity ownership and don’t even think about it, in fact I’m sure a lot of CRM developers don’t even know there is an choice about entity ownership (based on the fact I rarely see any choose organization entity ownership)
One reason making the choice takes a bit of time is once you make that choice and save it, there is no turning back.  It’s one of those decisions that cannot be reversed.  If you change your mind you have to delete the entity and start all over again.
Like some of the entity checkboxes – send email, queues, Connections, business process flows.  Once you tick these, they have the cross of doom and can never be unticked!!
Choosing ownership is probably more like selecting if an Entity is an activity, you make the decision and the only way back is deleting and recreating the entity.
So I have made it clear it’s a decision you don’t really want to get wrong and it’s not really that important because if in doubt you can choose user/team ownership and not use owning fields and functionality.
What’s the difference, Why does it matter
To understand why the decision is important you need to think about what happens when you choose one of the options and the security ramification of the decision

When you choose Ownership of User/Team

After you have chosen Entity ownership type of user/team, CRM will create some additional fields to enable the records to be owned by users/teams.
entity ownership 1
It creates fields for OwningUser, OwningTeam, owningbusinessunit and ownerid.
The reason it creates all the fields is for the security roles and the five access levels
  • Global
  • Deep
  • Local
  • Basic
  • None
You have to record the business unit of the user/team so the security role can work out what other users can view the record.
If you selected organization level of Entity Ownership then it has two access levels None and Global.
Organisation ownership means the entity will not have an owner field or any of the other user/team/business unit lookups.  Global or none visibility means the entity will ignore the business units of the users

7 Jan 2016

MS Dynamics CRM


Welcome MS Dynamics CRM.

CRM- Customer Relationship Management

MS Dynamics is a product of Microsoft. It's comes under Dynamics family after MS Dynamics 3.0 version. This product mainly focuses on Sales, Marketing and Service sectors. Dynamics is server-client application so we can access it from browser or outlook.