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); }
private static ProjectData ResetTaskResourceInitials(ProjectData project, TaskId id) { return(ResetTaskResourceNamesOrInitials(project, id, isInitials: true)); }
private static ProjectData SetTaskResourceInitials(ProjectData project, TaskId id, string value) { return(SetTaskResourceNamesOrInitials(project, id, value, isInitials: true)); }
private static ProjectData SetTaskPredecessorsOrSuccessors(ProjectData project, TaskId id, string value, bool isSuccessors) { var linkField = isSuccessors ? TaskFields.SuccessorLinks : TaskFields.PredecessorLinks; value = value.Trim(); var predecessorsBuilder = ImmutableArray.CreateBuilder <TaskId>(); var remainingTaskLinks = project.Get(linkField, id).ToList(); if (value.Length > 0) { var parts = value.Split(','); foreach (var part in parts) { var partText = part.Trim(); var taskText = partText; var sign = Math.Max(partText.IndexOf('+'), partText.IndexOf('-')); var lag = TimeSpan.Zero; if (sign >= 0) { var lagText = partText.Substring(sign).Trim(); lag = project.Information.TimeConversion.ParseDuration(lagText); taskText = partText.Substring(0, sign).Trim(); } var taskOrdinalText = taskText; var linkType = (TaskLinkType?)null; if (taskText.EndsWith("FS", StringComparison.OrdinalIgnoreCase)) { linkType = TaskLinkType.FinishToStart; } else if (taskText.EndsWith("SS", StringComparison.OrdinalIgnoreCase)) { linkType = TaskLinkType.StartToStart; } else if (taskText.EndsWith("FF", StringComparison.OrdinalIgnoreCase)) { linkType = TaskLinkType.FinishToFinish; } else if (taskText.EndsWith("SF", StringComparison.OrdinalIgnoreCase)) { linkType = TaskLinkType.StartToFinish; } if (linkType != null) { taskOrdinalText = taskText.Substring(0, taskText.Length - 2).Trim(); } else if (sign < 0) { linkType = TaskLinkType.FinishToStart; } else { throw new FormatException($"'{partText}' isn't a valid value"); } if (!int.TryParse(taskOrdinalText, out var taskOrdinal)) { throw new FormatException($"'{taskOrdinalText}' isn't a valid int"); } var taskId = project.GetTask(taskOrdinal); if (taskId.IsDefault) { throw new FormatException($"'{taskOrdinal}' isn't a valid task"); } var predecessorId = isSuccessors ? id : taskId; var successorId = isSuccessors ? taskId : id; var taskLink = TaskLink.Create(predecessorId, successorId, linkType.Value, lag); var existingLink = project.GetTaskLink(predecessorId, successorId); if (existingLink != null) { project = project.RemoveTaskLink(existingLink); } else if (project.TaskLinkCausesCycle(taskLink)) { var predecessorOrdinal = project.Get(TaskFields.Ordinal, predecessorId); var successorOrdinal = project.Get(TaskFields.Ordinal, successorId); throw new InvalidOperationException($"Cannot add a link from task {predecessorOrdinal} to task {successorOrdinal} as this would cause a cycle."); } project = project.AddTaskLink(taskLink); remainingTaskLinks.Remove(taskLink); } } foreach (var taskLink in remainingTaskLinks) { project = project.RemoveTaskLink(taskLink); } return(project); }
private static ProjectData SetTaskSuccessors(ProjectData project, TaskId id, string value) { return(SetTaskPredecessorsOrSuccessors(project, id, value, isSuccessors: true)); }
private static ProjectData ResetTaskSuccessors(ProjectData project, TaskId id) { return(ResetTaskPredecessorsOrSuccessors(project, id, isSuccessors: true)); }
internal static ProjectChanges Compute(ProjectData oldProject, ProjectData newProject) { // Tasks var oldTasks = oldProject.TaskMap; var newTasks = newProject.TaskMap; var addedTasks = newTasks.Keys .Where(id => !oldTasks.ContainsKey(id)) .ToImmutableArray(); var removedTasks = oldTasks.Keys .Where(id => !newTasks.ContainsKey(id)) .ToImmutableArray(); var changedTasks = oldTasks.Where(kv => newTasks.ContainsKey(kv.Key)) .Select(kv => (oldTask: kv.Value, newTask: newTasks[kv.Key])) .Where(t => t.oldTask != t.newTask) .Select(t => TaskChanges.Compute(t.oldTask, t.newTask)) .Where(c => c.FieldChanges.Any()) .ToImmutableArray(); // Resources var oldResources = oldProject.ResourceMap; var newResources = newProject.ResourceMap; var addedResources = newResources.Keys .Where(id => !oldResources.ContainsKey(id)) .ToImmutableArray(); var removedResources = oldResources.Keys .Where(id => !newResources.ContainsKey(id)) .ToImmutableArray(); var changedResources = oldResources.Where(kv => newResources.ContainsKey(kv.Key)) .Select(kv => (oldResource: kv.Value, newResource: newResources[kv.Key])) .Where(t => t.oldResource != t.newResource) .Select(t => ResourceChanges.Compute(t.oldResource, t.newResource)) .Where(c => c.FieldChanges.Any()) .ToImmutableArray(); // Assignments var oldAssignments = oldProject.AssignmentMapping; var newAssignments = newProject.AssignmentMapping; var addedAssignments = newAssignments.Keys .Where(id => !oldAssignments.ContainsKey(id)) .ToImmutableArray(); var removedAssignments = oldAssignments.Keys .Where(id => !newAssignments.ContainsKey(id)) .ToImmutableArray(); var changedAssignments = oldAssignments.Where(kv => newAssignments.ContainsKey(kv.Key)) .Select(kv => (oldAssignment: kv.Value, newAssignment: newAssignments[kv.Key])) .Where(t => t.oldAssignment != t.newAssignment) .Select(t => AssignmentChanges.Compute(t.oldAssignment, t.newAssignment)) .Where(c => c.FieldChanges.Any()) .ToImmutableArray(); return(new ProjectChanges(addedTasks, removedTasks, changedTasks, addedResources, removedResources, changedResources, addedAssignments, removedAssignments, changedAssignments)); }
private Project(ProjectData data) { Data = data; }