Doubts on migrating from legacy version (v6.4.0) to latest version (v9.3.0)

Hi,

I have a few questions of the Aspose.Tasks lib.

Context
I’m migrating Aspose.Tasks v6.4.0 to v9.3.0 in C# and I have bunch of incompatibilities.
I’ve read How to Migrate to Aspose.Tasks for .NET+8.0.0 or higher and was a huge help but there are a couple of doubts that I can’t get them resolved as expected.

Questions
1- I’m trying to set ‘Duration’ or ‘Work’ to Tasks so what I do is:

task.Set(Tsk.Work, (new Duration()).Add(TimeSpan.FromMinutes(230).TotalMinutes));

but I don’t like it… doesn’t sounds good nor intuitive to set the value in that manner.
It happens to me either with ‘Duration’ or ‘Work’ props because they’re Aspose.Tasks.Duration types.
what’s the best approach to set Duration types? there’s no example for this in .NET examples (see comments/suggestions)

2- can I create tasks without belonging to a parent project?
i.e.
I had unit tests with the objective of validating this scenario because before you could do things like:
earlier version:
var task = new Task(“some task name”);
or
var task = new Task(“some task name with parent project”) { ParentProject = aProject };

and now to create a task is mandatory that you create it in RootTask within aProject.
in 9.3.0 version:
var task = aProject.RootTask.Children.Add(“some task name”);

Same with ‘Resource’ and ‘ResourceAssignments’.

3- What’s the correct way of getting a task from ‘RootTask.Children’ ?
before I did something like:
var task = aProject.RootTask.Children[i];

should I do it like this now?:
var task = aProject.RootTask.Children.ToArray()[i];


Comments/Suggestions
4-documentation website’ link within .NET examples in github is broken

5- .NET examples are using Aspose.Tasks v8.5.0 and should be updated to latest version (v.9.3.0)

6- Please add an example on how to set properties with Aspose.Tasks.Duration types, i.e. ‘Tsk.Duration’ or ‘Tsk.Work’ props of Task.

Thank you,
Gustavo H.

Hi Gustavo,

Thank you for sharing your concerns.

Aspose.Tasks API was revamped to adopt this new structure of getter and setter methods for stability and ease of use. We understand your concerns about the migration issues you may face, but we are here to help you in this regard. I would answer your queries one by one below and if you have further queries, please feel free to ask us.

1. You can use the following method to set duration of a task in hours, day.

Sample Code:

Task task1 = project.RootTask.Children.Add(“Task 1”);
task1.Set(Tsk.Start, new DateTime(2016, 4, 8));
task1.Set(Tsk.Duration, project.GetDuration(3, TimeUnitType.Day)); //you can use TimeUnitType.Hour etc as well
task1.Set(Tsk.Work, newProject.GetDuration(120, TimeUnitType.Hour));

2. In the revamped API, you can not create a task without associating with the root task or any existing task in the project and it makes complete sense as MSP also don’t have any such option of creating non-associated tasks. The same is true for Resources and Resource Assignments. You can add a new task to an existing task as:

task1.Children.Add(“Child of Task1”);

3. You can directly get a task from using its id as shown below.

//Get this task
Task t1 = project.RootTask.Children.GetByUid(1);
Console.WriteLine(t1.Get(Tsk.Name));

4. Thank you for sharing. We have fixed this.

5. We are currently in process of updating over documentation to the latest version of the API and you will see the changes in a couple of weeks.

6. Sure. The new examples will add code samples related to your requirements as well.

Hi Kashif,

Thanks for replying.

I'm having another issue on my migration and it's related to 'ResourceAssignment'.
I've read Creating Resource Assignments and still don't get how it is supposed to work and need your help.

I have several unit tests failing because they check resource assignments and I don't exactly get why this behavior has changed.

OLD TEST v6.4.0 (simplified version):

Project project = new Project();
project.RootTask = new Task("root task") { ParentProject = project };

var task1 = new Task("task1") { ParentProject = project };
project.RootTask.Children.Add(task1);

Assert.AreEqual(0, project.ResourceAssignments.Count);
Assert.AreEqual(0, task1.Assignments.Count);

var resource1 = new Resource("resource1");
project.Resources.Add(resource1);
project.ResourceAssignments.Add(new ResourceAssignment(task1, resource1));

Assert.AreEqual(1, project.ResourceAssignments.Count);
Assert.AreEqual(1, task1.Assignments.Count);


TEST v9.3.0 (simplified version FAILING)

var project = new Project();
var task1 = project.RootTask.Children.Add("task1");
var task2 = project.RootTask.Children.Add("task2");

Assert.AreEqual(0, project.ResourceAssignments.Count); //FAILS because 'count = 2'
Assert.AreEqual(0, task1.Assignments.Count); //FAILS because 'count = 1'
Assert.AreEqual(0, task2.Assignments.Count); //FAILS because 'count = 1'

At this point 'project.ResourceAssignments' should have 0 elements but somehow 'ResourceAssignments' has 2 and each element has 'Task' porperty already set with each task but doesn't have 'Resource' property set (which make sense because I didn't actually created an resource assignment).

Resource resource1 = project.Resources.Add("resource1");
project.ResourceAssignments.Add(task1, resource1);

I expect that after this two lines 'project.ResourceAssignments' should have 1 element with both props set ('Task' and 'Resource').

So two doubts:
1- why creating a task already creates an assignment for it even if it doesn't have it?
2- is there a way to check that no resource has been assigned to the task?

Hi Gustavo,

When we add a task in a project, it automatically adds an assignment to Task and a ResourceAssignment to the project. This behavior is implemented similar to the one in MS Project. To verify it, you may perform following steps:

  1. Open MS Project 2010
  2. Create a task say “Task1” of duration 1 day.
  3. Create another task say “Task2” of duration 1 day.
  4. Save this project as XML say project1.xml
  5. Now open this XML file in notepad. You will observe two resource assignments in the project node, although you have not added any one manually.

Similarly if you open this project using Aspose.Tasks, it shows 1 assignment for each task and two resource assignments for the project as shown below:

Project MSP2010Proj = new Project(path + “Project1.xml”);
Task task3 = MSP2010Proj.RootTask.Children.GetByUid(1);
Task task4 = MSP2010Proj.RootTask.Children.GetByUid(2);

Console.WriteLine(MSP2010Proj.ResourceAssignments.Count);
Console.WriteLine(task3.Assignments.Count);
Console.WriteLine(task4.Assignments.Count);

This shows that the issue you have identified, is not an issue with Aspose.Tasks but this behavior in implemented to synchronize project contents with the one generated by Microsoft Project.

For users ease, Aspose.Tasks has implemented a function Project.RemoveInvalidResourceAssignments(). This function removes these invalid assignments and provides results similar to the one you are expecting. Please give it a try and let us know the feedback.

var project = new Project();
var task1 = project.RootTask.Children.Add("task1");
var task2 = project.RootTask.Children.Add("task2");

Console.WriteLine("Before removing invalid resource assignments");
Console.WriteLine(project.ResourceAssignments.Count);
Console.WriteLine(task1.Assignments.Count);
Console.WriteLine(task2.Assignments.Count);

project.RemoveInvalidResourceAssignments();
Console.WriteLine("After removing invalid resource assignments");
Console.WriteLine(project.ResourceAssignments.Count);
Console.WriteLine(task1.Assignments.Count);
Console.WriteLine(task2.Assignments.Count);

Console.WriteLine("After adding valid resource assignments");
Resource resource1 = project.Resources.Add("resource1");
project.ResourceAssignments.Add(task1, resource1);

Console.WriteLine(project.ResourceAssignments.Count);
Console.WriteLine(task1.Assignments.Count);
Console.WriteLine(task2.Assignments.Count);