Bhoopathi

"Be Somebody Nobody Thought You could Be"

Saturday, July 30

Email Router Configuration - MS CRM 2013

** Email Router Configuring - MS CRM 2013 **

Server-side synchronization eliminates the need for Microsoft Dynamics CRM for Outlook that existed with earlier versions of Microsoft Dynamics to manage and track emails from/to Outlook.
Microsoft Dynamics CRM integrates with Outlook using the Microsoft Dynamics CRM for Outlook client (the Outlook plug-in), but earlier versions of Microsoft Dynamics CRM usually required both an installed and configured email router (typically on a separate machine) and Outlook to be running (for it to send and receive emails). Use of server-side synchronization eliminates the need for the email router.
In addition, server-side synchronization now provides a level of integration with Exchange directly to allow for this functionality. An example of this is as follows:
1. A user creates a new email and selects the Track in CRM option.
2. The user clicks Send on the email, which sends it to Exchange for routing (sending).
3. Exchange communicates with Microsoft Dynamics CRM, which creates a corresponding record in CRM, which in turn updates Exchange.
Note
The Outlook client is still necessary to promote emails from Outlook to CRM.
The following scenarios are supported for server-side synchronization:
Image Microsoft Dynamics CRM On-Premise using either:
Image Exchange Server 2010/2013
Image Gmail, MSN, Outlook.com, Windows Live Mail, Yahoo! Mail using POP3/SMTP
Note
Only Exchange supports both Email and Appointment, Contacts, and Tasks synchronization. Using a POP3/SMTP email server will still provide email synchronization, but Appointments, Contacts, and Tasks are not synchronized.
The following scenarios are not supported for server-side synchronization:
Image Microsoft Dynamics CRM Online with Exchange On-Premise
Image Microsoft Dynamics CRM On-Premise with Exchange Online
Image Any version of Exchange prior to 2010
In addition, because the server-side synchronization requires a mailbox record for every user and queue in the organization that wants to leverage server-side synchronization, it can create some administrative overhead.
Tip
If your organization has many mailboxes, it might make sense to use the Forward mailbox, which creates a single mailbox that forwards the email to the user’s mailbox.

Configure Server-Side Synchronization

To configure server-side synchronization, follow these steps:
1. Navigate to Settings > Email Configuration (see Figure 16.1). Select Email Server Profiles to create a profile.
Image
FIGURE 16.1 Email configuration settings.
2. Select + New to create a new profile (see Figure 16.2). Select either Exchange or POP3-SMTP Profile depending on your email server. For this example, we configure an Exchange server and so select Exchange Profile.
Image
FIGURE 16.2 Select a new configuration.
Tip
Data encryption must be active; otherwise, you will receive the error shown inFigure 16.3.
Image
FIGURE 16.3 Data encryption requirement error.
3. To activate data encryption, navigate to Settings > Data Management and select the Data Encryption option (see Figure 16.4).
Image
FIGURE 16.4 Disabled data encryption.
Note
HTTPS must be enabled to use the Data Encryption option.
4. Select Activate to enable data encryption (see Figure 16.5).
Image
FIGURE 16.5 Activated data encryption.
5. The new email server profile page will open (see Figure 16.6), allowing you to enter the information for the Exchange server.
Image
FIGURE 16.6 Email server profile configuration.
Caution
If you are accessing Dynamics CRM without Secure Sockets Layer (SSL), you will receive the error message shown in Figure 16.7, which will prevent you from setting the username and password for the profile. To enable the username and password, you must adjust theAllowCredentialsEntryViaNonSecureChannels value in the configuration database. Alternatively, you can change the authentication to use Windows-integrated authentication.
Image
FIGURE 16.7 Email server profile error.
6. Enter a value for Name and select Save. The Ribbon menu will now give you a Test & Enable Mailboxes option (see Figure 16.8), as well as set the profile as default.
Image
FIGURE 16.8 Enabled profile.
At this point, you can also specify the credentials used by the Exchange server, as follows:
ImageCredentials Specified by a User or Queue—Use this option when you want to use credentials specified in the mailbox record of the user or queue.
ImageCredentials Specified in Email Server Profile—This option can be used when you want to use a single credential for all the mailboxes. The credentials require that they have impersonation rights on Exchange.
ImageWindows Integrated Authentication—This option leverages the same credentials that the CRM Asynchronous Service is configured with (only applicable to Exchange and SMTP servers).
ImageWithout Credentials (Anonymous)—This is not a valid selection when working with Exchange.
7. As the Authenticate Using value, select Credentials Specified by a User or Queue. Because we’re only going to set up one profile, we’re going to set this profile as the default profile by selecting that option on the Ribbon menu.
8. Now we need to set up our mailboxes. Close this window and navigate to Mailboxes, and select Active Mailboxes.
9. By default, you will see a mailbox for all created users in the CRM system (see Figure 16.9). Select the mailbox you want to update, and open it.
Image
FIGURE 16.9 Active mailboxes.
10. By default, the Incoming and Outgoing Email and Appointments, Contacts, and Tasks Statuses are set to Microsoft Dynamics CRM for Outlook (see Figure 16.10).
Image
FIGURE 16.10 Mailbox configuration.
11. Change the settings to “Server-Side Synchronization or Email Router,” as shown in Figure 16.11. Notice also that the Server Profile value is the newly created server profile that we created in step 4. Select Save.
Image
FIGURE 16.11 Mailbox configuration set for server-side synchronization.
12. Because we selected Server-Side Synchronization, we are prompted to specify credentials. (If you select CRM for Outlook or integrated windows authentication, no credentials are necessary.) Enter the credentials, as shown in Figure 16.12, and select Save.
Image
FIGURE 16.12 Enter credentials.
13. Notice that the alert still indicates that the mailbox is disabled for incoming email processing. This is because the mailbox has not been tested/enabled. To do that, select the Test & Enable Mailbox option from the Ribbon menu (see Figure 16.13).
Image
FIGURE 16.13 Test and enable the mailbox.
14. If the test is successful, you will receive an email showing the test message (see Figure 16.14).
Image
FIGURE 16.14 Test message.
Tip
You may also need to approve the email address by clicking the Approve Email button to verify the test (see Figure 16.12).
15. If you review the record in Dynamics CRM, you will see that results show Success for the test (seeFigure 16.15).
Image
FIGURE 16.15 Successful test results.
The server-side synchronization is now set up and configured to work. You can perform the same configurations on a Forward mailbox.
Tip
If you have failures during the setup and configuration, you can navigate to the Alerts section and review and correct any specific problems shown.

Thursday, July 28

Bind CRM Data to GridView on ASP.NET Page - MS DYNAMICS CRM

//*********** Bind Data to GridView ************//

string fetch = @"   <fetch mapping="logical">
<entity name="card_contactdetails">
<attribute name="card_contactdetailsid"/>
<attribute name="card_firstname"/>
<attribute name="card_lastname"/>
<attribute name="card_ssn"/>
<attribute name="card_state"/>
<attribute name="card_dateofbirth"/>
</entity>
</fetch>";

string result = service.Fetch(fetch);

XmlDocument doc = new XmlDocument();
doc.LoadXml(result);
doc.DocumentElement.Attributes.RemoveAll();

StringReader sr = new StringReader(doc.OuterXml);
DataSet ds = new DataSet();
ds.ReadXml(sr);

GridView1.DataSource = ds;
GridView1.DataBind();

Wednesday, July 27

/** List of Actions in MS Dynamics CRM - 2013 **/

/** List of Actions in MS Dynamics CRM - 2013 &&
MS CRM Audit Database Table Details **/

Action: 

Action column stores what kind of action performed on record. Action would be Create, Update, Delete, Activate, Fulfill etc. In audit table CRM stored action value like 2 or 3 or 4 etc.

To get all action value from Database  use following query

SELECT Value as Action,AttributeValue as ActionValue FROM StringMap WHERE AttributeName='action'

and here is list of actions in CRM 2013.
0 - Unknown, 25 - Disqualify, 44 - Win, 63 - Enabled for organization, 
1 - Create, 26 - Submit, 45 - Lose, 64 - User Access via Web, 
2 - Update, 27 - Reject, 46 - Internal Processing, 65 - User Access via Web Services, 
3 - Delete, 28 - Approve, 47 - Reschedule, 100 - Delete Entity, 
4 - Activate, 29 - Invoice, 48 - Modify Share, 101 - Delete Attribute, 
5 - Deactivate, 30 - Hold, 49 - Unshare, 102 - Audit Change at Entity Level, 
11 - Cascade, 31 - Add Member, 50 - Book, 103 - Audit Change at Attribute Level, 
12 - Merge, 32 - Remove Member, 51 - Generate Quote From Opportunity, 104 - Audit Change at Org Level, 
13 - Assign, 33 - Associate Entities, 52 - Add To Queue, 105 - Entity Audit Started, 
14 - Share, 34 - Disassociate Entities, 53 - Assign Role To Team, 106 - Attribute Audit Started, 
15 - Retrieve, 35 - Add Members, 54 - Remove Role From Team, 107 - Audit Enabled, 
16 - Close, 36 - Remove Members, 55 - Assign Role To User, 108 - Entity Audit Stopped, 
17 - Cancel, 37 - Add Item, 56 - Remove Role From User, 109 - Attribute Audit Stopped, 
18 - Complete, 38 - Remove Item, 57 - Add Privileges to Role, 110 - Audit Disabled, 
20 - Resolve, 39 - Add Substitute, 58 - Remove Privileges From Role, 111 - Audit Log Deletion, 
21 - Reopen, 40 - Remove Substitute, 59 - Replace Privileges In Role, 112 - User Access Audit Started, 
22 - Fulfill, 41 - Set State, 60 - Import Mappings, 113 - User Access Audit Stopped, 
23 - Paid, 42 - Renew, 61 - Clone, 
24 - Qualify, 43 - Revise, 62 - Send Direct Email, 


ObjectId: 
Object Id the record id, for which this audit record is created.

UserId:
The user who performed action on record. 

ChangeData:
Change Data column stores old data for the attribute. If you changed First name of contact from James to Jim, then in Change data James will be stored.
Values in Change Data are stored in same order as attribute mask stored.
If First name attribute mask is 2 and last name is 3, then in AttributeMask it would be ,2,3 and Change data would beJames~Bond

Change Data column data is separated by ~ by per attribute.

Operation:
Operation column stores information of what kind of operation is performed on record.
CRM has only four operations
1 - Create , 2 - Update, 3 - Delete, 4 - Access. 

To get directly operation values from database use

SELECT Value,AttributeValue FROM StringMap WHERE AttributeName='operation'

ObjectTypeCode:
Object Type code is entity object type code.

To find object type code for entity use

SELECT ObjectTypeCode, LogicalName FROM Entity WHERE Name='contact'

If want to get entity details from object type code then use
SELECT ObjectTypeCode, LogicalName FROM Entity WHERE ObjectTypeCode=1




** Code for retrieving Audit History in MSCRM **


/** Code for retrieving Audit History in Microsoft Dynamics CRM 2011 **/

For retrieving from the Audit history we need to use “RetrieveRecordChangeHistoryResponse”.
The following sample (which I partially found something similar in the SDK) retrieves the information of the Audit history for any object in CRM

Create Organization Service Proxy
        static void Main(string[] args)
        {

            try
            {
               //Grab the organization service url by navigating to
               // Settings -> Customizations - > Developer Resources
               // CrmInstance.CrmServer URL for your CRM
               //CrmInstance.cc create a new ClientCredentials and pass your user name/password and domain
             using (var XrmProxy = new OrganizationServiceProxy(new Uri(CrmInstance.CrmServer + "/XRMServices/2011/Organization.svc"), null, CrmInstance.cc, null))
                {
                    ExtractFromAudit(XrmProxy);
                    Console.WriteLine("Thank you for participating in this amazing experiment! muwhaha!");
                    Console.ReadLine();
                 }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.ReadKey(true);
            }
        }
ExtractFromAudit Method
        private static void ExtractFromAudit(OrganizationServiceProxy XrmProxy)
        {
            // The GUID of the object you want to retirve in this case i am passing contactid
            var entityId = new Guid("4DC98353-CF88-E011-87E1-005056B30007");

            Console.WriteLine("Retrieving the change history.\n");
            // Retrieve the audit history for the account and display it.
            RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest();
            changeRequest.Target = new EntityReference(Contact.EntityLogicalName, entityId);

            RetrieveRecordChangeHistoryResponse changeResponse =
                (RetrieveRecordChangeHistoryResponse)XrmProxy.Execute(changeRequest);

            AuditDetailCollection details = changeResponse.AuditDetailCollection;

            foreach (AttributeAuditDetail detail in details.AuditDetails)
            {
                // Display some of the detail information in each audit record. 
                DisplayAuditDetails(detail);
            }
        }
DisplayAuditDetails (found in CRM SDK and modified a bit)
/// 
        /// Displays audit change history details on the console.
        /// 
        /// 
        private static void DisplayAuditDetails(AuditDetail detail)
        {
            // Write out some of the change history information in the audit record. 
            Entity record = detail.AuditRecord;

            Console.WriteLine("\nAudit record created on: {0}", record["createdon"]);
            Console.WriteLine("Entity: {0}, Action: {1}, Operation: {2}",
                record.LogicalName ,record.FormattedValues["action"],
                record.FormattedValues["operation"]);

            // Show additional details for certain AuditDetail sub-types.
            var detailType = detail.GetType();
            if (detailType == typeof(AttributeAuditDetail))
            {
                var attributeDetail = (AttributeAuditDetail)detail;

                // Display the old and new attribute values.
                foreach (KeyValuePair attribute in attributeDetail.NewValue.Attributes)
                {
                    String oldValue = "(no value)", newValue = "(no value)";

                    //TODO Display the lookup values of those attributes that do not contain strings.
                    if (attributeDetail.OldValue.Contains(attribute.Key))
                        oldValue = attributeDetail.OldValue[attribute.Key].ToString();

                    newValue = attributeDetail.NewValue[attribute.Key].ToString();

                    Console.WriteLine("Attribute: {0}, old value: {1}, new value: {2}",
                        attribute.Key, oldValue, newValue);
                }

                foreach (KeyValuePair attribute in attributeDetail.OldValue.Attributes)
                {
                    if (!attributeDetail.NewValue.Contains(attribute.Key))
                    {
                        String newValue = "(no value)";

                        //TODO Display the lookup values of those attributes that do not contain strings.
                        String oldValue = attributeDetail.OldValue[attribute.Key].ToString();

                        Console.WriteLine("Attribute: {0}, old value: {1}, new value: {2}",
                            attribute.Key, oldValue, newValue);
                    }
                }
            }
            Console.WriteLine();
        }
Result:


Send an E-mail on Account Creates - Plugins - MS Dynamics CRM

/** Send an E-Mail on Account Create using PLUGIN **/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace Email.Account.Create
{
    public class mailtosend : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                Entity account = (Entity)context.InputParameters["Target"];
                Entity email = new Entity("email");
                Entity fromParty = new Entity("activityparty");
                Entity toParty = new Entity("activityparty");
                toParty["partyid"] = new EntityReference("systemuser", context.UserId);
                fromParty["partyid"] = new EntityReference("systemuser", context.UserId);
                email["from"] = new Entity[] { fromParty };
                email["to"] = new Entity[] { toParty };
                email["subject"] = "email subject - " + DateTime.Now.ToString();
                email["description"] = "email description";
                email["regardingobjectid"] = new EntityReference("account", account.Id);
                Guid emailId = service.Create(email);
                SendEmailRequest sendEmailreq = new SendEmailRequest
                {
                    EmailId = emailId,
                    TrackingToken = "",
                    IssueSend = true
                };
                SendEmailResponse sendEmailresp = (SendEmailResponse)service.Execute(sendEmailreq);
            }
        }
    }
}


Retrieving Data using Query by expression in MS CRM

/** Retrieving Data using Query by expression in MS CRM **/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;

namespace estd.crmconnection
{
    class Program
    {
        static IOrganizationService _service;
        public static void Main(string[] args)
        {
            EntityCollection ec = null;
            Guid userid = ((WhoAmIResponse)_service.Execute(new WhoAmIRequest())).UserId;
            if (userid != Guid.Empty)
            {
                Console.WriteLine("connection successfuly established");
                Console.ReadKey();

            }
            Entity contact = new Entity("contact");
            contact.LogicalName = "contact";
            contact.Attributes.Add("firstname", "aa great");
            contact.Attributes.Add("lastname", "superrr");
            contact.Attributes.Add("jobtitle", "senior software engineer");
            _service.Create(contact);



            ec = GetEntityCollection(_service, "contact", "fullname", "Bhoopathi K", new ColumnSet("fullname", "parentcustomerid", "gendercode", "birthdate", "creditlimit", "donotsendmm"));

            if (ec.Entities.Count > 0) //Check for EntityCollection count
            {
                string output = string.Empty;
                foreach (var item in ec.Entities)
                {
                    //String
                    if (item.Attributes.Contains("fullname")) //Check for fullname value exists or not in Entity Collection
                        output += "Full Name : " + item.Attributes["fullname"] + "\n";

                    //Lookup
                    if (item.Attributes.Contains("parentcustomerid")) //Check for parentcustomerid exists or not in Entity Collection
                        output += "Company : " + ((EntityReference)item.Attributes["parentcustomerid"]).Name + "\n";

                    //OptionSet
                    if (item.Attributes.Contains("gendercode")) //Check for gendercode exists or not in Entity Collection
                        output += "Gender : Name - " + item.FormattedValues["gendercode"] + ", Value - " + ((OptionSetValue)item.Attributes["gendercode"]).Value + "\n";

                    //Date
                    if (item.Attributes.Contains("birthdate")) //Check for birthdate exists or not in Entity Collection
                        output += "Birthday : " + ((DateTime)item.Attributes["birthdate"]).ToLocalTime().ToShortDateString().ToString() + "\n";

                    //Currency
                    if (item.Attributes.Contains("creditlimit")) //Check for creditlimit exists or not in Entity Collection
                        output += "Credit Limit : " + ((Money)item.Attributes["creditlimit"]).Value + "\n";

                    //Two Options
                    if (item.Attributes.Contains("donotsendmm")) //Check for donotsendmm exists or not in Entity Collection
                        output += "Send Marketing Materials : Name - " + item.FormattedValues["donotsendmm"] + ", Value - " + ((Boolean)item.Attributes["donotsendmm"]).ToString();

                }
                Console.WriteLine(output);
                Console.ReadKey();
            }
        }
        public static void ConnectToMSCRM(string UserName, string Password, string SoapOrgServiceUri)
        {
            try
            {
                ClientCredentials credentials = new ClientCredentials();
                credentials.UserName.UserName = UserName;
                credentials.UserName.Password = Password;
                Uri serviceUri = new Uri(SoapOrgServiceUri);
                OrganizationServiceProxy proxy = new OrganizationServiceProxy(serviceUri, null, credentials, null);
                proxy.EnableProxyTypes();
                _service = (IOrganizationService)proxy;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error while connecting to CRM " + ex.Message);
                Console.ReadKey();
            }
        }
        private static EntityCollection GetEntityCollection(IOrganizationService service, string entityName, string attributeName, string attributeValue, ColumnSet cols)
        {
            QueryExpression query = new QueryExpression { EntityName = entityName, ColumnSet = cols, Criteria = new FilterExpression { Conditions = { new ConditionExpression { AttributeName = attributeName, Operator = ConditionOperator.Equal, Values = { attributeValue } } } } };
            return service.RetrieveMultiple(query);
        }
    }
}