public void MapForProjectUtilizationViewModel_WithValidParams_ShouldReturnValidModel()
        {
            // ARRANGE
            var project = new Project
            {
                Id               = Guid.Parse("bfb77fc0-12a9-4250-a5fb-e52ddc48ff86"),
                Title            = "TimesheetEntity App",
                ClientName       = "Microsoft",
                BillableHours    = 200,
                NonBillableHours = 200,
                StartDate        = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 2),
                EndDate          = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 28),
                CreatedBy        = Guid.Parse("08310120-ff64-45a4-b67a-6f2f19fba937"),
                CreatedOn        = DateTime.Now,
            };

            var members = new List <Member>
            {
                new Member
                {
                    Id         = Guid.Parse("d3d964ae-2979-4dac-b1e0-6c1b936c2640"),
                    ProjectId  = Guid.Parse("bfb77fc0-12a9-4250-a5fb-e52ddc48ff86"),
                    UserId     = Guid.Parse("3fd7af65-67df-43cb-baa0-30917e133d94"),
                    IsBillable = true,
                    IsRemoved  = false,
                },
                new Member
                {
                    Id         = Guid.Parse("d3d764ae-2979-4dac-b1e0-6c1b936c2640"),
                    ProjectId  = Guid.Parse("bfb77fc0-12a9-4250-a5fb-e52ddc48ff86"),
                    UserId     = Guid.Parse("3fd8af65-67df-43cb-baa0-30917e133d94"),
                    IsBillable = true,
                    IsRemoved  = false,
                },
            };

            var expectedProjectUtilization = new ProjectUtilizationDTO
            {
                Id    = project.Id,
                Title = project.Title,
                BillableUtilizedHours         = 10,
                NonBillableUtilizedHours      = 0,
                BillableUnderutilizedHours    = project.BillableHours - 10,
                NonBillableUnderutilizedHours = project.NonBillableHours - 0,
                TotalHours = project.BillableHours + project.NonBillableHours,
            };

            // ACT
            var resultUtilizationModel = this.projectMapper.MapForProjectUtilizationViewModel(project, TestData.TestData.ApprovedTimesheets, members);

            // ASSERT
            Assert.AreEqual(expectedProjectUtilization.BillableUtilizedHours, resultUtilizationModel.BillableUtilizedHours);
            Assert.AreEqual(expectedProjectUtilization.NonBillableUtilizedHours, resultUtilizationModel.NonBillableUtilizedHours);
            Assert.AreEqual(expectedProjectUtilization.BillableUnderutilizedHours, resultUtilizationModel.BillableUnderutilizedHours);
            Assert.AreEqual(expectedProjectUtilization.NonBillableUnderutilizedHours, resultUtilizationModel.NonBillableUnderutilizedHours);
            Assert.AreEqual(expectedProjectUtilization.TotalHours, resultUtilizationModel.TotalHours);
        }
コード例 #2
0
        /// <summary>
        /// Gets project utilization view model to be sent as API response.
        /// </summary>
        /// <param name="project">The project entity model.</param>
        /// <param name="timesheets">Collection of timesheet entity model.</param>
        /// <returns>Returns a project utilization view entity model.</returns>
        public ProjectUtilizationDTO MapForProjectUtilizationViewModel(Project project, IEnumerable <TimesheetEntity> timesheets)
        {
            project = project ?? throw new ArgumentNullException(nameof(project));

            var totalHours         = project.BillableHours + project.NonBillableHours;
            var projectUtilization = new ProjectUtilizationDTO
            {
                Id               = project.Id,
                Title            = project.Title,
                BillableHours    = project.BillableHours,
                NonBillableHours = project.NonBillableHours,
                NotUtilizedHours = totalHours - timesheets.Sum(timesheet => timesheet.Hours),
            };

            return(projectUtilization);
        }
コード例 #3
0
        /// <summary>
        /// Gets project utilization view model to be sent as API response.
        /// </summary>
        /// <param name="project">The project entity model.</param>
        /// <param name="timesheets">List of timesheet entity model.</param>
        /// <param name="members">List of project members.</param>
        /// <returns>Returns a project utilization view entity model.</returns>
        public ProjectUtilizationDTO MapForProjectUtilizationViewModel(Project project, IEnumerable <TimesheetEntity> timesheets, IEnumerable <Member> members)
        {
            project    = project ?? throw new ArgumentNullException(nameof(project));
            timesheets = timesheets ?? throw new ArgumentNullException(nameof(timesheets));
            members    = members ?? throw new ArgumentNullException(nameof(members));

            var billableUtilizedHours    = 0;
            var nonBillableUtilizedHours = 0;
            var membersDictionary        = members.ToDictionary(member => member.UserId);

            foreach (var timesheet in timesheets)
            {
                if (membersDictionary.TryGetValue(timesheet.UserId, out var member))
                {
                    if (member.IsBillable)
                    {
                        billableUtilizedHours += timesheet.Hours;
                    }
                    else
                    {
                        nonBillableUtilizedHours += timesheet.Hours;
                    }
                }
                else
                {
                    this.logger.LogError($"Member {timesheet.UserId} is not part of project {project.Id}");
                    return(null);
                }
            }

            var projectUtilization = new ProjectUtilizationDTO
            {
                Id                            = project.Id,
                Title                         = project.Title,
                ProjectStartDate              = project.StartDate,
                ProjectEndDate                = project.EndDate,
                BillableUtilizedHours         = billableUtilizedHours,
                NonBillableUtilizedHours      = nonBillableUtilizedHours,
                BillableUnderutilizedHours    = project.BillableHours - billableUtilizedHours,
                NonBillableUnderutilizedHours = project.NonBillableHours - nonBillableUtilizedHours,
                TotalHours                    = project.BillableHours + project.NonBillableHours,
            };

            return(projectUtilization);
        }
コード例 #4
0
        public async Task GetProjectUtilization_WhenProjectNotFound_ShouldReturnNotFoundStatus()
        {
            // ARRANGE
            ProjectUtilizationDTO project = null;

            this.projectHelper
            .Setup(helper => helper.GetProjectUtilizationAsync(It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <DateTime>(), It.IsAny <DateTime>()))
            .Returns(Task.FromResult(project));

            var projectId = Guid.NewGuid();
            var startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 5);
            var endDate   = new DateTime(DateTime.Now.Year, DateTime.Now.Month, startDate.Day + 1);

            // ACT
            var result = (ObjectResult)await this.projectController.GetProjectUtilizationAsync(projectId, startDate, endDate);

            // ASSERT
            Assert.AreEqual(StatusCodes.Status404NotFound, result.StatusCode);
        }
コード例 #5
0
ファイル: ProjectMapper.cs プロジェクト: MAK-12/timetally
        /// <summary>
        /// Gets project utilization view model to be sent as API response.
        /// </summary>
        /// <param name="project">The project entity model.</param>
        /// <param name="timesheets">List of timesheet entity model.</param>
        /// <param name="members">List of members.</param>
        /// <returns>Returns a project utilization view entity model.</returns>
        public ProjectUtilizationDTO MapForProjectUtilizationViewModel(Project project, List <TimesheetEntity> timesheets, List <Member> members)
        {
            project = project ?? throw new ArgumentNullException(nameof(project));

            var billableUtilizedHours    = 0;
            var nonBillableUtilizedHours = 0;

#pragma warning disable CA1062 // Validate arguments of public methods
            foreach (var timesheet in timesheets)
#pragma warning restore CA1062 // Validate arguments of public methods
            {
#pragma warning disable CA1062 // Validate arguments of public methods
                foreach (var member in members)
#pragma warning restore CA1062 // Validate arguments of public methods
                {
                    if (timesheet.UserId == member.UserId)
                    {
                        if (member.IsBillable)
                        {
                            billableUtilizedHours += timesheet.Hours;
                        }
                        else
                        {
                            nonBillableUtilizedHours += timesheet.Hours;
                        }
                    }
                }
            }

            var projectUtilization = new ProjectUtilizationDTO
            {
                Id    = project.Id,
                Title = project.Title,
                BillableUtilizedHours         = billableUtilizedHours,
                NonBillableUtilizedHours      = nonBillableUtilizedHours,
                UnderutilizedBillableHours    = project.BillableHours - billableUtilizedHours,
                UnderutilizedNonBillableHours = project.NonBillableHours - nonBillableUtilizedHours,
                TotalHours = project.BillableHours + project.NonBillableHours,
            };

            return(projectUtilization);
        }