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

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

Replace personService.currentUser() with the more groovy personService.getCurrentUser() so that personService.currentUser can be called.

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