/// <summary> /// Merges the recurrence. /// </summary> /// <param name="outlookCalendarItem">The outlook calendar item.</param> /// <param name="recurrence">The recurrence.</param> /// <returns>True if Change.</returns> public static bool MergeRecurrence(this AppointmentItem outlookCalendarItem, Recurrence recurrence) { if (recurrence != null && !string.IsNullOrWhiteSpace(recurrence.Value)) { var result = false; var outlookRecurrencePattern = outlookCalendarItem.GetRecurrencePattern(); var googleRecurrencePattern = RecurrenceSerializer.Deserialize(recurrence.Value); try { result |= outlookCalendarItem.ApplyProperty(r => r.AllDayEvent, googleRecurrencePattern.AllDayEvent); } catch (TargetInvocationException) { } result |= outlookRecurrencePattern.ApplyProperty(r => r.RecurrenceType, googleRecurrencePattern.RecurrenceType); result |= outlookRecurrencePattern.ApplyProperty(r => r.PatternStartDate, googleRecurrencePattern.StartPattern.HasValue ? googleRecurrencePattern.StartPattern.Value.Date : DateTime.Today); if (googleRecurrencePattern.EndPattern.HasValue) { result |= outlookRecurrencePattern.ApplyProperty(r => r.PatternEndDate, googleRecurrencePattern.EndPattern.Value.Date); } else { result |= outlookRecurrencePattern.ApplyProperty(r => r.NoEndDate, true); } result |= outlookRecurrencePattern.ApplyProperty(r => r.DayOfMonth, googleRecurrencePattern.DayOfMonth); result |= outlookRecurrencePattern.ApplyProperty(r => r.DayOfWeekMask, googleRecurrencePattern.DayOfWeek); result |= outlookRecurrencePattern.ApplyProperty(r => r.MonthOfYear, googleRecurrencePattern.MonthOfYear); if (outlookRecurrencePattern.StartTime.TimeOfDay.Ticks != googleRecurrencePattern.StartTime.TimeOfDay.Ticks) { result |= outlookRecurrencePattern.ApplyProperty(r => r.StartTime, googleRecurrencePattern.StartTime); } if (outlookRecurrencePattern.EndTime.TimeOfDay.Ticks != googleRecurrencePattern.EndTime.TimeOfDay.Ticks) { result |= outlookRecurrencePattern.ApplyProperty(r => r.EndTime, googleRecurrencePattern.EndTime); } if (googleRecurrencePattern.Count.HasValue) { result |= outlookRecurrencePattern.ApplyProperty(r => r.Occurrences, googleRecurrencePattern.Count.Value); } if (googleRecurrencePattern.Interval.HasValue) { result |= outlookRecurrencePattern.ApplyProperty(r => r.Interval, googleRecurrencePattern.Interval.Value); } return(result); } if (outlookCalendarItem.RecurrenceState == OlRecurrenceState.olApptNotRecurring) { outlookCalendarItem.ClearRecurrencePattern(); return(true); } return(false); }
public AppointmentItem UpdateCalendarEntry(AppointmentItem ai, Event ev, ref int itemModified, Boolean forceCompare = false) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) //The exception child objects might have changed { log.Debug("Processing recurring master appointment."); } else { if (!forceCompare) //Needed if the exception has just been created, but now needs updating { if (Settings.Instance.SyncDirection != SyncDirection.Bidirectional) { if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated)) { return(null); } } else { if (GoogleCalendar.OGCSlastModified(ev).AddSeconds(5) >= DateTime.Parse(ev.Updated)) { //Google last modified by OGCS return(null); } if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated)) { return(null); } } } } String evSummary = GoogleCalendar.GetEventSummary(ev); log.Debug("Processing >> " + evSummary); System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.AppendLine(evSummary); RecurrencePattern oPattern = (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring) ? null : ai.GetRecurrencePattern(); if (ev.Start.Date != null) { if (ai.RecurrenceState != OlRecurrenceState.olApptMaster) { ai.AllDayEvent = true; } if (MainForm.CompareAttribute("Start time", SyncDirection.GoogleToOutlook, ev.Start.Date, ai.Start.ToString("yyyy-MM-dd"), sb, ref itemModified)) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { oPattern.PatternStartDate = DateTime.Parse(ev.Start.Date); } else { ai.Start = DateTime.Parse(ev.Start.Date); } } if (MainForm.CompareAttribute("End time", SyncDirection.GoogleToOutlook, ev.End.Date, ai.End.ToString("yyyy-MM-dd"), sb, ref itemModified)) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { oPattern.PatternEndDate = DateTime.Parse(ev.End.Date); } else { ai.End = DateTime.Parse(ev.End.Date); } } } else { if (ai.RecurrenceState != OlRecurrenceState.olApptMaster) { ai.AllDayEvent = false; } if (MainForm.CompareAttribute("Start time", SyncDirection.GoogleToOutlook, GoogleCalendar.GoogleTimeFrom(DateTime.Parse(ev.Start.DateTime)), GoogleCalendar.GoogleTimeFrom(ai.Start), sb, ref itemModified)) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { oPattern.PatternStartDate = DateTime.Parse(ev.Start.DateTime); } else { ai.Start = DateTime.Parse(ev.Start.DateTime); } } if (MainForm.CompareAttribute("End time", SyncDirection.GoogleToOutlook, GoogleCalendar.GoogleTimeFrom(DateTime.Parse(ev.End.DateTime)), GoogleCalendar.GoogleTimeFrom(ai.End), sb, ref itemModified)) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { oPattern.PatternEndDate = DateTime.Parse(ev.End.DateTime); } else { ai.End = DateTime.Parse(ev.End.DateTime); } } } oPattern = (RecurrencePattern)ReleaseObject(oPattern); if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { if (ev.Recurrence == null || ev.RecurringEventId != null) { log.Debug("Converting to non-recurring events."); ai.ClearRecurrencePattern(); itemModified++; } else { Recurrence.Instance.CompareOutlookPattern(ev, ai, sb, ref itemModified); Recurrence.Instance.UpdateOutlookExceptions(ai, ev); } } else if (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring) { if (!ai.IsRecurring && ev.Recurrence != null && ev.RecurringEventId == null) { log.Debug("Converting to recurring appointment."); Recurrence.Instance.CreateOutlookExceptions(ai, ev); itemModified++; } } String summaryObfuscated = Obfuscate.ApplyRegex(ev.Summary, SyncDirection.GoogleToOutlook); if (MainForm.CompareAttribute("Subject", SyncDirection.GoogleToOutlook, summaryObfuscated, ai.Subject, sb, ref itemModified)) { ai.Subject = summaryObfuscated; } if (!Settings.Instance.AddDescription) { ev.Description = ""; } if (Settings.Instance.SyncDirection == SyncDirection.GoogleToOutlook || !Settings.Instance.AddDescription_OnlyToGoogle) { if (MainForm.CompareAttribute("Description", SyncDirection.GoogleToOutlook, ev.Description, ai.Body, sb, ref itemModified)) { ai.Body = ev.Description; } } if (MainForm.CompareAttribute("Location", SyncDirection.GoogleToOutlook, ev.Location, ai.Location, sb, ref itemModified)) { ai.Location = ev.Location; } String oPrivacy = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private"; String gPrivacy = (ev.Visibility == null ? "default" : ev.Visibility); if (MainForm.CompareAttribute("Private", SyncDirection.GoogleToOutlook, gPrivacy, oPrivacy, sb, ref itemModified)) { ai.Sensitivity = (ev.Visibility != null && ev.Visibility == "private") ? OlSensitivity.olPrivate : OlSensitivity.olNormal; } String oFreeBusy = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque"; String gFreeBusy = (ev.Transparency == null ? "opaque" : ev.Transparency); if (MainForm.CompareAttribute("Free/Busy", SyncDirection.GoogleToOutlook, gFreeBusy, oFreeBusy, sb, ref itemModified)) { ai.BusyStatus = (ev.Transparency != null && ev.Transparency == "transparent") ? OlBusyStatus.olFree : OlBusyStatus.olBusy; } if (Settings.Instance.AddAttendees) { if (ev.Description != null && ev.Description.Contains("===--- Attendees ---===")) { //Protect against <v1.2.4 where attendees were stored as text log.Info("This event still has attendee information in the description - cannot sync them."); } else if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional && ev.Attendees != null && ev.Attendees.Count == 0 && ai.Recipients.Count > 150) { log.Info("Attendees not being synced - there are too many (" + ai.Recipients.Count + ") for Google."); } else { //Build a list of Outlook attendees. Any remaining at the end of the diff must be deleted. List <Recipient> removeRecipient = new List <Recipient>(); if (ai.Recipients != null) { foreach (Recipient recipient in ai.Recipients) { if (recipient.Name != ai.Organizer) { removeRecipient.Add(recipient); } } } if (ev.Attendees != null) { for (int g = ev.Attendees.Count - 1; g >= 0; g--) { bool foundRecipient = false; EventAttendee attendee = ev.Attendees[g]; foreach (Recipient recipient in ai.Recipients) { if (!recipient.Resolved) { recipient.Resolve(); } String recipientSMTP = IOutlook.GetRecipientEmail(recipient); if (recipientSMTP.ToLower() == attendee.Email.ToLower()) { foundRecipient = true; removeRecipient.Remove(recipient); //Optional attendee bool oOptional = (ai.OptionalAttendees != null && ai.OptionalAttendees.Contains(attendee.DisplayName ?? attendee.Email)); bool gOptional = (attendee.Optional == null) ? false : (bool)attendee.Optional; if (MainForm.CompareAttribute("Recipient " + recipient.Name + " - Optional Check", SyncDirection.GoogleToOutlook, gOptional, oOptional, sb, ref itemModified)) { if (gOptional) { recipient.Type = (int)OlMeetingRecipientType.olOptional; } else { recipient.Type = (int)OlMeetingRecipientType.olRequired; } } //Response is readonly in Outlook :( break; } } if (!foundRecipient && (attendee.DisplayName != ai.Organizer)) //Attendee in Google is owner in Outlook, so can't also be added as a recipient) { sb.AppendLine("Recipient added: " + (attendee.DisplayName ?? attendee.Email)); createRecipient(attendee, ai); itemModified++; } } } foreach (Recipient recipient in removeRecipient) { sb.AppendLine("Recipient removed: " + recipient.Name); recipient.Delete(); itemModified++; } } } //Reminders if (Settings.Instance.AddReminders) { if (ev.Reminders.Overrides != null) { //Find the popup reminder in Google for (int r = ev.Reminders.Overrides.Count - 1; r >= 0; r--) { EventReminder reminder = ev.Reminders.Overrides[r]; if (reminder.Method == "popup") { if (ai.ReminderSet) { if (MainForm.CompareAttribute("Reminder", SyncDirection.GoogleToOutlook, reminder.Minutes.ToString(), ai.ReminderMinutesBeforeStart.ToString(), sb, ref itemModified)) { ai.ReminderMinutesBeforeStart = (int)reminder.Minutes; } } else { sb.AppendLine("Reminder: nothing => " + reminder.Minutes); ai.ReminderSet = true; ai.ReminderMinutesBeforeStart = (int)reminder.Minutes; itemModified++; } //if Outlook reminders set } //if google reminder found } //foreach reminder } else //no google reminders set { if (ai.ReminderSet) { sb.AppendLine("Reminder: " + ai.ReminderMinutesBeforeStart + " => removed"); ai.ReminderSet = false; itemModified++; } } } if (itemModified > 0) { MainForm.Instance.Logboxout(sb.ToString(), false, verbose: true); MainForm.Instance.Logboxout(itemModified + " attributes updated.", verbose: true); System.Windows.Forms.Application.DoEvents(); } return(ai); }
public AppointmentItem UpdateCalendarEntry(AppointmentItem ai, Event ev, ref int itemModified, Boolean forceCompare = false) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { //The exception child objects might have changed log.Debug("Processing recurring master appointment."); } else { if (!(MainForm.Instance.ManualForceCompare || forceCompare)) { //Needed if the exception has just been created, but now needs updating if (Settings.Instance.SyncDirection != SyncDirection.Bidirectional) { if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated)) return null; } else { if (GoogleCalendar.GetOGCSlastModified(ev).AddSeconds(5) >= DateTime.Parse(ev.Updated)) //Google last modified by OGCS return null; if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated)) return null; } } } String evSummary = GoogleCalendar.GetEventSummary(ev); log.Debug("Processing >> " + evSummary); System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.AppendLine(evSummary); if (ai.RecurrenceState != OlRecurrenceState.olApptMaster) { if (ai.AllDayEvent != (ev.Start.DateTime == null)) { sb.AppendLine("All-Day: " + ai.AllDayEvent + " => " + (ev.Start.DateTime == null)); ai.AllDayEvent = (ev.Start.DateTime == null); itemModified++; } } RecurrencePattern oPattern = (ai.RecurrenceState == OlRecurrenceState.olApptMaster) ? ai.GetRecurrencePattern() : null; Recurrence.Instance.CompareOutlookPattern(ev, ai, SyncDirection.GoogleToOutlook, sb, ref itemModified); DateTime evParsedDate = DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime); if (MainForm.CompareAttribute("Start time", SyncDirection.GoogleToOutlook, GoogleCalendar.GoogleTimeFrom(evParsedDate), GoogleCalendar.GoogleTimeFrom(ai.Start), sb, ref itemModified)) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { oPattern.PatternStartDate = evParsedDate; oPattern.StartTime = evParsedDate; } else { ai.Start = evParsedDate; } } evParsedDate = DateTime.Parse(ev.End.Date ?? ev.End.DateTime); if (MainForm.CompareAttribute("End time", SyncDirection.GoogleToOutlook, GoogleCalendar.GoogleTimeFrom(evParsedDate), GoogleCalendar.GoogleTimeFrom(ai.End), sb, ref itemModified)) { if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { oPattern.EndTime = evParsedDate; } else { ai.End = evParsedDate; } } if (oPattern != null) { oPattern.Duration = Convert.ToInt32((evParsedDate - DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime)).TotalMinutes); oPattern = (RecurrencePattern)ReleaseObject(oPattern); } if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { if (ev.Recurrence == null || ev.RecurringEventId != null) { log.Debug("Converting to non-recurring events."); ai.ClearRecurrencePattern(); itemModified++; } else { Recurrence.Instance.UpdateOutlookExceptions(ai, ev); } } else if (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring) { if (!ai.IsRecurring && ev.Recurrence != null && ev.RecurringEventId == null) { log.Debug("Converting to recurring appointment."); Recurrence.Instance.CreateOutlookExceptions(ai, ev); itemModified++; } } String summaryObfuscated = Obfuscate.ApplyRegex(ev.Summary, SyncDirection.GoogleToOutlook); if (MainForm.CompareAttribute("Subject", SyncDirection.GoogleToOutlook, summaryObfuscated, ai.Subject, sb, ref itemModified)) { ai.Subject = summaryObfuscated; } if (!Settings.Instance.AddDescription) ev.Description = ""; if (Settings.Instance.SyncDirection == SyncDirection.GoogleToOutlook || !Settings.Instance.AddDescription_OnlyToGoogle) { if (MainForm.CompareAttribute("Description", SyncDirection.GoogleToOutlook, ev.Description, ai.Body, sb, ref itemModified)) ai.Body = ev.Description; } if (MainForm.CompareAttribute("Location", SyncDirection.GoogleToOutlook, ev.Location, ai.Location, sb, ref itemModified)) ai.Location = ev.Location; String oPrivacy = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private"; String gPrivacy = ev.Visibility ?? "default"; if (MainForm.CompareAttribute("Private", SyncDirection.GoogleToOutlook, gPrivacy, oPrivacy, sb, ref itemModified)) { ai.Sensitivity = (ev.Visibility != null && ev.Visibility == "private") ? OlSensitivity.olPrivate : OlSensitivity.olNormal; } String oFreeBusy = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque"; String gFreeBusy = ev.Transparency ?? "opaque"; if (MainForm.CompareAttribute("Free/Busy", SyncDirection.GoogleToOutlook, gFreeBusy, oFreeBusy, sb, ref itemModified)) { ai.BusyStatus = (ev.Transparency != null && ev.Transparency == "transparent") ? OlBusyStatus.olFree : OlBusyStatus.olBusy; } if (Settings.Instance.AddAttendees) { if (ev.Description != null && ev.Description.Contains("===--- Attendees ---===")) { //Protect against <v1.2.4 where attendees were stored as text log.Info("This event still has attendee information in the description - cannot sync them."); } else if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional && ev.Attendees != null && ev.Attendees.Count == 0 && ai.Recipients.Count > 150) { log.Info("Attendees not being synced - there are too many ("+ ai.Recipients.Count +") for Google."); } else { //Build a list of Outlook attendees. Any remaining at the end of the diff must be deleted. List<Recipient> removeRecipient = new List<Recipient>(); if (ai.Recipients != null) { foreach (Recipient recipient in ai.Recipients) { if (recipient.Name != ai.Organizer) removeRecipient.Add(recipient); } } if (ev.Attendees != null) { for (int g = ev.Attendees.Count - 1; g >= 0; g--) { bool foundRecipient = false; EventAttendee attendee = ev.Attendees[g]; foreach (Recipient recipient in ai.Recipients) { if (!recipient.Resolved) recipient.Resolve(); String recipientSMTP = IOutlook.GetRecipientEmail(recipient); if (recipientSMTP.ToLower() == attendee.Email.ToLower()) { foundRecipient = true; removeRecipient.Remove(recipient); //Optional attendee bool oOptional = (ai.OptionalAttendees != null && ai.OptionalAttendees.Contains(attendee.DisplayName ?? attendee.Email)); bool gOptional = (attendee.Optional == null) ? false : (bool)attendee.Optional; if (MainForm.CompareAttribute("Recipient " + recipient.Name + " - Optional Check", SyncDirection.GoogleToOutlook, gOptional, oOptional, sb, ref itemModified)) { if (gOptional) { recipient.Type = (int)OlMeetingRecipientType.olOptional; } else { recipient.Type = (int)OlMeetingRecipientType.olRequired; } } //Response is readonly in Outlook :( break; } } if (!foundRecipient && (attendee.DisplayName != ai.Organizer)) //Attendee in Google is owner in Outlook, so can't also be added as a recipient) { sb.AppendLine("Recipient added: " + (attendee.DisplayName ?? attendee.Email)); createRecipient(attendee, ai); itemModified++; } } } foreach (Recipient recipient in removeRecipient) { sb.AppendLine("Recipient removed: " + recipient.Name); recipient.Delete(); itemModified++; } } } //Reminders if (Settings.Instance.AddReminders) { if (ev.Reminders.Overrides != null) { //Find the popup reminder in Google for (int r = ev.Reminders.Overrides.Count - 1; r >= 0; r--) { EventReminder reminder = ev.Reminders.Overrides[r]; if (reminder.Method == "popup") { if (ai.ReminderSet) { if (MainForm.CompareAttribute("Reminder", SyncDirection.GoogleToOutlook, reminder.Minutes.ToString(), ai.ReminderMinutesBeforeStart.ToString(), sb, ref itemModified)) { ai.ReminderMinutesBeforeStart = (int)reminder.Minutes; } } else { sb.AppendLine("Reminder: nothing => " + reminder.Minutes); ai.ReminderSet = true; ai.ReminderMinutesBeforeStart = (int)reminder.Minutes; itemModified++; } //if Outlook reminders set } //if google reminder found } //foreach reminder } else { //no google reminders set if (ai.ReminderSet && IsOKtoSyncReminder(ai)) { sb.AppendLine("Reminder: " + ai.ReminderMinutesBeforeStart + " => removed"); ai.ReminderSet = false; itemModified++; } } } if (itemModified > 0) { MainForm.Instance.Logboxout(sb.ToString(), false, verbose: true); MainForm.Instance.Logboxout(itemModified + " attributes updated.", verbose: true); System.Windows.Forms.Application.DoEvents(); } return ai; }
private static void UpdateOutlookAppointment(AppointmentItem appointment, string mtg_id, MeetingRequest request, bool reload_pattern = false) { int mrbs_id = -1; int.TryParse(mtg_id.Substring(0, mtg_id.IndexOf(";")), out mrbs_id); // appointment.Subject = request.Description; if ((appointment.RecurrenceState != OlRecurrenceState.olApptMaster) || (appointment.EntryID == "")) { appointment.Start = request.Start; appointment.End = request.End; } appointment.Location = String.Format("{0} - {1}", Database.GetAreaNameByRoomId(request.RoomId), Database.GetRoomNameById(request.RoomId)); if (request.RepeatTypeId > 0) { RecurrencePattern pattern; if (reload_pattern) { appointment.ClearRecurrencePattern(); } pattern = appointment.GetRecurrencePattern(); switch (request.RepeatTypeId) { case 1: pattern.RecurrenceType = OlRecurrenceType.olRecursDaily; pattern.Interval = 1; break; case 2: char[] rev = request.RepeatWeeklyCode.ToCharArray(); pattern.RecurrenceType = OlRecurrenceType.olRecursWeekly; pattern.Interval = request.RepeatNumberOfWeeks; pattern.DayOfWeekMask = (OlDaysOfWeek)Convert.ToInt32(new string(request.RepeatWeeklyCode.ToCharArray().Reverse().ToArray()), 2); break; case 3: if (request.RepeatMonthlyByWeekday) { pattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth; pattern.Interval = 1; pattern.DayOfWeekMask = (OlDaysOfWeek)((int)Math.Pow(2, request.RepeatWeekdayOfMonth)); pattern.Instance = request.RepeatWeekdaysOfMonth; } else { pattern.RecurrenceType = OlRecurrenceType.olRecursMonthly; pattern.Interval = 1; pattern.DayOfMonth = request.RepeatDayOfMonth; } break; case 4: pattern.RecurrenceType = OlRecurrenceType.olRecursYearly; break; } pattern.Duration = (request.End - request.Start).Minutes; pattern.EndTime = request.RepeatEnd.Date + request.End.TimeOfDay; pattern.NoEndDate = false; pattern.PatternStartDate = request.Start; pattern.PatternEndDate = request.RepeatEnd + request.End.TimeOfDay; pattern.StartTime = request.Start; } try { appointment.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText); } catch (UnauthorizedAccessException) { //appointment.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText); } appointment.UserProperties["MJ-MRBS-ID"].Value = mtg_id; if (!appointment.Body.Contains("has been linked to a reservation in MRBS.")) { appointment.Body += String.Format("\n\n\n***** This {0} has been linked to a reservation in MRBS. To change the {0} location, you must use the Modify Reservation button in the ribbon. *****", appointment.MeetingStatus == OlMeetingStatus.olNonMeeting ? "appointment" : "meeting"); } appointment.Save(); if (request.RepeatTypeId > 0) { RecurrencePattern pattern = appointment.GetRecurrencePattern(); List <Entry> entries = Database.GetAllEntries(mrbs_id); List <Entry> conflicts = Database.FindConflicts(request, mrbs_id); foreach (Entry conflict in conflicts) { DateTime start_time = Database.UnixTimeStampToDateTime(conflict.start_time); AppointmentItem item = pattern.GetOccurrence(start_time); item.Delete(); } foreach (Entry entry in entries) { try { DateTime start_time = Database.UnixTimeStampToDateTime(entry.start_time); AppointmentItem item = pattern.GetOccurrence(start_time); item.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText); item.UserProperties["MJ-MRBS-ID"].Value = String.Format("{0};{1}", entry.id, entry.ical_uid); item.Save(); } catch { } } appointment.Save(); } }