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

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

Adding an entry to a task with no time booked will now leave the task as "Not Started".
Reopening a task will check if the task should be "In Progress" or "Not Started".
Added integration tests for above.
Added TaskService.delete() since it is required for integration tests.

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