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

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

Setup approved and scheduled during subTask creation.

File size: 33.5 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        p.scheduled = params.scheduled ?:  parentTask.scheduled
188
189        p.taskGroup = params.taskGroup ?: parentTask.taskGroup
190        p.taskStatus = TaskStatus.get(1) // A new subTask must always be "Not Started".
191        p.taskPriority = parentTask.taskPriority
192        p.taskType = params.taskType ?: parentTask.taskType
193        p.leadPerson = params.leadPerson ?: parentTask.leadPerson
194        p.primaryAsset = params.primaryAsset ?: parentTask.primaryAsset
195        p.associatedAssets = params.associatedAssets ?: new ArrayList(parentTask.associatedAssets) // Collection.
196
197        // Supplied by recurring tasks.
198        if(params.taskProcedure) p.taskProcedure = params.taskProcedure
199        if(params.assignedGroups) p.assignedGroups = params.assignedGroups // Collection.
200        if(params.assignedPersons) p.assignedPersons = params.assignedPersons // Collection.
201
202        // trash: A new subTask must always have trash=false, which is already the domain class default.
203
204        // These would be considered copying, hence not done.
205        // taskRecurringSchedule, entries, taskModifications, subTasks, inventoryMovements.
206
207        // Create the sub task and return the result.
208        result = save(p)
209
210        // Approve.
211        if(!result.error && parentTask.approved) {
212            p = [:]
213            p.id = result.taskInstance.id
214            approve(p)
215        }
216
217        // Success.
218        return result
219
220    } // end createSubTask()
221
222    /**
223    * Creates a new task entry.
224    * @param params The params to use when creating the new entry.
225    * @returns A map containing result.error=true (if any error), result.entryInstance and result.taskId.
226    */
227    def saveEntry(params) {
228        Task.withTransaction { status ->
229            def result = [:]
230
231            def fail = { Map m ->
232                status.setRollbackOnly()
233                if(result.taskInstance && m.field)
234                    result.taskInstance.errors.rejectValue(m.field, m.code)
235                result.error = [ code: m.code, args: ["Entry", params.id] ]
236                return result
237            }
238
239            result.entryInstance = new Entry(params)
240            result.entryInstance.enteredBy = authService.currentUser
241
242            def taskInstance
243            if(result.entryInstance.task.id) {
244                result.taskId = result.entryInstance.task.id
245                taskInstance = Task.lock(result.entryInstance.task.id)
246            }
247
248            if(!taskInstance)
249                return fail(field:"task", code:"task.notFound")
250
251            if(result.entryInstance.hasErrors() || !result.entryInstance.save())
252                return fail(code:"default.create.failure")
253
254            if(taskInstance.taskStatus.id == 3)
255                return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
256
257            // If task status is "Not Started" and entry type is "Work Done" then we create the started modification and set the status.
258            if(taskInstance.taskStatus.id == 1 && result.entryInstance.entryType.id == 3) {
259
260                // Create the "Started" task modification, this provides the "Actual Started Date".
261                def taskModification = new TaskModification(person: authService.currentUser,
262                                                        taskModificationType: TaskModificationType.get(2),
263                                                        task: taskInstance)
264
265                if(taskModification.hasErrors() || !taskModification.save())
266                    return fail(field:"task", code:"task.modifications.failedToSave")
267
268                // Set task status to "In Progress".
269                taskInstance.taskStatus = TaskStatus.get(2)
270
271                if(taskInstance.hasErrors() || !taskInstance.save())
272                    return fail(field:"task", code:"task.failedToSave")
273            }
274
275            if(result.entryInstance.hasErrors() || !result.entryInstance.save())
276                return fail(field:"task", code:"default.create.failure")
277
278            // Success.
279            return result
280
281        } //end withTransaction
282    } // end saveEntry()
283
284    /**
285    * Updates an existing task.
286    * @param params The params to update for task with id of params.id.
287    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
288    */
289    def update(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: ["Task", params.id] ]
298                return result
299            }
300
301            result.taskInstance = Task.get(params.id)
302
303            if(!result.taskInstance)
304                return fail('id', "task.notFound")
305
306            // Optimistic locking check.
307            if(params.version) {
308                if(result.taskInstance.version > params.version.toLong())
309                    return fail(field:"version", code:"default.optimistic.locking.failure")
310            }
311
312            result.taskInstance.properties = params
313
314            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
315                return fail(code:"default.update.failure")
316
317            def taskModification = new TaskModification(person:authService.currentUser,
318                                                    taskModificationType: TaskModificationType.get(3),
319                                                    task: result.taskInstance)
320
321            if(taskModification.hasErrors() || !taskModification.save())
322                return fail(code:"task.modifications.failedToSave")
323
324            // Success.
325            return result
326
327        } //end withTransaction
328    }  // end update()
329
330    /**
331    * Completes an existing task.
332    * @param params The params for task with id of params.id.
333    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
334    */
335    def complete(params) {
336        Task.withTransaction { status ->
337            def result = [:]
338
339            def fail = { Map m ->
340                status.setRollbackOnly()
341                if(result.taskInstance && m.field)
342                    result.taskInstance.errors.rejectValue(m.field, m.code)
343                result.error = [ code: m.code, args: ["Task", params.id] ]
344                return result
345            }
346
347            result.taskInstance = Task.get(params.id)
348
349            if(!result.taskInstance)
350                return fail(code:"default.not.found")
351
352            // Optimistic locking check.
353            if(params.version) {
354                if(result.taskInstance.version > params.version.toLong())
355                    return fail(field:"version", code:"default.optimistic.locking.failure")
356            }
357
358            result.taskInstance.taskStatus = TaskStatus.get(3)
359            result.taskInstance.attentionFlag = false
360            result.taskInstance.taskRecurringSchedule?.enabled = false
361
362            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
363                return fail(code:"default.update.failure")
364
365            def taskModification = new TaskModification(person:authService.currentUser,
366                                                    taskModificationType: TaskModificationType.get(4),
367                                                    task: result.taskInstance)
368
369
370            if(taskModification.hasErrors() || !taskModification.save())
371                return fail(code:"task.modifications.failedToSave")
372
373            // Success.
374            return result
375
376        } //end withTransaction
377    }  // end complete()
378
379    /**
380    * Sets the attentionFlag on an existing task.
381    * @param params The params for task with id of params.id.
382    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
383    */
384    def setAttentionFlag(params) {
385        Task.withTransaction { status ->
386            def result = [:]
387
388            def fail = { Map m ->
389                status.setRollbackOnly()
390                if(result.taskInstance && m.field)
391                    result.taskInstance.errors.rejectValue(m.field, m.code)
392                result.error = [ code: m.code, args: ["Task", params.id] ]
393                return result
394            }
395
396            result.taskInstance = Task.get(params.id)
397
398            if(!result.taskInstance)
399                return fail(code:"default.not.found")
400
401            // Optimistic locking check.
402            if(params.version) {
403                if(result.taskInstance.version > params.version.toLong())
404                    return fail(field:"version", code:"default.optimistic.locking.failure")
405            }
406
407            result.taskInstance.attentionFlag = true
408
409            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
410                return fail(code:"default.update.failure")
411
412            def taskModification = new TaskModification(person:authService.currentUser,
413                                                    taskModificationType: TaskModificationType.get(12),
414                                                    task: result.taskInstance)
415
416            if(taskModification.hasErrors() || !taskModification.save())
417                return fail(code:"task.modifications.failedToSave")
418
419            // Success.
420            return result
421
422        } //end withTransaction
423    }  // end flag()
424
425    /**
426    * Clears the attentionFlag on an existing task.
427    * @param params The params for task with id of params.id.
428    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
429    */
430    def clearAttentionFlag(params) {
431        Task.withTransaction { status ->
432            def result = [:]
433
434            def fail = { Map m ->
435                status.setRollbackOnly()
436                if(result.taskInstance && m.field)
437                    result.taskInstance.errors.rejectValue(m.field, m.code)
438                result.error = [ code: m.code, args: ["Task", params.id] ]
439                return result
440            }
441
442            result.taskInstance = Task.get(params.id)
443
444            if(!result.taskInstance)
445                return fail(code:"default.not.found")
446
447            // Optimistic locking check.
448            if(params.version) {
449                if(result.taskInstance.version > params.version.toLong())
450                    return fail(field:"version", code:"default.optimistic.locking.failure")
451            }
452
453            result.taskInstance.attentionFlag = false
454
455            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
456                return fail(code:"default.update.failure")
457
458            def taskModification = new TaskModification(person:authService.currentUser,
459                                                    taskModificationType: TaskModificationType.get(13),
460                                                    task: result.taskInstance)
461
462            if(taskModification.hasErrors() || !taskModification.save())
463                return fail(code:"task.modifications.failedToSave")
464
465            // Success.
466            return result
467
468        } //end withTransaction
469    }  // end clearFlag()
470
471    /**
472    * Reopens an existing task.
473    * @param params The params for task with id of params.id.
474    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
475    */
476    def reopen(params) {
477        Task.withTransaction { status ->
478            def result = [:]
479
480            def fail = { Map m ->
481                status.setRollbackOnly()
482                if(result.taskInstance && m.field)
483                    result.taskInstance.errors.rejectValue(m.field, m.code)
484                result.error = [ code: m.code, args: ["Task", params.id] ]
485                return result
486            }
487
488            result.taskInstance = Task.get(params.id)
489
490            if(!result.taskInstance)
491                return fail(code:"default.not.found")
492
493            // Optimistic locking check.
494            if(params.version) {
495                if(result.taskInstance.version > params.version.toLong())
496                    return fail(field:"version", code:"default.optimistic.locking.failure")
497            }
498
499            result.taskInstance.taskStatus = TaskStatus.get(2)
500
501            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
502                return fail(code:"default.update.failure")
503
504            def taskModification = new TaskModification(person:authService.currentUser,
505                                                    taskModificationType: TaskModificationType.get(5),
506                                                    task: result.taskInstance)
507
508            if(taskModification.hasErrors() || !taskModification.save())
509                return fail(code:"task.modifications.failedToSave")
510
511            // Success.
512            return result
513
514        } //end withTransaction
515    }  // end reopen()
516
517    /**
518    * Move a task to the trash.
519    * @param params The params for task with id of params.id.
520    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
521    */
522    def trash(params) {
523        Task.withTransaction { status ->
524            def result = [:]
525
526            def fail = { Map m ->
527                status.setRollbackOnly()
528                if(result.taskInstance && m.field)
529                    result.taskInstance.errors.rejectValue(m.field, m.code)
530                result.error = [ code: m.code, args: ["Task", params.id] ]
531                return result
532            }
533
534            result.taskInstance = Task.get(params.id)
535
536            if(!result.taskInstance)
537                return fail(code:"default.not.found")
538
539            // Optimistic locking check.
540            if(params.version) {
541                if(result.taskInstance.version > params.version.toLong())
542                    return fail(field:"version", code:"default.optimistic.locking.failure")
543            }
544
545            result.taskInstance.trash = true
546            result.taskInstance.attentionFlag = false
547            result.taskInstance.taskRecurringSchedule?.enabled = false
548
549            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
550                return fail(code:"default.update.failure")
551
552            def taskModification = new TaskModification(person:authService.currentUser,
553                                                    taskModificationType: TaskModificationType.get(6),
554                                                    task: result.taskInstance)
555
556            if(taskModification.hasErrors() || !taskModification.save())
557                return fail(code:"task.modifications.failedToSave")
558
559            // Success.
560            return result
561
562        } //end withTransaction
563    }  // end trash()
564
565    /**
566    * Restore a task from the trash.
567    * @param params The params for task with id of params.id.
568    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
569    */
570    def restore(params) {
571        Task.withTransaction { status ->
572            def result = [:]
573
574            def fail = { Map m ->
575                status.setRollbackOnly()
576                if(result.taskInstance && m.field)
577                    result.taskInstance.errors.rejectValue(m.field, m.code)
578                result.error = [ code: m.code, args: ["Task", params.id] ]
579                return result
580            }
581
582            result.taskInstance = Task.get(params.id)
583
584            if(!result.taskInstance)
585                return fail(code:"default.not.found")
586
587            // Optimistic locking check.
588            if(params.version) {
589                if(result.taskInstance.version > params.version.toLong())
590                    return fail(field:"version", code:"default.optimistic.locking.failure")
591            }
592
593            result.taskInstance.trash = false
594
595            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
596                return fail(code:"default.update.failure")
597
598            def taskModification = new TaskModification(person:authService.currentUser,
599                                                    taskModificationType: TaskModificationType.get(7),
600                                                    task: result.taskInstance)
601
602            if(taskModification.hasErrors() || !taskModification.save())
603                return fail(code:"task.modifications.failedToSave")
604
605            // Success.
606            return result
607
608        } //end withTransaction
609    }  // end restore()
610
611    /**
612    * Approve a task.
613    * @param params The params for task with id of params.id.
614    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
615    */
616    def approve(params) {
617        Task.withTransaction { status ->
618            def result = [:]
619
620            def fail = { Map m ->
621                status.setRollbackOnly()
622                if(result.taskInstance && m.field)
623                    result.taskInstance.errors.rejectValue(m.field, m.code)
624                result.error = [ code: m.code, args: ["Task", params.id] ]
625                return result
626            }
627
628            result.taskInstance = Task.get(params.id)
629
630            if(!result.taskInstance)
631                return fail(code:"default.not.found")
632
633            // Optimistic locking check.
634            if(params.version) {
635                if(result.taskInstance.version > params.version.toLong())
636                    return fail(field:"version", code:"default.optimistic.locking.failure")
637            }
638
639            result.taskInstance.approved = true
640
641            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
642                return fail(code:"default.update.failure")
643
644            def taskModification = new TaskModification(person:authService.currentUser,
645                                                    taskModificationType: TaskModificationType.get(8),
646                                                    task: result.taskInstance)
647
648            if(taskModification.hasErrors() || !taskModification.save())
649                return fail(code:"task.modifications.failedToSave")
650
651            // Success.
652            return result
653
654        } //end withTransaction
655    }  // end approve()
656
657    /**
658    * Remove a previously given approval from a task.
659    * @param params The params for task with id of params.id.
660    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
661    */
662    def renegeApproval(params) {
663        Task.withTransaction { status ->
664            def result = [:]
665
666            def fail = { Map m ->
667                status.setRollbackOnly()
668                if(result.taskInstance && m.field)
669                    result.taskInstance.errors.rejectValue(m.field, m.code)
670                result.error = [ code: m.code, args: ["Task", params.id] ]
671                return result
672            }
673
674            result.taskInstance = Task.get(params.id)
675
676            if(!result.taskInstance)
677                return fail(code:"default.not.found")
678
679            // Optimistic locking check.
680            if(params.version) {
681                if(result.taskInstance.version > params.version.toLong())
682                    return fail(field:"version", code:"default.optimistic.locking.failure")
683            }
684
685            result.taskInstance.approved = false
686
687            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
688                return fail(code:"default.update.failure")
689
690            def taskModification = new TaskModification(person:authService.currentUser,
691                                                    taskModificationType: TaskModificationType.get(9),
692                                                    task: result.taskInstance)
693
694            if(taskModification.hasErrors() || !taskModification.save())
695                return fail(code:"task.modifications.failedToSave")
696
697            // Success.
698            return result
699
700        } //end withTransaction
701    }  // end renegeApproval()
702
703    /**
704    * Creates a new unscheduled breakin task with the given params.
705    * @param params The params to use when creating the new task.
706    * @returns A map containing result.error (if any error) and result.taskInstance.
707    */
708    def saveUnscheduled(params) {
709        Task.withTransaction { status ->
710            def result = [:]
711
712            def fail = { Map m ->
713                status.setRollbackOnly()
714                if(result.taskInstance && m.field)
715                    result.taskInstance.errors.rejectValue(m.field, m.code)
716                result.error = [ code: m.code, args: ["Task", params.id] ]
717                return result
718            }
719
720            // If not supplied.
721            if(!params.taskStatus)
722                params.taskStatus = TaskStatus.get(1) // Not Started.
723
724            result.taskInstance = new Task(params)
725
726            // Always for an unscheduled breakin..
727            result.taskInstance.taskType = TaskType.get(2) // Unscheduled Breakin.
728            result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
729
730            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
731                fail(code:"default.create.failure")
732
733            if(!result.error) {
734                def taskModification = new TaskModification(person: authService.currentUser,
735                                                                taskModificationType: TaskModificationType.get(1), // Created.
736                                                                task: result.taskInstance)
737
738                if(taskModification.hasErrors() || !taskModification.save())
739                    fail(field:"taskModifications", code:"task.modifications.failedToSave")
740            }
741
742            // Success.
743            return result
744
745        } //end withTransaction
746    } // end saveUnscheduled()
747
748    /**
749    * Creates a new immediate callout task with the given params.
750    * @param params The params to use when creating the new task.
751    * @returns A map containing result.error (if any error) and result.taskInstance.
752    */
753    def saveImmediateCallout(params) {
754        Task.withTransaction { status ->
755            def result = [:]
756
757            def fail = { Map m ->
758                status.setRollbackOnly()
759                if(result.taskInstance && m.field)
760                    result.taskInstance.errors.rejectValue(m.field, m.code)
761                result.error = [ code: m.code, args: ["Task", params.id] ]
762                return result
763            }
764
765            // If not supplied.
766            if(!params.taskStatus)
767                params.taskStatus = TaskStatus.get(1) // Not Started.
768
769            result.taskInstance = new Task(params)
770
771            // Always for an immediate callout.
772            result.taskInstance.taskType = TaskType.get(1) // Immediate Callout.
773            result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
774            result.taskInstance.taskPriority = TaskPriority.get(1) // Immediate.
775            result.taskInstance.taskGroup = TaskGroup.get(1) // Engineering Activites.
776            result.taskInstance.approved = true
777            result.taskInstance.leadPerson = authService.currentUser
778            result.taskInstance.targetCompletionDate = result.taskInstance.targetStartDate
779
780            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
781                fail(code:"default.create.failure")
782
783            if(!result.error) {
784                def taskModification = new TaskModification(person: authService.currentUser,
785                                                                taskModificationType: TaskModificationType.get(1), // Created.
786                                                                task: result.taskInstance)
787
788                if(taskModification.hasErrors() || !taskModification.save())
789                    fail(field:"taskModifications", code:"task.modifications.failedToSave")
790            }
791
792            def productionReference
793            if(params.entryFault.productionReference.id.isLong())
794                productionReference = ProductionReference.get(params.entryFault.productionReference.id.toLong())
795
796            def faultParams = [task: result.taskInstance,
797                                            entryType: EntryType.get(1),
798                                            comment: params.entryFault.comment,
799                                            dateDone: result.taskInstance.targetStartDate,
800                                            productionReference: productionReference,
801                                            durationHour: params.entryFault.durationHour,
802                                            durationMinute: params.entryFault.durationMinute]
803            def faultResult = saveEntry(faultParams)
804            result.entryFaultInstance = faultResult.entryInstance
805
806            def causeParams = [task: result.taskInstance,
807                                            entryType: EntryType.get(2),
808                                            dateDone: result.taskInstance.targetStartDate,
809                                            comment: params.entryCause.comment]
810            def causeResult = saveEntry(causeParams)
811            result.entryCauseInstance = causeResult.entryInstance
812
813            def workDoneParams = [task: result.taskInstance,
814                                                    entryType: EntryType.get(3),
815                                                    comment: params.entryWorkDone.comment,
816                                            dateDone: result.taskInstance.targetStartDate,
817                                                    durationHour: params.entryWorkDone.durationHour,
818                                                    durationMinute: params.entryWorkDone.durationMinute]
819            def workDoneResult = saveEntry(workDoneParams)
820            result.entryWorkDoneInstance = workDoneResult.entryInstance
821
822            if(result.error)
823                return result
824
825            if(causeResult.error)
826                return fail(code: "default.create.failure")
827
828            if(faultResult.error)
829                return fail(code: "default.create.failure")
830
831            if(workDoneResult.error)
832                return fail(code: "default.create.failure")
833
834            // Success.
835            return result
836
837        } //end withTransaction
838    } // end saveImmediateCallout()
839
840} // end TaskService
Note: See TracBrowser for help on using the repository browser.