Index: /trunk/grails-app/controllers/AssetDetailedController.groovy
===================================================================
--- /trunk/grails-app/controllers/AssetDetailedController.groovy	(revision 349)
+++ /trunk/grails-app/controllers/AssetDetailedController.groovy	(revision 350)
@@ -232,20 +232,20 @@
     */
     def delete = {
-        def assetInstance = Asset.get( params.id )
-        if(assetInstance) {
-            try {
-                assetInstance.delete(flush:true)
-                flash.message = "Asset ${params.id} deleted"
-                redirect(action:search)
-            }
-            catch(org.springframework.dao.DataIntegrityViolationException e) {
-                flash.message = "Asset ${params.id} could not be deleted"
-                redirect(action:show,id:params.id)
-            }
-        }
-        else {
-            flash.message = "Asset not found with id ${params.id}"
-            redirect(action:search)
-        }
+        def result = assetService.delete(params)
+
+        if(!result.error) {
+            flash.message = g.message(code: "default.delete.success", args: ["Asset", params.id])
+            redirect(action:search)
+            return
+        }
+
+        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
+
+        if(result.error.code == "default.not.found") {
+            redirect(action:search)
+            return
+        }
+
+        redirect(action:show, id: params.id)
     }
 
Index: /trunk/grails-app/i18n/messages.properties
===================================================================
--- /trunk/grails-app/i18n/messages.properties	(revision 349)
+++ /trunk/grails-app/i18n/messages.properties	(revision 350)
@@ -11,7 +11,10 @@
 asset.copy.asset.required=Please select an asset to copy.
 
+maintenanceActions.still.associated=Could not complete operation as maintenance actions are still associated with this item.
+
+asset.subItems.delete.failure=Could not complete operation as orphan sub items failed to delete.
+
 assetSubItem.asset.not.found=Could not complete operation as an asset was supplied but not found.
 assetSubItem.assets.associated=Could not complete operation as assets are still associated with this sub item.
-assetSubItem.maintenanceActions.associated=Could not complete operation as maintenance actions are still associated with this sub item.
 
 sub.task.create.confirm=Immediately create and save a new sub task?
Index: /trunk/grails-app/services/AssetService.groovy
===================================================================
--- /trunk/grails-app/services/AssetService.groovy	(revision 349)
+++ /trunk/grails-app/services/AssetService.groovy	(revision 350)
@@ -2,4 +2,6 @@
 
     boolean transactional = false
+
+    def assetSubItemService
 
     /**
@@ -13,4 +15,52 @@
         }
     }
+
+    def delete(params) {
+        Asset.withTransaction { status ->
+            def result = [:]
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.assetInstance && m.field)
+                    result.assetInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Asset", params.id] ]
+                return result
+            }
+
+            result.assetInstance = Asset.get(params.id)
+
+            if(!result.assetInstance)
+                return fail(code:"default.not.found")
+
+            if(result.assetInstance.maintenanceActions)
+                return fail(code:"maintenanceActions.still.associated")
+
+            // Remove orphan assetSubItems.
+            def assetSubItems = new ArrayList(result.assetInstance.assetSubItems) // avoid ConcurrentModificationException.
+            def r
+            for(assetSubItem in assetSubItems) {
+                result.assetInstance.removeFromAssetSubItems(assetSubItem)
+                if(!assetSubItem.assets && !assetSubItem.parentItem) {
+                    r = assetSubItemService.delete(id: assetSubItem.id)
+                    if(r.error) {
+                        fail(code:"asset.subItems.delete.failure")
+                        break
+                    }
+                }
+            }
+
+            if(result.error)
+                return result
+
+            try {
+                result.assetInstance.delete(flush:true)
+                return result //Success.
+            }
+            catch(org.springframework.dao.DataIntegrityViolationException e) {
+                return fail(code:"default.delete.failure")
+            }
+
+        } // end withTransaction
+    } // end delete()
 
     def create(params) {
@@ -164,5 +214,5 @@
             return result
 
-        } //end withTransaction
+        } // end withTransaction
     } // end saveCopySrvce
 
Index: /trunk/grails-app/services/AssetSubItemService.groovy
===================================================================
--- /trunk/grails-app/services/AssetSubItemService.groovy	(revision 349)
+++ /trunk/grails-app/services/AssetSubItemService.groovy	(revision 350)
@@ -19,5 +19,5 @@
 
         if(result.assetSubItemInstance.maintenanceActions)
-            return fail(code:"assetSubItem.maintenanceActions.associated")
+            return fail(code:"maintenanceActions.still.associated")
 
         try {
