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

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

New task type 'Parent PM', display these tasks as 'Life Plan' in asset views.

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