]> err.no Git - scalable-opengroupware.org/blob - UI/Scheduler/UIxTaskEditor.m
8ea3b9edf1b1641d45fce7cc022121c7e83c64d0
[scalable-opengroupware.org] / UI / Scheduler / UIxTaskEditor.m
1 /* UIxTaskEditor.m - this file is part of SOGo
2  *
3  * Copyright (C) 2007 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <NGObjWeb/SoObject.h>
24 #import <NGObjWeb/WORequest.h>
25 #import <NGObjWeb/NSException+HTTP.h>
26 #import <NGExtensions/NSCalendarDate+misc.h>
27
28 #import <NGCards/iCalCalendar.h>
29 #import <NGCards/iCalToDo.h>
30 #import <NGCards/iCalPerson.h>
31
32 #import <SoObjects/SOGo/SOGoUser.h>
33 #import <SoObjects/SOGo/SOGoContentObject.h>
34 #import <SoObjects/Appointments/SOGoAppointmentFolder.h>
35 #import <SoObjects/Appointments/SOGoTaskObject.h>
36
37 #import "UIxComponentEditor.h"
38 #import "UIxTaskEditor.h"
39
40 @implementation UIxTaskEditor
41
42 - (id) init
43 {
44   if ((self = [super init]))
45     {
46       taskStartDate = nil;
47       taskDueDate = nil;
48       statusDate = nil;
49       hasStartDate = NO;
50       hasDueDate = NO;
51       status = nil;
52       statusPercent = nil;
53       item = nil;
54       todo = nil;
55     }
56
57   return self;
58 }
59
60 - (void) dealloc
61 {
62   [taskStartDate release];
63   [taskDueDate release];
64   [statusDate release];
65   [status release];
66   [statusPercent release];
67   [todo release];
68   [super dealloc];
69 }
70
71 /* template values */
72 - (iCalToDo *) todo
73 {
74   if (!todo)
75     {
76       todo = (iCalToDo *) [[self clientObject] component: NO secure: NO];
77       [todo retain];
78     }
79
80   return todo;
81 }
82
83 - (NSString *) saveURL
84 {
85   return [NSString stringWithFormat: @"%@/saveAsTask",
86                    [[self clientObject] baseURL]];
87 }
88
89 /* icalendar values */
90 - (void) setTaskStartDate: (NSCalendarDate *) newTaskStartDate
91 {
92   ASSIGN (taskStartDate, newTaskStartDate);
93 }
94
95 - (NSCalendarDate *) taskStartDate
96 {
97   return taskStartDate;
98 }
99
100 - (void) setHasStartDate: (BOOL) newHasStartDate
101 {
102   hasStartDate = newHasStartDate;
103 }
104
105 - (BOOL) hasStartDate
106 {
107   return hasStartDate;
108 }
109
110 - (BOOL) startDateDisabled
111 {
112   return !hasStartDate;
113 }
114
115 - (void) setTaskDueDate: (NSCalendarDate *) newTaskDueDate
116 {
117   ASSIGN (taskDueDate, newTaskDueDate);
118 }
119
120 - (NSCalendarDate *) taskDueDate
121 {
122   return taskDueDate;
123 }
124
125 - (void) setHasDueDate: (BOOL) newHasDueDate
126 {
127   hasDueDate = newHasDueDate;
128 }
129
130 - (BOOL) hasDueDate
131 {
132   return hasDueDate;
133 }
134
135 - (BOOL) dueDateDisabled
136 {
137   return !hasDueDate;
138 }
139
140 - (NSArray *) repeatList
141 {
142   static NSArray *repeatItems = nil;
143
144   if (!repeatItems)
145     {
146       repeatItems = [NSArray arrayWithObjects: @"DAILY",
147                              @"WEEKLY",
148                              @"BI-WEEKLY",
149                              @"EVERY WEEKDAY",
150                              @"MONTHLY",
151                              @"YEARLY",
152                              @"-",
153                              @"CUSTOM",
154                              nil];
155       [repeatItems retain];
156     }
157
158   return repeatItems;
159 }
160
161 - (NSString *) itemRepeatText
162 {
163   NSString *text;
164
165   if ([item isEqualToString: @"-"])
166     text = item;
167   else
168     text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
169
170   return text;
171 }
172
173 - (NSArray *) statusList
174 {
175   static NSArray *statusItems = nil;
176
177   if (!statusItems)
178     {
179       statusItems = [NSArray arrayWithObjects: @"NEEDS-ACTION",
180                              @"IN-PROCESS",
181                              @"COMPLETED",
182                              @"CANCELLED",
183                              nil];
184       [statusItems retain];
185     }
186
187   return statusItems;
188 }
189
190 - (NSString *) itemStatusText
191 {
192   return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
193 }
194
195 - (void) setItem: (NSString *) newItem
196 {
197   item = newItem;
198 }
199
200 - (NSString *) item
201 {
202   return item;
203 }
204
205 - (NSString *) repeat
206 {
207   return @"";
208 }
209
210 - (void) setRepeat: (NSString *) newRepeat
211 {
212 }
213
214 - (NSString *) status
215 {
216   return status;
217 }
218
219 - (void) setStatus: (NSString *) newStatus
220 {
221   status = newStatus;
222 }
223
224 - (void) setStatusDate: (NSCalendarDate *) newStatusDate
225 {
226   ASSIGN (statusDate, newStatusDate);
227 }
228
229 - (NSCalendarDate *) statusDate
230 {
231   return statusDate;
232 }
233
234 - (BOOL) statusDateDisabled
235 {
236   return ![status isEqualToString: @"COMPLETED"];
237 }
238
239 - (BOOL) statusPercentDisabled
240 {
241   return ([status length] == 0
242           || [status isEqualToString: @"CANCELLED"]);
243 }
244
245 - (void) setStatusPercent: (NSString *) newStatusPercent
246 {
247   ASSIGN (statusPercent, newStatusPercent);
248 }
249
250 - (NSString *) statusPercent
251 {
252   return statusPercent;
253 }
254
255 /* actions */
256 - (NSCalendarDate *) newStartDate
257 {
258   NSCalendarDate *newStartDate, *now;
259   int hour;
260   NSTimeZone *timeZone;
261
262   timeZone = [[context activeUser] timeZone];
263
264   newStartDate = [self selectedDate];
265   if ([[self queryParameterForKey: @"hm"] length] == 0)
266     {
267       now = [NSCalendarDate calendarDate];
268       [now setTimeZone: timeZone];
269       if ([now isDateOnSameDay: newStartDate])
270         {
271           hour = [now hourOfDay];
272           if (hour < 8)
273             newStartDate = [now hour: 8 minute: 0];
274           else if (hour > 18)
275             newStartDate = [[now tomorrow] hour: 8 minute: 0];
276           else
277             newStartDate = now;
278         }
279       else
280         newStartDate = [newStartDate hour: 8 minute: 0];
281     }
282
283   return newStartDate;
284 }
285
286 - (id <WOActionResults>) defaultAction
287 {
288   NSCalendarDate *startDate, *dueDate;
289   NSString *duration;
290   unsigned int minutes;
291
292   todo = (iCalToDo *) [[self clientObject] component: NO secure: YES];
293   if (todo)
294     {
295       startDate = [todo startDate];
296       dueDate = [todo due];
297       hasStartDate = (startDate != nil);
298       hasDueDate = (dueDate != nil);
299       ASSIGN (status, [todo status]);
300       if ([status isEqualToString: @"COMPLETED"])
301         ASSIGN (statusDate, [todo completed]);
302       else
303         ASSIGN (statusDate, [self newStartDate]);
304       ASSIGN (statusPercent, [todo percentComplete]);
305     }
306   else
307     {
308       startDate = [self newStartDate];
309       duration = [self queryParameterForKey:@"dur"];
310       if ([duration length] > 0)
311         minutes = [duration intValue];
312       else
313         minutes = 60;
314       dueDate = [startDate dateByAddingYears: 0 months: 0 days: 0
315                            hours: 0 minutes: minutes seconds: 0];
316       hasStartDate = NO;
317       hasDueDate = NO;
318       ASSIGN (statusDate, [self newStartDate]);
319       ASSIGN (status, @"");
320       ASSIGN (statusPercent, @"");
321     }
322
323   ASSIGN (taskStartDate, startDate);
324   ASSIGN (taskDueDate, dueDate);
325
326   /* here comes the code for initializing repeat, reminder and isAllDay... */
327
328   return self;
329 }
330
331 - (id <WOActionResults>) newAction
332 {
333   NSString *objectId, *method, *uri;
334   id <WOActionResults> result;
335   SOGoAppointmentFolder *co;
336
337   co = [self clientObject];
338   objectId = [co globallyUniqueObjectId];
339   if ([objectId length] > 0)
340     {
341       method = [NSString stringWithFormat:@"%@/%@/editAsTask",
342                          [co soURL], objectId];
343       uri = [self completeHrefForMethod: method];
344       result = [self redirectToLocation: uri];
345     }
346   else
347     result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */
348                           reason: @"could not create a unique ID"];
349
350   return result;
351 }
352
353 - (id <WOActionResults>) saveAction
354 {
355   [[self clientObject] saveComponent: todo];
356
357   return [self jsCloseWithRefreshMethod: @"refreshTasks()"];
358 }
359
360 // - (id <WOActionResults>) saveAction
361 // {
362 //   SOGoTaskObject *clientObject;
363 //   NSString *iCalString;
364
365 //   clientObject = [self clientObject];
366 //   iCalString = [[clientObject calendar: NO secure: NO] versitString];
367 //   [clientObject saveContentString: iCalString];
368
369 //   return [self jsCloseWithRefreshMethod: @"refreshTasks()"];
370 // }
371
372 - (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
373                            inContext: (WOContext*) context
374 {
375   NSString *actionName;
376
377   actionName = [[request requestHandlerPath] lastPathComponent];
378
379   return ([[self clientObject] isKindOfClass: [SOGoTaskObject class]]
380           && [actionName hasPrefix: @"save"]);
381 }
382
383 - (void) takeValuesFromRequest: (WORequest *) _rq
384                      inContext: (WOContext *) _ctx
385 {
386   SOGoTaskObject *clientObject;
387
388   clientObject = [self clientObject];
389   todo = (iCalToDo *) [clientObject component: YES secure: NO];
390
391   [super takeValuesFromRequest: _rq inContext: _ctx];
392
393   if (hasStartDate)
394     [todo setStartDate: taskStartDate];
395   else
396     [todo setStartDate: nil];
397
398   if (hasDueDate)
399     [todo setDue: taskDueDate];
400   else
401     [todo setDue: nil];
402
403   if ([status isEqualToString: @"COMPLETED"])
404     [todo setCompleted: statusDate];
405   else
406     [todo setCompleted: nil];
407   if ([status length] > 0)
408     {
409       [todo setStatus: status];
410       [todo setPercentComplete: statusPercent];
411     }
412   else
413     {
414       [todo setStatus: @""];
415       [todo setPercentComplete: @""];
416     }
417 }
418
419 // TODO: add tentatively
420
421 // - (id) acceptOrDeclineAction: (BOOL) _accept
422 // {
423 //   [[self clientObject] changeParticipationStatus:
424 //                          _accept ? @"ACCEPTED" : @"DECLINED"];
425
426 //   return self;
427 // }
428
429 // - (id) acceptAction
430 // {
431 //   return [self acceptOrDeclineAction: YES];
432 // }
433
434 // - (id) declineAction
435 // {
436 //   return [self acceptOrDeclineAction: NO];
437 // }
438
439 - (id) changeStatusAction
440 {
441   SOGoTaskObject *clientObject;
442   NSString *newStatus;
443
444   clientObject = [self clientObject];
445   todo = (iCalToDo *) [clientObject component: NO secure: NO];
446   [todo retain];
447   if (todo)
448     {
449       newStatus = [self queryParameterForKey: @"status"];
450       if ([newStatus intValue])
451         [todo setCompleted: [NSCalendarDate date]];
452       else
453         {
454           [todo setCompleted: nil];
455           [todo setPercentComplete: @"0"];
456           [todo setStatus: @"IN-PROCESS"];
457         }
458       [clientObject saveComponent: todo];
459     }
460
461   return [self responseWith204];
462 }
463
464 @end