public async Task <IActionResult> UpdateHearingDetails(Guid hearingId, [FromBody] UpdateHearingRequest request)
        {
            if (hearingId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            var result = new UpdateHearingRequestValidation().Validate(request);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            var getHearingByIdQuery = new GetHearingByIdQuery(hearingId);
            var videoHearing        = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery);

            if (videoHearing == null)
            {
                return(NotFound());
            }

            var venue = await GetVenue(request.HearingVenueName);

            if (venue == null)
            {
                ModelState.AddModelError(nameof(request.HearingVenueName), "Hearing venue does not exist");
                return(BadRequest(ModelState));
            }

            var cases = MapCase(request.Cases);

            // use existing video hearing values here when request properties are null
            request.AudioRecordingRequired ??= videoHearing.AudioRecordingRequired;
            request.QuestionnaireNotRequired ??= videoHearing.QuestionnaireNotRequired;
            request.HearingRoomName ??= videoHearing.HearingRoomName;
            request.OtherInformation ??= videoHearing.OtherInformation;

            var command = new UpdateHearingCommand(hearingId, request.ScheduledDateTime,
                                                   request.ScheduledDuration, venue, request.HearingRoomName, request.OtherInformation,
                                                   request.UpdatedBy, cases, request.QuestionnaireNotRequired.Value, request.AudioRecordingRequired.Value);

            await _commandHandler.Handle(command);

            var hearingMapper  = new HearingToDetailsResponseMapper();
            var updatedHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery);

            var response = hearingMapper.MapHearingToDetailedResponse(updatedHearing);

            if (videoHearing.Status == BookingStatus.Created)
            {
                // publish this event when Hearing is set for ready for video
                await _eventPublisher.PublishAsync(new HearingDetailsUpdatedIntegrationEvent(updatedHearing));
            }

            return(Ok(response));
        }
Esempio n. 2
0
        public async Task <IActionResult> UpdateBookingStatus(Guid hearingId, UpdateBookingStatusRequest updateBookingStatusRequest)
        {
            if (hearingId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            var result = new UpdateBookingStatusRequestValidation().Validate(updateBookingStatusRequest);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            try
            {
                var bookingStatus = MapUpdateBookingStatus(updateBookingStatusRequest.Status);
                var command       = new UpdateHearingStatusCommand(hearingId, bookingStatus, updateBookingStatusRequest.UpdatedBy,
                                                                   updateBookingStatusRequest.CancelReason);
                await _commandHandler.Handle(command);

                switch (bookingStatus)
                {
                case BookingStatus.Booked:
                    break;

                case BookingStatus.Created:
                    var queriedVideoHearing = await GetHearingToPublish(hearingId);

                    var createVideoHearingEvent = new HearingIsReadyForVideoIntegrationEvent(queriedVideoHearing);
                    await _eventPublisher.PublishAsync(createVideoHearingEvent);

                    break;

                case BookingStatus.Cancelled:
                    await _eventPublisher.PublishAsync(new HearingCancelledIntegrationEvent(hearingId));

                    break;

                default:
                    break;
                }

                return(NoContent());
            }
            catch (HearingNotFoundException)
            {
                return(NotFound());
            }
            catch (DomainRuleException exception)
            {
                exception.ValidationFailures.ForEach(x => ModelState.AddModelError(x.Name, x.Message));
                return(Conflict(ModelState));
            }
        }
        public async Task <IActionResult> UpdateEndpointAsync(Guid hearingId, Guid endpointId, UpdateEndpointRequest updateEndpointRequest)
        {
            if (hearingId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            var result = new UpdateEndpointRequestValidation().Validate(updateEndpointRequest);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            try
            {
                var hearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(new GetHearingByIdQuery(hearingId));

                if (hearing == null)
                {
                    throw new HearingNotFoundException(hearingId);
                }
                var defenceAdvocate =
                    DefenceAdvocateHelper.CheckAndReturnDefenceAdvocate(updateEndpointRequest.DefenceAdvocateUsername,
                                                                        hearing.GetParticipants());
                var command = new UpdateEndPointOfHearingCommand(hearingId, endpointId, updateEndpointRequest.DisplayName, defenceAdvocate);
                await _commandHandler.Handle(command);

                var endpoint = hearing.GetEndpoints().SingleOrDefault(x => x.Id == endpointId);

                if (endpoint != null && hearing.Status == BookingStatus.Created)
                {
                    await _eventPublisher.PublishAsync(new EndpointUpdatedIntegrationEvent(hearingId, endpoint.Sip,
                                                                                           updateEndpointRequest.DisplayName, defenceAdvocate?.Person.Username));
                }
            }
            catch (HearingNotFoundException exception)
            {
                return(NotFound(exception.Message));
            }
            catch (EndPointNotFoundException exception)
            {
                return(NotFound(exception.Message));
            }

            return(NoContent());
        }
        public async Task <ActionResult <IList <PersonResponse> > > UpdatePersonDetails([FromRoute] Guid personId, [FromBody] UpdatePersonDetailsRequest payload)
        {
            var validation = await new UpdatePersonDetailsRequestValidation().ValidateAsync(payload);

            if (!validation.IsValid)
            {
                ModelState.AddFluentValidationErrors(validation.Errors);
                return(BadRequest(ModelState));
            }

            try
            {
                var command = new UpdatePersonCommand(personId, payload.FirstName, payload.LastName, payload.Username);
                await _commandHandler.Handle(command);
            }
            catch (PersonNotFoundException e)
            {
                _logger.LogError(e, "Failed to update a person because the person {Person} does not exist", personId);
                return(NotFound($"{personId} does not exist"));
            }

            // get all hearings for user
            var query    = new GetHearingsByUsernameQuery(payload.Username);
            var hearings = await _queryHandler.Handle <GetHearingsByUsernameQuery, List <VideoHearing> >(query);

            // raise an update event for each hearing to ensure consistency between video and bookings api
            var anonymisedText            = "@hmcts.net";
            var nonAnonymisedParticipants = hearings
                                            .Where(x => x.Status == BookingStatus.Created &&
                                                   x.GetCases().Any(c => !c.Name.EndsWith(anonymisedText))).SelectMany(c => c.Participants)
                                            .Where(p => p.PersonId == personId && !p.DisplayName.EndsWith(anonymisedText)).ToList();

            _logger.LogDebug("Updating {Count} non-anonymised participants", nonAnonymisedParticipants.Count);

            foreach (var participant in nonAnonymisedParticipants)
            {
                // map to updated participant event
                await _eventPublisher.PublishAsync(new ParticipantUpdatedIntegrationEvent(participant.HearingId, participant));
            }

            return(Accepted());
        }
        public async Task <IActionResult> CloneHearing([FromRoute] Guid hearingId,
                                                       [FromBody] CloneHearingRequest request)
        {
            var getHearingByIdQuery = new GetHearingByIdQuery(hearingId);
            var videoHearing        = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery);

            if (videoHearing == null)
            {
                return(NotFound());
            }

            var validationResult =
                new CloneHearingRequestValidation(videoHearing)
                .ValidateDates(request);

            if (!validationResult.IsValid)
            {
                ModelState.AddFluentValidationErrors(validationResult.Errors);
                return(BadRequest(ModelState));
            }

            var orderedDates = request.Dates.OrderBy(x => x).ToList();
            var totalDays    = orderedDates.Count + 1; // include original hearing
            var commands     = orderedDates.Select((newDate, index) =>
            {
                var hearingDay = index + 2; // zero index including original hearing
                return(CloneHearingToCommandMapper.CloneToCommand(videoHearing, newDate, _randomGenerator,
                                                                  _kinlyConfiguration.SipAddressStem, totalDays, hearingDay));
            }).ToList();

            foreach (var command in commands)
            {
                // dbcontext is not thread safe. loop one at a time
                await _commandHandler.Handle(command);
            }

            var existingCase = videoHearing.GetCases().First();
            await _hearingService.UpdateHearingCaseName(hearingId, $"{existingCase.Name} Day {1} of {totalDays}");

            return(NoContent());
        }
        public async Task <IActionResult> AddEndPointToHearingAsync(Guid hearingId, AddEndpointRequest addEndpointRequest)
        {
            if (hearingId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            var result = await new AddEndpointRequestValidation().ValidateAsync(addEndpointRequest);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            try
            {
                var newEp = EndpointToResponseMapper.MapRequestToNewEndpointDto(addEndpointRequest, _randomGenerator,
                                                                                _kinlyConfiguration.SipAddressStem);

                var command = new AddEndPointToHearingCommand(hearingId, newEp);
                await _commandHandler.Handle(command);

                var hearing =
                    await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(new GetHearingByIdQuery(hearingId));

                var endpoint = hearing.GetEndpoints().FirstOrDefault(x => x.DisplayName.Equals(addEndpointRequest.DisplayName));
                if (endpoint != null && hearing.Status == BookingStatus.Created)
                {
                    await _eventPublisher.PublishAsync(new EndpointAddedIntegrationEvent(hearingId, endpoint));
                }
            }
            catch (HearingNotFoundException exception)
            {
                return(NotFound(exception.Message));
            }

            return(NoContent());
        }
Esempio n. 7
0
        public async Task <IActionResult> UpdateParticipantDetails(Guid hearingId, Guid participantId, [FromBody] UpdateParticipantRequest request)
        {
            if (hearingId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            if (participantId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(participantId), $"Please provide a valid {nameof(participantId)}");
                return(BadRequest(ModelState));
            }

            var result = new UpdateParticipantRequestValidation().Validate(request);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            var getHearingByIdQuery = new GetHearingByIdQuery(hearingId);
            var videoHearing        = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery);

            if (videoHearing == null)
            {
                return(NotFound());
            }
            Participant participant  = null;
            var         participants = videoHearing.GetParticipants();

            if (participants != null)
            {
                participant = participants.SingleOrDefault(x => x.Id.Equals(participantId));
            }

            if (participant == null)
            {
                return(NotFound());
            }

            if (participant.HearingRole.UserRole.IsIndividual)
            {
                var addressValidationResult = new AddressValidation().Validate(request);
                if (!addressValidationResult.IsValid)
                {
                    ModelState.AddFluentValidationErrors(result.Errors);
                    return(BadRequest(ModelState));
                }
            }

            if (participant.HearingRole.UserRole.IsRepresentative)
            {
                var repValidationResult = new RepresentativeValidation().Validate(request);
                if (!repValidationResult.IsValid)
                {
                    ModelState.AddFluentValidationErrors(result.Errors);
                    return(BadRequest(ModelState));
                }
            }

            var mapper  = new UpdateParticipantRequestToNewAddressMapper();
            var address = mapper.MapRequestToNewAddress(request);

            var representativeMapper = new UpdateParticipantRequestToNewRepresentativeMapper();
            var representative       = representativeMapper.MapRequestToNewRepresentativeInfo(request);

            var updateParticipantCommand = new UpdateParticipantCommand(participantId, request.Title,
                                                                        request.DisplayName, request.TelephoneNumber, address,
                                                                        request.OrganisationName, videoHearing, representative);

            await _commandHandler.Handle(updateParticipantCommand);

            var updatedParticipant = updateParticipantCommand.UpdatedParticipant;

            var participantMapper = new ParticipantToResponseMapper();

            ParticipantResponse response = null;

            if (updatedParticipant != null)
            {
                response = participantMapper.MapParticipantToResponse(updatedParticipant);
            }

            // ONLY publish this event when Hearing is set for ready for video
            if (videoHearing.Status == Domain.Enumerations.BookingStatus.Created)
            {
                await _eventPublisher.PublishAsync(new ParticipantUpdatedIntegrationEvent(hearingId, updatedParticipant));
            }

            return(Ok(response));
        }
Esempio n. 8
0
        public async Task <IActionResult> AddParticipantsToHearing(Guid hearingId,
                                                                   [FromBody] AddParticipantsToHearingRequest request)
        {
            if (hearingId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            var result = new AddParticipantsToHearingRequestValidation().Validate(request);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            var query        = new GetHearingByIdQuery(hearingId);
            var videoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(query);

            if (videoHearing == null)
            {
                return(NotFound());
            }

            var caseTypequery = new GetCaseTypeQuery(videoHearing.CaseType.Name);
            var caseType      = await _queryHandler.Handle <GetCaseTypeQuery, CaseType>(caseTypequery);

            var individualRoles = caseType.CaseRoles.SelectMany(x => x.HearingRoles).Where(x => x.UserRole.IsIndividual).Select(x => x.Name).ToList();

            var addressValidationResult = AddressValidationHelper.ValidateAddress(individualRoles, request.Participants);

            if (!addressValidationResult.IsValid)
            {
                ModelState.AddFluentValidationErrors(addressValidationResult.Errors);
                return(BadRequest(ModelState));
            }

            var representativeRoles = caseType.CaseRoles.SelectMany(x => x.HearingRoles).Where(x => x.UserRole.IsRepresentative).Select(x => x.Name).ToList();
            var reprensentatives    = request.Participants.Where(x => representativeRoles.Contains(x.HearingRoleName)).ToList();

            var representativeValidationResult = RepresentativeValidationHelper.ValidateRepresentativeInfo(reprensentatives);

            if (!representativeValidationResult.IsValid)
            {
                ModelState.AddFluentValidationErrors(representativeValidationResult.Errors);
                return(BadRequest(ModelState));
            }


            var mapper       = new ParticipantRequestToNewParticipantMapper();
            var participants = request.Participants
                               .Select(x => mapper.MapRequestToNewParticipant(x, videoHearing.CaseType)).ToList();
            var command = new AddParticipantsToVideoHearingCommand(hearingId, participants);

            try
            {
                await _commandHandler.Handle(command);
            }
            catch (DomainRuleException e)
            {
                ModelState.AddDomainRuleErrors(e.ValidationFailures);
                return(BadRequest(ModelState));
            }

            var hearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(query);

            // ONLY publish this event when Hearing is set for ready for video
            if (hearing.Status == Domain.Enumerations.BookingStatus.Created)
            {
                await PublishParticipantsAddedEvent(participants, hearing);
            }

            return(NoContent());
        }
        public async Task <ActionResult <HearingDetailsResponse> > EditHearing(Guid hearingId,
                                                                               [FromBody] EditHearingRequest request)
        {
            var usernameAdIdDict = new Dictionary <string, User>();

            if (hearingId == Guid.Empty)
            {
                _logger.LogWarning("No hearing id found to edit");
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            _logger.LogDebug("Attempting to edit hearing {Hearing}", hearingId);

            var result = _editHearingRequestValidator.Validate(request);

            if (!result.IsValid)
            {
                _logger.LogWarning("Failed edit hearing validation");
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            HearingDetailsResponse originalHearing;

            try
            {
                originalHearing = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId);
            }
            catch (BookingsApiException e)
            {
                _logger.LogError(e,
                                 "Failed to get hearing {Hearing}. Status Code {StatusCode} - Message {Message}",
                                 hearingId, e.StatusCode, e.Response);
                if (e.StatusCode != (int)HttpStatusCode.NotFound)
                {
                    throw;
                }

                return(NotFound($"No hearing with id found [{hearingId}]"));
            }

            try
            {
                //Save hearing details
                var updateHearingRequest =
                    HearingUpdateRequestMapper.MapTo(request, _userIdentity.GetUserIdentityName());
                await _bookingsApiClient.UpdateHearingDetailsAsync(hearingId, updateHearingRequest);

                var newParticipantList = new List <ParticipantRequest>();

                foreach (var participant in request.Participants)
                {
                    if (!participant.Id.HasValue)
                    {
                        await _hearingsService.ProcessNewParticipants(hearingId, participant, originalHearing,
                                                                      usernameAdIdDict, newParticipantList);
                    }
                    else
                    {
                        await _hearingsService.ProcessExistingParticipants(hearingId, originalHearing, participant);
                    }
                }

                // Delete existing participants if the request doesn't contain any update information
                originalHearing.Participants ??= new List <ParticipantResponse>();
                await RemoveParticipantsFromHearing(hearingId, request, originalHearing);

                // Add new participants
                await _hearingsService.SaveNewParticipants(hearingId, newParticipantList);

                var addedParticipantToHearing = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId);

                await _hearingsService.UpdateParticipantLinks(hearingId, request, addedParticipantToHearing);

                // endpoints
                await _hearingsService.ProcessEndpoints(hearingId, request, originalHearing, newParticipantList);

                var updatedHearing = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId);

                await _hearingsService.AddParticipantLinks(hearingId, request, updatedHearing);

                _logger.LogDebug("Attempting assign participants to the correct group");
                await _hearingsService.AssignParticipantToCorrectGroups(updatedHearing, usernameAdIdDict);

                _logger.LogDebug("Successfully assigned participants to the correct group");

                // Send a notification email to newly created participants
                var newParticipantEmails = newParticipantList.Select(p => p.ContactEmail).ToList();
                await SendEmailsToParticipantsAddedToHearing(newParticipantList, updatedHearing, usernameAdIdDict, newParticipantEmails);

                await SendJudgeEmailIfNeeded(updatedHearing, originalHearing);

                if (!updatedHearing.HasScheduleAmended(originalHearing))
                {
                    return(Ok(updatedHearing));
                }


                var participantsForAmendment = updatedHearing.Participants
                                               .Where(p => !newParticipantEmails.Contains(p.ContactEmail)).ToList();
                await _hearingsService.SendHearingUpdateEmail(originalHearing, updatedHearing,
                                                              participantsForAmendment);


                return(Ok(updatedHearing));
            }
            catch (BookingsApiException e)
            {
                _logger.LogError(e,
                                 "Failed to edit hearing {Hearing}. Status Code {StatusCode} - Message {Message}",
                                 hearingId, e.StatusCode, e.Response);
                if (e.StatusCode == (int)HttpStatusCode.BadRequest)
                {
                    return(BadRequest(e.Response));
                }

                throw;
            }
        }
Esempio n. 10
0
        public async Task <IActionResult> BookNewHearing(BookNewHearingRequest request)
        {
            try
            {
                if (request == null)
                {
                    const string modelErrorMessage    = "BookNewHearingRequest is null";
                    const string logModelErrorMessage = "BookNewHearing Error: BookNewHearingRequest is null";

                    return(ModelStateErrorLogger(nameof(BookNewHearingRequest), modelErrorMessage, logModelErrorMessage,
                                                 null, SeverityLevel.Information));
                }

                var result = await new BookNewHearingRequestValidation().ValidateAsync(request);
                if (!result.IsValid)
                {
                    const string logBookNewHearingValidationError = "BookNewHearing Validation Errors";
                    const string emptyPayLoadErrorMessage         = "Empty Payload";
                    const string keyPayload = "payload";

                    ModelState.AddFluentValidationErrors(result.Errors);
                    var dictionary = result.Errors.ToDictionary(x => x.PropertyName + "-" + Guid.NewGuid(), x => x.ErrorMessage);
                    var payload    = JsonConvert.SerializeObject(request);
                    dictionary.Add(keyPayload, !string.IsNullOrWhiteSpace(payload) ? payload : emptyPayLoadErrorMessage);
                    _logger.TrackTrace(logBookNewHearingValidationError, SeverityLevel.Error, dictionary);
                    return(BadRequest(ModelState));
                }

                var query    = new GetCaseTypeQuery(request.CaseTypeName);
                var caseType = await _queryHandler.Handle <GetCaseTypeQuery, CaseType>(query);

                if (caseType == null)
                {
                    const string logCaseDoesNotExist = "BookNewHearing Error: Case type does not exist";
                    return(ModelStateErrorLogger(nameof(request.CaseTypeName),
                                                 "Case type does not exist", logCaseDoesNotExist, request.CaseTypeName, SeverityLevel.Error));
                }

                var hearingType = caseType.HearingTypes.SingleOrDefault(x => x.Name == request.HearingTypeName);
                if (hearingType == null)
                {
                    const string logHearingTypeDoesNotExist = "BookNewHearing Error: Hearing type does not exist";
                    return(ModelStateErrorLogger(nameof(request.HearingTypeName),
                                                 "Hearing type does not exist", logHearingTypeDoesNotExist, request.HearingTypeName, SeverityLevel.Error));
                }

                var venue = await GetVenue(request.HearingVenueName);

                if (venue == null)
                {
                    const string logHearingVenueDoesNotExist = "BookNewHearing Error: Hearing venue does not exist";

                    return(ModelStateErrorLogger(nameof(request.HearingVenueName),
                                                 "Hearing venue does not exist", logHearingVenueDoesNotExist, request.HearingVenueName, SeverityLevel.Error));
                }

                var          cases       = request.Cases.Select(x => new Case(x.Number, x.Name)).ToList();
                const string logHasCases = "BookNewHearing got cases";
                const string keyCases    = "Cases";
                _logger.TrackTrace(logHasCases, SeverityLevel.Information, new Dictionary <string, string>
                {
                    { keyCases, string.Join(", ", cases.Select(x => new { x.Name, x.Number })) }
                });

                var createVideoHearingCommand = BookNewHearingRequestToCreateVideoHearingCommandMapper.Map(
                    request, caseType, hearingType, venue, cases, _randomGenerator, _kinlyConfiguration.SipAddressStem);

                const string logCallingDb    = "BookNewHearing Calling DB...";
                const string dbCommand       = "createVideoHearingCommand";
                const string logSaveSuccess  = "BookNewHearing DB Save Success";
                const string logNewHearingId = "NewHearingId";

                _logger.TrackTrace(logCallingDb, SeverityLevel.Information, new Dictionary <string, string> {
                    { dbCommand, JsonConvert.SerializeObject(createVideoHearingCommand) }
                });
                await _commandHandler.Handle(createVideoHearingCommand);

                _logger.TrackTrace(logSaveSuccess, SeverityLevel.Information, new Dictionary <string, string> {
                    { logNewHearingId, createVideoHearingCommand.NewHearingId.ToString() }
                });

                var videoHearingId = createVideoHearingCommand.NewHearingId;

                var getHearingByIdQuery = new GetHearingByIdQuery(videoHearingId);
                var queriedVideoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery);

                const string logRetrieveNewHearing = "BookNewHearing Retrieved new hearing from DB";
                const string keyHearingId          = "HearingId";
                const string keyCaseType           = "CaseType";
                const string keyParticipantCount   = "Participants.Count";
                _logger.TrackTrace(logRetrieveNewHearing, SeverityLevel.Information, new Dictionary <string, string>
                {
                    { keyHearingId, queriedVideoHearing.Id.ToString() },
                    { keyCaseType, queriedVideoHearing.CaseType?.Name },
                    { keyParticipantCount, queriedVideoHearing.Participants.Count.ToString() },
                });

                var          hearingMapper      = new HearingToDetailsResponseMapper();
                var          response           = hearingMapper.MapHearingToDetailedResponse(queriedVideoHearing);
                const string logProcessFinished = "BookNewHearing Finished, returning response";
                _logger.TrackTrace(logProcessFinished, SeverityLevel.Information, new Dictionary <string, string> {
                    { "response", JsonConvert.SerializeObject(response) }
                });
                return(CreatedAtAction(nameof(GetHearingDetailsById), new { hearingId = response.Id }, response));
            }
            catch (Exception ex)
            {
                const string keyPayload           = "payload";
                const string keyScheduledDateTime = "ScheduledDateTime";
                const string keyScheduledDuration = "ScheduledDuration";
                const string keyCaseTypeName      = "CaseTypeName";
                const string keyHearingTypeName   = "HearingTypeName";

                if (request != null)
                {
                    var payload = JsonConvert.SerializeObject(request);
                    _logger.TrackError(ex, new Dictionary <string, string>
                    {
                        { keyPayload, !string.IsNullOrWhiteSpace(payload) ? payload : "Empty Payload" },
                        { keyScheduledDateTime, request.ScheduledDateTime.ToString("s") },
                        { keyScheduledDuration, request.ScheduledDuration.ToString() },
                        { keyCaseTypeName, request.CaseTypeName },
                        { keyHearingTypeName, request.HearingTypeName }
                    });
                }

                throw;
            }
        }
Esempio n. 11
0
        public async Task <IActionResult> BookNewHearing(BookNewHearingRequest request)
        {
            var result = new BookNewHearingRequestValidation().Validate(request);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            var query    = new GetCaseTypeQuery(request.CaseTypeName);
            var caseType = await _queryHandler.Handle <GetCaseTypeQuery, CaseType>(query);


            if (caseType == null)
            {
                ModelState.AddModelError(nameof(request.CaseTypeName), "Case type does not exist");
                return(BadRequest(ModelState));
            }

            var individualRoles = caseType.CaseRoles.SelectMany(x => x.HearingRoles).Where(x => x.UserRole.IsIndividual).Select(x => x.Name).ToList();

            var addressValidationResult = AddressValidationHelper.ValidateAddress(individualRoles, request.Participants);

            if (!addressValidationResult.IsValid)
            {
                ModelState.AddFluentValidationErrors(addressValidationResult.Errors);
                return(BadRequest(ModelState));
            }

            var hearingType = caseType.HearingTypes.SingleOrDefault(x => x.Name == request.HearingTypeName);

            if (hearingType == null)
            {
                ModelState.AddModelError(nameof(request.HearingTypeName), "Hearing type does not exist");
                return(BadRequest(ModelState));
            }

            var venue = await GetVenue(request.HearingVenueName);

            if (venue == null)
            {
                ModelState.AddModelError(nameof(request.HearingVenueName), "Hearing venue does not exist");
                return(BadRequest(ModelState));
            }

            var mapper          = new ParticipantRequestToNewParticipantMapper();
            var newParticipants = request.Participants.Select(x => mapper.MapRequestToNewParticipant(x, caseType))
                                  .ToList();

            var cases = request.Cases.Select(x => new Case(x.Number, x.Name)).ToList();

            var createVideoHearingCommand = new CreateVideoHearingCommand(caseType, hearingType,
                                                                          request.ScheduledDateTime, request.ScheduledDuration, venue, newParticipants, cases,
                                                                          request.QuestionnaireNotRequired, request.AudioRecordingRequired)
            {
                HearingRoomName  = request.HearingRoomName,
                OtherInformation = request.OtherInformation,
                CreatedBy        = request.CreatedBy
            };

            await _commandHandler.Handle(createVideoHearingCommand);

            var videoHearingId = createVideoHearingCommand.NewHearingId;

            var getHearingByIdQuery = new GetHearingByIdQuery(videoHearingId);

            var queriedVideoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery);

            var hearingMapper = new HearingToDetailResponseMapper();
            var response      = hearingMapper.MapHearingToDetailedResponse(queriedVideoHearing);

            return(CreatedAtAction(nameof(GetHearingDetailsById), new { hearingId = response.Id }, response));
        }
Esempio n. 12
0
        public async Task <IActionResult> UpdateHearingParticipants(Guid hearingId,
                                                                    [FromBody] UpdateHearingParticipantsRequest request)
        {
            if (hearingId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}");
                return(BadRequest(ModelState));
            }

            var result = new UpdateHearingParticipantsRequestValidation().Validate(request);

            if (!result.IsValid)
            {
                ModelState.AddFluentValidationErrors(result.Errors);
                return(BadRequest(ModelState));
            }

            var query        = new GetHearingByIdQuery(hearingId);
            var videoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(query);

            if (videoHearing == null)
            {
                return(NotFound());
            }

            var caseTypequery = new GetCaseTypeQuery(videoHearing.CaseType.Name);
            var caseType      = await _queryHandler.Handle <GetCaseTypeQuery, CaseType>(caseTypequery);

            var representativeRoles = caseType.CaseRoles.SelectMany(x => x.HearingRoles).Where(x => x.UserRole.IsRepresentative).Select(x => x.Name).ToList();
            var representatives     = request.NewParticipants.Where(x => representativeRoles.Contains(x.HearingRoleName)).ToList();

            var representativeValidationResult = RepresentativeValidationHelper.ValidateRepresentativeInfo(representatives);

            if (!representativeValidationResult.IsValid)
            {
                ModelState.AddFluentValidationErrors(representativeValidationResult.Errors);
                return(BadRequest(ModelState));
            }

            var newParticipants = request.NewParticipants
                                  .Select(x => ParticipantRequestToNewParticipantMapper.Map(x, videoHearing.CaseType)).ToList();

            var existingParticipants = request.ExistingParticipants
                                       .Select(x => new ExistingParticipantDetails
            {
                DisplayName               = x.DisplayName,
                OrganisationName          = x.OrganisationName,
                ParticipantId             = x.ParticipantId,
                RepresentativeInformation = new RepresentativeInformation {
                    Representee = x.Representee
                },
                TelephoneNumber = x.TelephoneNumber,
                Title           = x.Title
            }).ToList();

            var linkedParticipants =
                LinkedParticipantRequestToLinkedParticipantDtoMapper.MapToDto(request.LinkedParticipants);

            var command = new UpdateHearingParticipantsCommand(hearingId, existingParticipants, newParticipants, request.RemovedParticipantIds, linkedParticipants);

            try
            {
                await _commandHandler.Handle(command);
            }
            catch (DomainRuleException e)
            {
                ModelState.AddDomainRuleErrors(e.ValidationFailures);
                return(BadRequest(ModelState));
            }

            var hearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(query);

            // Publish this event if the hearing is ready for video
            if (hearing.Status == BookingStatus.Created)
            {
                await PublishUpdateHearingParticipantsEvent(hearing, existingParticipants, newParticipants, request.RemovedParticipantIds, linkedParticipants);
            }

            return(NoContent());
        }