Index: trunk/grails-app/controllers/MaintenanceActionDetailedController.groovy
===================================================================
--- trunk/grails-app/controllers/MaintenanceActionDetailedController.groovy	(revision 751)
+++ 	(revision )
@@ -1,95 +1,0 @@
-import org.codehaus.groovy.grails.plugins.springsecurity.Secured
-
-@Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_AssetManager'])
-class MaintenanceActionDetailedController extends BaseController {
-
-    // the delete, save and update actions only accept POST requests
-    static allowedMethods = [delete:'POST', save:'POST', update:'POST']
-
-    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_AssetManager', 'ROLE_AssetUser'])
-    def show = {
-        def maintenanceActionInstance = MaintenanceAction.get( params.id )
-
-        if(!maintenanceActionInstance) {
-            flash.message = "MaintenanceAction not found with id ${params.id}"
-            redirect(controller: "appCore", action:"start")
-        }
-        else { return [ maintenanceActionInstance : maintenanceActionInstance ] }
-    }
-
-    def delete = {
-        def maintenanceActionInstance = MaintenanceAction.get( params.id )
-        if(maintenanceActionInstance) {
-            try {
-                def taskProcedure = maintenanceActionInstance.taskProcedure
-                maintenanceActionInstance.delete(flush:true)
-                flash.message = "MaintenanceAction ${params.id} deleted"
-                redirect(controller: "taskProcedureDetailed", action:"show", id:taskProcedure.id)
-            }
-            catch(org.springframework.dao.DataIntegrityViolationException e) {
-                flash.message = "MaintenanceAction ${params.id} could not be deleted"
-                redirect(action:show,id:params.id)
-            }
-        }
-        else {
-            flash.message = "MaintenanceAction not found with id ${params.id}"
-            redirect(controller: "appCore", action:"start")
-        }
-    }
-
-    def edit = {
-        def maintenanceActionInstance = MaintenanceAction.get( params.id )
-
-        if(!maintenanceActionInstance) {
-            flash.message = "MaintenanceAction not found with id ${params.id}"
-            redirect(controller: "appCore", action:"start")
-        }
-        else {
-            return [ maintenanceActionInstance : maintenanceActionInstance ]
-        }
-    }
-
-    def update = {
-        def maintenanceActionInstance = MaintenanceAction.get( params.id )
-        if(maintenanceActionInstance) {
-            if(params.version) {
-                def version = params.version.toLong()
-                if(maintenanceActionInstance.version > version) {
-                    
-                    maintenanceActionInstance.errors.rejectValue("version", "default.optimistic.locking.failure")
-                    render(view:'edit',model:[maintenanceActionInstance:maintenanceActionInstance])
-                    return
-                }
-            }
-            maintenanceActionInstance.properties = params
-            if(!maintenanceActionInstance.hasErrors() && maintenanceActionInstance.save(flush: true)) {
-                flash.message = "MaintenanceAction ${params.id} updated"
-                redirect(action:show,id:maintenanceActionInstance.id)
-            }
-            else {
-                render(view:'edit',model:[maintenanceActionInstance:maintenanceActionInstance])
-            }
-        }
-        else {
-            flash.message = "MaintenanceAction not found with id ${params.id}"
-            redirect(controller: "appCore", action:"start")
-        }
-    }
-
-    def create = {
-        def maintenanceActionInstance = new MaintenanceAction()
-        maintenanceActionInstance.properties = params
-        return ['maintenanceActionInstance':maintenanceActionInstance]
-    }
-
-    def save = {
-        def maintenanceActionInstance = new MaintenanceAction(params)
-        if(!maintenanceActionInstance.hasErrors() && maintenanceActionInstance.save(flush: true)) {
-            flash.message = "MaintenanceAction ${maintenanceActionInstance.id} created"
-            redirect(action:show,id:maintenanceActionInstance.id)
-        }
-        else {
-            render(view:'create',model:[maintenanceActionInstance:maintenanceActionInstance])
-        }
-    }
-}
Index: trunk/grails-app/controllers/TaskProcedureController.groovy
===================================================================
--- trunk/grails-app/controllers/TaskProcedureController.groovy	(revision 751)
+++ 	(revision )
@@ -1,99 +1,0 @@
-import org.codehaus.groovy.grails.plugins.springsecurity.Secured
-
-class TaskProcedureController extends BaseAppAdminController {
-    
-    def index = { redirect(action:list,params:params) }
-
-    // the delete, save and update actions only accept POST requests
-    static allowedMethods = [delete:'POST', save:'POST', update:'POST']
-
-    def list = {
-        params.max = Math.min( params.max ? params.max.toInteger() : 10,  100)
-        [ taskProcedureInstanceList: TaskProcedure.list( params ), taskProcedureInstanceTotal: TaskProcedure.count() ]
-    }
-
-    def show = {
-        def taskProcedureInstance = TaskProcedure.get( params.id )
-
-        if(!taskProcedureInstance) {
-            flash.message = "TaskProcedure not found with id ${params.id}"
-            redirect(action:list)
-        }
-        else { return [ taskProcedureInstance : taskProcedureInstance ] }
-    }
-
-    def delete = {
-        def taskProcedureInstance = TaskProcedure.get( params.id )
-        if(taskProcedureInstance) {
-            try {
-                taskProcedureInstance.delete(flush:true)
-                flash.message = "TaskProcedure ${params.id} deleted"
-                redirect(action:list)
-            }
-            catch(org.springframework.dao.DataIntegrityViolationException e) {
-                flash.message = "TaskProcedure ${params.id} could not be deleted"
-                redirect(action:show,id:params.id)
-            }
-        }
-        else {
-            flash.message = "TaskProcedure not found with id ${params.id}"
-            redirect(action:list)
-        }
-    }
-
-    def edit = {
-        def taskProcedureInstance = TaskProcedure.get( params.id )
-
-        if(!taskProcedureInstance) {
-            flash.message = "TaskProcedure not found with id ${params.id}"
-            redirect(action:list)
-        }
-        else {
-            return [ taskProcedureInstance : taskProcedureInstance ]
-        }
-    }
-
-    def update = {
-        def taskProcedureInstance = TaskProcedure.get( params.id )
-        if(taskProcedureInstance) {
-            if(params.version) {
-                def version = params.version.toLong()
-                if(taskProcedureInstance.version > version) {
-                    
-                    taskProcedureInstance.errors.rejectValue("version", "default.optimistic.locking.failure")
-                    render(view:'edit',model:[taskProcedureInstance:taskProcedureInstance])
-                    return
-                }
-            }
-            taskProcedureInstance.properties = params
-            if(!taskProcedureInstance.hasErrors() && taskProcedureInstance.save(flush: true)) {
-                flash.message = "TaskProcedure ${params.id} updated"
-                redirect(action:show,id:taskProcedureInstance.id)
-            }
-            else {
-                render(view:'edit',model:[taskProcedureInstance:taskProcedureInstance])
-            }
-        }
-        else {
-            flash.message = "TaskProcedure not found with id ${params.id}"
-            redirect(action:list)
-        }
-    }
-
-    def create = {
-        def taskProcedureInstance = new TaskProcedure()
-        taskProcedureInstance.properties = params
-        return ['taskProcedureInstance':taskProcedureInstance]
-    }
-
-    def save = {
-        def taskProcedureInstance = new TaskProcedure(params)
-        if(!taskProcedureInstance.hasErrors() && taskProcedureInstance.save(flush: true)) {
-            flash.message = "TaskProcedure ${taskProcedureInstance.id} created"
-            redirect(action:show,id:taskProcedureInstance.id)
-        }
-        else {
-            render(view:'create',model:[taskProcedureInstance:taskProcedureInstance])
-        }
-    }
-}
Index: trunk/grails-app/controllers/TaskProcedureDetailedController.groovy
===================================================================
--- trunk/grails-app/controllers/TaskProcedureDetailedController.groovy	(revision 751)
+++ trunk/grails-app/controllers/TaskProcedureDetailedController.groovy	(revision 798)
@@ -5,4 +5,6 @@
 
     def filterService
+    def assetService
+    def taskProcedureService
 
     def index = { redirect(action:list,params:params) }
@@ -40,8 +42,13 @@
 
         if(!taskProcedureInstance) {
-            flash.message = "TaskProcedure not found with id ${params.id}"
-            redirect(action:list)
-        }
-        else { return [ taskProcedureInstance : taskProcedureInstance ] }
+            flash.errorMessage = "TaskProcedure not found with id ${params.id}"
+            redirect(controller:'taskDetailed', action:'search')
+            return
+        }
+
+        redirect(controller:'taskDetailed',
+                        action:'show',
+                        id:taskProcedureInstance.linkedTask?.id,
+                        params:[showTab:"showProcedureTab"])
     }
 
@@ -49,16 +56,26 @@
         def taskProcedureInstance = TaskProcedure.get( params.id )
         if(taskProcedureInstance) {
+            def taskInstance = taskProcedureInstance.linkedTask
             try {
+                taskProcedureInstance.tasks.each {
+                    it.taskProcedure = null
+                }
                 taskProcedureInstance.delete(flush:true)
                 flash.message = "TaskProcedure ${params.id} deleted"
-                redirect(action:list)
+                redirect(controller:'taskDetailed',
+                                action:'show',
+                                id:taskInstance.id,
+                                params:[showTab:"showProcedureTab"])
             }
             catch(org.springframework.dao.DataIntegrityViolationException e) {
-                flash.message = "TaskProcedure ${params.id} could not be deleted"
-                redirect(action:show,id:params.id)
+                flash.errorMessage = "TaskProcedure ${params.id} could not be deleted"
+                redirect(controller:'taskDetailed',
+                                action:'show',
+                                id:taskInstance.id,
+                                params:[showTab:"showProcedureTab"])
             }
         }
         else {
-            flash.message = "TaskProcedure not found with id ${params.id}"
+            flash.errorMessage = "TaskProcedure not found with id ${params.id}"
             redirect(action:list)
         }
@@ -74,65 +91,116 @@
 
         if(!taskProcedureInstance) {
-            flash.message = "TaskProcedure not found with id ${params.id}"
+            flash.errorMessage = "TaskProcedure not found with id ${params.id}"
             redirect(action:list)
         }
         else {
-            return [ taskProcedureInstance : taskProcedureInstance ]
+            def assemblies = assetService.getAssemblies(taskProcedureInstance.linkedTask.primaryAsset)
+            return [ taskProcedureInstance : taskProcedureInstance,
+                            assemblies: assemblies ]
         }
     }
 
     def update = {
-        def taskProcedureInstance = TaskProcedure.get( params.id )
-        if(taskProcedureInstance) {
-            if(params.version) {
-                def version = params.version.toLong()
-                if(taskProcedureInstance.version > version) {
-
-                    taskProcedureInstance.errors.rejectValue("version", "default.optimistic.locking.failure")
-                    render(view:'edit',model:[taskProcedureInstance:taskProcedureInstance])
-                    return
-                }
-            }
-            taskProcedureInstance.properties = params
-            if(!taskProcedureInstance.hasErrors() && taskProcedureInstance.save(flush: true)) {
-                flash.message = "TaskProcedure ${params.id} updated"
-                redirect(action:show,id:taskProcedureInstance.id)
-            }
-            else {
-                render(view:'edit',model:[taskProcedureInstance:taskProcedureInstance])
-            }
-        }
-        else {
-            flash.message = "TaskProcedure not found with id ${params.id}"
+        def result = taskProcedureService.update(params)
+
+        if(!result.error) {
+            flash.message = g.message(code: "default.update.success", args: ["TaskProcedure", params.id])
+            redirect(controller:'taskDetailed',
+                            action:'show',
+                            id:result.taskProcedureInstance.linkedTask.id,
+                            params:[showTab:"showProcedureTab"])
+            return
+        }
+
+        if(result.error.code == "default.not.found") {
+            flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
             redirect(action:list)
-        }
+            return
+        }
+
+        if(result.error.code == "default.optimistic.locking.failure") {
+            flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
+            redirect(controller:'taskDetailed',
+                            action:'show',
+                            id:result.taskProcedureInstance.linkedTask.id,
+                            params:[showTab:"showProcedureTab"])
+            return
+        }
+
+        def assemblies = assetService.getAssemblies(result.taskProcedureInstance.linkedTask.primaryAsset)
+        render(view:'edit', model:[taskProcedureInstance: result.taskProcedureInstance,
+                                                assemblies: assemblies])
     }
 
     def create = {
-        if(params.taskInstance?.id) {
-            def taskInstance = Task.get(params.taskInstance.id)
-
-            def taskProcedureInstance = new TaskProcedure()
-            taskProcedureInstance.properties = params
-            return ['taskProcedureInstance':taskProcedureInstance,
-                            taskInstance: taskInstance]
-        } else {
-            flash.message = "Please select or create a task, then go to the Procedure tab."
+
+        if(!params.taskInstance?.id) {
+            flash.errorMessage = "Please select or create a task, then go to the Procedure tab."
             redirect(controller:"taskDetailed", action:"search")
-        }
+            return
+        }
+
+        params.linkedTask = Task.get(params.taskInstance.id)
+
+        // Task already has a taskProcedure.
+        if(params.linkedTask.taskProcedure) {
+            flash.errorMessage = g.message(code: 'default.optimistic.locking.failure')
+            redirect(controller:'taskDetailed',
+                            action:'show',
+                            id:params.linkedTask.id,
+                            params:[showTab:"showProcedureTab"])
+            return
+        }
+
+        // Task does not have a primaryAsset.
+        if(!params.linkedTask?.primaryAsset) {
+            flash.errorMessage = "Please set a Primary Asset first, then go to the Procedure tab."
+            redirect(controller:"taskDetailed", action:"show", id:params.linkedTask?.id)
+            return
+        }
+
+        def taskProcedureInstance = new TaskProcedure()
+        taskProcedureInstance.properties = params
+
+        // Populate a couple of maintenanceActions for the first assembly.
+        def assemblies = assetService.getAssemblies(params.linkedTask.primaryAsset)
+        if(assemblies) {
+            def assembly = assemblies[0]
+            def ma = taskProcedureInstance.maintenanceActionLazyList.get(0)
+            ma.assetSubItem = assembly
+            ma.procedureStepNumber = 10
+            ma = taskProcedureInstance.maintenanceActionLazyList.get(1)
+            ma.assetSubItem = assembly
+            ma.procedureStepNumber = 20
+        }
+
+        return ['taskProcedureInstance':taskProcedureInstance, 'assemblies': assemblies]
     }
 
     def save = {
-        def taskProcedureInstance = new TaskProcedure(params)
-        def taskInstance = Task.get(params.taskInstance.id)
-
-        if(!taskProcedureInstance.hasErrors() && taskProcedureInstance.save(flush: true)) {
-            taskProcedureInstance.addToTasks(taskInstance)
-            flash.message = "TaskProcedure ${taskProcedureInstance.id} created."
-            redirect(action:show,id:taskProcedureInstance.id)
-        }
-        else {
-            render(view:'create',model:[taskProcedureInstance:taskProcedureInstance, taskInstance: taskInstance])
-        }
-    }
+        def result = taskProcedureService.save(params)
+
+        if(!result.error) {
+            flash.message = g.message(code: "default.create.success", args: ["TaskProcedure", result.taskProcedureInstance.id])
+            redirect(controller:'taskDetailed',
+                            action:'show',
+                            id:result.taskProcedureInstance.linkedTask.id,
+                            params:[showTab:"showProcedureTab"])
+            return
+        }
+
+        if(result.error.code == "default.optimistic.locking.failure") {
+            flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
+            redirect(controller:'taskDetailed',
+                            action:'show',
+                            id:result.taskProcedureInstance.linkedTask.id,
+                            params:[showTab:"showProcedureTab"])
+            return
+        }
+
+        def assemblies = assetService.getAssemblies(result.taskProcedureInstance.linkedTask.primaryAsset)
+        render(view:'create', model:[taskProcedureInstance: result.taskProcedureInstance,
+                                                    assemblies: assemblies])
+    }
+
 }
