source: trunk/grails-app/services/TaskService.groovy @ 202

Last change on this file since 202 was 202, checked in by gav, 14 years ago

Some commenting and tweak to disable recurring schedule when completing or moving a task to trash.

File size: 21.3 KB
Line 
1/**
2* Provides a service class for the Task domain class.
3*
4*/
5class TaskService {
6
7    boolean transactional = false
8
9    def dateUtilService
10    def personService
11
12    /**
13    * Determines and returns a possible parent list
14    * @param taskInstance The task to use when determining the possible parent list.
15    * @returns A list of the possible parents.
16    */
17    def possibleParentList(taskInstance) {
18        def criteria = taskInstance.createCriteria()
19        def possibleParentList = criteria {
20            and {
21                notEqual('trash', true)
22                notEqual('id', taskInstance.id)
23                taskInstance.subTasks.each() { notEqual('id', it.id) }
24                }
25        }
26    }
27
28    /**
29    * Creates a new task with the given params.
30    * @param params The params to use when creating the new task.
31    * @returns A map containing result.error=true (if any error) and result.taskInstance.
32    */
33    def create(params) {
34        Task.withTransaction { status ->
35            def result = [:]
36            // Default status to "not started" if not supplied.
37            params.taskStatus = params.taskStatus ?: TaskStatus.get(1)
38            def taskInstance = new Task(params)
39            result.taskInstance = taskInstance
40
41            if(result.taskInstance.parentTask?.trash) {
42                status.setRollbackOnly()
43                result.taskInstance.errors.rejectValue("parentTask", "task.operationNotPermittedOnTaskInTrash")
44                result.error = true
45                return result
46            }
47
48            if(taskInstance.save()) {
49                def taskModification = new TaskModification(person: personService.currentUser(),
50                                                        taskModificationType: TaskModificationType.get(1),
51                                                        task: taskInstance)
52
53                if(!taskModification.save()) {
54                    status.setRollbackOnly()
55                    taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
56                    result.error = true
57                    return result
58                }
59
60                // If we get here all went well.
61                return result
62            }
63            else {
64                result.error = true
65                return result
66            }
67
68        } //end withTransaction
69    } // end create()
70
71    /**
72    * Creates a subTask copying attributes from the parentTask unless otherwise specified.
73    * The taskProcedure is only assigned to the sub task if given in params.
74    * @param parentTask The parent task to get attributes from, also set as the parent.
75    * @param params Overrides the parent task values if specified.
76    * @returns A map containing result.error=true (if any error) and result.taskInstance.
77    */
78    def createSubTask(parentTask, params = [:]) {
79
80        def result = [:]
81
82        //Make our new Task a subTask and set the required properites.
83        def p = [:]
84        p.parentTask = parentTask
85        p.description = params.description ?: parentTask.description
86        p.comment = params.comment ?: parentTask.comment
87
88        p.taskGroup = params.taskGroup ?: parentTask.taskGroup
89        p.taskStatus = TaskStatus.get(1) // A new subTask must always be "Not Started".
90        p.taskPriority = parentTask.taskPriority
91        p.taskType = params.taskType ?: parentTask.taskType
92        p.leadPerson = params.leadPerson ?: parentTask.leadPerson
93        p.primaryAsset = params.primaryAsset ?: parentTask.primaryAsset
94
95        p.targetStartDate = params.targetStartDate ?: parentTask.targetStartDate
96        p.targetCompletionDate = params.targetCompletionDate ?: parentTask.targetCompletionDate
97
98        if(params.taskProcedure) p.taskProcedure = params.taskProcedure
99
100                    //Set the assignedPersons
101//                     taskInstance.assignedPersons.each() {
102//
103//                     def assignedPerson = new AssignedPerson(person: it.person,
104//                                                                                             task: subTaskInstance,
105//                                                                                             estimatedHour: it.estimatedHour,
106//                                                                                             estimatedMinute: it.estimatedMinute).save()
107//                     }
108
109        result = create(p)
110
111    } // end createSubTask()
112
113    /**
114    * Creates a new task entry.
115    * @param params The params to use when creating the new entry.
116    * @returns A map containing result.error=true (if any error), result.entryInstance and result.taskId.
117    */
118    def createEntry(params) {
119        Task.withTransaction { status ->
120            def result = [:]
121            result.entryInstance = new Entry(params)
122            result.entryInstance.enteredBy = personService.currentUser()
123
124            if(result.entryInstance.validate()) {
125                def taskInstance = Task.lock(result.entryInstance.task.id)
126                result.taskId = result.entryInstance.task.id
127
128                if(!taskInstance) {
129                    status.setRollbackOnly()
130                    result.entryInstance.errors.rejectValue('task', "entry.task.notFound")
131                    result.error = true
132                    return result
133                }
134
135                if(taskInstance.taskStatus.id == 3) {
136                    status.setRollbackOnly()
137                    result.entryInstance.errors.rejectValue('task', "task.operationNotPermittedOnCompleteTask")
138                    result.error = true
139                    return result
140                }
141
142                // If task status is "Not Started" and entry type is "Work Done" then we create the started modification and set the status.
143                if(taskInstance.taskStatus.id == 1 && result.entryInstance.entryType.id == 2) {
144
145                    // Create the "Started" task modification, this provides the "Actual started date".
146                    def taskModification = new TaskModification(person: personService.currentUser(),
147                                                            taskModificationType: TaskModificationType.get(2),
148                                                            task: taskInstance)
149
150                    if(!taskModification.save()) {
151                        status.setRollbackOnly()
152                        taskInstance.errors.rejectValue("task", "entry.task.failedToSaveTaskModification")
153                        result.error = true
154                        return result
155                    }
156
157                    // Set task status to "In progress".
158                    taskInstance.taskStatus = TaskStatus.get(2)
159
160                    if(!taskInstance.save()) {
161                        status.setRollbackOnly()
162                        result.entryInstance.errors.rejectValue("task", "entry.task.failedToSave")
163                        result.error = true
164                        return result
165                    }
166                }
167
168                if(!result.entryInstance.save()) {
169                    status.setRollbackOnly()
170                    result.error = true
171                    return result
172                }
173
174                // All went well if we get to here.
175                return result
176            }
177            else {
178                result.error = true
179                return result
180            }
181
182        } //end withTransaction
183    } // end create()
184
185    /**
186    * Updates an existing task.
187    * @param params The params to update for task with id of params.id.
188    * @returns A map containing result.error=true (if any error) and result.taskInstance.
189    */
190    def update(params) {
191        Task.withTransaction { status ->
192            def result = [:]
193            result.taskInstance = Task.get(params.id)
194            if(result.taskInstance) {
195
196                // Optimistic locking check.
197                if(params.version) {
198                    def version = params.version.toLong()
199                    if(result.taskInstance.version > version) {
200                        status.setRollbackOnly()
201                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
202                        result.error = true
203                        return result
204                    }
205                }
206
207                result.taskInstance.properties = params
208
209                if(result.taskInstance.save()) {
210                    def taskModification = new TaskModification(person:personService.currentUser(),
211                                                            taskModificationType: TaskModificationType.get(3),
212                                                            task: result.taskInstance)
213                    if(taskModification.save()) {
214                        // All went well.
215                        return result
216                    }
217                    else {
218                        status.setRollbackOnly()
219                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
220                        result.error = true
221                        return result
222                    }
223                }
224            }
225            // Something failed.
226            status.setRollbackOnly()
227            result.error = true
228            return result
229
230        } //end withTransaction
231    }  // end update()
232
233    /**
234    * Completes an existing task.
235    * @param params The params for task with id of params.id.
236    * @returns A map containing result.error=true (if any error) and result.taskInstance.
237    */
238    def complete(params) {
239        Task.withTransaction { status ->
240            def result = [:]
241            result.taskInstance = Task.get(params.id)
242            if(result.taskInstance) {
243
244                // Optimistic locking check.
245                if(params.version) {
246                    def version = params.version.toLong()
247                    if(result.taskInstance.version > version) {
248                        status.setRollbackOnly()
249                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
250                        result.error = true
251                        return result
252                    }
253                }
254
255                result.taskInstance.taskStatus = TaskStatus.get(3)
256                result.taskInstance.taskRecurringSchedule?.enabled = false
257
258                if(result.taskInstance.save()) {
259                    def taskModification = new TaskModification(person:personService.currentUser(),
260                                                            taskModificationType: TaskModificationType.get(4),
261                                                            task: result.taskInstance)
262
263                    if(taskModification.save()) {
264                        // All went well.
265                        return result
266                    }
267                    else {
268                        status.setRollbackOnly()
269                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
270                        result.error = true
271                        return result
272                    }
273                }
274            }
275            // Something failed.
276            status.setRollbackOnly()
277            result.error = true
278            return result
279
280        } //end withTransaction
281    }  // end complete()
282
283    /**
284    * Reopens an existing task.
285    * @param params The params for task with id of params.id.
286    * @returns A map containing result.error=true (if any error) and result.taskInstance.
287    */
288    def reopen(params) {
289        Task.withTransaction { status ->
290            def result = [:]
291            result.taskInstance = Task.get(params.id)
292            if(result.taskInstance) {
293
294                // Optimistic locking check.
295                if(params.version) {
296                    def version = params.version.toLong()
297                    if(result.taskInstance.version > version) {
298                        status.setRollbackOnly()
299                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
300                        result.error = true
301                        return result
302                    }
303                }
304
305                result.taskInstance.taskStatus = TaskStatus.get(2)
306
307                if(result.taskInstance.save()) {
308                    def taskModification = new TaskModification(person:personService.currentUser(),
309                                                            taskModificationType: TaskModificationType.get(5),
310                                                            task: result.taskInstance)
311                    if(taskModification.save()) {
312                        // All went well.
313                        return result
314                    }
315                    else {
316                        status.setRollbackOnly()
317                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
318                        result.error = true
319                        return result
320                    }
321                }
322            }
323            // Something failed.
324            status.setRollbackOnly()
325            result.error = true
326            return result
327
328        } //end withTransaction
329    }  // end reopen()
330
331    /**
332    * Move a task to the trash.
333    * @param params The params for task with id of params.id.
334    * @returns A map containing result.error=true (if any error) and result.taskInstance.
335    */
336    def trash(params) {
337        Task.withTransaction { status ->
338            def result = [:]
339            result.taskInstance = Task.get(params.id)
340            if(result.taskInstance) {
341
342                // Optimistic locking check.
343                if(params.version) {
344                    def version = params.version.toLong()
345                    if(result.taskInstance.version > version) {
346                        status.setRollbackOnly()
347                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
348                        result.error = true
349                        return result
350                    }
351                }
352
353                result.taskInstance.trash = true
354                result.taskInstance.taskRecurringSchedule?.enabled = false
355
356                if(result.taskInstance.save()) {
357                    def taskModification = new TaskModification(person:personService.currentUser(),
358                                                            taskModificationType: TaskModificationType.get(6),
359                                                            task: result.taskInstance)
360                    if(taskModification.save()) {
361                        // All went well.
362                        return result
363                    }
364                    else {
365                        status.setRollbackOnly()
366                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
367                        result.error = true
368                        return result
369                    }
370                }
371            }
372            // Something failed.
373            status.setRollbackOnly()
374            result.error = true
375            return result
376
377        } //end withTransaction
378    }  // end trash()
379
380    /**
381    * Restore a task from the trash.
382    * @param params The params for task with id of params.id.
383    * @returns A map containing result.error=true (if any error) and result.taskInstance.
384    */
385    def restore(params) {
386        Task.withTransaction { status ->
387            def result = [:]
388            result.taskInstance = Task.get(params.id)
389            if(result.taskInstance) {
390
391                // Optimistic locking check.
392                if(params.version) {
393                    def version = params.version.toLong()
394                    if(result.taskInstance.version > version) {
395                        status.setRollbackOnly()
396                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
397                        result.error = true
398                        return result
399                    }
400                }
401
402                result.taskInstance.trash = false
403
404                if(result.taskInstance.save()) {
405                    def taskModification = new TaskModification(person:personService.currentUser(),
406                                                            taskModificationType: TaskModificationType.get(7),
407                                                            task: result.taskInstance)
408                    if(taskModification.save()) {
409                        // All went well.
410                        return result
411                    }
412                    else {
413                        status.setRollbackOnly()
414                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
415                        result.error = true
416                        return result
417                    }
418                }
419            }
420            // Something failed.
421            status.setRollbackOnly()
422            result.error = true
423            return result
424
425        } //end withTransaction
426    }  // end restore()
427
428    /**
429    * Approve a task.
430    * @param params The params for task with id of params.id.
431    * @returns A map containing result.error=true (if any error) and result.taskInstance.
432    */
433    def approve(params) {
434        Task.withTransaction { status ->
435            def result = [:]
436            result.taskInstance = Task.get(params.id)
437            if(result.taskInstance) {
438
439                // Optimistic locking check.
440                if(params.version) {
441                    def version = params.version.toLong()
442                    if(result.taskInstance.version > version) {
443                        status.setRollbackOnly()
444                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
445                        result.error = true
446                        return result
447                    }
448                }
449
450                result.taskInstance.approved = true
451
452                if(result.taskInstance.save()) {
453                    def taskModification = new TaskModification(person:personService.currentUser(),
454                                                            taskModificationType: TaskModificationType.get(8),
455                                                            task: result.taskInstance)
456                    if(taskModification.save()) {
457                        // All went well.
458                        return result
459                    }
460                    else {
461                        status.setRollbackOnly()
462                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
463                        result.error = true
464                        return result
465                    }
466                }
467            }
468            // Something failed.
469            status.setRollbackOnly()
470            result.error = true
471            return result
472
473        } //end withTransaction
474    }  // end approve()
475
476    /**
477    * Remove a previously given approval from a task.
478    * @param params The params for task with id of params.id.
479    * @returns A map containing result.error=true (if any error) and result.taskInstance.
480    */
481    def renegeApproval(params) {
482        Task.withTransaction { status ->
483            def result = [:]
484            result.taskInstance = Task.get(params.id)
485            if(result.taskInstance) {
486
487                // Optimistic locking check.
488                if(params.version) {
489                    def version = params.version.toLong()
490                    if(result.taskInstance.version > version) {
491                        status.setRollbackOnly()
492                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
493                        result.error = true
494                        return result
495                    }
496                }
497
498                result.taskInstance.approved = false
499
500                if(result.taskInstance.save()) {
501                    def taskModification = new TaskModification(person:personService.currentUser(),
502                                                            taskModificationType: TaskModificationType.get(9),
503                                                            task: result.taskInstance)
504                    if(taskModification.save()) {
505                        // All went well.
506                        return result
507                    }
508                    else {
509                        status.setRollbackOnly()
510                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
511                        result.error = true
512                        return result
513                    }
514                }
515            }
516            // Something failed.
517            status.setRollbackOnly()
518            result.error = true
519            return result
520
521        } //end withTransaction
522    }  // end renegeApproval()
523
524} // end TaskService
Note: See TracBrowser for help on using the repository browser.