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

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

Domain change, added safetyRequirement, mandatoryRegulatory and positiveFault attributes to Task.
Update views and logic to suite.
Complete's ticket #70.

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