public async Task <IActionResult> RemoveHearing(Guid hearingId) { if (hearingId == Guid.Empty) { ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}"); return(BadRequest(ModelState)); } var getHearingByIdQuery = new GetHearingByIdQuery(hearingId); var videoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery); if (videoHearing == null) { return(NotFound($"{hearingId} does not exist")); } var command = new RemoveHearingCommand(hearingId); await _commandHandler.Handle(command); if (videoHearing.Status == BookingStatus.Created) { // publish the event only for confirmed(created) hearing await _eventPublisher.PublishAsync(new HearingCancelledIntegrationEvent(hearingId)); } return(NoContent()); }
private async Task <Hearing> GetHearingToPublishAsync(Guid hearingId) { var getHearingByIdQuery = new GetHearingByIdQuery(hearingId); var videoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery); return(videoHearing); }
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)); }
public async Task <IActionResult> RemoveParticipantFromHearing(Guid hearingId, Guid participantId) { if (hearingId == Guid.Empty) { ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}"); return(BadRequest(ModelState)); } var getHearingByIdQuery = new GetHearingByIdQuery(hearingId); var videoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(getHearingByIdQuery); if (videoHearing == null) { return(NotFound()); } if (participantId == Guid.Empty) { ModelState.AddModelError(nameof(participantId), $"Please provide a valid {nameof(participantId)}"); return(BadRequest(ModelState)); } List <Participant> participants; var query = new GetParticipantsInHearingQuery(hearingId); try { participants = await _queryHandler.Handle <GetParticipantsInHearingQuery, List <Participant> >(query); } catch (HearingNotFoundException) { return(NotFound()); } var participant = participants.FirstOrDefault(x => x.Id == participantId); if (participant == null) { return(NotFound()); } var command = new RemoveParticipantFromHearingCommand(hearingId, participant); await _commandHandler.Handle(command); // ONLY publish this event when Hearing is set for ready for video if (videoHearing.Status == Domain.Enumerations.BookingStatus.Created) { await _eventPublisher.PublishAsync(new ParticipantRemovedIntegrationEvent(hearingId, participantId)); } return(NoContent()); }
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> GetHearingDetailsById(Guid hearingId) { if (hearingId == Guid.Empty) { ModelState.AddModelError(nameof(hearingId), $"Please provide a valid {nameof(hearingId)}"); return(BadRequest(ModelState)); } var query = new GetHearingByIdQuery(hearingId); var videoHearing = await _queryHandler.Handle <GetHearingByIdQuery, VideoHearing>(query); if (videoHearing == null) { return(NotFound()); } var hearingMapper = new HearingToDetailsResponseMapper(); var response = hearingMapper.MapHearingToDetailedResponse(videoHearing); return(Ok(response)); }
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)); }
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 <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; } }
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)); }
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()); }