Well I’m back from my holidays and raring to go, so let’s take a look at our project management application. In the previous post we fleshed out the basic “shape” of the application, safe in the knowledge that we can go back and change it if required. In this post we are going to look at the area of task estimation.
As you can see from this image (click to enlarge) an Estimate has a name, a summary, an effort in days and – optionally – one or more resources who will have their time allocated to this estimate. You can think of an estimate as being analogous to a user story, a fine grained, fully formed piece of work. Later we’ll look at taking these estimates and adding them as tasks to a “real” project but, for now, let’s work with the Estimate.
First of all, we need to ensure that an estimate has a name, as we need to identify it later and, of course, an estimate wouldn’t be much use without an effort so we’ll make sure to validate for that using the code below:
private string _Name;
[RuleRequiredField("EstimateNameRequired",DefaultContexts.Save)]
public string Name
{
get
{
return _Name;
}
set
{
SetPropertyValue("Name", ref _Name, value);
}
}
private float _EffortInDays;
[RuleValueComparison(
"EfforMustBeGreaterThanZero",
DefaultContexts.Save,
ValueComparisonType.GreaterThan,0)]
public float EffortInDays
{
get
{
return _EffortInDays;
}
set
{
SetPropertyValue("EffortInDays", ref _EffortInDays, value);
}
}
Assuming you have created some Estimates, as a place to hold some ideas you are having about functionality etc, then there will come a point when you want to add them a Project, so let’s look at that now. Firstly, create a Project and ensure the Estimate tab is selected:
Now prees the “plus” button to open a list of Estimates:
Select the one(s) you wish to add to this project and then press the “Okay” button to add those estimates to the Project:
So now we’ve got our estimates in the Project and we can add tasks to the project too (we’ll look at that in a later post) but wouldn’t it be simpler, if we have estimates, just to create tasks from them? I think so, so let’s look at that now. Firstly, you need to know that there is a one to one relationship between an Estimate and a Task. We have to use special syntax to define this. In the Estimate class, define the task property like so:
private ProjectTask _Task;
public ProjectTask Task
{
get
{
return _Task;
}
set
{
if (_Task == value)
return;
// GS - Store a reference to the former Task.
ProjectTask previousTask = _Task;
_Task = value;
if (IsLoading) return;
// GS - Remove the Task's reference to this Estimate
if (previousTask != null && previousTask.Estimate == this)
previousTask.Estimate = null;
// GS - Tell the Task that I am its Estimate.
if (_Task != null)
_Task.Estimate = this;
OnChanged("Task");
}
}
And inversely in the ProjectTask class define the estimate property like so:
private Estimate _Estimate;
public Estimate Estimate
{
get
{
return _Estimate;
}
set
{
if (_Estimate == value)
return;
// GS - Store a reference to the former estimate.
Estimate previousEstimate = _Estimate;
_Estimate = value;
if (IsLoading) return;
// GS - Remove an estimate's reference to this task, if it exists.
if (previousEstimate != null && previousEstimate.Task == this)
previousEstimate.Task = null;
// GS - Tell the Estimate that I am its Task.
if (_Estimate != null)
_Estimate.Task = this;
OnChanged("Estimate");
}
}
The next thing we have to do is to create a controller with a simple action that will enable us to take the selected estimates and generate tasks from them. We only want this action to appear in the nested list of estimates under the project though. To do this set the TargetViewId of the action to be “Project_Estimates_ListView”. This will result in the desired behaviour:
Having done this, the only thing left for us to do is to write the code in the action’s execute function to create our Task from our Estimate, like so:
private void CreateTasksFromEstimatesAction_Execute(object sender, SimpleActionExecuteEventArgs e)
{
//GS - Create a task from each of the selected estimates
foreach (Estimate estimate in e.SelectedObjects)
{
ProjectTask task = View.ObjectSpace.CreateObject<ProjectTask>();
task.Estimate = estimate;
task.Name = "Task auto-created from: " + estimate.Name;
task.Project = estimate.Project;
task.Summary = estimate.Summary;
foreach (ProjectManager.Module.Resource estimateResource in estimate.Resources)
{
task.Resources.Add(estimateResource);
}
}
View.ObjectSpace.CommitChanges();
View.ObjectSpace.Refresh();
}
Clicking on the action button then causes our tasks to be generated for us:
Righty ho; well we’ve covered a lot in this post so I think we all deserve a nice cup of tea and a sticky bun, don’t you? Join me next time when we continue our project management application.