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

Last change on this file since 514 was 514, checked in by gav, 9 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.