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

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

Domain change, added safetyRequirement, mandatoryRegulatory and positiveFault attributes to Task.
Update views and logic to suite.
Complete's ticket #70.

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