public override NameValueCollection AsNameValues() { return(new NameValueCollection { RestAPIWrapper.SetNameValuePair("email1", Email1Address), RestAPIWrapper.SetNameValuePair("title", JobTitle), RestAPIWrapper.SetNameValuePair("phone_work", BusinessTelephoneNumber), RestAPIWrapper.SetNameValuePair("phone_home", HomeTelephoneNumber), RestAPIWrapper.SetNameValuePair("phone_mobile", MobileTelephoneNumber), RestAPIWrapper.SetNameValuePair("phone_fax", BusinessFaxNumber), RestAPIWrapper.SetNameValuePair("department", Department), RestAPIWrapper.SetNameValuePair("primary_address_city", BusinessAddressCity), RestAPIWrapper.SetNameValuePair("primary_address_state", BusinessAddressState), RestAPIWrapper.SetNameValuePair("primary_address_postalcode", BusinessAddressPostalCode), RestAPIWrapper.SetNameValuePair("primary_address_country", BusinessAddressCountry), RestAPIWrapper.SetNameValuePair("primary_address_street", BusinessAddressStreet), RestAPIWrapper.SetNameValuePair("description", Body), RestAPIWrapper.SetNameValuePair("last_name", LastName), RestAPIWrapper.SetNameValuePair("first_name", FirstName), RestAPIWrapper.SetNameValuePair("account_name", CompanyName), RestAPIWrapper.SetNameValuePair("salutation", Title), CrmId.IsValid(CrmEntryId) ? RestAPIWrapper.SetNameValuePair("id", CrmEntryId.ToString()) : RestAPIWrapper.SetNameValuePair("assigned_user_id", RestAPIWrapper.GetUserId()), RestAPIWrapper.SetNameValuePair("sync_contact", this.isPublic) }); }
/// <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> /// 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()); } }
private void ProcessNewMeetingItem(Outlook.MeetingItem meetingItem) { string vCalId = meetingItem.GetVCalId(); if (CrmId.IsValid(vCalId) && RestAPIWrapper.GetEntry(MeetingsSynchroniser.DefaultCrmModule, vCalId, new string[] { "id" }) != null) { meetingItem.GetAssociatedAppointment(false).SetCrmId(CrmId.Get(vCalId)); } }
/// <summary> /// AsNameValues is used in transmission to CRM as well as for comparison, so it should NOT /// access our cache of recipient addresses. /// </summary> /// <returns>A set of name/value pairs suitable for transmitting to CRM.</returns> public override NameValueCollection AsNameValues() { string statusString; string name; switch (this.Status) { case Outlook.OlMeetingStatus.olMeetingCanceled: statusString = "Not Held"; name = this.subject.StartsWith(CancelledPrefix) ? this.subject : $"{CancelledPrefix}: {this.subject}"; break; default: statusString = this.start < DateTime.Now ? "Held" : "Planned"; name = this.subject; break; } NameValueCollection data = new NameValueCollection { RestAPIWrapper.SetNameValuePair("name", name), RestAPIWrapper.SetNameValuePair("description", this.body), RestAPIWrapper.SetNameValuePair("location", this.location), RestAPIWrapper.SetNameValuePair("date_start", string.Format("{0:yyyy-MM-dd HH:mm:ss}", this.start.ToUniversalTime())), RestAPIWrapper.SetNameValuePair("date_end", string.Format("{0:yyyy-MM-dd HH:mm:ss}", this.end.ToUniversalTime())), RestAPIWrapper.SetNameValuePair("duration_minutes", (this.duration % 60).ToString()), RestAPIWrapper.SetNameValuePair("duration_hours", (this.duration / 60).ToString()), RestAPIWrapper.SetNameValuePair("outlook_id", this.globalId), RestAPIWrapper.SetNameValuePair("status", statusString) }; if (CrmId.IsValid(this.organiser)) { data.Add(RestAPIWrapper.SetNameValuePair("assigned_user_id", this.organiser.ToString())); } if (CrmId.IsInvalid(CrmEntryId)) { /* A Guid can be constructed from a 32 digit hex string. The globalId is a * 112 digit hex string. It appears from inspection that the least significant * bytes are those that vary between examples, with the most significant bytes * being invariant in the samples we have to hand. */ CrmEntryId = CrmId.Get(new Guid(this.globalId.Substring(this.globalId.Length - 32))); data.Add(RestAPIWrapper.SetNameValuePair("new_with_id", true)); } data.Add(RestAPIWrapper.SetNameValuePair("id", CrmEntryId.ToString())); return(data); }
public override string Perform() { string result; /* #223: ensure that the state has a crmId that is null or empty. * If not null or empty then this is not a new item: do nothing and exit. */ if (CrmId.IsInvalid(syncState.CrmEntryId)) { if (syncState.TxState == TransmissionState.Queued) { try { CrmId returnedCrmId = this.synchroniser.AddOrUpdateItemFromOutlookToCrm(syncState); result = $"synced new item as {returnedCrmId}.\n\t{syncState.Description}"; } catch (WebException wex) { if (wex.Status == WebExceptionStatus.ProtocolError) { using (HttpWebResponse response = wex.Response as HttpWebResponse) { switch (response.StatusCode) { case HttpStatusCode.RequestTimeout: case HttpStatusCode.ServiceUnavailable: throw new ActionRetryableException($"Temporary error ({response.StatusCode})", wex); default: throw new ActionFailedException($"Permanent error ({response.StatusCode})", wex); } } } else { throw new ActionRetryableException("Temporary network error", wex); } } } else { result = $"State is {syncState.TxState}; not retransmitting"; } } else { result = $"item was already synced as {syncState.CrmEntryId}; aborted.\n{this.syncState.Description}"; } return(result); }
/// <summary> /// Construct a name value list (to be serialised as JSON) representing this task. /// </summary> /// <returns>a name value list representing this task</returns> public override NameValueCollection AsNameValues() { return(new NameValueCollection { RestAPIWrapper.SetNameValuePair("name", this.subject), RestAPIWrapper.SetNameValuePair("description", this.description), RestAPIWrapper.SetNameValuePair("status", this.taskStatus), RestAPIWrapper.SetNameValuePair("date_due", this.dateDue), RestAPIWrapper.SetNameValuePair("date_start", this.dateStart), RestAPIWrapper.SetNameValuePair("priority", this.priority), CrmId.IsValid(crmEntryId) ? RestAPIWrapper.SetNameValuePair("id", crmEntryId.ToString()) : RestAPIWrapper.SetNameValuePair("assigned_user_id", RestAPIWrapper.GetUserId()) }); }
/// <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.TaskItem olItem) { Outlook.UserProperty property = olItem.UserProperties[SyncStateManager.CrmIdPropertyName]; if (property == null) { /* #6661: fail over to legacy property name if current property * name not found */ property = olItem.UserProperties[SyncStateManager.LegacyCrmIdPropertyName]; } CrmId result = property != null?CrmId.Get(property.Value) : CrmId.Empty; return(result); }
/// <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.AppointmentItem olItem) { string result; Outlook.UserProperty property = olItem.UserProperties[SyncStateManager.CrmIdPropertyName]; if (property != null && !string.IsNullOrEmpty(property.Value)) { result = property.Value; } else { result = olItem.GetVCalId(); } return(CrmId.Get(result)); }
/// <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.TaskItem olItem) { string result; Outlook.UserProperty property = olItem.UserProperties[SyncStateManager.CrmIdPropertyName]; if (property != null) { result = property.Value; } else { result = string.Empty; } return(CrmId.Get(result)); }
/// <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 null.</returns> public static CrmId GetCrmId(this Outlook.AppointmentItem olItem) { string result; if (olItem.IsValid()) { try { Outlook.UserProperty property = olItem.UserProperties[SyncStateManager.CrmIdPropertyName]; if (property == null) { /* #6661: fail over to legacy property name if current property * name not found */ property = olItem.UserProperties[SyncStateManager.LegacyCrmIdPropertyName]; } if (property != null && !string.IsNullOrEmpty(property.Value)) { result = property.Value; } else { result = olItem.GetVCalId(); } } catch (COMException) { /* this is bad! It shouldn't be possible to get here, but * it is. */ try { result = olItem.GetVCalId(); } catch (COMException) { result = null; } } } else { result = null; } return(CrmId.Get(result)); }
public static void ChangeCrmId(this Outlook.ContactItem olItem, string text) { var crmId = new CrmId(text); var state = SyncStateManager.Instance.GetExistingSyncState(olItem); var userProperty = olItem.UserProperties.Find(SyncStateManager.CrmIdPropertyName) ?? olItem.UserProperties.Add(SyncStateManager.CrmIdPropertyName, Outlook.OlUserPropertyType.olText); userProperty.Value = crmId.ToString(); if (state != null) { state.CrmEntryId = crmId; } olItem.Save(); }
/// <summary> /// Set the CRM id for this item to this value. /// </summary> /// <param name="olItem">The Outlook item under consideration.</param> /// <param name="crmId">The value to set.</param> public static void SetCrmId(this Outlook.AppointmentItem olItem, CrmId crmId) { Outlook.UserProperty property = olItem.UserProperties[SyncStateManager.CrmIdPropertyName]; if (property == null) { property = olItem.UserProperties.Add(SyncStateManager.CrmIdPropertyName, Outlook.OlUserPropertyType.olText); SyncStateManager.Instance.SetByCrmId(crmId, SyncStateManager.Instance.GetOrCreateSyncState(olItem)); } if (CrmId.IsInvalid(crmId)) { property.Delete(); } else { property.Value = crmId.ToString(); } }
/// <summary> /// Try to resolve the organiser of this Outlook Item against the users of the CRM. /// </summary> /// <param name="olItem">The Outlook item representing a meeting.</param> /// <returns>The id of the related user if any, else the empty string.</returns> public static CrmId TryResolveOrganiser(Outlook.AppointmentItem olItem) { CrmId result = CrmId.Empty; string organiser = olItem.Organizer; try { if (organiser.IndexOf('@') > -1) { foreach (string pattern in new string[] { @".*<(.+@.+)>", @".+@.+" }) { Match match = Regex.Match(organiser, pattern, RegexOptions.IgnoreCase); if (match.Success) { string address = match.Groups[0].Value; try { result = CrmId.Get(RestAPIWrapper.GetUserId(new MailAddress(address))); } catch (FormatException) { // not a valid email address - no matter. } } } } else { result = CrmId.Get(RestAPIWrapper.GetUserId(organiser)); } } catch (Exception any) { ErrorHandler.Handle($"Failed to resolve organiser `{olItem.Organizer}` of meeting `{olItem.Subject}`", any); } return(result); }
public ProtoContact(Outlook.ContactItem olItem) { this.Body = olItem.Body; this.BusinessAddressCity = olItem.BusinessAddressCity; this.BusinessAddressCountry = olItem.BusinessAddressCountry; this.BusinessAddressPostalCode = olItem.BusinessAddressPostalCode; this.BusinessAddressState = olItem.BusinessAddressState; this.BusinessAddressStreet = olItem.BusinessAddressStreet; this.BusinessFaxNumber = olItem.BusinessFaxNumber; this.BusinessTelephoneNumber = olItem.BusinessTelephoneNumber; this.CompanyName = olItem.CompanyName; this.Department = olItem.Department; this.Email1Address = olItem.Email1Address; this.CrmEntryId = olItem.GetCrmId(); this.FirstName = olItem.FirstName; this.HomeTelephoneNumber = olItem.HomeTelephoneNumber; this.JobTitle = olItem.JobTitle; this.LastName = olItem.LastName; this.MobileTelephoneNumber = olItem.MobileTelephoneNumber; this.Title = olItem.Title; this.isPublic = olItem.Sensitivity == Microsoft.Office.Interop.Outlook.OlSensitivity.olNormal; }
public ProtoTask(Outlook.TaskItem oItem) { this.oItem = oItem; this.subject = this.oItem.Subject; this.crmEntryId = oItem.GetCrmId(); if (oItem.Body != null) { body = oItem.Body; var times = ParseTimesFromTaskBody(body); if (times != null) { DateTime utcStart = oItem.StartDate.ToUniversalTime(); DateTime utcDue = new DateTime(); if (oItem.DueDate.ToUniversalTime() > DateTime.MinValue && oItem.DueDate.ToUniversalTime() < DateTime.MaxValue) { utcDue = oItem.DueDate.ToUniversalTime(); } utcDue = utcDue.Add(times[1]); //check max date, date must has value ! if (utcStart.ToUniversalTime().Year < 4000) { dateStart = string.Format("{0:yyyy-MM-dd HH:mm:ss}", utcStart.ToUniversalTime()); } if (utcDue.ToUniversalTime().Year < 4000) { dateDue = string.Format("{0:yyyy-MM-dd HH:mm:ss}", utcDue.ToUniversalTime()); } } else { this.TakePeriodFromOutlookItem(); } } else { this.TakePeriodFromOutlookItem(); } if (!string.IsNullOrEmpty(body)) { int lastIndex = body.LastIndexOf("#<"); if (lastIndex >= 0) { description = body.Remove(lastIndex); } else { description = body; } } switch (oItem.Status) { case Outlook.OlTaskStatus.olTaskNotStarted: taskStatus = "Not Started"; break; case Outlook.OlTaskStatus.olTaskInProgress: taskStatus = "In Progress"; break; case Outlook.OlTaskStatus.olTaskComplete: taskStatus = "Completed"; break; case Outlook.OlTaskStatus.olTaskDeferred: taskStatus = "Deferred"; break; default: taskStatus = string.Empty; break; } switch (oItem.Importance) { case Outlook.OlImportance.olImportanceLow: priority = "Low"; break; case Outlook.OlImportance.olImportanceNormal: priority = "Medium"; break; case Outlook.OlImportance.olImportanceHigh: priority = "High"; break; default: priority = string.Empty; break; } }
public DuplicateCrmIdException(SyncState syncState, CrmId id) : base($"Shouldn't happen: more than one Outlook object with CRM id '{id}' ({syncState.Description})") { }