Dynamics CRM 2013 Server Side Sync - Auto-answer scheduling conflict alerts

Imagine the following scenario in CRM 2013 Service Pack 1:

You use server side synchronization to keep all your appointments, contacts and tasks in sync with your Exchange mailbox. To track appointments from Outlook to Exchange you use the Dynamics CRM 2013 Outlook Client.

You create a meeting which spans over several days (a business trip) and track it in CRM.

Then, you create another appointment which takes place during the business trip (a meeting with a customer) and track it in CRM.

 

When you try to see the appointment in CRM, you notice that it is not there, instead you get an alert telling you that there is a scheduling conflict and you have to allow CRM to ignore the conflict and create the appointment.

A scheduling conflict was found when saving the appointment “test” from Exchange to Microsoft Dynamics CRM because Smith, John is unavailable at this time. Do you want to ignore the conflict and save anyway?

image

Here is a short description of the process and how you can auto-answer the alerts by using a plugin:

 

1. When a conflict appears, records are created in the TraceLog and the ExchangeSyncIdMapping entities.

a. The record in the TraceLog has some special values:

TraceActionXml with a value like the following, where the “oid” is the ExchangeSyncIdMappingId

<actions>

<action type="0"><param name="oid">{da4bc81b-d797-e411-b8e8-00155d17bf0c}</param></action>

<action type="1"><param name="oid">{da4bc81b-d797-e411-b8e8-00155d17bf0c}</param></action>

</actions>

CanBeDeleted = 0 (The alerts are persistent in the Alert wall, until an option Yes/No is selected by the user.

TraceCode = 101 (ExchangeSyncSchedulingConflictsError)

 

b. The record in the ExchangeSyncIdMapping is created with the ObjectId field set to 00000000-0000-0000-0000-000000000000.

image

 

UserDecision has the following possible values:

NotApplicable = –1

NotDecided = 0

Confirm = 1

Deny = 2

ObjectId is filled in when the Activity is created (after the user accepts the conflict).

 

2. When the conflict is confirmed, there are 2 main operations:

a. The TraceLog record is deleted.

b. The UserDecision value for the ExchangeSyncIdMapping record is set to 1.

c. The activity record is not immediately created, instead it is created during the next synchronization cycle.

 

3. Therefore, to automatically “accept” the scheduling conflict you can create a plugin which simply changes the UserDecision value to 1 and the TraceLog|CanBeDeleted value to 1, so the conflict alerts can be deleted together with the rest of the alerts of a mailbox.

image

 

image

public class TraceLogPlugin: IPlugin

    {

/// <summary>

/// </summary>

/// <remarks>Register this plug-in on the Create message, and pre-operation stage.

/// </remarks>

public void Execute(IServiceProvider serviceProvider)

        {

// Obtain the execution context from the service provider.

            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)

                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

// The InputParameters collection contains all the data passed in the message request.

if (context.InputParameters.Contains("Target") &&

                context.InputParameters["Target"] is Entity)

            {

Entity entity = (Entity)context.InputParameters["Target"];

if (entity.LogicalName == "exchangesyncidmapping")

                {

if ((int)entity.Attributes["userdecision"] == 0 && (int)entity.Attributes["lastsyncerrorcode"] == 101)

                    {

                        entity.Attributes["userdecision"] = 1;

                    }

else

                    {

throw new InvalidPluginExecutionException("not working");

                    }

                }

if (entity.LogicalName == "tracelog")

                {

if ( (int)entity.Attributes["tracecode"] == 101)

                    {

                        entity.Attributes["canbedeleted"] = true;

                    }

else

                    {

throw new InvalidPluginExecutionException("not working");

                    }

                }

            }

        }

    }

Best Regards

EMEA Dynamics CRM Support Team

 

Share this Blog Article on Twitter

Tweet

Follow Us on Twitter

Follow @MSDynCRMSupport