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

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

Add create unsheduled task feature.
Refactor task priorities.
Limit task types and priorites during task creation.
Add work around for show and edit navigation links in task views.

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