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); }
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); }
public void On(TimeTrackedEvent @event) { State.On(@event); }
public void On(TimeTrackedEvent @event, ProjectTimeAggregateRootState state) { RecalculateSummary(@event.UserId, @event.ProjectId, state); }
public void On(TimeTrackedEvent evt, ProjectTimeAggregateRootState state) { _readModels = state.DailyTime.ToList(); }
public void Append(TimeTrackedEvent @event) { Db.InsertWithIdentity(@event); }