Index: trunk/grails-app/services/CreateBulkDataService.groovy
===================================================================
--- trunk/grails-app/services/CreateBulkDataService.groovy	(revision 414)
+++ trunk/grails-app/services/CreateBulkDataService.groovy	(revision 418)
@@ -145,5 +145,5 @@
         def taskGroup1 = TaskGroup.get(1)
         def taskPriority2 = TaskPriority.get(2)
-        def taskType1 = TaskType.get(1)
+        def taskType3 = TaskType.get(3)
         def leadPerson2 = Person.get(2)
 
@@ -168,5 +168,5 @@
             p = [taskGroup: taskGroup1,
                     taskPriority: taskPriority2,
-                    taskType: taskType1,
+                    taskType: taskType3,
                     leadPerson: leadPerson2,
                     description: btDescription,
Index: trunk/grails-app/services/CreateDataService.groovy
===================================================================
--- trunk/grails-app/services/CreateDataService.groovy	(revision 414)
+++ trunk/grails-app/services/CreateDataService.groovy	(revision 418)
@@ -685,17 +685,20 @@
         def taskTypeInstance
 
-        taskTypeInstance = new TaskType(name:"Unscheduled Breakin") // #1
+        taskTypeInstance = new TaskType(name:"Immediate Callout") // #1
         saveAndTest(taskTypeInstance)
 
-        taskTypeInstance = new TaskType(name:"Preventative Maintenance") // #2
+        taskTypeInstance = new TaskType(name:"Unscheduled Breakin") // #2
         saveAndTest(taskTypeInstance)
 
-        taskTypeInstance = new TaskType(name:"Project") // #3
+        taskTypeInstance = new TaskType(name:"Scheduled") // #3
         saveAndTest(taskTypeInstance)
 
-        taskTypeInstance = new TaskType(name:"Turnaround") // #4
+        taskTypeInstance = new TaskType(name:"Preventative Maintenance") // #4
         saveAndTest(taskTypeInstance)
 
-        taskTypeInstance = new TaskType(name:"Production Run") // #5
+        taskTypeInstance = new TaskType(name:"Predictive Maintenance") // #5
+        saveAndTest(taskTypeInstance)
+
+        taskTypeInstance = new TaskType(name:"Project") // #6
         saveAndTest(taskTypeInstance)
     }
@@ -716,4 +719,6 @@
         taskModificationTypeInstance = new TaskModificationType(name:"Modified (Assigned Groups)").save()  // #10
         taskModificationTypeInstance = new TaskModificationType(name:"Modified (Assigned Persons)").save()  // #11
+        taskModificationTypeInstance = new TaskModificationType(name:"Modified (Flagged for attention)").save()  // #12
+        taskModificationTypeInstance = new TaskModificationType(name:"Modified (Attention flag cleared)").save()  // #13
     }
 
@@ -728,5 +733,5 @@
                 taskType:TaskType.get(1),
                 leadPerson:Person.get(2),
-                description:"Check specific level sensor",
+                description:"Level sensor not working",
                 comment:"Has been noted as problematic, try recalibrating.",
                 targetStartDate: dateUtilService.today]
@@ -737,5 +742,5 @@
         p = [taskGroup:TaskGroup.findByName("Engineering Activites"),
                 taskPriority:TaskPriority.get(2),
-                taskType:TaskType.get(1),
+                taskType:TaskType.get(3),
                 leadPerson:Person.get(5),
                 description:"Some follow-up work",
@@ -749,7 +754,7 @@
         p = [taskGroup:TaskGroup.findByName("Engineering Activites"),
                 taskPriority:TaskPriority.get(2),
-                taskType:TaskType.get(1),
+                taskType:TaskType.get(3),
                 leadPerson:Person.get(5),
-                description:"A Sub Task can be created from the Sub Task's tab.",
+                description:"A Sub Task can be created from the 'Sub Task' tab.",
                 comment:"Some help required",
                 targetStartDate: dateUtilService.yesterday,
@@ -761,8 +766,8 @@
         p = [taskGroup:TaskGroup.findByName("Engineering Activites"),
                  taskPriority:TaskPriority.get(2),
-                 taskType:TaskType.get(1),
+                 taskType:TaskType.get(2),
                  leadPerson:Person.get(4),
-                 description:"Replace sensor at next opportunity.",
-                 comment:"Nothing else has worked.",
+                 description:"Please replace sensor at next available opportunity.",
+                 comment:"Nothing else has worked. So we now require the part to be replaced.",
                 targetStartDate: dateUtilService.oneWeekFromNow,
                 parentTask: Task.get(1)]
@@ -773,8 +778,8 @@
         p = [taskGroup:TaskGroup.findByName("Production Activites"),
                  taskPriority:TaskPriority.get(2),
-                 taskType:TaskType.get(5),
+                 taskType:TaskType.get(3),
                  leadPerson:Person.get(6),
-                 description:"Production Report",
-                 comment:"Production report for specific production run or shift",
+                 description:"Production Task",
+                 comment:"Production task for specific production run or shift",
                 targetStartDate: dateUtilService.today - 6]
 
@@ -783,8 +788,8 @@
         //Task #6
         p = [taskGroup:TaskGroup.findByName("Engineering Activites"),
-                 taskPriority:TaskPriority.get(1),
-                 taskType:TaskType.get(2),
+                 taskPriority:TaskPriority.get(4),
+                 taskType:TaskType.get(3),
                  leadPerson:Person.get(4),
-                 description:"This is a recurring task",
+                 description:"This is a recurring preventative maintenance task.",
                  comment:"If there is a parent task specified then this is a generated sub task, if there is a recurring schedule specified then this is a parent task.",
                 targetStartDate: dateUtilService.today]
@@ -801,11 +806,14 @@
         saveAndTest(entryTypeInstance)
 
-        entryTypeInstance = new EntryType(name:"Work Done") // #2
+        entryTypeInstance = new EntryType(name:"Cause") // #2
         saveAndTest(entryTypeInstance)
 
-        entryTypeInstance = new EntryType(name:"Production Note") // #3
+        entryTypeInstance = new EntryType(name:"Work Done") // #3
         saveAndTest(entryTypeInstance)
 
-        entryTypeInstance = new EntryType(name:"Work Request") // #4
+        entryTypeInstance = new EntryType(name:"Production Note") // #4
+        saveAndTest(entryTypeInstance)
+
+        entryTypeInstance = new EntryType(name:"Work Request") // #5
         saveAndTest(entryTypeInstance)
     }
@@ -826,5 +834,5 @@
         //Entry #2
         p = [task: Task.get(1),
-                entryType: EntryType.get(2),
+                entryType: EntryType.get(3),
                 comment: "Cleaned sensor, see how it goes.",
                 durationMinute: 30]
@@ -834,5 +842,5 @@
         //Entry #3
         p = [task: Task.get(1),
-                entryType: EntryType.get(2),
+                entryType: EntryType.get(3),
                 comment: "Checked up on it later and sensor is dropping out intermittently, created sub task to replace sensor.",
                 durationMinute: 20]
@@ -933,5 +941,5 @@
         saveAndTest(inventoryLocation)
 
-        inventoryLocation = new InventoryLocation(inventoryStore: InventoryStore.get(1), name: "C55")
+        inventoryLocation = new InventoryLocation(inventoryStore: InventoryStore.get(2), name: "C55")
         saveAndTest(inventoryLocation)
     }
Index: trunk/grails-app/services/TaskService.groovy
===================================================================
--- trunk/grails-app/services/TaskService.groovy	(revision 414)
+++ trunk/grails-app/services/TaskService.groovy	(revision 418)
@@ -31,14 +31,23 @@
     * Creates a new task with the given params.
     * @param params The params to use when creating the new task.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
+    * @returns A map containing result.error (if any error) and result.taskInstance.
     */
     def save(params) {
         Task.withTransaction { status ->
             def result = [:]
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
             // Default status to "not started" if not supplied.
             params.taskStatus = params.taskStatus ?: TaskStatus.get(1)
 
             // Set budgetStatus.
-            if(params.taskType?.id?.toLong() == 1) // Unscheduled Breakin.
+            if(params.taskType?.id?.toLong() == 1 || params.taskType?.id?.toLong() == 2) // Immediate Callout or Unsheduled Breakin.
                 params.taskBudgetStatus = params.taskBudgetStatus ?: TaskBudgetStatus.get(1) // Unplanned.
             else
@@ -48,76 +57,57 @@
             result.taskInstance = taskInstance
 
-            if(result.taskInstance.parentTask?.trash) {
-                status.setRollbackOnly()
-                result.taskInstance.errors.rejectValue("parentTask", "task.operationNotPermittedOnTaskInTrash")
-                result.error = true
-                return result
-            }
-
-            if(taskInstance.save()) {
-                def taskModification = new TaskModification(person: authService.currentUser,
-                                                        taskModificationType: TaskModificationType.get(1),
-                                                        task: taskInstance)
-
-                if(!taskModification.save()) {
-                    status.setRollbackOnly()
-                    taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
-                    result.error = true
-                    return result
+            if(result.taskInstance.parentTask?.trash)
+                return fail(field:"parentTask", code:"task.operationNotPermittedOnTaskInTrash")
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.create.failure")
+
+            def taskModification = new TaskModification(person: authService.currentUser,
+                                                taskModificationType: TaskModificationType.get(1),
+                                                task: taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(field:"taskModifications", code:"task.modifications.failedToSave")
+
+            //Add the assignedGroups, provided by a new ArrayList(task.assignedGroups)
+            if(params.assignedGroups) {
+                def assignedGroupsResult
+                def assignedGroupParams = [:]
+                params.assignedGroups.each() {
+
+                    assignedGroupParams = [personGroup: it.personGroup,
+                                                                task: taskInstance,
+                                                                estimatedHour: it.estimatedHour,
+                                                                estimatedMinute: it.estimatedMinute]
+
+                    assignedGroupsResult = assignedGroupService.save(assignedGroupParams)
+
+                    if(assignedGroupsResult.error)
+                        return fail(field:"assignedGroups", code:"task.assignedGroups.failedToSave")
+
                 }
-
-                //Add the assignedGroups, provided by a new ArrayList(task.assignedGroups)
-                if(params.assignedGroups) {
-                    def assignedGroupsResult
-                    def assignedGroupParams = [:]
-                    params.assignedGroups.each() {
-
-                        assignedGroupParams = [personGroup: it.personGroup,
-                                                                    task: taskInstance,
-                                                                    estimatedHour: it.estimatedHour,
-                                                                    estimatedMinute: it.estimatedMinute]
-
-                        assignedGroupsResult = assignedGroupService.save(assignedGroupParams)
-
-                        if(assignedGroupsResult.error) {
-                            status.setRollbackOnly()
-                            taskInstance.errors.rejectValue("assignedGroups", "task.assignedGroups.failedToSave")
-                            result.error = true
-                            return result
-                        }
-
-                    }
+            }
+
+            //Add the assignedPersons, provided by a new ArrayList(task.assignedPersons)
+            if(params.assignedPersons) {
+                def assignedPersonsResult
+                def assignedPersonsParams = [:]
+                params.assignedPersons.each() {
+
+                    assignedPersonsParams = [person: it.person,
+                                                                task: taskInstance,
+                                                                estimatedHour: it.estimatedHour,
+                                                                estimatedMinute: it.estimatedMinute]
+
+                    assignedPersonsResult = assignedPersonService.save(assignedPersonsParams)
+
+                    if(assignedPersonsResult.error)
+                        return fail(field:"assignedPersons", code:"task.assignedPersons.failedToSave")
+
                 }
-
-                //Add the assignedPersons, provided by a new ArrayList(task.assignedPersons)
-                if(params.assignedPersons) {
-                    def assignedPersonsResult
-                    def assignedPersonsParams = [:]
-                    params.assignedPersons.each() {
-
-                        assignedPersonsParams = [person: it.person,
-                                                                    task: taskInstance,
-                                                                    estimatedHour: it.estimatedHour,
-                                                                    estimatedMinute: it.estimatedMinute]
-
-                        assignedPersonsResult = assignedPersonService.save(assignedPersonsParams)
-
-                        if(assignedPersonsResult.error) {
-                            status.setRollbackOnly()
-                            taskInstance.errors.rejectValue("assignedPersons", "task.assignedPersons.failedToSave")
-                            result.error = true
-                            return result
-                        }
-
-                    }
-                }
-
-                // Success.
-                return result
-            }
-            else {
-                result.error = true
-                return result
-            }
+            }
+
+            // Success.
+            return result
 
         } //end withTransaction
@@ -210,5 +200,5 @@
 
             // If task status is "Not Started" and entry type is "Work Done" then we create the started modification and set the status.
-            if(taskInstance.taskStatus.id == 1 && result.entryInstance.entryType.id == 2) {
+            if(taskInstance.taskStatus.id == 1 && result.entryInstance.entryType.id == 3) {
 
                 // Create the "Started" task modification, this provides the "Actual Started Date".
@@ -239,5 +229,5 @@
     * Updates an existing task.
     * @param params The params to update for task with id of params.id.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance (if available).
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
     */
     def update(params) {
@@ -245,8 +235,9 @@
             def result = [:]
 
-            def fail = { Object[] args ->
-                status.setRollbackOnly()
-                if(args.size() == 2) result.taskInstance.errors.rejectValue(args[0], args[1])
-                result.error = true
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
                 return result
             }
@@ -259,7 +250,6 @@
             // Optimistic locking check.
             if(params.version) {
-                def version = params.version.toLong()
-                if(result.taskInstance.version > version)
-                    return fail("version", "default.optimistic.locking.failure")
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
             }
 
@@ -267,5 +257,5 @@
 
             if(result.taskInstance.hasErrors() || !result.taskInstance.save())
-                return fail()
+                return fail(code:"default.update.failure")
 
             def taskModification = new TaskModification(person:authService.currentUser,
@@ -273,8 +263,8 @@
                                                     task: result.taskInstance)
 
-            if(!taskModification.save())
-                return fail("taskModifications", "task.modifications.failedToSave")
-
-            // If we get here all went well.
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
             return result
 
@@ -285,94 +275,183 @@
     * Completes an existing task.
     * @param params The params for task with id of params.id.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
     */
     def complete(params) {
         Task.withTransaction { status ->
             def result = [:]
-            result.taskInstance = Task.get(params.id)
-            if(result.taskInstance) {
-
-                // Optimistic locking check.
-                if(params.version) {
-                    def version = params.version.toLong()
-                    if(result.taskInstance.version > version) {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
-                        result.error = true
-                        return result
-                    }
-                }
-
-                result.taskInstance.taskStatus = TaskStatus.get(3)
-                result.taskInstance.taskRecurringSchedule?.enabled = false
-
-                if(result.taskInstance.save()) {
-                    def taskModification = new TaskModification(person:authService.currentUser,
-                                                            taskModificationType: TaskModificationType.get(4),
-                                                            task: result.taskInstance)
-
-                    if(taskModification.save()) {
-                        // All went well.
-                        return result
-                    }
-                    else {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
-                        result.error = true
-                        return result
-                    }
-                }
-            }
-            // Something failed.
-            status.setRollbackOnly()
-            result.error = true
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.taskStatus = TaskStatus.get(3)
+            result.taskInstance.attentionFlag = false
+            result.taskInstance.taskRecurringSchedule?.enabled = false
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(4),
+                                                    task: result.taskInstance)
+
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
             return result
 
         } //end withTransaction
     }  // end complete()
+
+    /**
+    * Sets the attentionFlag on an existing task.
+    * @param params The params for task with id of params.id.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
+    */
+    def setAttentionFlag(params) {
+        Task.withTransaction { status ->
+            def result = [:]
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.attentionFlag = true
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(12),
+                                                    task: result.taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
+            return result
+
+        } //end withTransaction
+    }  // end flag()
+
+    /**
+    * Clears the attentionFlag on an existing task.
+    * @param params The params for task with id of params.id.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
+    */
+    def clearAttentionFlag(params) {
+        Task.withTransaction { status ->
+            def result = [:]
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.attentionFlag = false
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(13),
+                                                    task: result.taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
+            return result
+
+        } //end withTransaction
+    }  // end clearFlag()
 
     /**
     * Reopens an existing task.
     * @param params The params for task with id of params.id.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
     */
     def reopen(params) {
         Task.withTransaction { status ->
             def result = [:]
-            result.taskInstance = Task.get(params.id)
-            if(result.taskInstance) {
-
-                // Optimistic locking check.
-                if(params.version) {
-                    def version = params.version.toLong()
-                    if(result.taskInstance.version > version) {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
-                        result.error = true
-                        return result
-                    }
-                }
-
-                result.taskInstance.taskStatus = TaskStatus.get(2)
-
-                if(result.taskInstance.save()) {
-                    def taskModification = new TaskModification(person:authService.currentUser,
-                                                            taskModificationType: TaskModificationType.get(5),
-                                                            task: result.taskInstance)
-                    if(taskModification.save()) {
-                        // All went well.
-                        return result
-                    }
-                    else {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
-                        result.error = true
-                        return result
-                    }
-                }
-            }
-            // Something failed.
-            status.setRollbackOnly()
-            result.error = true
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.taskStatus = TaskStatus.get(2)
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(5),
+                                                    task: result.taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
             return result
 
@@ -383,45 +462,44 @@
     * Move a task to the trash.
     * @param params The params for task with id of params.id.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
     */
     def trash(params) {
         Task.withTransaction { status ->
             def result = [:]
-            result.taskInstance = Task.get(params.id)
-            if(result.taskInstance) {
-
-                // Optimistic locking check.
-                if(params.version) {
-                    def version = params.version.toLong()
-                    if(result.taskInstance.version > version) {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
-                        result.error = true
-                        return result
-                    }
-                }
-
-                result.taskInstance.trash = true
-                result.taskInstance.taskRecurringSchedule?.enabled = false
-
-                if(result.taskInstance.save()) {
-                    def taskModification = new TaskModification(person:authService.currentUser,
-                                                            taskModificationType: TaskModificationType.get(6),
-                                                            task: result.taskInstance)
-                    if(taskModification.save()) {
-                        // All went well.
-                        return result
-                    }
-                    else {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
-                        result.error = true
-                        return result
-                    }
-                }
-            }
-            // Something failed.
-            status.setRollbackOnly()
-            result.error = true
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.trash = true
+            result.taskInstance.attentionFlag = false
+            result.taskInstance.taskRecurringSchedule?.enabled = false
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(6),
+                                                    task: result.taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
             return result
 
@@ -432,44 +510,42 @@
     * Restore a task from the trash.
     * @param params The params for task with id of params.id.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
     */
     def restore(params) {
         Task.withTransaction { status ->
             def result = [:]
-            result.taskInstance = Task.get(params.id)
-            if(result.taskInstance) {
-
-                // Optimistic locking check.
-                if(params.version) {
-                    def version = params.version.toLong()
-                    if(result.taskInstance.version > version) {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
-                        result.error = true
-                        return result
-                    }
-                }
-
-                result.taskInstance.trash = false
-
-                if(result.taskInstance.save()) {
-                    def taskModification = new TaskModification(person:authService.currentUser,
-                                                            taskModificationType: TaskModificationType.get(7),
-                                                            task: result.taskInstance)
-                    if(taskModification.save()) {
-                        // All went well.
-                        return result
-                    }
-                    else {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
-                        result.error = true
-                        return result
-                    }
-                }
-            }
-            // Something failed.
-            status.setRollbackOnly()
-            result.error = true
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.trash = false
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(7),
+                                                    task: result.taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
             return result
 
@@ -480,44 +556,42 @@
     * Approve a task.
     * @param params The params for task with id of params.id.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
     */
     def approve(params) {
         Task.withTransaction { status ->
             def result = [:]
-            result.taskInstance = Task.get(params.id)
-            if(result.taskInstance) {
-
-                // Optimistic locking check.
-                if(params.version) {
-                    def version = params.version.toLong()
-                    if(result.taskInstance.version > version) {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
-                        result.error = true
-                        return result
-                    }
-                }
-
-                result.taskInstance.approved = true
-
-                if(result.taskInstance.save()) {
-                    def taskModification = new TaskModification(person:authService.currentUser,
-                                                            taskModificationType: TaskModificationType.get(8),
-                                                            task: result.taskInstance)
-                    if(taskModification.save()) {
-                        // All went well.
-                        return result
-                    }
-                    else {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
-                        result.error = true
-                        return result
-                    }
-                }
-            }
-            // Something failed.
-            status.setRollbackOnly()
-            result.error = true
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.approved = true
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(8),
+                                                    task: result.taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
             return result
 
@@ -528,44 +602,42 @@
     * Remove a previously given approval from a task.
     * @param params The params for task with id of params.id.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
+    * @returns A map containing result.error (if any error) and result.taskInstance (if available).
     */
     def renegeApproval(params) {
         Task.withTransaction { status ->
             def result = [:]
-            result.taskInstance = Task.get(params.id)
-            if(result.taskInstance) {
-
-                // Optimistic locking check.
-                if(params.version) {
-                    def version = params.version.toLong()
-                    if(result.taskInstance.version > version) {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("version", "task.optimistic.locking.failure", "Another user has updated this Task while you were editing.")
-                        result.error = true
-                        return result
-                    }
-                }
-
-                result.taskInstance.approved = false
-
-                if(result.taskInstance.save()) {
-                    def taskModification = new TaskModification(person:authService.currentUser,
-                                                            taskModificationType: TaskModificationType.get(9),
-                                                            task: result.taskInstance)
-                    if(taskModification.save()) {
-                        // All went well.
-                        return result
-                    }
-                    else {
-                        status.setRollbackOnly()
-                        result.taskInstance.errors.rejectValue("taskModifications", "task.modifications.failedToSave")
-                        result.error = true
-                        return result
-                    }
-                }
-            }
-            // Something failed.
-            status.setRollbackOnly()
-            result.error = true
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.taskInstance && m.field)
+                    result.taskInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Task", params.id] ]
+                return result
+            }
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Optimistic locking check.
+            if(params.version) {
+                if(result.taskInstance.version > params.version.toLong())
+                    return fail(field:"version", code:"default.optimistic.locking.failure")
+            }
+
+            result.taskInstance.approved = false
+
+            if(result.taskInstance.hasErrors() || !result.taskInstance.save())
+                return fail(code:"default.update.failure")
+
+            def taskModification = new TaskModification(person:authService.currentUser,
+                                                    taskModificationType: TaskModificationType.get(9),
+                                                    task: result.taskInstance)
+
+            if(taskModification.hasErrors() || !taskModification.save())
+                return fail(code:"task.modifications.failedToSave")
+
+            // Success.
             return result
 
@@ -574,9 +646,9 @@
 
     /**
-    * Creates a new breakin task with the given params.
+    * Creates a new immediate callout task with the given params.
     * @param params The params to use when creating the new task.
-    * @returns A map containing result.error=true (if any error) and result.taskInstance.
-    */
-    def saveBreakin(params) {
+    * @returns A map containing result.error (if any error) and result.taskInstance.
+    */
+    def saveImmediateCallout(params) {
         Task.withTransaction { status ->
             def result = [:]
@@ -596,6 +668,6 @@
             result.taskInstance = new Task(params)
 
-            // Always for a breakin.
-            result.taskInstance.taskType = TaskType.get(1) // Unscheduled Breakin.
+            // Always for an immediate callout.
+            result.taskInstance.taskType = TaskType.get(1) // Immediate Callout.
             result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned.
             result.taskInstance.taskPriority = TaskPriority.get(4) // Immediate.
@@ -624,6 +696,12 @@
             result.entryFaultInstance = faultResult.entryInstance
 
+            def causeParams = [task: result.taskInstance,
+                                            entryType: EntryType.get(2),
+                                            comment: params.entryCause.comment]
+            def causeResult = saveEntry(causeParams)
+            result.entryCauseInstance = causeResult.entryInstance
+
             def workDoneParams = [task: result.taskInstance,
-                                                    entryType: EntryType.get(2),
+                                                    entryType: EntryType.get(3),
                                                     comment: params.entryWorkDone.comment,
                                                     durationHour: params.entryWorkDone.durationHour,
@@ -635,4 +713,7 @@
                 return result
 
+            if(causeResult.error)
+                return fail(code: "default.create.failure")
+
             if(faultResult.error)
                 return fail(code: "default.create.failure")
@@ -645,5 +726,5 @@
 
         } //end withTransaction
-    } // end saveBreakin()
+    } // end saveImmediateCallout()
 
 } // end TaskService
