public T Get <T>(AssignmentField <T> field, AssignmentId id) { Debug.Assert(field != null); Debug.Assert(!id.IsDefault); return(_assignmentMap[id].GetValue(field)); }
public Assignment AddAssignment(TaskId taskId, ResourceId resourceId, AssignmentId assignmentId = default) { assignmentId = assignmentId.CreateIfDefault(); if (GetAssignment(assignmentId) != null) { throw new ArgumentException($"Project already contains an assignment with ID {assignmentId}."); } if (GetAssignment(taskId, resourceId) != null) { throw new ArgumentException($"An assignment for task ID {taskId} and resource ID {resourceId} already exists."); } var task = GetTask(taskId); if (task == null) { throw new ArgumentException($"The project doesn't contain a task with ID {taskId}.", nameof(taskId)); } var resource = GetResource(resourceId); if (resource == null) { throw new ArgumentException($"The project doesn't contain a resource with ID {resourceId}.", nameof(resourceId)); } var projectData = Data.AddAssignment(assignmentId, taskId, resourceId); return(UpdateProject(projectData).GetAssignment(assignmentId)); }
public ProjectData AddAssignment(AssignmentId assignmentId, TaskId taskId, ResourceId resourceId) { Debug.Assert(!assignmentId.IsDefault); Debug.Assert(!taskId.IsDefault); Debug.Assert(!resourceId.IsDefault); var project = this; var numberOfExistingAssignments = project.GetAssignments(taskId).Count(); // Add assignment var assignment = AssignmentData.Create(assignmentId, taskId, resourceId); var taskAssignments = project.Get(TaskFields.Assignments, taskId).Add(assignmentId); var resourceAssignments = project.Get(ResourceFields.Assignments, resourceId).Add(assignmentId); project = project.WithAssignmentMap(_assignmentMap.Add(assignment.Id, assignment)) .Set(TaskFields.Assignments, taskId, taskAssignments) .Set(ResourceFields.Assignments, resourceId, resourceAssignments); // Initialize Assignment.Work and update Task.Work if (numberOfExistingAssignments == 0) { var work = project.Get(TaskFields.Work, taskId); if (work == TimeSpan.Zero) { work = project.Get(TaskFields.Duration, taskId); } project = project.SetRaw(TaskFields.Work, taskId, work) .SetRaw(AssignmentFields.Work, assignmentId, work); } else { var taskWork = project.Get(TaskFields.Work, taskId); var newTaskWorkHours = taskWork.TotalHours / numberOfExistingAssignments * (numberOfExistingAssignments + 1); var newAssignmentWorkHours = newTaskWorkHours - taskWork.TotalHours; var newTaskWork = TimeSpan.FromHours(newTaskWorkHours); var newAssignmentWork = TimeSpan.FromHours(newAssignmentWorkHours); project = project.SetRaw(TaskFields.Work, taskId, newTaskWork) .SetRaw(AssignmentFields.Work, assignmentId, newAssignmentWork); } // Initialize Assignment.TaskName and Assignment.ResourceName var taskName = project.Get(TaskFields.Name, taskId); var resourceName = project.Get(ResourceFields.Name, resourceId); project = project.SetRaw(AssignmentFields.TaskName, assignmentId, taskName) .SetRaw(AssignmentFields.ResourceName, assignmentId, resourceName); // Update Task.ResourceNames project = project.Reset(TaskFields.ResourceNames, taskId) .Reset(TaskFields.ResourceInitials, taskId); return(project); }
public ProjectData RemoveAssignment(AssignmentId assignmentId) { Debug.Assert(!assignmentId.IsDefault); // Avoid cascading errors when we remove assignments that don't exist if (!_assignmentMap.ContainsKey(assignmentId)) { return(this); } var taskId = Get(AssignmentFields.TaskId, assignmentId); var resourceId = Get(AssignmentFields.ResourceId, assignmentId); var assignmentWork = Get(AssignmentFields.Work, assignmentId); var taskWork = Get(TaskFields.Work, taskId); var taskAssignments = Get(TaskFields.Assignments, taskId).Remove(assignmentId); var resourceAssignments = Get(ResourceFields.Assignments, resourceId).Remove(assignmentId); // Remove assignment from project var project = WithAssignmentMap(_assignmentMap.Remove(assignmentId)) .Set(TaskFields.Assignments, taskId, taskAssignments) .Set(ResourceFields.Assignments, resourceId, resourceAssignments); // Update work and resource names project = project.Set(TaskFields.Work, taskId, taskWork - assignmentWork) .Reset(TaskFields.ResourceNames, taskId) .Reset(TaskFields.ResourceInitials, taskId); return(project); }
private static ProjectData SetAssignmentUnits(ProjectData project, AssignmentId id, double value) { var taskId = project.Get(AssignmentFields.TaskId, id); return(project.SetRaw(AssignmentFields.Units, id, value) .Reset(TaskFields.ResourceNames, taskId) .Reset(TaskFields.ResourceInitials, taskId)); }
public Assignment GetAssignment(AssignmentId id) { if (!Data.AssignmentMapping.TryGetValue(id, out var data)) { return(null); } return(ImmutableInterlocked.GetOrAdd(ref _assignments, data, k => new Assignment(this, k))); }
public ProjectData SetRaw(AssignmentField field, AssignmentId id, object value) { Debug.Assert(field != null); Debug.Assert(!id.IsDefault); var assignment = _assignmentMap[id].SetValue(field, value); return(WithAssignmentMap(_assignmentMap.SetItem(assignment.Id, assignment))); }
private static ProjectData SetAssignmentWork(ProjectData project, AssignmentId id, TimeSpan value) { var taskId = project.Get(AssignmentFields.TaskId, id); var oldTaskWork = project.Get(TaskFields.Work, taskId); var oldAssignmentWork = project.Get(AssignmentFields.Work, id); var newAssignmentWork = value; var newTaskWork = oldTaskWork + newAssignmentWork - oldAssignmentWork; return(project.SetRaw(TaskFields.Work, taskId, newTaskWork) .SetRaw(AssignmentFields.Work, id, newAssignmentWork)); }
public static AssignmentData Create(AssignmentId id, TaskId taskId, ResourceId resourceId) { Debug.Assert(!id.IsDefault); Debug.Assert(!taskId.IsDefault); Debug.Assert(!resourceId.IsDefault); var fields = ImmutableDictionary.Create <AssignmentField, object>() .Add(AssignmentFields.Id, id) .Add(AssignmentFields.TaskId, taskId) .Add(AssignmentFields.ResourceId, resourceId); return(new AssignmentData(fields)); }
public ProjectData Set(AssignmentField field, AssignmentId id, object value) { Debug.Assert(field != null); Debug.Assert(!id.IsDefault); if (field == AssignmentFields.Work) { return(SetAssignmentWork(this, id, (TimeSpan)value)); } else if (field == AssignmentFields.Units) { return(SetAssignmentUnits(this, id, (double)value)); } else { return(SetRaw(field, id, value)); } }
private AssignmentChanges(AssignmentId id, ImmutableArray <FieldChange <AssignmentField> > fieldChanges) { Id = id; FieldChanges = fieldChanges; }
private static ProjectData SetTaskResourceNamesOrInitials(ProjectData project, TaskId id, string value, bool isInitials) { var field = isInitials ? ResourceFields.Initials : ResourceFields.Name; value = value.Trim(); var remainingAssignmentIds = project.GetAssignments(id).ToList(); if (value.Length > 0) { var resourceParts = value.Split(','); foreach (var resourcePart in resourceParts) { var initials = resourcePart.Trim(); var units = 1.0; var openBracket = initials.IndexOf("["); if (openBracket >= 0) { var closeBracket = initials.IndexOf("]"); if (closeBracket < openBracket) { throw new FormatException("Missing ']'"); } var percentageText = initials.Substring(openBracket + 1, closeBracket - openBracket - 1).Trim(); if (percentageText.EndsWith("%")) { percentageText = percentageText.Substring(0, percentageText.Length - 1).Trim(); } if (!double.TryParse(percentageText, out var percentage)) { throw new FormatException($"'{percentageText}' isn't a valid percentage"); } initials = initials.Substring(0, openBracket).Trim(); units = percentage / 100.0; } var resourceId = project.GetResources(initials, isInitials).FirstOrDefault(); if (resourceId.IsDefault) { resourceId = ResourceId.Create(); project = project.AddResource(resourceId).Set(field, resourceId, initials); } var assignmentId = project.GetAssignment(id, resourceId); if (assignmentId.IsDefault) { assignmentId = AssignmentId.Create(); project = project.AddAssignment(assignmentId, id, resourceId); } project = project.Set(AssignmentFields.Units, assignmentId, units); remainingAssignmentIds.Remove(assignmentId); } } foreach (var assignmentId in remainingAssignmentIds) { project = project.RemoveAssignment(assignmentId); } return(project); }
public Project RemoveAssignment(AssignmentId assignmentId) { var projectData = Data.RemoveAssignment(assignmentId); return(UpdateProject(projectData)); }