private async Task Handle(Guid applicationReviewId, VacancyUser user, ApplicationReviewStatus status, string candidateFeedback = null)
        {
            var applicationReview = await _applicationReviewRepository.GetAsync(applicationReviewId);

            if (applicationReview.CanReview == false)
            {
                _logger.LogWarning("Cannot review ApplicationReviewId:{applicationReviewId} as not in correct state", applicationReview.Id);
                return;
            }

            applicationReview.Status            = status;
            applicationReview.CandidateFeedback = candidateFeedback;
            applicationReview.StatusUpdatedDate = _timeProvider.Now;
            applicationReview.StatusUpdatedBy   = user;

            Validate(applicationReview);

            await _applicationReviewRepository.UpdateAsync(applicationReview);

            await _messaging.PublishEvent(new ApplicationReviewedEvent
            {
                Status            = applicationReview.Status,
                VacancyReference  = applicationReview.VacancyReference,
                CandidateFeedback = applicationReview.CandidateFeedback,
                CandidateId       = applicationReview.CandidateId
            });
        }
        public async Task Handle(WithdrawApplicationCommand message, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Withdrawing application for vacancyReference:{vacancyReference} and candidateId:{candidateId}", message.VacancyReference, message.CandidateId);

            var applicationReview = await _applicationReviewRepository.GetAsync(message.VacancyReference, message.CandidateId);

            if (applicationReview == null)
            {
                _logger.LogInformation("Cannot find application to withdraw for vacancyReference:{vacancyReference} and candidateId:{candidateId}", message.VacancyReference, message.CandidateId);
                return;
            }

            if (applicationReview.CanWithdraw == false)
            {
                _logger.LogWarning("Cannot withdraw ApplicationReviewId:{applicationReviewId} as not in correct state", applicationReview.Id);
                return;
            }

            applicationReview.IsWithdrawn       = true;
            applicationReview.WithdrawnDate     = _timeProvider.Now;
            applicationReview.Application       = null;
            applicationReview.CandidateFeedback = null;

            await _applicationReviewRepository.UpdateAsync(applicationReview);

            await _messaging.PublishEvent(new ApplicationReviewWithdrawnEvent
            {
                VacancyReference = applicationReview.VacancyReference
            });

            _logger.LogInformation("Finished withdrawing application for vacancyReference:{vacancyReference} and candidateId:{candidateId}", message.VacancyReference, message.CandidateId);
        }
        public async Task <Unit> Handle(CreateApplicationReviewCommand message, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Submitting application for vacancyId: {vacancyReference} for candidateId: {candidateId}", message.Application.VacancyReference, message.Application.CandidateId);

            var vacancy = await _vacancyRepository.GetVacancyAsync(message.Application.VacancyReference);

            var existingReview = await _applicationReviewRepository.GetAsync(vacancy.VacancyReference.Value, message.Application.CandidateId);

            if (existingReview != null)
            {
                _logger.LogWarning("Application review already exists for vacancyReference:{vacancyReference} and candidateId:{candidateId}. Found applicationReviewId:{applicationReviewId}",
                                   vacancy.VacancyReference.Value, message.Application.CandidateId, existingReview.Id);
                return(Unit.Value);
            }

            var review = new ApplicationReview
            {
                Id = Guid.NewGuid(),
                VacancyReference = vacancy.VacancyReference.Value,
                Application      = message.Application,
                CandidateId      = message.Application.CandidateId,
                CreatedDate      = _timeProvider.Now,
                Status           = ApplicationReviewStatus.New,
                SubmittedDate    = message.Application.ApplicationDate
            };

            await _applicationReviewRepository.CreateAsync(review);

            await _messaging.PublishEvent(new ApplicationReviewCreatedEvent
            {
                VacancyReference = vacancy.VacancyReference.Value
            });

            return(Unit.Value);
        }
 public Task <ApplicationReview> GetApplicationReviewAsync(Guid applicationReviewId)
 {
     return(_applicationReviewRepository.GetAsync(applicationReviewId));
 }