Example #1
0
        public void On(TimeTrackedEvent e)
        {
            var date = Date(e.At);

            if (e.Hours == 0)
            {
                DailyTime.RemoveAll(t => t.Date == date && t.UserId == e.UserId);
            }
            else
            {
                var dailyTime = DailyTime.SingleOrDefault(t => t.Date == date && t.UserId == e.UserId);

                if (dailyTime == null)
                {
                    dailyTime = new DailyTime
                    {
                        Date       = date,
                        HourlyRate = e.HourlyRate,
                        ProjectId  = e.ProjectId,
                        UserId     = e.UserId
                    };
                    DailyTime.Add(dailyTime);
                }

                dailyTime.TotalHours = e.Hours;
            }

            UpdateUserBilling(e.UserId);
        }
Example #2
0
        public IEnumerable <IEvent <ProjectTimeAggregateRoot, int> > Execute(TrackTimeCommand command)
        {
            var project = _projectService.GetById(command.ProjectId);

            if (project == null || project.Status != ProjectStatus.Active)
            {
                throw new ProjectNotReportableException();
            }

            var targetUserProjectData = _projectService.GetProjectUserInfo(command.ForUserId, command.ProjectId);

            if (targetUserProjectData == null)
            {
                throw new ProjectAuthorizationException("User is not assigned to the project.");
            }

            var trackingPermissions = command.ForUserId == command.ByUserId ? ProjectPermissions.TrackSelf : ProjectPermissions.TrackAsOtherUser;
            var trackerUserData     = _projectService.GetProjectUserInfo(command.ByUserId, project.Id);

            if (trackerUserData == null ||
                (trackerUserData.UserPermissions & trackingPermissions) == 0)
            {
                throw new ProjectAuthorizationException();
            }

            if (project.StartDate.Date > command.At.Date)
            {
                throw new ProjectNotReportableException();
            }
            if (project.EndDate != null && project.EndDate < command.At.Date)
            {
                throw new ProjectNotReportableException();
            }

            var trackedTime = State.DailyTime.SingleOrDefault(t => t.Date == command.At.Date && t.UserId == command.ForUserId);

            if (trackedTime != null && command.Hours < trackedTime.TotalHours)
            {
                if (command.Hours < trackedTime.PaidHours)
                {
                    throw new IncorrectHoursException(String.Format("{0} hours already paid for this day.", trackedTime.BilledHours));
                }

                // By decreasing time you will decrease number of billing hours available
                // (because already billed hours will distribute on further time).
                // So you couldn't decrease billing hours down zero.
                var billingHoursAvailable = State.MaxBillableHours(command.ForUserId);
                if (command.Hours - trackedTime.TotalHours + billingHoursAvailable < 0)
                {
                    throw new IncorrectHoursException("The hours already billed.");
                }
            }

            var maxDailyHours = targetUserProjectData.MaxDailyHours ?? 24;

            if (command.Hours > maxDailyHours)
            {
                throw new IncorrectHoursException(String.Format("Max daily hours value {0} exceeded.", maxDailyHours));
            }

            if (targetUserProjectData.MaxProjectHours != null)
            {
                var userProjectHours = State.DailyTime
                                       .Where(p => p.Date != command.At.Date)      /* Exclude reported hours */
                                       .Where(p => p.UserId == command.ForUserId)
                                       .SumOrDefault(p => p.TotalHours);
                if (userProjectHours + command.Hours > targetUserProjectData.MaxProjectHours)
                {
                    throw new IncorrectHoursException("All your hours available for the project are exceeded.");
                }
            }

            if (project.MaxTotalHours != null)
            {
                var totalProjectHours = State.DailyTime
                                        .Where(p => p.Date != command.At.Date)     /* Exclude reported hours */
                                        .SumOrDefault(p => p.TotalHours);

                if (totalProjectHours + command.Hours > project.MaxTotalHours)
                {
                    throw new IncorrectHoursException("Project maximum hours exceeded.");
                }
            }

            var @event = new TimeTrackedEvent
            {
                At                 = command.At.Date,
                Hours              = command.Hours,
                ProjectId          = project.Id,
                RegisteredAt       = DateTimeOffset.Now,
                RegisteredByUserId = command.ByUserId,
                UserId             = command.ForUserId,
                HourlyRate         = trackerUserData.HourlyRate
            };

            yield return(@event);
        }
Example #3
0
 public void On(TimeTrackedEvent @event)
 {
     State.On(@event);
 }
 public void On(TimeTrackedEvent @event, ProjectTimeAggregateRootState state)
 {
     RecalculateSummary(@event.UserId, @event.ProjectId, state);
 }
Example #5
0
 public void On(TimeTrackedEvent evt, ProjectTimeAggregateRootState state)
 {
     _readModels = state.DailyTime.ToList();
 }
Example #6
0
 public void Append(TimeTrackedEvent @event)
 {
     Db.InsertWithIdentity(@event);
 }