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

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

Check for authorisation on recurring tasks.

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