Tuesday, 5 March 2013

CRM 2011 Date Only Issue Plugin

As explained quite well in Kelvin's blog, CRM 2011 handles Date Only fields in a strange way.  So I have developed a plugin that will get round this.

The code for this is below and it should be deployed pre validation for the entities you wish to use it with, create or update.


/// <summary>
/// Fix for getting round the timezone issues with date only fields
/// </summary>
public class TimeZoneFix : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        //Get an instance of the helper class.
        PluginHelper helper = new PluginHelper(serviceProvider);
        helper.tracer.Trace("Loaded Helper");
        if (helper.targetEntity.Attributes.Any(a => a.Value != null && a.Value.GetType() == typeof(DateTime)))
        {
            IOrganizationService service = helper.service;
            helper.tracer.Trace("Building Request");
            RetrieveEntityRequest request = new RetrieveEntityRequest();
            request.LogicalName = helper.context.PrimaryEntityName;
            request.EntityFilters = EntityFilters.Attributes;
            RetrieveEntityResponse response =  (RetrieveEntityResponse)service.Execute(request);
            if (response != null && response.EntityMetadata != null)
            {
                List<KeyValuePair<string, object>> attribs = helper.targetEntity.Attributes.Where(a => a.Value != null && a.Value.GetType() == typeof(DateTime)).ToList();
                foreach (var att in attribs)
                {
                    DateTime date = (DateTime)helper.targetEntity[att.Key];
                    DateTime localDate = date.ToLocalTime();
                    TimeSpan dateDiff = localDate - date;
                    //Get the attribute metadata
                    AttributeMetadata meta = response.EntityMetadata.Attributes.FirstOrDefault(am => am.LogicalName.ToLower().Equals(att.Key));
                    //Check in the attribute metadata if the attribute is a date only.
                    if (meta != null && meta.AttributeType != null &&
                        meta.AttributeType == AttributeTypeCode.DateTime &&
                        ((DateTimeAttributeMetadata)meta).Format == DateTimeFormat.DateOnly)
                    {
                        helper.targetEntity[att.Key] = localDate.AddHours(dateDiff.Hours + 10);
                    }
                }
            }
        }
    }
}