From 3de6e0fc5aeb95f34cd5a7d941fe430703420927 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 29 Aug 2016 14:36:04 -0400 Subject: [PATCH] Until date of repeat must end after first event --- NEWS | 2 +- .../English.lproj/Localizable.strings | 2 + UI/Scheduler/UIxAppointmentEditor.m | 116 ++++++++++-------- 3 files changed, 69 insertions(+), 51 deletions(-) diff --git a/NEWS b/NEWS index d8f6a2492..f42b39a65 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,7 @@ New features - Enhancements - - + - [web] don't allow a recurrence rule to end before the first occurrence Bug fixes - [eas] properly generate the BusyStatus for normal events diff --git a/UI/Scheduler/English.lproj/Localizable.strings b/UI/Scheduler/English.lproj/Localizable.strings index 67800b4b1..0dd662120 100644 --- a/UI/Scheduler/English.lproj/Localizable.strings +++ b/UI/Scheduler/English.lproj/Localizable.strings @@ -379,6 +379,8 @@ validate_notitle = "No title is set, continue?"; validate_invalid_startdate = "Incorrect startdate field!"; validate_invalid_enddate = "Incorrect enddate field!"; validate_endbeforestart = "The end date that you entered occurs before the start date."; +validate_untilbeforeend = "The recurrence must end after the first occurrence."; + "Events" = "Events"; "Tasks" = "Tasks"; "Show completed tasks" = "Show completed tasks"; diff --git a/UI/Scheduler/UIxAppointmentEditor.m b/UI/Scheduler/UIxAppointmentEditor.m index a6cdd165f..3f0a52cee 100644 --- a/UI/Scheduler/UIxAppointmentEditor.m +++ b/UI/Scheduler/UIxAppointmentEditor.m @@ -362,15 +362,17 @@ return result; } -- (void) _adjustRecurrentRules +- (NSException *) _adjustRecurrentRules { iCalRecurrenceRule *rule; NSEnumerator *rules; + NSException *ex; NSCalendarDate *untilDate; SOGoUserDefaults *ud; NSTimeZone *timeZone; rules = [[event recurrenceRules] objectEnumerator]; + ex = nil; ud = [[context activeUser] userDefaults]; timeZone = [ud timeZone]; @@ -379,22 +381,33 @@ untilDate = [rule untilDate]; if (untilDate) { - // The until date must match the time of the end date - NSCalendarDate *date; + if ([untilDate compare: [event endDate]] == NSOrderedAscending) + { + ex = [NSException exceptionWithHTTPStatus: 500 + reason: [self labelForKey: @"validate_untilbeforeend"]]; + break; + } + else + { + // The until date must match the time of the end date + NSCalendarDate *date; - date = [[event endDate] copy]; - [date setTimeZone: timeZone]; - [untilDate setTimeZone: timeZone]; - untilDate = [untilDate dateByAddingYears:0 - months:0 - days:0 - hours:[date hourOfDay] - minutes:[date minuteOfHour] - seconds:0]; - [rule setUntilDate: untilDate]; - [date release]; + date = [[event endDate] copy]; + [date setTimeZone: timeZone]; + [untilDate setTimeZone: timeZone]; + untilDate = [untilDate dateByAddingYears:0 + months:0 + days:0 + hours:[date hourOfDay] + minutes:[date minuteOfHour] + seconds:0]; + [rule setUntilDate: untilDate]; + [date release]; + } } } + + return ex; } // @@ -544,47 +557,50 @@ ex = nil; if ([event hasRecurrenceRules]) - [self _adjustRecurrentRules]; + ex = [self _adjustRecurrentRules]; - if ([co isNew]) + if (!ex) { - if (componentCalendar - && ![[componentCalendar ocsPath] - isEqualToString: [previousCalendar ocsPath]]) + if ([co isNew]) { - // New event in a different calendar -- make sure the user can - // write to the selected calendar since the rights were verified - // on the calendar specified in the URL, not on the selected - // calendar of the popup menu. - if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles - onObject: componentCalendar - inContext: context]) - co = [componentCalendar lookupName: [co nameInContainer] - inContext: context - acquire: NO]; - } - - // Save the event. - ex = [co saveComponent: event]; - } - else - { - // The event was modified -- save it. - ex = [co saveComponent: event]; - - if (componentCalendar - && ![[componentCalendar ocsPath] - isEqualToString: [previousCalendar ocsPath]]) - { - // The event was moved to a different calendar. - if (![sm validatePermission: SoPerm_DeleteObjects - onObject: previousCalendar - inContext: context]) + if (componentCalendar + && ![[componentCalendar ocsPath] + isEqualToString: [previousCalendar ocsPath]]) { + // New event in a different calendar -- make sure the user can + // write to the selected calendar since the rights were verified + // on the calendar specified in the URL, not on the selected + // calendar of the popup menu. if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles - onObject: componentCalendar - inContext: context]) - ex = [co moveToFolder: componentCalendar]; + onObject: componentCalendar + inContext: context]) + co = [componentCalendar lookupName: [co nameInContainer] + inContext: context + acquire: NO]; + } + + // Save the event. + ex = [co saveComponent: event]; + } + else + { + // The event was modified -- save it. + ex = [co saveComponent: event]; + + if (componentCalendar + && ![[componentCalendar ocsPath] + isEqualToString: [previousCalendar ocsPath]]) + { + // The event was moved to a different calendar. + if (![sm validatePermission: SoPerm_DeleteObjects + onObject: previousCalendar + inContext: context]) + { + if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles + onObject: componentCalendar + inContext: context]) + ex = [co moveToFolder: componentCalendar]; + } } } }