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

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

Add default.please.select.text and default.none.select.text messages.
Update Task views and service to use new messages.

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