/// <summary>
        /// Create an appropriate sync state for an appointment item.
        /// </summary>
        /// <remarks>Outlook items are not true objects and don't have a common superclass,
        /// so we have to use this rather clumsy overloading.</remarks>
        /// <param name="appointment">The item.</param>
        /// <returns>An appropriate sync state, or null if the appointment was invalid.</returns>
        private AppointmentSyncState CreateSyncState(Outlook.AppointmentItem appointment)
        {
            AppointmentSyncState result;

            CrmId crmId = appointment.GetCrmId();

            if (CrmId.IsValid(crmId) && this.byCrmId.ContainsKey(crmId) && this.byCrmId[crmId] != null)
            {
                result = CheckUnexpectedFoundState <Outlook.AppointmentItem, AppointmentSyncState>(appointment, crmId);
            }
            else
            {
                var modifiedDate = ParseDateTimeFromUserProperty(appointment.UserProperties[ModifiedDatePropertyName]);
                if (appointment.IsCall())
                {
                    result = this.SetByOutlookId <AppointmentSyncState>(appointment.EntryID,
                                                                        new CallSyncState(appointment, crmId, modifiedDate));
                }
                else
                {
                    result = this.SetByOutlookId <AppointmentSyncState>(appointment.EntryID,
                                                                        new MeetingSyncState(appointment, crmId, modifiedDate));
                }
                this.byGlobalId[appointment.GlobalAppointmentID] = result;
            }

            if (result != null && CrmId.IsValid(crmId))
            {
                this.byCrmId[crmId] = result;
            }

            return(result);
        }
        /// <summary>
        /// Get the existing sync state for this item, if it exists and is of the appropriate
        /// type, else null.
        /// </summary>
        /// <remarks>Outlook items are not true objects and don't have a common superclass,
        /// so we have to use this rather clumsy overloading.</remarks>
        /// <param name="appointment">The item.</param>
        /// <returns>The appropriate sync state, or null if none.</returns>
        /// <exception cref="UnexpectedSyncStateClassException">if the sync state found is not of the expected class (shouldn't happen).</exception>
        public AppointmentSyncState GetSyncState(Outlook.AppointmentItem appointment)
        {
            SyncState result;

            try
            {
                result = (appointment.IsValid() && this.byOutlookId.ContainsKey(appointment.EntryID)) ? this.byOutlookId[appointment.EntryID] : null;
                CrmId crmId = result == null?appointment.GetCrmId() : CheckForDuplicateSyncState(result, appointment.GetCrmId());

                if (CrmId.IsValid(crmId))
                {
                    if (result == null && this.byCrmId.ContainsKey(crmId))
                    {
                        result = this.byCrmId[crmId];
                    }
                    else if (result != null && this.byCrmId.ContainsKey(crmId) == false)
                    {
                        this.byCrmId[crmId] = result;
                        result.CrmEntryId   = crmId;
                    }
                }

                if (result != null && !(result is AppointmentSyncState))
                {
                    throw new UnexpectedSyncStateClassException("AppointmentSyncState", result);
                }
            }
            catch (COMException)
            {
                // dead item passed.
                result = null;
            }

            return(result as AppointmentSyncState);
        }
Exemple #3
0
        /// <summary>
        /// Create a new instance of ProtoAppointment, taking values from this Outlook item.
        /// </summary>
        /// <param name="olItem">The Outlook item to take values from.</param>
        public ProtoAppointment(Outlook.AppointmentItem olItem) : base(olItem.MeetingStatus)
        {
            this.olItem     = olItem;
            this.body       = olItem.Body;
            this.CrmEntryId = olItem.GetCrmId();
            this.duration   = olItem.Duration;
            this.end        = olItem.End;
            this.location   = olItem.Location;
            this.start      = olItem.Start;
            this.subject    = olItem.Subject;
            this.globalId   = olItem.GlobalAppointmentID;

            var organiserProperty = olItem.UserProperties[AppointmentsSynchroniser <SyncStateType> .OrganiserPropertyName];

            if (organiserProperty == null || string.IsNullOrWhiteSpace(organiserProperty.Value))
            {
                if (olItem.Organizer == Globals.ThisAddIn.Application.GetCurrentUsername())
                {
                    this.organiser = CrmId.Get(RestAPIWrapper.GetUserId());
                }
                else
                {
                    this.organiser = TryResolveOrganiser(olItem);
                }
            }
            else
            {
                this.organiser = CrmId.Get(organiserProperty.Value.ToString());
            }

            foreach (Outlook.Recipient recipient in olItem.Recipients)
            {
                this.recipientAddresses.Add(recipient.GetSmtpAddress());
            }
        }
Exemple #4
0
        /// <summary>
        /// Set the meeting acceptance status, in CRM, for this invitee to this meeting from
        /// their acceptance status in Outlook.
        /// </summary>
        /// <param name="meeting">The appointment item representing the meeting</param>
        /// <param name="invitee">The recipient item representing the invitee</param>
        /// <param name="acceptance">The acceptance status of this invitee of this meeting
        /// as a string recognised by CRM.</param>
        ///
        private int AddOrUpdateMeetingAcceptanceFromOutlookToCRM(Outlook.AppointmentItem meeting, Outlook.Recipient invitee, string acceptance)
        {
            int    count       = 0;
            string smtpAddress = invitee.GetSmtpAddress();
            var    meetingId   = meeting.GetCrmId();

            if (meetingId != null &&
                !string.IsNullOrEmpty(acceptance) &&
                SyncDirection.AllowOutbound(this.Direction))
            {
                foreach (AddressResolutionData resolution in this.ResolveRecipient(meeting, invitee))
                {
                    try
                    {
                        RestAPIWrapper.SetMeetingAcceptance(meetingId.ToString(), resolution.ModuleName, resolution.ModuleId.ToString(), acceptance);
                        count++;
                    }
                    catch (System.Exception any)
                    {
                        ErrorHandler.Handle($"Failed to resolve meeting invitee {smtpAddress}:", any);
                    }
                }
            }

            return(count);
        }
Exemple #5
0
        /// <summary>
        /// Find all CRM records related to this recipient of this meeting, and produce address
        /// resolution data from them.
        /// </summary>
        /// <param name="olItem">An appointment, assumed to be a meeting.</param>
        /// <param name="recipient">A recipient of that meeting request.</param>
        /// <returns>A list of address resolution objects.</returns>
        private List <AddressResolutionData> ResolveRecipient(Outlook.AppointmentItem olItem, Outlook.Recipient recipient)
        {
            List <AddressResolutionData> result = new List <AddressResolutionData>();
            var smtpAddress = recipient.GetSmtpAddress();

            Log.Info($"recepientName= {recipient.Name}, recepient= {smtpAddress}");

            if (this.meetingRecipientsCache.ContainsKey(smtpAddress))
            {
                result.AddRange(meetingRecipientsCache[smtpAddress]);
            }
            else
            {
                CrmId meetingId = olItem.GetCrmId();
                Dictionary <string, CrmId> moduleIds = new Dictionary <string, CrmId>();

                if (CrmId.IsValid(meetingId))
                {
                    foreach (string moduleName in new string[] { "Leads", "Users", ContactSynchroniser.CrmModule })
                    {
                        CrmId moduleId = this.GetInviteeIdBySmtpAddress(smtpAddress, moduleName);
                        if (CrmId.IsValid(moduleId))
                        {
                            moduleIds[moduleName] = moduleId;
                            AddressResolutionData data = new AddressResolutionData(moduleName, moduleId, smtpAddress);
                            this.CacheAddressResolutionData(data);
                            result.Add(data);
                        }
                    }

                    if (moduleIds.ContainsKey(ContactSynchroniser.CrmModule))
                    {
                        CrmId accountId = CrmId.Get(RestAPIWrapper.GetRelationship(
                                                        ContactSynchroniser.CrmModule,
                                                        moduleIds[ContactSynchroniser.CrmModule].ToString(),
                                                        "accounts"));

                        if (CrmId.IsValid(accountId) &&
                            SetCrmRelationshipFromOutlook(this, meetingId, "Accounts", accountId))
                        {
                            var data = new AddressResolutionData("Accounts", accountId, smtpAddress);
                            this.CacheAddressResolutionData(data);
                            result.Add(data);
                        }
                    }
                }
            }

            return(result);
        }