Beispiel #1
0
        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));
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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)));
        }
Beispiel #7
0
        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)));
        }
Beispiel #8
0
        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));
        }
Beispiel #9
0
        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));
        }
Beispiel #10
0
        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));
        }