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

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

Default task dates to today when manually creating a sub task.

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