Exemplo n.º 1
0
        public async Task <Unit> Handle(SubmitAnswerRequest request, CancellationToken cancellationToken)
        {
            var(participant, pollId, answer) = request;

            var poll = await _repository.GetPoll(participant.ConferenceId, pollId);

            if (poll == null)
            {
                throw PollError.PollNotFound.ToException();
            }

            var state = await _repository.GetPollState(participant.ConferenceId, pollId);

            if (state?.IsOpen != true)
            {
                throw PollError.PollClosed.ToException();
            }

            if (answer == null)
            {
                if (poll.Config.IsAnswerFinal)
                {
                    throw PollError.AnswerCannotBeChanged.ToException();
                }

                await _repository.DeletePollAnswer(participant, pollId);
            }
            else
            {
                var wrapper          = new PollAnswerValidatorWrapper(_context);
                var validationResult = wrapper.Validate(poll.Instruction, answer);
                if (validationResult != null)
                {
                    throw validationResult.ToException();
                }

                if (poll.Config.IsAnswerFinal)
                {
                    var existingAnswer = await _repository.GetPollAnswer(participant, pollId);

                    if (existingAnswer != null)
                    {
                        throw PollError.AnswerCannotBeChanged.ToException();
                    }
                }

                var key = Guid.NewGuid().ToString("N");

                await _repository.SetPollAnswer(participant, pollId, new PollAnswerWithKey(answer, key));

                poll = await _repository.GetPoll(participant.ConferenceId, pollId);

                if (poll == null)
                {
                    // optimistic concurrency
                    await _repository.DeletePollAnswers(participant.ConferenceId, pollId);

                    throw PollError.PollNotFound.ToException();
                }
            }

            await _mediator.Send(new UpdateSynchronizedObjectRequest(participant.ConferenceId,
                                                                     SynchronizedPollAnswers.SyncObjId(participant.Id)));

            await _mediator.Send(new UpdateSynchronizedObjectRequest(participant.ConferenceId,
                                                                     SynchronizedPollResult.SyncObjId(pollId)));

            return(Unit.Value);
        }