Index: /trunk/grails-app/controllers/TaskRecurringScheduleDetailedController.groovy
===================================================================
--- /trunk/grails-app/controllers/TaskRecurringScheduleDetailedController.groovy	(revision 206)
+++ /trunk/grails-app/controllers/TaskRecurringScheduleDetailedController.groovy	(revision 207)
@@ -60,55 +60,21 @@
 
     def update = {
-        TaskRecurringSchedule.withTransaction { status ->
 
-            def taskRecurringScheduleInstance = TaskRecurringSchedule.get( params.id )
-            if(taskRecurringScheduleInstance) {
+        if(!TaskRecurringSchedule.exists(params.id)) {
+            flash.message = "Recurring Schedule not found with id ${params.id}"
+            redirect(action: 'list')
+        }
 
-                if(params.version) {
-                    def version = params.version.toLong()
-                    if(taskRecurringScheduleInstance.version > version) {
-                        taskRecurringScheduleInstance.errors.rejectValue("version", "taskRecurringSchedule.optimistic.locking.failure", "Another user has updated this Recurring Schedule while you were editing.")
-                        render(view:'edit',model:[taskRecurringScheduleInstance:taskRecurringScheduleInstance])
-                        return
-                    }
-                }
+        def result = taskRecurringScheduleService.update(params)
 
-                Date originalDate = taskRecurringScheduleInstance.nextTargetStartDate
-                taskRecurringScheduleInstance.properties = params  // Domain object is now 'dirty'.
-                Date newDate = taskRecurringScheduleInstance.nextTargetStartDate
+        if(!result.error) {
+                flash.message = "Recurring Schedule ${params.id} updated"
+                redirect(action: 'show', id: result.taskRecurringScheduleInstance.id)
+        }
+        else {
+            render(view:'edit',model:[taskRecurringScheduleInstance: result.taskRecurringScheduleInstance.attach()])
+        }
 
-                // If user changes nextTargetStartDate then ensure it is in the future, otherwise it's ok to keep the original date.
-                if(originalDate.getTime() != newDate.getTime())
-                {
-                    if(newDate < dateUtilService.getToday()) 
-                    {
-                        status.setRollbackOnly()  // Only allow the transaction to Rollback, preventing flush due to 'dirty'.
-                        taskRecurringScheduleInstance.errors.rejectValue("nextTargetStartDate", "taskRecurring.nextTargetStartDate.NotInTheFuture")
-                        render(view:'edit',model:[taskRecurringScheduleInstance:taskRecurringScheduleInstance])
-                        return
-                    }
-                }
-
-                taskRecurringScheduleInstance.setNextGenerationDate()
-                taskRecurringScheduleInstance.setNextTargetCompletionDate()
-
-                if(!taskRecurringScheduleInstance.hasErrors() && taskRecurringScheduleInstance.save(flush: true))
-                {
-                    flash.message = "Recurring Schedule ${params.id} updated"
-                    redirect(action:show,id:taskRecurringScheduleInstance.id)
-                }
-                else 
-                {
-                    render(view:'edit',model:[taskRecurringScheduleInstance:taskRecurringScheduleInstance])
-                }
-            }
-            else 
-            {
-                flash.message = "Recurring Schedule not found with id ${params.id}"
-                redirect(action:edit,id:params.id)
-            }
-
-        } // end withTransaction
-    } // end update()
+    }
 
     def create = {
Index: /trunk/grails-app/i18n/messages.properties
===================================================================
--- /trunk/grails-app/i18n/messages.properties	(revision 206)
+++ /trunk/grails-app/i18n/messages.properties	(revision 207)
@@ -31,4 +31,6 @@
 task.modifications.failedToSave=Could not complete operation, as task modification record failed to save.
 tast.taskRecurringSchedule.alreadyExists=This task already has a recurring schedule.
+
+taskRecurringSchedule.notFound=Could not complete operation, recurring schedule not found.
 
 task.assignedPersons=Assigned Persons
Index: /trunk/grails-app/services/TaskRecurringScheduleService.groovy
===================================================================
--- /trunk/grails-app/services/TaskRecurringScheduleService.groovy	(revision 206)
+++ /trunk/grails-app/services/TaskRecurringScheduleService.groovy	(revision 207)
@@ -81,5 +81,5 @@
                 return fail()
 
-            // All went well if we get to here.
+             // If we get here all went well.
             return result
 
@@ -87,3 +87,56 @@
     } // end create()
 
+    /**
+    * Updates an existing recurring schedule.
+    * @param params The params to update for recurring schedule with id of params.id.
+    * @returns A map containing result.error=true (if any error) and result.taskRecurringScheduleInstance (if available).
+    */
+    def update(params) {
+        TaskRecurringSchedule.withTransaction { status ->
+            def result = [:]
+
+            def fail = { Object[] args ->
+                status.setRollbackOnly()
+                if(args.size() == 2) result.taskRecurringScheduleInstance.errors.rejectValue(args[0], args[1])
+                result.error = true
+                return result
+            }
+
+            result.taskRecurringScheduleInstance = TaskRecurringSchedule.get(params.id)
+
+            if(!result.taskRecurringScheduleInstance)
+                return fail('id', "taskRecurringSchedule.notFound")
+
+            // Optimistic locking check.
+            if(params.version) {
+                def version = params.version.toLong()
+                if(result.taskRecurringScheduleInstance.version > version)
+                    return fail("version", "default.optimistic.locking.failure")
+            }
+
+            result.taskRecurringScheduleInstance.validate()
+
+            Date originalDate = result.taskRecurringScheduleInstance.nextTargetStartDate
+            result.taskRecurringScheduleInstance.properties = params
+            Date newDate = result.taskRecurringScheduleInstance.nextTargetStartDate
+
+            // If user changes nextTargetStartDate then ensure it is in the future, otherwise it's ok to keep the original date.
+            if(originalDate.getTime() != newDate.getTime())
+            {
+                if(newDate < dateUtilService.getToday())
+                    return fail("nextTargetStartDate", "taskRecurring.nextTargetStartDate.NotInTheFuture")
+            }
+
+            result.taskRecurringScheduleInstance.setNextGenerationDate()
+            result.taskRecurringScheduleInstance.setNextTargetCompletionDate()
+
+            if(result.taskRecurringScheduleInstance.hasErrors() || !result.taskRecurringScheduleInstance.save())
+                return fail()
+
+            // If we get here all went well.
+            return result
+
+        } //end withTransaction
+    }  // end update()
+
 } // end of class
