/// <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); }
/// <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()); } }
/// <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); }
/// <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); }