Ejemplo n.º 1
0
        public Result <Nothing, Error> RecordTrainingResults(
            RecordTrainingResults.Command command, ApplicationUser recordingCoordinator,
            IReadOnlyCollection <Training> preferredTrainings, Training selectedTraining, Instant now)
        {
            Guard.Against.Null(command, nameof(command));
            Guard.Against.Null(recordingCoordinator, nameof(recordingCoordinator));
            Guard.Against.Null(preferredTrainings, nameof(preferredTrainings));
            Guard.Against.Null(selectedTraining, nameof(selectedTraining));
            Guard.Against.Null(now, nameof(now));
            ValidateIdMatchOrThrow(command.EnrollmentId);
            if (command.TrainingId != selectedTraining.ID)
            {
                throw new InvalidOperationException($"{nameof(command)}.{nameof(command.TrainingId)} must be the same as {nameof(selectedTraining)}.{nameof(Id)}");
            }

            var absent = Recruitment.Enrollments.RecordTrainingResults.TrainingResult.Absent;

            return
                (Validate(new RecordTrainingResults.Validator(), command)
                 .Ensure(_ => CanRecordTrainingResultsFor(selectedTraining, now))
                 .Ensure(
                     _ => PreferredTrainingIds.Contains(selectedTraining.ID),
                     new Error.DomainError(RecordTrainingResults_Messages.TrainingNotSelectedAsPreferred))
                 .Ensure(
                     _ => selectedTraining.EndDateTime.ToInstant() < now,
                     new Error.DomainError(RecordTrainingResults_Messages.CannotRecordTrainingAttendanceBeforeTrainingEnd))
                 .EnsureNot(_ => command.TrainingResult == absent && _trainingInvitationState != TrainingInvitationStateEnum.Accepted,
                            new Error.DomainError(RecordTrainingResults_Messages.CannotRecordCandidateAsAbsentIfTheyDidNotAcceptTrainingInvitation))
                 .TapIf(
                     command.TrainingResult == absent,
                     () => Emit(new CandidateWasAbsentFromTraining(recordingCoordinator.Id, command.TrainingId, command.AdditionalNotes ?? string.Empty)))
                 .TapIf(
                     command.TrainingResult == Recruitment.Enrollments.RecordTrainingResults.TrainingResult.PresentButNotAcceptedAsLecturer,
                     () => Emit(new CandidateAttendedTraining(recordingCoordinator.Id, command.TrainingId, command.AdditionalNotes ?? string.Empty)))
                 .TapIf(
                     command.TrainingResult == Recruitment.Enrollments.RecordTrainingResults.TrainingResult.PresentAndAcceptedAsLecturer,
                     () => {
                Emit(new CandidateAttendedTraining(recordingCoordinator.Id, command.TrainingId, command.AdditionalNotes ?? string.Empty));
                Emit(new CandidateObtainedLecturerRights(recordingCoordinator.Id, command.AdditionalNotes ?? string.Empty));
            }));
        }
        public async Task <Result <Nothing, Error> > Handle(RecordTrainingResults.Command request, CancellationToken cancellationToken)
        {
            var user = await _userAccessor.GetUser();

            var selectedTraining = await _trainingRepository.GetById(request.TrainingId);

            if (selectedTraining.HasNoValue)
            {
                return(Result.Failure <Nothing, Error>(new Error.ResourceNotFound($"Training with ID={request.TrainingId} not found")));
            }

            var enrollment = await _aggregateStore.LoadAsync <EnrollmentAggregate, EnrollmentId>(EnrollmentId.With(request.EnrollmentId), cancellationToken);

            var preferredTrainings = await _trainingRepository.GetByIds(enrollment.PreferredTrainingIds);

            var result = await _aggregateStore.Update <EnrollmentAggregate, EnrollmentId, Result <Nothing, Error> >(
                EnrollmentId.With(request.EnrollmentId), CommandId.New,
                (aggregate) => aggregate.RecordTrainingResults(request, user, preferredTrainings, selectedTraining.Value, _clock.GetCurrentInstant()),
                cancellationToken);

            return(result.Unwrap());
        }
        public async Task <IActionResult> RecordTrainingResults(RecordTrainingResults.Command command)
        {
            var result = await _engine.Execute(command);

            return(result.MatchToActionResult(success => Ok()));
        }