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

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

Check for authorisation on recurring tasks.

File size: 39.8 KB
RevLine 
[510]1import grails.util.Environment
2
[202]3/**
4* Provides a service class for the Task domain class.
[196]5*
6*/
[137]7class TaskService {
8
[180]9    boolean transactional = false
[137]10
[291]11    def authService
[515]12    def dateUtilService
[631]13    def authenticateService
[251]14    def assignedGroupService
15    def assignedPersonService
[137]16
[202]17    /**
[203]18    * Determines and returns a possible parent list for a task.
[245]19    * @todo Create and use another method that limits the results to say the latest 20 or 100 tasks?
[202]20    * @param taskInstance The task to use when determining the possible parent list.
[196]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
[202]34    /**
[433]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    /**
[196]84    * Creates a new task with the given params.
[202]85    * @param params The params to use when creating the new task.
[418]86    * @returns A map containing result.error (if any error) and result.taskInstance.
[196]87    */
[394]88    def save(params) {
[180]89        Task.withTransaction { status ->
90            def result = [:]
[418]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
[180]100            def taskInstance = new Task(params)
101            result.taskInstance = taskInstance
102
[601]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
[418]115            if(result.taskInstance.parentTask?.trash)
116                return fail(field:"parentTask", code:"task.operationNotPermittedOnTaskInTrash")
[196]117
[418]118            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
119                return fail(code:"default.create.failure")
[180]120
[418]121            def taskModification = new TaskModification(person: authService.currentUser,
122                                                taskModificationType: TaskModificationType.get(1),
123                                                task: taskInstance)
[180]124
[418]125            if(taskModification.hasErrors() || !taskModification.save())
126                return fail(field:"taskModifications", code:"task.modifications.failedToSave")
[243]127
[418]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() {
[251]133
[418]134                    assignedGroupParams = [personGroup: it.personGroup,
135                                                                task: taskInstance,
136                                                                estimatedHour: it.estimatedHour,
137                                                                estimatedMinute: it.estimatedMinute]
[251]138
[418]139                    assignedGroupsResult = assignedGroupService.save(assignedGroupParams)
[251]140
[418]141                    if(assignedGroupsResult.error)
142                        return fail(field:"assignedGroups", code:"task.assignedGroups.failedToSave")
143
[243]144                }
[418]145            }
[243]146
[418]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() {
[243]152
[418]153                    assignedPersonsParams = [person: it.person,
154                                                                task: taskInstance,
155                                                                estimatedHour: it.estimatedHour,
156                                                                estimatedMinute: it.estimatedMinute]
[251]157
[418]158                    assignedPersonsResult = assignedPersonService.save(assignedPersonsParams)
[251]159
[418]160                    if(assignedPersonsResult.error)
161                        return fail(field:"assignedPersons", code:"task.assignedPersons.failedToSave")
[251]162
[243]163                }
[180]164            }
165
[418]166            // Success.
167            return result
168
[180]169        } //end withTransaction
[394]170    } // end save()
[180]171
[202]172    /**
[245]173    * Creates a subTask copying sane attributes from the parentTask unless otherwise specified in params.
[515]174    * The targetStartDate and targetCompletionDate default to today since that is the sane thing to do.
[245]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.
[592]177    * The positiveFault property is never set on the subTask.
[245]178    * Collections in params must be supplied as new ArrayList's.
179    * This method is not intended to be a copyTask method.
[515]180    * There should be no reason to copy tasks, recurrence can be used to create similar tasks.
[196]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
[592]189        //Make our new Task a subTask and set the required properties.
[196]190        def p = [:]
191        p.parentTask = parentTask
192        p.description = params.description ?: parentTask.description
193        p.comment = params.comment ?: parentTask.comment
[515]194        p.targetStartDate = params.targetStartDate ?: dateUtilService.today
195        p.targetCompletionDate = params.targetCompletionDate ?: dateUtilService.today
[196]196
[592]197        p.safetyRequirement = params.safetyRequirement ?: parentTask.safetyRequirement
198        p.mandatoryRegulatory = params.mandatoryRegulatory ?: parentTask.mandatoryRegulatory
199
[196]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
[245]206        p.associatedAssets = params.associatedAssets ?: new ArrayList(parentTask.associatedAssets) // Collection.
[196]207
[245]208        // Supplied by recurring tasks.
[202]209        if(params.taskProcedure) p.taskProcedure = params.taskProcedure
[245]210        if(params.assignedGroups) p.assignedGroups = params.assignedGroups // Collection.
211        if(params.assignedPersons) p.assignedPersons = params.assignedPersons // Collection.
[202]212
[245]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.
[394]219        result = save(p)
[196]220
[478]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
[196]231    } // end createSubTask()
232
[202]233    /**
[510]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
[514]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
[510]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    /**
[196]294    * Creates a new task entry.
[202]295    * @param params The params to use when creating the new entry.
[196]296    * @returns A map containing result.error=true (if any error), result.entryInstance and result.taskId.
297    */
[394]298    def saveEntry(params) {
[186]299        Task.withTransaction { status ->
300            def result = [:]
[395]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
[186]310            result.entryInstance = new Entry(params)
[291]311            result.entryInstance.enteredBy = authService.currentUser
[180]312
[395]313            def taskInstance
[510]314            if(result.entryInstance.task?.id) {
[186]315                result.taskId = result.entryInstance.task.id
[395]316                taskInstance = Task.lock(result.entryInstance.task.id)
317            }
[186]318
[395]319            if(!taskInstance)
320                return fail(field:"task", code:"task.notFound")
[186]321
[395]322            if(result.entryInstance.hasErrors() || !result.entryInstance.save())
323                return fail(code:"default.create.failure")
[186]324
[395]325            if(taskInstance.taskStatus.id == 3)
326                return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
[186]327
[631]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
[510]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)) {
[186]338
[395]339                // Create the "Started" task modification, this provides the "Actual Started Date".
340                def taskModification = new TaskModification(person: authService.currentUser,
[510]341                                                        taskModificationType: TaskModificationType.read(2),
[395]342                                                        task: taskInstance)
[186]343
[395]344                if(taskModification.hasErrors() || !taskModification.save())
345                    return fail(field:"task", code:"task.modifications.failedToSave")
[186]346
[395]347                // Set task status to "In Progress".
[510]348                taskInstance.taskStatus = TaskStatus.read(2)
[186]349
[395]350                if(taskInstance.hasErrors() || !taskInstance.save())
351                    return fail(field:"task", code:"task.failedToSave")
[186]352            }
353
[395]354            // Success.
355            return result
356
[482]357        } // end withTransaction
[394]358    } // end saveEntry()
[186]359
[202]360    /**
361    * Updates an existing task.
362    * @param params The params to update for task with id of params.id.
[418]363    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]364    */
[180]365    def update(params) {
366        Task.withTransaction { status ->
367            def result = [:]
[204]368
[418]369            def fail = { Map m ->
[204]370                status.setRollbackOnly()
[418]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] ]
[204]374                return result
375            }
376
[180]377            result.taskInstance = Task.get(params.id)
378
[204]379            if(!result.taskInstance)
[206]380                return fail('id', "task.notFound")
[180]381
[204]382            // Optimistic locking check.
383            if(params.version) {
[418]384                if(result.taskInstance.version > params.version.toLong())
385                    return fail(field:"version", code:"default.optimistic.locking.failure")
[204]386            }
[180]387
[631]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
[204]394            result.taskInstance.properties = params
395
396            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
[418]397                return fail(code:"default.update.failure")
[204]398
[291]399            def taskModification = new TaskModification(person:authService.currentUser,
[204]400                                                    taskModificationType: TaskModificationType.get(3),
401                                                    task: result.taskInstance)
402
[418]403            if(taskModification.hasErrors() || !taskModification.save())
404                return fail(code:"task.modifications.failedToSave")
[204]405
[418]406            // Success.
[180]407            return result
408
409        } //end withTransaction
410    }  // end update()
411
[202]412    /**
413    * Completes an existing task.
414    * @param params The params for task with id of params.id.
[418]415    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]416    */
[181]417    def complete(params) {
418        Task.withTransaction { status ->
419            def result = [:]
[418]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
[181]429            result.taskInstance = Task.get(params.id)
430
[418]431            if(!result.taskInstance)
432                return fail(code:"default.not.found")
[181]433
[418]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            }
[181]439
[631]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
[418]446            result.taskInstance.taskStatus = TaskStatus.get(3)
447            result.taskInstance.attentionFlag = false
448            result.taskInstance.taskRecurringSchedule?.enabled = false
[201]449
[418]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.
[181]462            return result
463
464        } //end withTransaction
[180]465    }  // end complete()
466
[202]467    /**
[418]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
[631]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
[418]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
[631]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
[418]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    /**
[202]572    * Reopens an existing task.
573    * @param params The params for task with id of params.id.
[418]574    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]575    */
[181]576    def reopen(params) {
577        Task.withTransaction { status ->
578            def result = [:]
[418]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
[181]588            result.taskInstance = Task.get(params.id)
589
[418]590            if(!result.taskInstance)
591                return fail(code:"default.not.found")
[181]592
[418]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            }
[181]598
[631]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
[510]605            def isInProgress = false
606            result.taskInstance.entries.each() {
607                if(it.entryType.id == 3 && (it.durationHour + it.durationMinute > 0) )
608                    isInProgress = true
609            }
[418]610
[510]611            if(isInProgress)
612                result.taskInstance.taskStatus = TaskStatus.read(2) // In Progress
613            else
614                result.taskInstance.taskStatus = TaskStatus.read(1) // Not Started
615
[418]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.
[181]627            return result
628
629        } //end withTransaction
[180]630    }  // end reopen()
631
[202]632    /**
633    * Move a task to the trash.
634    * @param params The params for task with id of params.id.
[418]635    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]636    */
[181]637    def trash(params) {
638        Task.withTransaction { status ->
639            def result = [:]
[418]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
[181]649            result.taskInstance = Task.get(params.id)
650
[418]651            if(!result.taskInstance)
652                return fail(code:"default.not.found")
[181]653
[418]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            }
[181]659
[631]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
[418]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.
[181]681            return result
682
683        } //end withTransaction
[180]684    }  // end trash()
685
[202]686    /**
687    * Restore a task from the trash.
688    * @param params The params for task with id of params.id.
[418]689    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]690    */
[181]691    def restore(params) {
692        Task.withTransaction { status ->
693            def result = [:]
[418]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
[181]703            result.taskInstance = Task.get(params.id)
704
[418]705            if(!result.taskInstance)
706                return fail(code:"default.not.found")
[181]707
[418]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            }
[181]713
[631]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
[418]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.
[181]733            return result
734
735        } //end withTransaction
[180]736    }  // end restore()
737
[202]738    /**
739    * Approve a task.
740    * @param params The params for task with id of params.id.
[418]741    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]742    */
[181]743    def approve(params) {
744        Task.withTransaction { status ->
745            def result = [:]
[418]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
[181]755            result.taskInstance = Task.get(params.id)
756
[418]757            if(!result.taskInstance)
758                return fail(code:"default.not.found")
[181]759
[418]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            }
[181]765
[631]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
[418]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.
[181]785            return result
786
787        } //end withTransaction
[180]788    }  // end approve()
789
[202]790    /**
791    * Remove a previously given approval from a task.
792    * @param params The params for task with id of params.id.
[418]793    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]794    */
[181]795    def renegeApproval(params) {
796        Task.withTransaction { status ->
797            def result = [:]
[418]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
[181]807            result.taskInstance = Task.get(params.id)
808
[418]809            if(!result.taskInstance)
810                return fail(code:"default.not.found")
[181]811
[418]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            }
[181]817
[631]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
[418]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.
[181]837            return result
838
839        } //end withTransaction
[180]840    }  // end renegeApproval()
841
[395]842    /**
[433]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    /**
[418]888    * Creates a new immediate callout task with the given params.
[395]889    * @param params The params to use when creating the new task.
[418]890    * @returns A map containing result.error (if any error) and result.taskInstance.
[395]891    */
[418]892    def saveImmediateCallout(params) {
[395]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
[418]910            // Always for an immediate callout.
911            result.taskInstance.taskType = TaskType.get(1) // Immediate Callout.
[395]912            result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
[433]913            result.taskInstance.taskPriority = TaskPriority.get(1) // Immediate.
[395]914            result.taskInstance.taskGroup = TaskGroup.get(1) // Engineering Activites.
915            result.taskInstance.approved = true
916            result.taskInstance.leadPerson = authService.currentUser
[432]917            result.taskInstance.targetCompletionDate = result.taskInstance.targetStartDate
[395]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
[431]931            def productionReference
932            if(params.entryFault.productionReference.id.isLong())
933                productionReference = ProductionReference.get(params.entryFault.productionReference.id.toLong())
934
[395]935            def faultParams = [task: result.taskInstance,
936                                            entryType: EntryType.get(1),
937                                            comment: params.entryFault.comment,
[432]938                                            dateDone: result.taskInstance.targetStartDate,
[431]939                                            productionReference: productionReference,
[395]940                                            durationHour: params.entryFault.durationHour,
941                                            durationMinute: params.entryFault.durationMinute]
942            def faultResult = saveEntry(faultParams)
943            result.entryFaultInstance = faultResult.entryInstance
944
[418]945            def causeParams = [task: result.taskInstance,
946                                            entryType: EntryType.get(2),
[432]947                                            dateDone: result.taskInstance.targetStartDate,
[418]948                                            comment: params.entryCause.comment]
949            def causeResult = saveEntry(causeParams)
950            result.entryCauseInstance = causeResult.entryInstance
951
[395]952            def workDoneParams = [task: result.taskInstance,
[418]953                                                    entryType: EntryType.get(3),
[395]954                                                    comment: params.entryWorkDone.comment,
[432]955                                            dateDone: result.taskInstance.targetStartDate,
[395]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
[418]964            if(causeResult.error)
965                return fail(code: "default.create.failure")
966
[395]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
[418]977    } // end saveImmediateCallout()
[395]978
[180]979} // end TaskService
Note: See TracBrowser for help on using the repository browser.