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
Line 
1import grails.util.Environment
2
3/**
4* Provides a service class for the Task domain class.
5*
6*/
7class TaskService {
8
9    boolean transactional = false
10
11    def authService
12    def dateUtilService
13    def assignedGroupService
14    def assignedPersonService
15
16    /**
17    * Determines and returns a possible parent list for a task.
18    * @todo Create and use another method that limits the results to say the latest 20 or 100 tasks?
19    * @param taskInstance The task to use when determining the possible parent list.
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
33    /**
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    /**
83    * Creates a new task with the given params.
84    * @param params The params to use when creating the new task.
85    * @returns A map containing result.error (if any error) and result.taskInstance.
86    */
87    def save(params) {
88        Task.withTransaction { status ->
89            def result = [:]
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
99            // Default status to "not started" if not supplied.
100            params.taskStatus = params.taskStatus ?: TaskStatus.get(1)
101
102            // Set budgetStatus.
103            if(params.taskType?.id?.toLong() == 1 || params.taskType?.id?.toLong() == 2) // Immediate Callout or Unsheduled Breakin.
104                params.taskBudgetStatus = params.taskBudgetStatus ?: TaskBudgetStatus.get(1) // Unplanned.
105            else
106                params.taskBudgetStatus = params.taskBudgetStatus ?: TaskBudgetStatus.get(2) // Planned.
107
108            def taskInstance = new Task(params)
109            result.taskInstance = taskInstance
110
111            if(result.taskInstance.parentTask?.trash)
112                return fail(field:"parentTask", code:"task.operationNotPermittedOnTaskInTrash")
113
114            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
115                return fail(code:"default.create.failure")
116
117            def taskModification = new TaskModification(person: authService.currentUser,
118                                                taskModificationType: TaskModificationType.get(1),
119                                                task: taskInstance)
120
121            if(taskModification.hasErrors() || !taskModification.save())
122                return fail(field:"taskModifications", code:"task.modifications.failedToSave")
123
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() {
129
130                    assignedGroupParams = [personGroup: it.personGroup,
131                                                                task: taskInstance,
132                                                                estimatedHour: it.estimatedHour,
133                                                                estimatedMinute: it.estimatedMinute]
134
135                    assignedGroupsResult = assignedGroupService.save(assignedGroupParams)
136
137                    if(assignedGroupsResult.error)
138                        return fail(field:"assignedGroups", code:"task.assignedGroups.failedToSave")
139
140                }
141            }
142
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() {
148
149                    assignedPersonsParams = [person: it.person,
150                                                                task: taskInstance,
151                                                                estimatedHour: it.estimatedHour,
152                                                                estimatedMinute: it.estimatedMinute]
153
154                    assignedPersonsResult = assignedPersonService.save(assignedPersonsParams)
155
156                    if(assignedPersonsResult.error)
157                        return fail(field:"assignedPersons", code:"task.assignedPersons.failedToSave")
158
159                }
160            }
161
162            // Success.
163            return result
164
165        } //end withTransaction
166    } // end save()
167
168    /**
169    * Creates a subTask copying sane attributes from the parentTask unless otherwise specified in params.
170    * The targetStartDate and targetCompletionDate default to today since that is the sane thing to do.
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.
175    * There should be no reason to copy tasks, recurrence can be used to create similar tasks.
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
189        p.targetStartDate = params.targetStartDate ?: dateUtilService.today
190        p.targetCompletionDate = params.targetCompletionDate ?: dateUtilService.today
191        p.scheduled = params.scheduled ?:  parentTask.scheduled
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
199        p.associatedAssets = params.associatedAssets ?: new ArrayList(parentTask.associatedAssets) // Collection.
200
201        // Supplied by recurring tasks.
202        if(params.taskProcedure) p.taskProcedure = params.taskProcedure
203        if(params.assignedGroups) p.assignedGroups = params.assignedGroups // Collection.
204        if(params.assignedPersons) p.assignedPersons = params.assignedPersons // Collection.
205
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.
212        result = save(p)
213
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
224    } // end createSubTask()
225
226    /**
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
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
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    /**
287    * Creates a new task entry.
288    * @param params The params to use when creating the new entry.
289    * @returns A map containing result.error=true (if any error), result.entryInstance and result.taskId.
290    */
291    def saveEntry(params) {
292        Task.withTransaction { status ->
293            def result = [:]
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
303            result.entryInstance = new Entry(params)
304            result.entryInstance.enteredBy = authService.currentUser
305
306            def taskInstance
307            if(result.entryInstance.task?.id) {
308                result.taskId = result.entryInstance.task.id
309                taskInstance = Task.lock(result.entryInstance.task.id)
310            }
311
312            if(!taskInstance)
313                return fail(field:"task", code:"task.notFound")
314
315            if(result.entryInstance.hasErrors() || !result.entryInstance.save())
316                return fail(code:"default.create.failure")
317
318            if(taskInstance.taskStatus.id == 3)
319                return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
320
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)) {
325
326                // Create the "Started" task modification, this provides the "Actual Started Date".
327                def taskModification = new TaskModification(person: authService.currentUser,
328                                                        taskModificationType: TaskModificationType.read(2),
329                                                        task: taskInstance)
330
331                if(taskModification.hasErrors() || !taskModification.save())
332                    return fail(field:"task", code:"task.modifications.failedToSave")
333
334                // Set task status to "In Progress".
335                taskInstance.taskStatus = TaskStatus.read(2)
336
337                if(taskInstance.hasErrors() || !taskInstance.save())
338                    return fail(field:"task", code:"task.failedToSave")
339            }
340
341            // Success.
342            return result
343
344        } // end withTransaction
345    } // end saveEntry()
346
347    /**
348    * Updates an existing task.
349    * @param params The params to update for task with id of params.id.
350    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
351    */
352    def update(params) {
353        Task.withTransaction { status ->
354            def result = [:]
355
356            def fail = { Map m ->
357                status.setRollbackOnly()
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] ]
361                return result
362            }
363
364            result.taskInstance = Task.get(params.id)
365
366            if(!result.taskInstance)
367                return fail('id', "task.notFound")
368
369            // Optimistic locking check.
370            if(params.version) {
371                if(result.taskInstance.version > params.version.toLong())
372                    return fail(field:"version", code:"default.optimistic.locking.failure")
373            }
374
375            result.taskInstance.properties = params
376
377            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
378                return fail(code:"default.update.failure")
379
380            def taskModification = new TaskModification(person:authService.currentUser,
381                                                    taskModificationType: TaskModificationType.get(3),
382                                                    task: result.taskInstance)
383
384            if(taskModification.hasErrors() || !taskModification.save())
385                return fail(code:"task.modifications.failedToSave")
386
387            // Success.
388            return result
389
390        } //end withTransaction
391    }  // end update()
392
393    /**
394    * Completes an existing task.
395    * @param params The params for task with id of params.id.
396    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
397    */
398    def complete(params) {
399        Task.withTransaction { status ->
400            def result = [:]
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
410            result.taskInstance = Task.get(params.id)
411
412            if(!result.taskInstance)
413                return fail(code:"default.not.found")
414
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            }
420
421            result.taskInstance.taskStatus = TaskStatus.get(3)
422            result.taskInstance.attentionFlag = false
423            result.taskInstance.taskRecurringSchedule?.enabled = false
424
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.
437            return result
438
439        } //end withTransaction
440    }  // end complete()
441
442    /**
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    /**
535    * Reopens an existing task.
536    * @param params The params for task with id of params.id.
537    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
538    */
539    def reopen(params) {
540        Task.withTransaction { status ->
541            def result = [:]
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
551            result.taskInstance = Task.get(params.id)
552
553            if(!result.taskInstance)
554                return fail(code:"default.not.found")
555
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            }
561
562            def isInProgress = false
563            result.taskInstance.entries.each() {
564                if(it.entryType.id == 3 && (it.durationHour + it.durationMinute > 0) )
565                    isInProgress = true
566            }
567
568            if(isInProgress)
569                result.taskInstance.taskStatus = TaskStatus.read(2) // In Progress
570            else
571                result.taskInstance.taskStatus = TaskStatus.read(1) // Not Started
572
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.
584            return result
585
586        } //end withTransaction
587    }  // end reopen()
588
589    /**
590    * Move a task to the trash.
591    * @param params The params for task with id of params.id.
592    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
593    */
594    def trash(params) {
595        Task.withTransaction { status ->
596            def result = [:]
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
606            result.taskInstance = Task.get(params.id)
607
608            if(!result.taskInstance)
609                return fail(code:"default.not.found")
610
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            }
616
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.
632            return result
633
634        } //end withTransaction
635    }  // end trash()
636
637    /**
638    * Restore a task from the trash.
639    * @param params The params for task with id of params.id.
640    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
641    */
642    def restore(params) {
643        Task.withTransaction { status ->
644            def result = [:]
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
654            result.taskInstance = Task.get(params.id)
655
656            if(!result.taskInstance)
657                return fail(code:"default.not.found")
658
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            }
664
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.
678            return result
679
680        } //end withTransaction
681    }  // end restore()
682
683    /**
684    * Approve a task.
685    * @param params The params for task with id of params.id.
686    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
687    */
688    def approve(params) {
689        Task.withTransaction { status ->
690            def result = [:]
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
700            result.taskInstance = Task.get(params.id)
701
702            if(!result.taskInstance)
703                return fail(code:"default.not.found")
704
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            }
710
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.
724            return result
725
726        } //end withTransaction
727    }  // end approve()
728
729    /**
730    * Remove a previously given approval from a task.
731    * @param params The params for task with id of params.id.
732    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
733    */
734    def renegeApproval(params) {
735        Task.withTransaction { status ->
736            def result = [:]
737
738            def fail = { Map m ->
739                status.setRollbackOnly()
740                if(result.taskInstance && m.field)
741                    result.taskInstance.errors.rejectValue(m.field, m.code)
742                result.error = [ code: m.code, args: ["Task", params.id] ]
743                return result
744            }
745
746            result.taskInstance = Task.get(params.id)
747
748            if(!result.taskInstance)
749                return fail(code:"default.not.found")
750
751            // Optimistic locking check.
752            if(params.version) {
753                if(result.taskInstance.version > params.version.toLong())
754                    return fail(field:"version", code:"default.optimistic.locking.failure")
755            }
756
757            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.
770            return result
771
772        } //end withTransaction
773    }  // end renegeApproval()
774
775    /**
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    /**
821    * Creates a new immediate callout task with the given params.
822    * @param params The params to use when creating the new task.
823    * @returns A map containing result.error (if any error) and result.taskInstance.
824    */
825    def saveImmediateCallout(params) {
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
843            // Always for an immediate callout.
844            result.taskInstance.taskType = TaskType.get(1) // Immediate Callout.
845            result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
846            result.taskInstance.taskPriority = TaskPriority.get(1) // Immediate.
847            result.taskInstance.taskGroup = TaskGroup.get(1) // Engineering Activites.
848            result.taskInstance.approved = true
849            result.taskInstance.leadPerson = authService.currentUser
850            result.taskInstance.targetCompletionDate = result.taskInstance.targetStartDate
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
864            def productionReference
865            if(params.entryFault.productionReference.id.isLong())
866                productionReference = ProductionReference.get(params.entryFault.productionReference.id.toLong())
867
868            def faultParams = [task: result.taskInstance,
869                                            entryType: EntryType.get(1),
870                                            comment: params.entryFault.comment,
871                                            dateDone: result.taskInstance.targetStartDate,
872                                            productionReference: productionReference,
873                                            durationHour: params.entryFault.durationHour,
874                                            durationMinute: params.entryFault.durationMinute]
875            def faultResult = saveEntry(faultParams)
876            result.entryFaultInstance = faultResult.entryInstance
877
878            def causeParams = [task: result.taskInstance,
879                                            entryType: EntryType.get(2),
880                                            dateDone: result.taskInstance.targetStartDate,
881                                            comment: params.entryCause.comment]
882            def causeResult = saveEntry(causeParams)
883            result.entryCauseInstance = causeResult.entryInstance
884
885            def workDoneParams = [task: result.taskInstance,
886                                                    entryType: EntryType.get(3),
887                                                    comment: params.entryWorkDone.comment,
888                                            dateDone: result.taskInstance.targetStartDate,
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
897            if(causeResult.error)
898                return fail(code: "default.create.failure")
899
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
910    } // end saveImmediateCallout()
911
912} // end TaskService
Note: See TracBrowser for help on using the repository browser.