(feat) we now handle optional and non-required attendee states
parent
2901560df9
commit
249671543e
3
NEWS
3
NEWS
|
@ -3,7 +3,8 @@
|
|||
|
||||
Enhancements
|
||||
- [web] create card from sender or recipient address (#3002, #4610)
|
||||
- [core] baseDN now accept dynamic domain values (#3685)
|
||||
- [core] baseDN now accept dynamic domain values (#3685 - sponsored by iRedMail)
|
||||
- [core] we now handle optional and non-required attendee states
|
||||
|
||||
Bug fixes
|
||||
- [web] fixed all-day event dates with different timezone
|
||||
|
|
|
@ -62,3 +62,8 @@ vtodo_class2 = "(Confidential task)";
|
|||
/* Resources */
|
||||
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Cannot access resource: \"%{Cn} %{SystemEmail}\"";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}.";
|
||||
|
||||
/* Participation role */
|
||||
"Your participation is required to this event" = "Your participation is required to this event";
|
||||
"Your participation is optional to this event" = "Your participation is optional to this event";
|
||||
"Your participation is not required to this event" = "Your participation is not required to this event";
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2007-2016 Inverse inc.
|
||||
Copyright (C) 2007-2019 Inverse inc.
|
||||
|
||||
This file is part of SOGo
|
||||
|
||||
|
@ -187,9 +187,17 @@
|
|||
{
|
||||
SOGoAppointmentObject *attendeeObject;
|
||||
iCalCalendar *iCalendarToSave;
|
||||
iCalPerson *attendee;
|
||||
SOGoUser *user;
|
||||
|
||||
iCalendarToSave = nil;
|
||||
user = [SOGoUser userWithLogin: theUID];
|
||||
attendeeObject = [self _lookupEvent: [newEvent uid] forUID: theUID];
|
||||
attendee = [newEvent userAsAttendee: user];
|
||||
|
||||
// If the atttende's role is NON-PARTICIPANT, we write nothing to its calendar
|
||||
if ([[attendee role] caseInsensitiveCompare: @"NON-PARTICIPANT"] == NSOrderedSame)
|
||||
return;
|
||||
|
||||
if ([newEvent recurrenceId])
|
||||
{
|
||||
|
@ -197,12 +205,11 @@
|
|||
if ([attendeeObject isNew])
|
||||
{
|
||||
iCalEvent *ownerEvent;
|
||||
SOGoUser *user;
|
||||
|
||||
// We check if the attendee that was added to a single occurence is
|
||||
// present in the master component. If not, we create a calendar with
|
||||
// a single event for the occurence.
|
||||
ownerEvent = [[[newEvent parent] events] objectAtIndex: 0];
|
||||
user = [SOGoUser userWithLogin: theUID];
|
||||
|
||||
if (![ownerEvent userAsAttendee: user])
|
||||
{
|
||||
|
@ -339,7 +346,7 @@
|
|||
}
|
||||
}
|
||||
else
|
||||
[self errorWithFormat: @"Unable to find event with UID %@ in %@'s calendar - skipping delete operation", nameInContainer, theUID];
|
||||
[self errorWithFormat: @"Unable to find event with UID %@ in %@'s calendar - skipping delete operation. This can be normal for NON-PARTICIPANT attendees.", nameInContainer, theUID];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1171,6 +1178,10 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
|||
NSException *error;
|
||||
BOOL addDelegate, removeDelegate;
|
||||
|
||||
// If the atttende's role is NON-PARTICIPANT, we write nothing to its calendar
|
||||
if ([[attendee role] caseInsensitiveCompare: @"NON-PARTICIPANT"] == NSOrderedSame)
|
||||
return;
|
||||
|
||||
error = nil;
|
||||
|
||||
eventObject = [self _lookupEvent: eventUID forUID: uid];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2010-2012 Inverse
|
||||
Copyright (C) 2010-2019 Inverse
|
||||
|
||||
This file is part of SOGo
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2006-2018 Inverse inc.
|
||||
Copyright (C) 2006-2019 Inverse inc.
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
|||
@class NSMutableDictionary;
|
||||
@class NSString;
|
||||
@class NSTimeZone;
|
||||
@class iCalPerson;
|
||||
@class iCalRepeatableEntityObject;
|
||||
@class SOGoDateFormatter;
|
||||
|
||||
|
@ -46,6 +47,7 @@
|
|||
NSCalendarDate *oldEndDate;
|
||||
NSCalendarDate *newEndDate;
|
||||
NSString *organizerName;
|
||||
iCalPerson *currentAttendee;
|
||||
NSMutableDictionary *values;
|
||||
SOGoDateFormatter *dateFormatter;
|
||||
}
|
||||
|
@ -61,6 +63,9 @@
|
|||
- (void) setOrganizerName: (NSString *) theString;
|
||||
- (NSString *) organizerName;
|
||||
|
||||
- (void) setCurrentAttendee: (iCalPerson *) theAttendee;
|
||||
- (iCalPerson *) currentAttendee;
|
||||
|
||||
- (NSCalendarDate *) oldStartDate;
|
||||
- (NSCalendarDate *) newStartDate;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2006-2013 Inverse inc.
|
||||
Copyright (C) 2006-2019 Inverse inc.
|
||||
Copyright (C) 2000-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of SOGo.
|
||||
|
@ -48,6 +48,8 @@
|
|||
apt = nil;
|
||||
values = nil;
|
||||
dateFormatter = RETAIN([[context activeUser] dateFormatterInContext: context]);
|
||||
organizerName = nil;
|
||||
currentAttendee = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -59,6 +61,7 @@
|
|||
[apt release];
|
||||
[previousApt release];
|
||||
[organizerName release];
|
||||
[currentAttendee release];
|
||||
[viewTZ release];
|
||||
[oldStartDate release];
|
||||
[newStartDate release];
|
||||
|
@ -164,6 +167,16 @@
|
|||
return organizerName;
|
||||
}
|
||||
|
||||
- (void) setCurrentAttendee: (iCalPerson *) theAttendee
|
||||
{
|
||||
ASSIGN(currentAttendee, theAttendee);
|
||||
}
|
||||
|
||||
- (iCalPerson *) currentAttendee
|
||||
{
|
||||
return currentAttendee;
|
||||
}
|
||||
|
||||
- (NSString *) sentByText
|
||||
{
|
||||
NSDictionary *sentByValues;
|
||||
|
@ -293,4 +306,21 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *) getParticipationRole
|
||||
{
|
||||
if ([[currentAttendee role] caseInsensitiveCompare: @"OPT-PARTICIPANT"] == NSOrderedSame)
|
||||
{
|
||||
return [self labelForKey: @"Your participation is optional to this event"
|
||||
inContext: context];
|
||||
}
|
||||
else if ([[currentAttendee role] caseInsensitiveCompare: @"NON-PARTICIPANT"] == NSOrderedSame)
|
||||
{
|
||||
return [self labelForKey: @"Your participation is not required to this event"
|
||||
inContext: context];
|
||||
}
|
||||
|
||||
return [self labelForKey: @"Your participation is required to this event"
|
||||
inContext: context];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SOGoCalendarComponent.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2016 Inverse inc.
|
||||
* Copyright (C) 2006-2019 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -846,6 +846,7 @@
|
|||
p = [app pageWithName: pageName inContext: context];
|
||||
[p setApt: (iCalEvent *) object];
|
||||
[p setPreviousApt: (iCalEvent *) previousObject];
|
||||
[p setCurrentAttendee: attendee];
|
||||
|
||||
if ([[object organizer] cn] && [[[object organizer] cn] length])
|
||||
{
|
||||
|
@ -893,7 +894,8 @@
|
|||
/* attach text part to multipart body */
|
||||
[body addBodyPart: bodyPart];
|
||||
|
||||
/* attach calendar part to multipart body */
|
||||
/* attach calendar part to multipart body only if the participation role is not NON-PARTICIPANT */
|
||||
if ([[attendee role] caseInsensitiveCompare: @"NON-PARTICIPANT"] != NSOrderedSame)
|
||||
[body addBodyPart: eventBodyPart];
|
||||
|
||||
/* attach multipart body to message */
|
||||
|
|
|
@ -20,7 +20,12 @@ th, td { font-family: Lucida Grande, Bitstream VeraSans, Tahoma, sans-serif; fon
|
|||
value="getSubject" const:escapeHTML="NO"/> <small style="font-size: 12px; color: #999;"><var:string
|
||||
value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1></td>
|
||||
</tr>
|
||||
<var:if condition="location.length"
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><h1 style="font-size: 14px; font-weight: normal;
|
||||
padding-bottom: 9px; border-bottom: 1px solid #ccc;"><var:string
|
||||
value="getParticipationRole" const:escapeHTML="NO"/></h1></td>
|
||||
</tr> <var:if condition="location.length"
|
||||
><tr>
|
||||
<th align="right" style="font-weight: bold;"><var:string label:value="location_label" const:escapeHTML="NO"/></th>
|
||||
<td><var:string value="location" const:escapeHTML="NO"/></td>
|
||||
|
|
|
@ -20,6 +20,12 @@ th, td { font-family: Lucida Grande, Bitstream VeraSans, Tahoma, sans-serif; fon
|
|||
value="getSubject" const:escapeHTML="NO"/> <small style="font-size: 12px; color: #999;"><var:string
|
||||
value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><h1 style="font-size: 14px; font-weight: normal;
|
||||
padding-bottom: 9px; border-bottom: 1px solid #ccc;"><var:string
|
||||
value="getParticipationRole" const:escapeHTML="NO"/></h1></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td><var:string value="bodyStartText" const:escapeHTML="NO"/></td>
|
||||
|
|
Loading…
Reference in New Issue