Index: /trunk/grails-app/conf/Config.groovy =================================================================== --- /trunk/grails-app/conf/Config.groovy (revision 394) +++ /trunk/grails-app/conf/Config.groovy (revision 395) @@ -147,4 +147,5 @@ [order:11, controller:'taskDetailed', title:'Calendar', action:'searchCalendar', isVisible: { true }], [order:20, controller:'taskDetailed', title:'Create', action:'create', isVisible: { true }], + [order:30, controller:'taskDetailed', title:'Breakin', action:'createBreakin', isVisible: { true }], [order:90, controller:'taskDetailed', title:'Show', action:'show', isVisible: { params.action == 'show' }], [order:91, controller:'taskDetailed', title:'Edit', action:'edit', isVisible: { params.action == 'edit' }] Index: /trunk/grails-app/controllers/TaskDetailedController.groovy =================================================================== --- /trunk/grails-app/controllers/TaskDetailedController.groovy (revision 394) +++ /trunk/grails-app/controllers/TaskDetailedController.groovy (revision 395) @@ -586,3 +586,35 @@ } + @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_TaskManager', 'ROLE_TaskUser']) + def createBreakin = { + def taskInstance = new Task() + + def entryFaultInstance = new Entry(entryType: EntryType.get(1)) // Fault. + def entryWorkDoneInstance = new Entry(entryType: EntryType.get(2)) // Work Done. + + return ['taskInstance': taskInstance, + 'entryFaultInstance': entryFaultInstance, + 'entryWorkDoneInstance': entryWorkDoneInstance] + } + + @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_TaskManager', 'ROLE_TaskUser']) + def saveBreakin = { + def result = taskService.saveBreakin(params) + + if(!result.error) { + flash.message = "Task ${result.taskInstance.id} created." + redirect(action: 'show', id: result.taskInstance.id) + return + } + + if(result.error.code == "task.modifications.failedToSave") + flash.errorMessage = g.message(code: result.error.code, args: result.error.args) + + render(view:'createBreakin', + model: ['taskInstance': result.taskInstance, + 'entryFaultInstance': result.entryFaultInstance, + 'entryWorkDoneInstance': result.entryWorkDoneInstance]) + + } + } // end of class. Index: /trunk/grails-app/services/TaskService.groovy =================================================================== --- /trunk/grails-app/services/TaskService.groovy (revision 394) +++ /trunk/grails-app/services/TaskService.groovy (revision 395) @@ -182,64 +182,54 @@ 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: ["Entry", params.id] ] + return result + } + result.entryInstance = new Entry(params) result.entryInstance.enteredBy = authService.currentUser - if(result.entryInstance.validate()) { + def taskInstance + if(result.entryInstance.task.id) { result.taskId = result.entryInstance.task.id - def taskInstance = Task.lock(result.taskId) - - if(!taskInstance) { - status.setRollbackOnly() - result.entryInstance.errors.rejectValue('task', "task.notFound") - result.error = true - return result - } - - if(taskInstance.taskStatus.id == 3) { - status.setRollbackOnly() - result.entryInstance.errors.rejectValue('task', "task.operationNotPermittedOnCompleteTask") - result.error = true - return result - } - - // 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) { - - // Create the "Started" task modification, this provides the "Actual started date". - def taskModification = new TaskModification(person: authService.currentUser, - taskModificationType: TaskModificationType.get(2), - task: taskInstance) - - if(!taskModification.save()) { - status.setRollbackOnly() - taskInstance.errors.rejectValue("task", "task.modifications.failedToSave") - result.error = true - return result - } - - // Set task status to "In progress". - taskInstance.taskStatus = TaskStatus.get(2) - - if(!taskInstance.save()) { - status.setRollbackOnly() - result.entryInstance.errors.rejectValue("task", "task.failedToSave") - result.error = true - return result - } - } - - if(!result.entryInstance.save()) { - status.setRollbackOnly() - result.error = true - return result - } - - // If we get here all went well. - return result - } - else { - result.error = true - return result - } + taskInstance = Task.lock(result.entryInstance.task.id) + } + + if(!taskInstance) + return fail(field:"task", code:"task.notFound") + + if(result.entryInstance.hasErrors() || !result.entryInstance.save()) + return fail(code:"default.create.failure") + + if(taskInstance.taskStatus.id == 3) + 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 == 2) { + + // Create the "Started" task modification, this provides the "Actual Started Date". + def taskModification = new TaskModification(person: authService.currentUser, + taskModificationType: TaskModificationType.get(2), + task: taskInstance) + + if(taskModification.hasErrors() || !taskModification.save()) + return fail(field:"task", code:"task.modifications.failedToSave") + + // Set task status to "In Progress". + taskInstance.taskStatus = TaskStatus.get(2) + + if(taskInstance.hasErrors() || !taskInstance.save()) + return fail(field:"task", code:"task.failedToSave") + } + + if(result.entryInstance.hasErrors() || !result.entryInstance.save()) + return fail(field:"task", code:"default.create.failure") + + // Success. + return result } //end withTransaction @@ -583,3 +573,77 @@ } // end renegeApproval() + /** + * Creates a new breakin 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) { + 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 not supplied. + if(!params.taskStatus) + params.taskStatus = TaskStatus.get(1) // Not Started. + + result.taskInstance = new Task(params) + + // Always for a breakin. + result.taskInstance.taskType = TaskType.get(1) // Unscheduled Breakin. + result.taskInstance.taskBudgetStatus = TaskBudgetStatus.get(1) // Unplanned. + result.taskInstance.taskPriority = TaskPriority.get(4) // Immediate. + result.taskInstance.taskGroup = TaskGroup.get(1) // Engineering Activites. + result.taskInstance.approved = true + result.taskInstance.leadPerson = authService.currentUser + + if(result.taskInstance.hasErrors() || !result.taskInstance.save()) + fail(code:"default.create.failure") + + if(!result.error) { + def taskModification = new TaskModification(person: authService.currentUser, + taskModificationType: TaskModificationType.get(1), // Created. + task: result.taskInstance) + + if(taskModification.hasErrors() || !taskModification.save()) + fail(field:"taskModifications", code:"task.modifications.failedToSave") + } + + def faultParams = [task: result.taskInstance, + entryType: EntryType.get(1), + comment: params.entryFault.comment, + durationHour: params.entryFault.durationHour, + durationMinute: params.entryFault.durationMinute] + def faultResult = saveEntry(faultParams) + result.entryFaultInstance = faultResult.entryInstance + + def workDoneParams = [task: result.taskInstance, + entryType: EntryType.get(2), + comment: params.entryWorkDone.comment, + durationHour: params.entryWorkDone.durationHour, + durationMinute: params.entryWorkDone.durationMinute] + def workDoneResult = saveEntry(workDoneParams) + result.entryWorkDoneInstance = workDoneResult.entryInstance + + if(result.error) + return result + + if(faultResult.error) + return fail(code: "default.create.failure") + + if(workDoneResult.error) + return fail(code: "default.create.failure") + + // Success. + return result + + } //end withTransaction + } // end saveBreakin() + } // end TaskService Index: /trunk/grails-app/views/entryDetailed/edit.gsp =================================================================== --- /trunk/grails-app/views/entryDetailed/edit.gsp (revision 394) +++ /trunk/grails-app/views/entryDetailed/edit.gsp (revision 395) @@ -105,4 +105,5 @@
Index: /trunk/grails-app/views/taskDetailed/createBreakin.gsp =================================================================== --- /trunk/grails-app/views/taskDetailed/createBreakin.gsp (revision 395) +++ /trunk/grails-app/views/taskDetailed/createBreakin.gsp (revision 395) @@ -0,0 +1,132 @@ + + + + ++ + | +
+
+ |
+
+ + | +
+
+ |
+
+ + | + +
+
+ :
+
+ |
+
+ + | +
+
+ |
+
+ + | + +
+
+ :
+
+ |
+
+ + | +
+ |
+
+ + | +
+ |
+