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

Last change on this file since 816 was 816, checked in by gav, 13 years ago

Add check to prevent changing a tasks primaryAsset if maintenanceActions have been created.

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