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

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

Added integration test for TaskSearchService.getPersonsTasks().
Extended TaskService.delete() to handle assignedPersons and assignedGroups.
Use safe collection navigation in AssignedGroupService and AssignedPersonService?.

File size: 35.9 KB
Line 
1import grails.util.Environment
2
3/**
4* Provides a service class for the Task domain class.
5*
6*/
7class TaskService {
8
9    boolean transactional = false
10
11    def authService
12    def assignedGroupService
13    def assignedPersonService
14
15    /**
16    * Determines and returns a possible parent list for a task.
17    * @todo Create and use another method that limits the results to say the latest 20 or 100 tasks?
18    * @param taskInstance The task to use when determining the possible parent list.
19    * @returns A list of the possible parents.
20    */
21    def possibleParentList(taskInstance) {
22        def criteria = taskInstance.createCriteria()
23        def possibleParentList = criteria {
24            and {
25                notEqual('trash', true)
26                notEqual('id', taskInstance.id)
27                taskInstance.subTasks.each() { notEqual('id', it.id) }
28                }
29        }
30    }
31
32    /**
33    * Determines and returns a list of possible task types for scheduled tasks.
34    * @returns A list of the possible task types.
35    */
36    def getScheduledTaskTypes() {
37        def criteria = TaskType.createCriteria()
38        def scheduledTaskTypes = criteria {
39            and {
40                eq('isActive', true)
41                gt('id', 2L)
42                }
43        }
44    }
45
46    /**
47    * Determines and returns a list of possible task priorites for Scheduled tasks.
48    * @returns A list of the possible task priorites.
49    */
50    def getScheduledTaskPriorities() {
51        def criteria = TaskPriority.createCriteria()
52        def scheduledTaskPriorities = [:]
53        scheduledTaskPriorities.list = criteria {
54            and {
55                eq('isActive', true)
56                gt('id', 1L)
57                }
58        }
59        scheduledTaskPriorities.default = scheduledTaskPriorities.list.find { it.id == 4L } //  1-Normal.
60        return scheduledTaskPriorities
61    }
62
63    /**
64    * Determines and returns a list of possible task priorites for Unscheduled tasks.
65    * @returns A map containing a list of the possible task priorites and the default priority.
66    */
67    def getUnscheduledTaskPriorities() {
68        def criteria = TaskPriority.createCriteria()
69        def unscheduledTaskPriorities = [:]
70        unscheduledTaskPriorities.list = criteria {
71            and {
72                eq('isActive', true)
73                lt('id', 5L)
74                ne('id', 1L)
75            }
76        }
77        unscheduledTaskPriorities.default = unscheduledTaskPriorities.list.find { it.id == 3L } // 2-High.
78        return unscheduledTaskPriorities
79    }
80
81    /**
82    * Creates a new task with the given params.
83    * @param params The params to use when creating the new task.
84    * @returns A map containing result.error (if any error) and result.taskInstance.
85    */
86    def save(params) {
87        Task.withTransaction { status ->
88            def result = [:]
89
90            def fail = { Map m ->
91                status.setRollbackOnly()
92                if(result.taskInstance && m.field)
93                    result.taskInstance.errors.rejectValue(m.field, m.code)
94                result.error = [ code: m.code, args: ["Task", params.id] ]
95                return result
96            }
97
98            // Default status to "not started" if not supplied.
99            params.taskStatus = params.taskStatus ?: TaskStatus.get(1)
100
101            // Set budgetStatus.
102            if(params.taskType?.id?.toLong() == 1 || params.taskType?.id?.toLong() == 2) // Immediate Callout or Unsheduled Breakin.
103                params.taskBudgetStatus = params.taskBudgetStatus ?: TaskBudgetStatus.get(1) // Unplanned.
104            else
105                params.taskBudgetStatus = params.taskBudgetStatus ?: TaskBudgetStatus.get(2) // Planned.
106
107            def taskInstance = new Task(params)
108            result.taskInstance = taskInstance
109
110            if(result.taskInstance.parentTask?.trash)
111                return fail(field:"parentTask", code:"task.operationNotPermittedOnTaskInTrash")
112
113            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
114                return fail(code:"default.create.failure")
115
116            def taskModification = new TaskModification(person: authService.currentUser,
117                                                taskModificationType: TaskModificationType.get(1),
118                                                task: taskInstance)
119
120            if(taskModification.hasErrors() || !taskModification.save())
121                return fail(field:"taskModifications", code:"task.modifications.failedToSave")
122
123            //Add the assignedGroups, provided by a new ArrayList(task.assignedGroups)
124            if(params.assignedGroups) {
125                def assignedGroupsResult
126                def assignedGroupParams = [:]
127                params.assignedGroups.each() {
128
129                    assignedGroupParams = [personGroup: it.personGroup,
130                                                                task: taskInstance,
131                                                                estimatedHour: it.estimatedHour,
132                                                                estimatedMinute: it.estimatedMinute]
133
134                    assignedGroupsResult = assignedGroupService.save(assignedGroupParams)
135
136                    if(assignedGroupsResult.error)
137                        return fail(field:"assignedGroups", code:"task.assignedGroups.failedToSave")
138
139                }
140            }
141
142            //Add the assignedPersons, provided by a new ArrayList(task.assignedPersons)
143            if(params.assignedPersons) {
144                def assignedPersonsResult
145                def assignedPersonsParams = [:]
146                params.assignedPersons.each() {
147
148                    assignedPersonsParams = [person: it.person,
149                                                                task: taskInstance,
150                                                                estimatedHour: it.estimatedHour,
151                                                                estimatedMinute: it.estimatedMinute]
152
153                    assignedPersonsResult = assignedPersonService.save(assignedPersonsParams)
154
155                    if(assignedPersonsResult.error)
156                        return fail(field:"assignedPersons", code:"task.assignedPersons.failedToSave")
157
158                }
159            }
160
161            // Success.
162            return result
163
164        } //end withTransaction
165    } // end save()
166
167    /**
168    * Creates a subTask copying sane attributes from the parentTask unless otherwise specified in params.
169    * The taskProcedure is only assigned to the sub task if supplied in params.
170    * The assignedPersons and assignedGroups are only added to the sub task if supplied in params.
171    * Collections in params must be supplied as new ArrayList's.
172    * This method is not intended to be a copyTask method.
173    * There should be no reason to copy tasks, try to find a better solution.
174    * @param parentTask The parent task to get attributes from, also set as the parent.
175    * @param params Overrides the parent task values if specified.
176    * @returns A map containing result.error=true (if any error) and result.taskInstance.
177    */
178    def createSubTask(parentTask, params = [:]) {
179
180        def result = [:]
181
182        //Make our new Task a subTask and set the required properites.
183        def p = [:]
184        p.parentTask = parentTask
185        p.description = params.description ?: parentTask.description
186        p.comment = params.comment ?: parentTask.comment
187        p.targetStartDate = params.targetStartDate ?: parentTask.targetStartDate
188        p.targetCompletionDate = params.targetCompletionDate ?: parentTask.targetCompletionDate
189        p.scheduled = params.scheduled ?:  parentTask.scheduled
190
191        p.taskGroup = params.taskGroup ?: parentTask.taskGroup
192        p.taskStatus = TaskStatus.get(1) // A new subTask must always be "Not Started".
193        p.taskPriority = parentTask.taskPriority
194        p.taskType = params.taskType ?: parentTask.taskType
195        p.leadPerson = params.leadPerson ?: parentTask.leadPerson
196        p.primaryAsset = params.primaryAsset ?: parentTask.primaryAsset
197        p.associatedAssets = params.associatedAssets ?: new ArrayList(parentTask.associatedAssets) // Collection.
198
199        // Supplied by recurring tasks.
200        if(params.taskProcedure) p.taskProcedure = params.taskProcedure
201        if(params.assignedGroups) p.assignedGroups = params.assignedGroups // Collection.
202        if(params.assignedPersons) p.assignedPersons = params.assignedPersons // Collection.
203
204        // trash: A new subTask must always have trash=false, which is already the domain class default.
205
206        // These would be considered copying, hence not done.
207        // taskRecurringSchedule, entries, taskModifications, subTasks, inventoryMovements.
208
209        // Create the sub task and return the result.
210        result = save(p)
211
212        // Approve.
213        if(!result.error && parentTask.approved) {
214            p = [:]
215            p.id = result.taskInstance.id
216            approve(p)
217        }
218
219        // Success.
220        return result
221
222    } // end createSubTask()
223
224    /**
225    * In production tasks are NEVER deleted, only the trash flag is set!
226    * However during testing it may be required to delete a task and that
227    * is why this method exists.
228    */
229    def delete(params) {
230        Task.withTransaction { status ->
231            def result = [:]
232
233            def fail = { Map m ->
234                status.setRollbackOnly()
235                if(result.taskInstance && m.field)
236                    result.taskInstance.errors.rejectValue(m.field, m.code)
237                result.error = [ code: m.code, args: ["Task", params.id] ]
238                return result
239            }
240
241            if(Environment.current == Environment.PRODUCTION)
242                return fail(code:"task.delete.failure.production")
243
244            result.taskInstance = Task.get(params.id)
245
246            if(!result.taskInstance)
247                return fail(code:"default.not.found")
248
249            // Handle taskModifications.
250            def taskModifications = TaskModification.findAllByTask(result.taskInstance)
251            taskModifications.each() {
252                result.taskInstance.removeFromTaskModifications(it)
253                it.delete()
254            }
255
256            // Handle assignedPersons.
257            def taskAssignedPersons = AssignedPerson.findAllByTask(result.taskInstance)
258            taskAssignedPersons.each() {
259                result.taskInstance.removeFromAssignedPersons(it)
260                it.delete()
261            }
262
263            // Handle assignedGroups.
264            def taskAssignedGroups = AssignedGroup.findAllByTask(result.taskInstance)
265            taskAssignedGroups.each() {
266                result.taskInstance.removeFromAssignedGroups(it)
267                it.delete()
268            }
269
270            if(result.error)
271                return result
272
273            try {
274                result.taskInstance.delete(flush:true)
275                return result //Success.
276            }
277            catch(org.springframework.dao.DataIntegrityViolationException e) {
278                return fail(code:"default.delete.failure")
279            }
280
281        } // end withTransaction
282    } // delete()
283
284    /**
285    * Creates a new task entry.
286    * @param params The params to use when creating the new entry.
287    * @returns A map containing result.error=true (if any error), result.entryInstance and result.taskId.
288    */
289    def saveEntry(params) {
290        Task.withTransaction { status ->
291            def result = [:]
292
293            def fail = { Map m ->
294                status.setRollbackOnly()
295                if(result.taskInstance && m.field)
296                    result.taskInstance.errors.rejectValue(m.field, m.code)
297                result.error = [ code: m.code, args: ["Entry", params.id] ]
298                return result
299            }
300
301            result.entryInstance = new Entry(params)
302            result.entryInstance.enteredBy = authService.currentUser
303
304            def taskInstance
305            if(result.entryInstance.task?.id) {
306                result.taskId = result.entryInstance.task.id
307                taskInstance = Task.lock(result.entryInstance.task.id)
308            }
309
310            if(!taskInstance)
311                return fail(field:"task", code:"task.notFound")
312
313            if(result.entryInstance.hasErrors() || !result.entryInstance.save())
314                return fail(code:"default.create.failure")
315
316            if(taskInstance.taskStatus.id == 3)
317                return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
318
319            // If task status is "Not Started" and entry type is "Work Done" and time has been booked.
320            // Then we create the started modification and set task status.
321            if(taskInstance.taskStatus.id == 1 && result.entryInstance.entryType.id == 3
322                && (result.entryInstance.durationHour + result.entryInstance.durationMinute > 0)) {
323
324                // Create the "Started" task modification, this provides the "Actual Started Date".
325                def taskModification = new TaskModification(person: authService.currentUser,
326                                                        taskModificationType: TaskModificationType.read(2),
327                                                        task: taskInstance)
328
329                if(taskModification.hasErrors() || !taskModification.save())
330                    return fail(field:"task", code:"task.modifications.failedToSave")
331
332                // Set task status to "In Progress".
333                taskInstance.taskStatus = TaskStatus.read(2)
334
335                if(taskInstance.hasErrors() || !taskInstance.save())
336                    return fail(field:"task", code:"task.failedToSave")
337            }
338
339            // Success.
340            return result
341
342        } // end withTransaction
343    } // end saveEntry()
344
345    /**
346    * Updates an existing task.
347    * @param params The params to update for task with id of params.id.
348    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
349    */
350    def update(params) {
351        Task.withTransaction { status ->
352            def result = [:]
353
354            def fail = { Map m ->
355                status.setRollbackOnly()
356                if(result.taskInstance && m.field)
357                    result.taskInstance.errors.rejectValue(m.field, m.code)
358                result.error = [ code: m.code, args: ["Task", params.id] ]
359                return result
360            }
361
362            result.taskInstance = Task.get(params.id)
363
364            if(!result.taskInstance)
365                return fail('id', "task.notFound")
366
367            // Optimistic locking check.
368            if(params.version) {
369                if(result.taskInstance.version > params.version.toLong())
370                    return fail(field:"version", code:"default.optimistic.locking.failure")
371            }
372
373            result.taskInstance.properties = params
374
375            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
376                return fail(code:"default.update.failure")
377
378            def taskModification = new TaskModification(person:authService.currentUser,
379                                                    taskModificationType: TaskModificationType.get(3),
380                                                    task: result.taskInstance)
381
382            if(taskModification.hasErrors() || !taskModification.save())
383                return fail(code:"task.modifications.failedToSave")
384
385            // Success.
386            return result
387
388        } //end withTransaction
389    }  // end update()
390
391    /**
392    * Completes an existing task.
393    * @param params The params for task with id of params.id.
394    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
395    */
396    def complete(params) {
397        Task.withTransaction { status ->
398            def result = [:]
399
400            def fail = { Map m ->
401                status.setRollbackOnly()
402                if(result.taskInstance && m.field)
403                    result.taskInstance.errors.rejectValue(m.field, m.code)
404                result.error = [ code: m.code, args: ["Task", params.id] ]
405                return result
406            }
407
408            result.taskInstance = Task.get(params.id)
409
410            if(!result.taskInstance)
411                return fail(code:"default.not.found")
412
413            // Optimistic locking check.
414            if(params.version) {
415                if(result.taskInstance.version > params.version.toLong())
416                    return fail(field:"version", code:"default.optimistic.locking.failure")
417            }
418
419            result.taskInstance.taskStatus = TaskStatus.get(3)
420            result.taskInstance.attentionFlag = false
421            result.taskInstance.taskRecurringSchedule?.enabled = false
422
423            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
424                return fail(code:"default.update.failure")
425
426            def taskModification = new TaskModification(person:authService.currentUser,
427                                                    taskModificationType: TaskModificationType.get(4),
428                                                    task: result.taskInstance)
429
430
431            if(taskModification.hasErrors() || !taskModification.save())
432                return fail(code:"task.modifications.failedToSave")
433
434            // Success.
435            return result
436
437        } //end withTransaction
438    }  // end complete()
439
440    /**
441    * Sets the attentionFlag on an existing task.
442    * @param params The params for task with id of params.id.
443    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
444    */
445    def setAttentionFlag(params) {
446        Task.withTransaction { status ->
447            def result = [:]
448
449            def fail = { Map m ->
450                status.setRollbackOnly()
451                if(result.taskInstance && m.field)
452                    result.taskInstance.errors.rejectValue(m.field, m.code)
453                result.error = [ code: m.code, args: ["Task", params.id] ]
454                return result
455            }
456
457            result.taskInstance = Task.get(params.id)
458
459            if(!result.taskInstance)
460                return fail(code:"default.not.found")
461
462            // Optimistic locking check.
463            if(params.version) {
464                if(result.taskInstance.version > params.version.toLong())
465                    return fail(field:"version", code:"default.optimistic.locking.failure")
466            }
467
468            result.taskInstance.attentionFlag = true
469
470            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
471                return fail(code:"default.update.failure")
472
473            def taskModification = new TaskModification(person:authService.currentUser,
474                                                    taskModificationType: TaskModificationType.get(12),
475                                                    task: result.taskInstance)
476
477            if(taskModification.hasErrors() || !taskModification.save())
478                return fail(code:"task.modifications.failedToSave")
479
480            // Success.
481            return result
482
483        } //end withTransaction
484    }  // end flag()
485
486    /**
487    * Clears the attentionFlag on an existing task.
488    * @param params The params for task with id of params.id.
489    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
490    */
491    def clearAttentionFlag(params) {
492        Task.withTransaction { status ->
493            def result = [:]
494
495            def fail = { Map m ->
496                status.setRollbackOnly()
497                if(result.taskInstance && m.field)
498                    result.taskInstance.errors.rejectValue(m.field, m.code)
499                result.error = [ code: m.code, args: ["Task", params.id] ]
500                return result
501            }
502
503            result.taskInstance = Task.get(params.id)
504
505            if(!result.taskInstance)
506                return fail(code:"default.not.found")
507
508            // Optimistic locking check.
509            if(params.version) {
510                if(result.taskInstance.version > params.version.toLong())
511                    return fail(field:"version", code:"default.optimistic.locking.failure")
512            }
513
514            result.taskInstance.attentionFlag = false
515
516            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
517                return fail(code:"default.update.failure")
518
519            def taskModification = new TaskModification(person:authService.currentUser,
520                                                    taskModificationType: TaskModificationType.get(13),
521                                                    task: result.taskInstance)
522
523            if(taskModification.hasErrors() || !taskModification.save())
524                return fail(code:"task.modifications.failedToSave")
525
526            // Success.
527            return result
528
529        } //end withTransaction
530    }  // end clearFlag()
531
532    /**
533    * Reopens an existing task.
534    * @param params The params for task with id of params.id.
535    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
536    */
537    def reopen(params) {
538        Task.withTransaction { status ->
539            def result = [:]
540
541            def fail = { Map m ->
542                status.setRollbackOnly()
543                if(result.taskInstance && m.field)
544                    result.taskInstance.errors.rejectValue(m.field, m.code)
545                result.error = [ code: m.code, args: ["Task", params.id] ]
546                return result
547            }
548
549            result.taskInstance = Task.get(params.id)
550
551            if(!result.taskInstance)
552                return fail(code:"default.not.found")
553
554            // Optimistic locking check.
555            if(params.version) {
556                if(result.taskInstance.version > params.version.toLong())
557                    return fail(field:"version", code:"default.optimistic.locking.failure")
558            }
559
560            def isInProgress = false
561            result.taskInstance.entries.each() {
562                if(it.entryType.id == 3 && (it.durationHour + it.durationMinute > 0) )
563                    isInProgress = true
564            }
565
566            if(isInProgress)
567                result.taskInstance.taskStatus = TaskStatus.read(2) // In Progress
568            else
569                result.taskInstance.taskStatus = TaskStatus.read(1) // Not Started
570
571            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
572                return fail(code:"default.update.failure")
573
574            def taskModification = new TaskModification(person:authService.currentUser,
575                                                    taskModificationType: TaskModificationType.get(5),
576                                                    task: result.taskInstance)
577
578            if(taskModification.hasErrors() || !taskModification.save())
579                return fail(code:"task.modifications.failedToSave")
580
581            // Success.
582            return result
583
584        } //end withTransaction
585    }  // end reopen()
586
587    /**
588    * Move a task to the trash.
589    * @param params The params for task with id of params.id.
590    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
591    */
592    def trash(params) {
593        Task.withTransaction { status ->
594            def result = [:]
595
596            def fail = { Map m ->
597                status.setRollbackOnly()
598                if(result.taskInstance && m.field)
599                    result.taskInstance.errors.rejectValue(m.field, m.code)
600                result.error = [ code: m.code, args: ["Task", params.id] ]
601                return result
602            }
603
604            result.taskInstance = Task.get(params.id)
605
606            if(!result.taskInstance)
607                return fail(code:"default.not.found")
608
609            // Optimistic locking check.
610            if(params.version) {
611                if(result.taskInstance.version > params.version.toLong())
612                    return fail(field:"version", code:"default.optimistic.locking.failure")
613            }
614
615            result.taskInstance.trash = true
616            result.taskInstance.attentionFlag = false
617            result.taskInstance.taskRecurringSchedule?.enabled = false
618
619            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
620                return fail(code:"default.update.failure")
621
622            def taskModification = new TaskModification(person:authService.currentUser,
623                                                    taskModificationType: TaskModificationType.get(6),
624                                                    task: result.taskInstance)
625
626            if(taskModification.hasErrors() || !taskModification.save())
627                return fail(code:"task.modifications.failedToSave")
628
629            // Success.
630            return result
631
632        } //end withTransaction
633    }  // end trash()
634
635    /**
636    * Restore a task from the trash.
637    * @param params The params for task with id of params.id.
638    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
639    */
640    def restore(params) {
641        Task.withTransaction { status ->
642            def result = [:]
643
644            def fail = { Map m ->
645                status.setRollbackOnly()
646                if(result.taskInstance && m.field)
647                    result.taskInstance.errors.rejectValue(m.field, m.code)
648                result.error = [ code: m.code, args: ["Task", params.id] ]
649                return result
650            }
651
652            result.taskInstance = Task.get(params.id)
653
654            if(!result.taskInstance)
655                return fail(code:"default.not.found")
656
657            // Optimistic locking check.
658            if(params.version) {
659                if(result.taskInstance.version > params.version.toLong())
660                    return fail(field:"version", code:"default.optimistic.locking.failure")
661            }
662
663            result.taskInstance.trash = false
664
665            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
666                return fail(code:"default.update.failure")
667
668            def taskModification = new TaskModification(person:authService.currentUser,
669                                                    taskModificationType: TaskModificationType.get(7),
670                                                    task: result.taskInstance)
671
672            if(taskModification.hasErrors() || !taskModification.save())
673                return fail(code:"task.modifications.failedToSave")
674
675            // Success.
676            return result
677
678        } //end withTransaction
679    }  // end restore()
680
681    /**
682    * Approve a task.
683    * @param params The params for task with id of params.id.
684    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
685    */
686    def approve(params) {
687        Task.withTransaction { status ->
688            def result = [:]
689
690            def fail = { Map m ->
691                status.setRollbackOnly()
692                if(result.taskInstance && m.field)
693                    result.taskInstance.errors.rejectValue(m.field, m.code)
694                result.error = [ code: m.code, args: ["Task", params.id] ]
695                return result
696            }
697
698            result.taskInstance = Task.get(params.id)
699
700            if(!result.taskInstance)
701                return fail(code:"default.not.found")
702
703            // Optimistic locking check.
704            if(params.version) {
705                if(result.taskInstance.version > params.version.toLong())
706                    return fail(field:"version", code:"default.optimistic.locking.failure")
707            }
708
709            result.taskInstance.approved = true
710
711            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
712                return fail(code:"default.update.failure")
713
714            def taskModification = new TaskModification(person:authService.currentUser,
715                                                    taskModificationType: TaskModificationType.get(8),
716                                                    task: result.taskInstance)
717
718            if(taskModification.hasErrors() || !taskModification.save())
719                return fail(code:"task.modifications.failedToSave")
720
721            // Success.
722            return result
723
724        } //end withTransaction
725    }  // end approve()
726
727    /**
728    * Remove a previously given approval from a task.
729    * @param params The params for task with id of params.id.
730    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
731    */
732    def renegeApproval(params) {
733        Task.withTransaction { status ->
734            def result = [:]
735
736            def fail = { Map m ->
737                status.setRollbackOnly()
738                if(result.taskInstance && m.field)
739                    result.taskInstance.errors.rejectValue(m.field, m.code)
740                result.error = [ code: m.code, args: ["Task", params.id] ]
741                return result
742            }
743
744            result.taskInstance = Task.get(params.id)
745
746            if(!result.taskInstance)
747                return fail(code:"default.not.found")
748
749            // Optimistic locking check.
750            if(params.version) {
751                if(result.taskInstance.version > params.version.toLong())
752                    return fail(field:"version", code:"default.optimistic.locking.failure")
753            }
754
755            result.taskInstance.approved = false
756
757            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
758                return fail(code:"default.update.failure")
759
760            def taskModification = new TaskModification(person:authService.currentUser,
761                                                    taskModificationType: TaskModificationType.get(9),
762                                                    task: result.taskInstance)
763
764            if(taskModification.hasErrors() || !taskModification.save())
765                return fail(code:"task.modifications.failedToSave")
766
767            // Success.
768            return result
769
770        } //end withTransaction
771    }  // end renegeApproval()
772
773    /**
774    * Creates a new unscheduled breakin task with the given params.
775    * @param params The params to use when creating the new task.
776    * @returns A map containing result.error (if any error) and result.taskInstance.
777    */
778    def saveUnscheduled(params) {
779        Task.withTransaction { status ->
780            def result = [:]
781
782            def fail = { Map m ->
783                status.setRollbackOnly()
784                if(result.taskInstance && m.field)
785                    result.taskInstance.errors.rejectValue(m.field, m.code)
786                result.error = [ code: m.code, args: ["Task", params.id] ]
787                return result
788            }
789
790            // If not supplied.
791            if(!params.taskStatus)
792                params.taskStatus = TaskStatus.get(1) // Not Started.
793
794            result.taskInstance = new Task(params)
795
796            // Always for an unscheduled breakin..
797            result.taskInstance.taskType = TaskType.get(2) // Unscheduled Breakin.
798            result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
799
800            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
801                fail(code:"default.create.failure")
802
803            if(!result.error) {
804                def taskModification = new TaskModification(person: authService.currentUser,
805                                                                taskModificationType: TaskModificationType.get(1), // Created.
806                                                                task: result.taskInstance)
807
808                if(taskModification.hasErrors() || !taskModification.save())
809                    fail(field:"taskModifications", code:"task.modifications.failedToSave")
810            }
811
812            // Success.
813            return result
814
815        } //end withTransaction
816    } // end saveUnscheduled()
817
818    /**
819    * Creates a new immediate callout task with the given params.
820    * @param params The params to use when creating the new task.
821    * @returns A map containing result.error (if any error) and result.taskInstance.
822    */
823    def saveImmediateCallout(params) {
824        Task.withTransaction { status ->
825            def result = [:]
826
827            def fail = { Map m ->
828                status.setRollbackOnly()
829                if(result.taskInstance && m.field)
830                    result.taskInstance.errors.rejectValue(m.field, m.code)
831                result.error = [ code: m.code, args: ["Task", params.id] ]
832                return result
833            }
834
835            // If not supplied.
836            if(!params.taskStatus)
837                params.taskStatus = TaskStatus.get(1) // Not Started.
838
839            result.taskInstance = new Task(params)
840
841            // Always for an immediate callout.
842            result.taskInstance.taskType = TaskType.get(1) // Immediate Callout.
843            result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
844            result.taskInstance.taskPriority = TaskPriority.get(1) // Immediate.
845            result.taskInstance.taskGroup = TaskGroup.get(1) // Engineering Activites.
846            result.taskInstance.approved = true
847            result.taskInstance.leadPerson = authService.currentUser
848            result.taskInstance.targetCompletionDate = result.taskInstance.targetStartDate
849
850            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
851                fail(code:"default.create.failure")
852
853            if(!result.error) {
854                def taskModification = new TaskModification(person: authService.currentUser,
855                                                                taskModificationType: TaskModificationType.get(1), // Created.
856                                                                task: result.taskInstance)
857
858                if(taskModification.hasErrors() || !taskModification.save())
859                    fail(field:"taskModifications", code:"task.modifications.failedToSave")
860            }
861
862            def productionReference
863            if(params.entryFault.productionReference.id.isLong())
864                productionReference = ProductionReference.get(params.entryFault.productionReference.id.toLong())
865
866            def faultParams = [task: result.taskInstance,
867                                            entryType: EntryType.get(1),
868                                            comment: params.entryFault.comment,
869                                            dateDone: result.taskInstance.targetStartDate,
870                                            productionReference: productionReference,
871                                            durationHour: params.entryFault.durationHour,
872                                            durationMinute: params.entryFault.durationMinute]
873            def faultResult = saveEntry(faultParams)
874            result.entryFaultInstance = faultResult.entryInstance
875
876            def causeParams = [task: result.taskInstance,
877                                            entryType: EntryType.get(2),
878                                            dateDone: result.taskInstance.targetStartDate,
879                                            comment: params.entryCause.comment]
880            def causeResult = saveEntry(causeParams)
881            result.entryCauseInstance = causeResult.entryInstance
882
883            def workDoneParams = [task: result.taskInstance,
884                                                    entryType: EntryType.get(3),
885                                                    comment: params.entryWorkDone.comment,
886                                            dateDone: result.taskInstance.targetStartDate,
887                                                    durationHour: params.entryWorkDone.durationHour,
888                                                    durationMinute: params.entryWorkDone.durationMinute]
889            def workDoneResult = saveEntry(workDoneParams)
890            result.entryWorkDoneInstance = workDoneResult.entryInstance
891
892            if(result.error)
893                return result
894
895            if(causeResult.error)
896                return fail(code: "default.create.failure")
897
898            if(faultResult.error)
899                return fail(code: "default.create.failure")
900
901            if(workDoneResult.error)
902                return fail(code: "default.create.failure")
903
904            // Success.
905            return result
906
907        } //end withTransaction
908    } // end saveImmediateCallout()
909
910} // end TaskService
Note: See TracBrowser for help on using the repository browser.