Index: trunk/grails-app/services/TaskService.groovy
===================================================================
--- trunk/grails-app/services/TaskService.groovy	(revision 482)
+++ trunk/grails-app/services/TaskService.groovy	(revision 510)
@@ -1,2 +1,4 @@
+import grails.util.Environment
+
 /**
 * Provides a service class for the Task domain class.
@@ -221,4 +223,50 @@
 
     /**
+    * In production tasks are NEVER deleted, only the trash flag is set!
+    * However during testing it may be required to delete a task and that
+    * is why this method exists.
+    */
+    def delete(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
+            }
+
+            if(Environment.current == Environment.PRODUCTION)
+                return fail(code:"task.delete.failure.production")
+
+            result.taskInstance = Task.get(params.id)
+
+            if(!result.taskInstance)
+                return fail(code:"default.not.found")
+
+            // Handle taskModifications.
+            def taskModifications = TaskModification.findAllByTask(result.taskInstance)
+            taskModifications.each() {
+                result.taskInstance.removeFromTaskModifications(it)
+                it.delete()
+            }
+
+            if(result.error)
+                return result
+
+            try {
+                result.taskInstance.delete(flush:true)
+                return result //Success.
+            }
+            catch(org.springframework.dao.DataIntegrityViolationException e) {
+                return fail(code:"default.delete.failure")
+            }
+
+        } // end withTransaction
+    } // delete()
+
+    /**
     * Creates a new task entry.
     * @param params The params to use when creating the new entry.
@@ -241,5 +289,5 @@
 
             def taskInstance
-            if(result.entryInstance.task.id) {
+            if(result.entryInstance.task?.id) {
                 result.taskId = result.entryInstance.task.id
                 taskInstance = Task.lock(result.entryInstance.task.id)
@@ -255,10 +303,12 @@
                 return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
 
-            // 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 == 3) {
+            // If task status is "Not Started" and entry type is "Work Done" and time has been booked.
+            // Then we create the started modification and set task status.
+            if(taskInstance.taskStatus.id == 1 && result.entryInstance.entryType.id == 3
+                && (result.entryInstance.durationHour + result.entryInstance.durationMinute > 0)) {
 
                 // Create the "Started" task modification, this provides the "Actual Started Date".
                 def taskModification = new TaskModification(person: authService.currentUser,
-                                                        taskModificationType: TaskModificationType.get(2),
+                                                        taskModificationType: TaskModificationType.read(2),
                                                         task: taskInstance)
 
@@ -267,5 +317,5 @@
 
                 // Set task status to "In Progress".
-                taskInstance.taskStatus = TaskStatus.get(2)
+                taskInstance.taskStatus = TaskStatus.read(2)
 
                 if(taskInstance.hasErrors() || !taskInstance.save())
@@ -494,5 +544,14 @@
             }
 
-            result.taskInstance.taskStatus = TaskStatus.get(2)
+            def isInProgress = false
+            result.taskInstance.entries.each() {
+                if(it.entryType.id == 3 && (it.durationHour + it.durationMinute > 0) )
+                    isInProgress = true
+            }
+
+            if(isInProgress)
+                result.taskInstance.taskStatus = TaskStatus.read(2) // In Progress
+            else
+                result.taskInstance.taskStatus = TaskStatus.read(1) // Not Started
 
             if(result.taskInstance.hasErrors() || !result.taskInstance.save())
