public async Task <IActionResult> UpdateLearningDay(UpdateLearningDayModel model)
        {
            UpdateLearningDayOperationRequest request = new UpdateLearningDayOperationRequest
            {
                Comments          = model.Comments,
                LearningDayId     = model.LearningDayId,
                LearningDayTopics = model.LearningDayTopics
                                    .Select(learningDayTopic => new UpdateLearningDayOperationRequest.LearningDayTopic
                {
                    ProgressStatus = MapProgressStatus(learningDayTopic.ProgressStatus),
                    TopicId        = learningDayTopic.TopicId
                })
                                    .ToList()
            };

            try
            {
                await _updateLearningDayOperation.Execute(request);
            }
            catch (LimitExceededException ex)
            {
                return(BadRequest(new ErrorModel(ex.Message)));
            }

            return(Ok());
        }
        private void UpdateAllDetails(
            Domain.Entity.LearningCalendar.LearningDay learningDay,
            Domain.Entity.LearningCalendar.Employee employee,
            UpdateLearningDayOperationRequest request)
        {
            List <(UpdateLearningDayOperationRequest.LearningDayTopic requestTopic, LearningDayTopic topic)> nonDeletedTopics =
                request.LearningDayTopics
                .Select(requestTopic => (requestTopic, learningDay.GetDayTopicByTopicId(requestTopic.TopicId)))
                .ToList();

            var createdTopics = nonDeletedTopics
                                .Where(group => group.topic == null)
                                .Select(group => CreateDayTopic(employee, group.requestTopic))
                                .ToList();

            var topicsToUpdate = nonDeletedTopics
                                 .Where(group => group.topic != null)
                                 .ToList();

            topicsToUpdate.ForEach(group => UpdateDayTopic(employee, group.requestTopic, group.topic));

            var updatedTopics = topicsToUpdate
                                .Select(group => group.topic);

            learningDay.LearningDayTopics = createdTopics
                                            .Concat(updatedTopics)
                                            .ToList();

            UpdateComment(learningDay, request);
        }
        public async Task Execute(UpdateLearningDayOperationRequest request)
        {
            var employee = await _authorizationContext.CurrentEmployee();

            var learningDay = employee.LearningDays
                              .FirstOrDefault(day => day.Id == request.LearningDayId);

            request.LearningDayTopics ??= new List <UpdateLearningDayOperationRequest.LearningDayTopic>();
            EnsureNoDuplicatedTopics(request);
            EnsureFitsLimits(request, employee);

            if (learningDay == null)
            {
                employee = await _employeeRepository.GetByLearningDayId(request.LearningDayId);

                learningDay = employee.LearningDays
                              .FirstOrDefault(day => day.Id == request.LearningDayId)
                              ?? throw new ApplicationException("Learning day not found");
                UpdateComment(learningDay, request);
            }
            else
            {
                UpdateAllDetails(learningDay, employee, request);
            }

            await _learningDayRepository.UpdateAsync(learningDay);

            await _goalRepository.UpdateAsync(employee.PersonalGoals);
        }
        private void EnsureFitsLimits(
            UpdateLearningDayOperationRequest request,
            Domain.Entity.LearningCalendar.Employee employee)
        {
            var limit = employee.Limit;

            if (request.LearningDayTopics.Count > limit.TopicsPerDay)
            {
                throw new LimitExceededException(nameof(Constants.Limit.MaxTopicsPerDay));
            }
        }
        private void EnsureNoDuplicatedTopics(UpdateLearningDayOperationRequest request)
        {
            var distinctTopics = request.LearningDayTopics
                                 .DistinctBy(dayTopic => dayTopic.TopicId)
                                 .ToList();

            if (distinctTopics.Count != request.LearningDayTopics.Count)
            {
                throw new ApplicationException("Cannot assign multiple instances of the same to topic to a learning day");
            }
        }
 private void UpdateComment(
     Domain.Entity.LearningCalendar.LearningDay learningDay,
     UpdateLearningDayOperationRequest request)
 {
     learningDay.Comments = request.Comments;
 }