Tuesday, February 21, 2012

Get the Entity Data based on user time zone

If your CRM application is used by multinational users, and if you have custom web pages or any client applications, you have to make sure you show the date and time with the user's time zone, rather than just showing the value you get by retrieving from the CRM Service.
I have below described an easier method to do so.

First we have to get the current user's time zone.
And then let's retrieve the entity object from the CRM Service.
Then we can call our method that will adjust all the DateTime properties in the CRM entity.
public partial class SystemUser
{
    RetrieveUserSettingsSystemUserResponse userSettingsSystemUserResponse;

    /// 
    /// Initialize RetrieveUserSettingsSystemUserResponse
    /// 
    private void InitializeUserSettings()
    {
        if (this.Id != Guid.Empty)
        {
            RetrieveUserSettingsSystemUserRequest userSettingsSystemUserRequest = 
                new RetrieveUserSettingsSystemUserRequest { 
                  RequestId = this.Id,  ColumnSet = new ColumnSet(true),  EntityId = this.Id };

            userSettingsSystemUserResponse = (RetrieveUserSettingsSystemUserResponse)CrmServiceManager
                          .GetService(this.Id).Execute(userSettingsSystemUserRequest);
        }
    }

    /// 
    /// Get a date and returns it back adjusting TimeZone difference
    /// 
    public DateTime GetUserTimeZoneBasedDateTime(DateTime dateTime)
    {
        if (this.Id != Guid.Empty)
        {
            if (userSettingsSystemUserResponse == null)
            {
                InitializeUserSettings();
            }

            if (userSettingsSystemUserResponse != null 
                && userSettingsSystemUserResponse.Results != null 
                && userSettingsSystemUserResponse.Results.Count > 0)
            {
                return dateTime.AddMinutes(
                     ((UserSettings)userSettingsSystemUserResponse.Entity).TimeZoneBias * -1);                    
            }                
        }

        return dateTime;
    }
        
    /// 
    /// Get the Entity and returns it back adjusting TimeZone difference
    /// 
    public T GetEntityWithUserTimeZoneBasedDateTime<t>(T t) where T : Entity
    {
        if (t != null)
        {
            Dictionary<string, Datetime> changedDateTimeDictionary = new Dictionary<string, Datetime>();
            foreach (var attribute in t.Attributes)
            {
                if (attribute.Value is DateTime)
                {
                    changedDateTimeDictionary.Add(
                         attribute.Key, GetUserTimeZoneBasedDateTime((DateTime)attribute.Value));
                }
            }

            foreach (var item in changedDateTimeDictionary)
            {
                t.Attributes[item.Key] = item.Value;
            }
        }

        return t;            
    }
And now you can call the method as below

Guid currentUser = //Set the current user

//Get the record from CRM Service using any convinient method
Account account = new CommonFacade().Get<account>(accountId);

//Pass the retrieved object and with the current user
//That adjust the all DateTime properties in the object
//And reassigned it before displaying the entity

account = new SystemUser {Id = currentUser }.GetEntityWithUserTimeZoneBasedDateTime<account>(account);

//Now you can use the object to any display purposed
//Example
accountCreatedOnLabel.Text = account.createdOn.ToString();

Monday, February 13, 2012

Error: You do not have the necessary permissions to change the domain logon name for this user

You may get an error called "You do not have the necessary permissions to change the domain logon name for this user" when you deploy you plugin to CRM Server in CRM 2011 and when it was triggered. Then you should check whether the plugin is a synchronous plugin or an asynchronous plugin.
If it is a synchronous plugin, means that this error occurs through IIS. And if this plugin is a asynchronous plugin, means that this error occurs through Microsoft Dynamics CRM Asynchronous Processing Service.

1. If it a synchronous plugin(means that this error occurs through IIS)
Check the 'CRMAppPool' running user

Add the Local Administrator Role to the user


Finally do not forget to reset IIS.

2. If it a asynchronous plugin(means that this error occurs through Microsoft Dynamics CRM Asynchronous Processing Service)

Navigate to the Service and check the service running user


Add the Local Administrator Role to the user


Finally do not forget to reset IIS.

Thursday, February 9, 2012

Sending Emails using SendEmailRequest

When you want to send emails through CRM 2011, it is important to set the IssueSend boolean field explicitly.
Because the default value is false, and if the value is false, CRM marks the email as 'Sent' but CRM 2011 does not send the email. So if you want to fire the email to end user, you must set the IssueSend field to true

1. Method 01
//The below code will mark as the email as 'Sent' but CRM 2011 will not send the email to the relevant user
SendEmailRequest sendEmailRequest = new SendEmailRequest { EmailId = emailId, TrackingToken = ""};
2. Method 02
//The below code will mark as the email as 'Sent' but CRM 2011 will not send the email to the relevant user
SendEmailRequest sendEmailRequest = new SendEmailRequest { EmailId = emailId, TrackingToken = "", IssueSend = false};
3. Method 03
//The below code will attempt to send the email to the relevant user
//And if it success, CRM 2011 will mark the email as Sent
SendEmailRequest sendEmailRequest = new SendEmailRequest { EmailId = emailId, TrackingToken = "", IssueSend = true};