/// <summary>
        /// Get all items in this appointments folder. Should be called just once (per folder?)
        /// when the add-in starts up; initialises the SyncState list.
        /// </summary>
        /// <param name="appointmentsFolder">The folder to scan.</param>
        protected override void GetOutlookItems(Outlook.MAPIFolder appointmentsFolder)
        {
            try
            {
                foreach (Outlook.AppointmentItem olItem in appointmentsFolder.Items)
                {
                    if (olItem.Start >= this.GetStartDate())
                    {
                        Outlook.UserProperty olPropertyModified = olItem.UserProperties[ModifiedDatePropertyName];
                        Outlook.UserProperty olPropertyType     = olItem.UserProperties[TypePropertyName];
                        Outlook.UserProperty olPropertyEntryId  = olItem.UserProperties[CrmIdPropertyName];
                        if (olPropertyModified != null &&
                            olPropertyType != null &&
                            olPropertyEntryId != null)
                        {
                            /* The appointment probably already has the three magic properties
                             * required for synchronisation; is that a proxy for believing that it
                             * already exists in CRM? If so, is it reliable? */
                            LogItemAction(olItem, "AppointmentSyncing.GetOutlookItems: Adding known item to queue");
                        }
                        else
                        {
                            LogItemAction(olItem, "AppointmentSyncing.GetOutlookItems: Adding unknown item to queue");
                        }

                        this.AddOrGetSyncState(olItem);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("ThisAddIn.GetOutlookCalItems", ex);
            }
        }
Example #2
0
        /// <summary>
        /// Get the CRM id for this item, if known, else the empty string.
        /// </summary>
        /// <param name="olItem">The Outlook item under consideration.</param>
        /// <returns>the CRM id for this item, if known, else the empty string.</returns>
        public static CrmId GetCrmId(this Outlook.ContactItem olItem)
        {
            Outlook.UserProperty property = olItem.UserProperties[SyncStateManager.CrmIdPropertyName];
            CrmId result = property != null?CrmId.Get(property.Value) : CrmId.Empty;

            return(result);
        }
        /// <summary>
        /// Add the item implied by this SyncState, which may not exist in CRM, to CRM.
        /// </summary>
        /// <param name="syncState">The sync state.</param>
        /// <returns>The id of the entry added or updated.</returns>
        internal override string AddOrUpdateItemFromOutlookToCrm(SyncState <Outlook.AppointmentItem> syncState)
        {
            Outlook.AppointmentItem olItem         = syncState.OutlookItem;
            Outlook.UserProperty    olPropertyType = olItem.UserProperties[TypePropertyName];
            var itemType = olPropertyType != null?olPropertyType.Value.ToString() : this.DefaultCrmModule;

            return(this.AddOrUpdateItemFromOutlookToCrm(syncState, itemType, syncState.CrmEntryId));
        }
        /// <summary>
        /// We should delete an item from CRM if it already exists in CRM, but it is now private.
        /// </summary>
        /// <param name="olItem">The Outlook item</param>
        /// <returns>true if the Outlook item should be deleted from CRM.</returns>
        private bool ShouldDeleteFromCrm(Outlook.AppointmentItem olItem)
        {
            Outlook.UserProperty olPropertyEntryId = olItem.UserProperties[CrmIdPropertyName];
            bool result = (olPropertyEntryId != null && olItem.Sensitivity != Outlook.OlSensitivity.olNormal);

            LogItemAction(olItem, $"ShouldDeleteFromCrm returning {result}");

            return(result);
        }
 /// <summary>
 /// Ensure that this Outlook item has a property of this name with this value.
 /// </summary>
 /// <param name="olItem">The Outlook item.</param>
 /// <param name="name">The name.</param>
 /// <param name="value">The value.</param>
 protected override void EnsureSynchronisationPropertyForOutlookItem(Outlook.AppointmentItem olItem, string name, string value)
 {
     try
     {
         Outlook.UserProperty olProperty = olItem.UserProperties[name];
         if (olProperty == null)
         {
             olProperty = olItem.UserProperties.Add(name, Outlook.OlUserPropertyType.olText);
         }
         olProperty.Value = value ?? string.Empty;
     }
     finally
     {
         this.SaveItem(olItem);
     }
 }
 /// <summary>
 /// Log a message regarding this Outlook appointment.
 /// </summary>
 /// <param name="olItem">The outlook item.</param>
 /// <param name="message">The message to be logged.</param>
 internal override void LogItemAction(Outlook.AppointmentItem olItem, string message)
 {
     try
     {
         Outlook.UserProperty olPropertyEntryId = olItem.UserProperties[CrmIdPropertyName];
         string crmId = olPropertyEntryId == null ?
                        "[not present]" :
                        olPropertyEntryId.Value;
         StringBuilder bob = new StringBuilder();
         bob.Append($"{message}:\n\tOutlook Id  : {olItem.EntryID}\n\tCRM Id      : {crmId}\n\tSubject     : '{olItem.Subject}'\n\tSensitivity : {olItem.Sensitivity}\n\tRecipients:\n");
         foreach (Outlook.Recipient recipient in olItem.Recipients)
         {
             bob.Append($"\t\t{recipient.Name}: {recipient.GetSmtpAddress()}\n");
         }
         Log.Info(bob.ToString());
     }
     catch (COMException)
     {
         // Ignore: happens if the outlook item is already deleted.
     }
 }
        /// <summary>
        /// Ensure that this Outlook item has a property of this name with this value.
        /// </summary>
        /// <param name="olItem">The Outlook item.</param>
        /// <param name="name">The name.</param>
        /// <param name="value">The value.</param>
        protected override void EnsureSynchronisationPropertyForOutlookItem(Outlook.AppointmentItem olItem, string name, string value)
        {
            try
            {
                Outlook.UserProperty olProperty = olItem.UserProperties[name];
                if (olProperty == null)
                {
                    olProperty = olItem.UserProperties.Add(name, Outlook.OlUserPropertyType.olText);
                }
                olProperty.Value = value ?? string.Empty;

                Log.Debug($"AppointmentSyncing.EnsureSynchronisationPropertyForOutlookItem: Set property {name} to value {value} on item {olItem.Subject}");
            }
            catch (Exception any)
            {
                Log.Error($"AppointmentSyncing.EnsureSynchronisationPropertyForOutlookItem: Failed to set property {name} to value {value} on item {olItem.Subject}", any);
            }
            finally
            {
                this.SaveItem(olItem);
            }
        }
        /// <summary>
        /// Update an existing Outlook item with values taken from a corresponding CRM item. Note that
        /// this just overwrites all values in the Outlook item.
        /// </summary>
        /// <param name="crmType">The CRM type of the item from which values are to be taken.</param>
        /// <param name="crmItem">The CRM item from which values are to be taken.</param>
        /// <param name="date_start">The state date/time of the item, adjusted for timezone.</param>
        /// <param name="syncState">The outlook item assumed to correspond with the CRM item.</param>
        /// <returns>An appropriate sync state.</returns>
        private SyncState <Outlook.AppointmentItem> UpdateExistingOutlookItemFromCrm(
            string crmType,
            EntryValue crmItem,
            DateTime date_start,
            SyncState <Outlook.AppointmentItem> syncState)
        {
            LogItemAction(syncState.OutlookItem, "AppointmentSyncing.UpdateExistingOutlookItemFromCrm");

            if (!syncState.IsDeletedInOutlook)
            {
                Outlook.AppointmentItem olItem = syncState.OutlookItem;
                Outlook.UserProperty    olPropertyModifiedDate = olItem.UserProperties[ModifiedDatePropertyName];

                if (olPropertyModifiedDate.Value != crmItem.GetValueAsString("date_modified"))
                {
                    try
                    {
                        olItem.Subject = crmItem.GetValueAsString("name");
                        olItem.Body    = crmItem.GetValueAsString("description");
                        if (!string.IsNullOrWhiteSpace(crmItem.GetValueAsString("date_start")))
                        {
                            UpdateOutlookStartAndDuration(crmType, crmItem, date_start, olItem);
                        }

                        EnsureSynchronisationPropertiesForOutlookItem(olItem, crmItem, crmType);
                        LogItemAction(syncState.OutlookItem, "AppointmentSyncing.UpdateExistingOutlookItemFromCrm, item saved");
                    }
                    finally
                    {
                        this.SaveItem(olItem);
                    }
                }
                Log.Warn((string)("Not default dResult.date_modified= " + crmItem.GetValueAsString("date_modified")));
                syncState.OModifiedDate = DateTime.ParseExact(crmItem.GetValueAsString("date_modified"), "yyyy-MM-dd HH:mm:ss", null);
            }

            return(syncState);
        }