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

Last change on this file since 772 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
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    /**
[749]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    /**
[433]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    /**
[196]99    * Creates a new task with the given params.
[202]100    * @param params The params to use when creating the new task.
[418]101    * @returns A map containing result.error (if any error) and result.taskInstance.
[196]102    */
[394]103    def save(params) {
[180]104        Task.withTransaction { status ->
105            def result = [:]
[418]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
[180]115            def taskInstance = new Task(params)
116            result.taskInstance = taskInstance
117
[601]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
[418]130            if(result.taskInstance.parentTask?.trash)
131                return fail(field:"parentTask", code:"task.operationNotPermittedOnTaskInTrash")
[196]132
[418]133            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
134                return fail(code:"default.create.failure")
[180]135
[418]136            def taskModification = new TaskModification(person: authService.currentUser,
137                                                taskModificationType: TaskModificationType.get(1),
138                                                task: taskInstance)
[180]139
[418]140            if(taskModification.hasErrors() || !taskModification.save())
141                return fail(field:"taskModifications", code:"task.modifications.failedToSave")
[243]142
[418]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() {
[251]148
[418]149                    assignedGroupParams = [personGroup: it.personGroup,
150                                                                task: taskInstance,
151                                                                estimatedHour: it.estimatedHour,
152                                                                estimatedMinute: it.estimatedMinute]
[251]153
[418]154                    assignedGroupsResult = assignedGroupService.save(assignedGroupParams)
[251]155
[418]156                    if(assignedGroupsResult.error)
157                        return fail(field:"assignedGroups", code:"task.assignedGroups.failedToSave")
158
[243]159                }
[418]160            }
[243]161
[418]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() {
[243]167
[418]168                    assignedPersonsParams = [person: it.person,
169                                                                task: taskInstance,
170                                                                estimatedHour: it.estimatedHour,
171                                                                estimatedMinute: it.estimatedMinute]
[251]172
[418]173                    assignedPersonsResult = assignedPersonService.save(assignedPersonsParams)
[251]174
[418]175                    if(assignedPersonsResult.error)
176                        return fail(field:"assignedPersons", code:"task.assignedPersons.failedToSave")
[251]177
[243]178                }
[180]179            }
180
[418]181            // Success.
182            return result
183
[180]184        } //end withTransaction
[394]185    } // end save()
[180]186
[202]187    /**
[245]188    * Creates a subTask copying sane attributes from the parentTask unless otherwise specified in params.
[515]189    * The targetStartDate and targetCompletionDate default to today since that is the sane thing to do.
[245]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.
[592]192    * The positiveFault property is never set on the subTask.
[245]193    * Collections in params must be supplied as new ArrayList's.
194    * This method is not intended to be a copyTask method.
[515]195    * There should be no reason to copy tasks, recurrence can be used to create similar tasks.
[196]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
[592]204        //Make our new Task a subTask and set the required properties.
[196]205        def p = [:]
206        p.parentTask = parentTask
207        p.description = params.description ?: parentTask.description
208        p.comment = params.comment ?: parentTask.comment
[515]209        p.targetStartDate = params.targetStartDate ?: dateUtilService.today
210        p.targetCompletionDate = params.targetCompletionDate ?: dateUtilService.today
[196]211
[592]212        p.safetyRequirement = params.safetyRequirement ?: parentTask.safetyRequirement
[728]213        p.regulatoryRequirement = params.regulatoryRequirement ?: parentTask.regulatoryRequirement
214        p.mandatoryRequirement = params.mandatoryRequirement ?: parentTask.mandatoryRequirement
[592]215
[196]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
[749]219
[196]220        p.taskType = params.taskType ?: parentTask.taskType
[749]221         // Convert "Parent PM" tasks to "Preventative Maintenance" tasks.
222        if(p.taskType.id == 6)
223            p.taskType = TaskType.get(4)
224
[196]225        p.leadPerson = params.leadPerson ?: parentTask.leadPerson
226        p.primaryAsset = params.primaryAsset ?: parentTask.primaryAsset
[245]227        p.associatedAssets = params.associatedAssets ?: new ArrayList(parentTask.associatedAssets) // Collection.
[196]228
[245]229        // Supplied by recurring tasks.
[202]230        if(params.taskProcedure) p.taskProcedure = params.taskProcedure
[245]231        if(params.assignedGroups) p.assignedGroups = params.assignedGroups // Collection.
232        if(params.assignedPersons) p.assignedPersons = params.assignedPersons // Collection.
[202]233
[245]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.
[394]240        result = save(p)
[196]241
[478]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
[196]252    } // end createSubTask()
253
[202]254    /**
[510]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
[514]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
[510]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    /**
[196]315    * Creates a new task entry.
[202]316    * @param params The params to use when creating the new entry.
[196]317    * @returns A map containing result.error=true (if any error), result.entryInstance and result.taskId.
318    */
[394]319    def saveEntry(params) {
[186]320        Task.withTransaction { status ->
321            def result = [:]
[395]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
[186]331            result.entryInstance = new Entry(params)
[291]332            result.entryInstance.enteredBy = authService.currentUser
[180]333
[395]334            def taskInstance
[510]335            if(result.entryInstance.task?.id) {
[186]336                result.taskId = result.entryInstance.task.id
[395]337                taskInstance = Task.lock(result.entryInstance.task.id)
338            }
[186]339
[395]340            if(!taskInstance)
341                return fail(field:"task", code:"task.notFound")
[186]342
[395]343            if(result.entryInstance.hasErrors() || !result.entryInstance.save())
344                return fail(code:"default.create.failure")
[186]345
[395]346            if(taskInstance.taskStatus.id == 3)
347                return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
[186]348
[631]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
[510]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)) {
[186]359
[395]360                // Create the "Started" task modification, this provides the "Actual Started Date".
361                def taskModification = new TaskModification(person: authService.currentUser,
[510]362                                                        taskModificationType: TaskModificationType.read(2),
[395]363                                                        task: taskInstance)
[186]364
[395]365                if(taskModification.hasErrors() || !taskModification.save())
366                    return fail(field:"task", code:"task.modifications.failedToSave")
[186]367
[395]368                // Set task status to "In Progress".
[510]369                taskInstance.taskStatus = TaskStatus.read(2)
[186]370
[395]371                if(taskInstance.hasErrors() || !taskInstance.save())
372                    return fail(field:"task", code:"task.failedToSave")
[186]373            }
374
[395]375            // Success.
376            return result
377
[482]378        } // end withTransaction
[394]379    } // end saveEntry()
[186]380
[202]381    /**
382    * Updates an existing task.
383    * @param params The params to update for task with id of params.id.
[418]384    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]385    */
[180]386    def update(params) {
387        Task.withTransaction { status ->
388            def result = [:]
[204]389
[418]390            def fail = { Map m ->
[204]391                status.setRollbackOnly()
[418]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] ]
[204]395                return result
396            }
397
[180]398            result.taskInstance = Task.get(params.id)
399
[204]400            if(!result.taskInstance)
[206]401                return fail('id', "task.notFound")
[180]402
[204]403            // Optimistic locking check.
404            if(params.version) {
[418]405                if(result.taskInstance.version > params.version.toLong())
406                    return fail(field:"version", code:"default.optimistic.locking.failure")
[204]407            }
[180]408
[631]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
[204]415            result.taskInstance.properties = params
416
417            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
[418]418                return fail(code:"default.update.failure")
[204]419
[291]420            def taskModification = new TaskModification(person:authService.currentUser,
[204]421                                                    taskModificationType: TaskModificationType.get(3),
422                                                    task: result.taskInstance)
423
[418]424            if(taskModification.hasErrors() || !taskModification.save())
425                return fail(code:"task.modifications.failedToSave")
[204]426
[418]427            // Success.
[180]428            return result
429
430        } //end withTransaction
431    }  // end update()
432
[202]433    /**
434    * Completes an existing task.
435    * @param params The params for task with id of params.id.
[418]436    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]437    */
[181]438    def complete(params) {
439        Task.withTransaction { status ->
440            def result = [:]
[418]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
[181]450            result.taskInstance = Task.get(params.id)
451
[418]452            if(!result.taskInstance)
453                return fail(code:"default.not.found")
[181]454
[418]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            }
[181]460
[631]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
[418]467            result.taskInstance.taskStatus = TaskStatus.get(3)
468            result.taskInstance.attentionFlag = false
469            result.taskInstance.taskRecurringSchedule?.enabled = false
[201]470
[418]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.
[181]483            return result
484
485        } //end withTransaction
[180]486    }  // end complete()
487
[202]488    /**
[418]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
[631]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
[418]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
[631]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
[418]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    /**
[202]593    * Reopens an existing task.
594    * @param params The params for task with id of params.id.
[418]595    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]596    */
[181]597    def reopen(params) {
598        Task.withTransaction { status ->
599            def result = [:]
[418]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
[181]609            result.taskInstance = Task.get(params.id)
610
[418]611            if(!result.taskInstance)
612                return fail(code:"default.not.found")
[181]613
[418]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            }
[181]619
[631]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
[510]626            def isInProgress = false
627            result.taskInstance.entries.each() {
628                if(it.entryType.id == 3 && (it.durationHour + it.durationMinute > 0) )
629                    isInProgress = true
630            }
[418]631
[510]632            if(isInProgress)
633                result.taskInstance.taskStatus = TaskStatus.read(2) // In Progress
634            else
635                result.taskInstance.taskStatus = TaskStatus.read(1) // Not Started
636
[418]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.
[181]648            return result
649
650        } //end withTransaction
[180]651    }  // end reopen()
652
[202]653    /**
654    * Move a task to the trash.
655    * @param params The params for task with id of params.id.
[418]656    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]657    */
[181]658    def trash(params) {
659        Task.withTransaction { status ->
660            def result = [:]
[418]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
[181]670            result.taskInstance = Task.get(params.id)
671
[418]672            if(!result.taskInstance)
673                return fail(code:"default.not.found")
[181]674
[418]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            }
[181]680
[631]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
[418]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.
[181]702            return result
703
704        } //end withTransaction
[180]705    }  // end trash()
706
[202]707    /**
708    * Restore a task from the trash.
709    * @param params The params for task with id of params.id.
[418]710    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]711    */
[181]712    def restore(params) {
713        Task.withTransaction { status ->
714            def result = [:]
[418]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
[181]724            result.taskInstance = Task.get(params.id)
725
[418]726            if(!result.taskInstance)
727                return fail(code:"default.not.found")
[181]728
[418]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            }
[181]734
[631]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
[418]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.
[181]754            return result
755
756        } //end withTransaction
[180]757    }  // end restore()
758
[202]759    /**
760    * Approve a task.
761    * @param params The params for task with id of params.id.
[418]762    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]763    */
[181]764    def approve(params) {
765        Task.withTransaction { status ->
766            def result = [:]
[418]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
[181]776            result.taskInstance = Task.get(params.id)
777
[418]778            if(!result.taskInstance)
779                return fail(code:"default.not.found")
[181]780
[418]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            }
[181]786
[631]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
[418]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.
[181]806            return result
807
808        } //end withTransaction
[180]809    }  // end approve()
810
[202]811    /**
812    * Remove a previously given approval from a task.
813    * @param params The params for task with id of params.id.
[418]814    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
[202]815    */
[181]816    def renegeApproval(params) {
817        Task.withTransaction { status ->
818            def result = [:]
[418]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
[181]828            result.taskInstance = Task.get(params.id)
829
[418]830            if(!result.taskInstance)
831                return fail(code:"default.not.found")
[181]832
[418]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            }
[181]838
[631]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
[418]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.
[181]858            return result
859
860        } //end withTransaction
[180]861    }  // end renegeApproval()
862
[395]863    /**
[433]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    /**
[418]909    * Creates a new immediate callout task with the given params.
[395]910    * @param params The params to use when creating the new task.
[418]911    * @returns A map containing result.error (if any error) and result.taskInstance.
[395]912    */
[418]913    def saveImmediateCallout(params) {
[395]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
[418]931            // Always for an immediate callout.
932            result.taskInstance.taskType = TaskType.get(1) // Immediate Callout.
[395]933            result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
[433]934            result.taskInstance.taskPriority = TaskPriority.get(1) // Immediate.
[395]935            result.taskInstance.taskGroup = TaskGroup.get(1) // Engineering Activites.
936            result.taskInstance.approved = true
937            result.taskInstance.leadPerson = authService.currentUser
[432]938            result.taskInstance.targetCompletionDate = result.taskInstance.targetStartDate
[395]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
[431]952            def productionReference
953            if(params.entryFault.productionReference.id.isLong())
954                productionReference = ProductionReference.get(params.entryFault.productionReference.id.toLong())
955
[395]956            def faultParams = [task: result.taskInstance,
957                                            entryType: EntryType.get(1),
958                                            comment: params.entryFault.comment,
[432]959                                            dateDone: result.taskInstance.targetStartDate,
[431]960                                            productionReference: productionReference,
[395]961                                            durationHour: params.entryFault.durationHour,
962                                            durationMinute: params.entryFault.durationMinute]
963            def faultResult = saveEntry(faultParams)
964            result.entryFaultInstance = faultResult.entryInstance
965
[418]966            def causeParams = [task: result.taskInstance,
967                                            entryType: EntryType.get(2),
[432]968                                            dateDone: result.taskInstance.targetStartDate,
[418]969                                            comment: params.entryCause.comment]
970            def causeResult = saveEntry(causeParams)
971            result.entryCauseInstance = causeResult.entryInstance
972
[395]973            def workDoneParams = [task: result.taskInstance,
[418]974                                                    entryType: EntryType.get(3),
[395]975                                                    comment: params.entryWorkDone.comment,
[432]976                                            dateDone: result.taskInstance.targetStartDate,
[395]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
[418]985            if(causeResult.error)
986                return fail(code: "default.create.failure")
987
[395]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
[418]998    } // end saveImmediateCallout()
[395]999
[180]1000} // end TaskService
Note: See TracBrowser for help on using the repository browser.