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)
     });
 }
Пример #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);
        }
Пример #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());
            }
        }
        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));
            }
        }
Пример #5
0
        /// <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);
        }
Пример #7
0
 /// <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())
     });
 }
Пример #8
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.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));
        }
Пример #12
0
        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();
            }
        }
Пример #14
0
        /// <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;
 }
Пример #16
0
        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;
            }
        }
Пример #17
0
 public DuplicateCrmIdException(SyncState syncState, CrmId id) : base($"Shouldn't happen: more than one Outlook object with CRM id '{id}' ({syncState.Description})")
 {
 }