diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1ed7cee6e..706fe8240 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,7 @@ -* @hmcts/vh -* @hmcts/vh-qa -azure-pipelines.yml @vh-DevOps -azure-pipelines.release.yml @vh-DevOps -azure-pipelines.nightly.yml @vh-DevOps -azure-pipelines.beta.yml @vh-DevOps +* @hmcts/vh @hmcts/vh-qa +/variables/ @hmcts/vh +/charts/ @hmcts/vh +/.github/ @hmcts/vh-devops +/.githooks/ @hmcts/vh-devops +/.config/ @hmcts/vh-devops +azure-pipelines* @hmcts/vh-devops diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 709b2fe79..e7b55b284 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,6 +13,6 @@ jobs: steps: - uses: deepakputhraya/action-pr-title@master with: - regex: '^(VIH-[0-9]{4} [a-zA-Z0-9._\- ]+)|(\[Snyk\].+)$' # Regex the title should match. + regex: '^(VIH-[0-9]{4,5} [a-zA-Z0-9._\- ]+)|(\[Snyk\].+)$' # Regex the title should match. allowed_prefixes: 'VIH-,[Snyk]' # title should start with the given prefix prefix_case_sensitive: true # title prefix are case insensitive diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertConference.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertConference.cs index 888538afb..bec0f4b8a 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertConference.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertConference.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using VideoApi.Contract.Enums; using VideoApi.Contract.Responses; @@ -39,7 +39,7 @@ private static void AssertConferenceDetails(HearingDetailsResponse hearing, Conf conference.MeetingRoom.TelephoneConferenceId.Should().NotBeNullOrWhiteSpace(); } - private static void AssertEndpoints(IReadOnlyCollection hearingEndpoints, + private static void AssertEndpoints(IReadOnlyCollection hearingEndpoints, IEnumerable conferenceEndpoints, IReadOnlyCollection hearingParticipants) { foreach (var conferenceEndpoint in conferenceEndpoints) diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertHearing.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertHearing.cs index ff96e77a8..c4c1fde62 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertHearing.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Data/AssertHearing.cs @@ -6,7 +6,7 @@ using AcceptanceTests.Common.Model.Participant; using AdminWebsite.AcceptanceTests.Helpers; using AdminWebsite.AcceptanceTests.Steps; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.AcceptanceTests.Data { diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Data/Test.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Data/Test.cs index 50b99bab9..5ac738bb2 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Data/Test.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Data/Test.cs @@ -2,7 +2,7 @@ using AcceptanceTests.Common.Configuration.Users; using AcceptanceTests.Common.Data.TestData; using AdminWebsite.AcceptanceTests.Data.TestData; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using VideoApi.Contract.Responses; namespace AdminWebsite.AcceptanceTests.Data diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Helpers/SuitabilityAnswers.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Helpers/SuitabilityAnswers.cs index 80f8659e6..e52482d76 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Helpers/SuitabilityAnswers.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Helpers/SuitabilityAnswers.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using AcceptanceTests.Common.Data.Questions; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.AcceptanceTests.Helpers { diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/ConfigHooks.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/ConfigHooks.cs index b4561fd4f..79966246f 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/ConfigHooks.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/ConfigHooks.cs @@ -8,7 +8,7 @@ using AdminWebsite.AcceptanceTests.Data; using AdminWebsite.AcceptanceTests.Data.TestData; using AdminWebsite.AcceptanceTests.Helpers; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using TestApi.Contract.Dtos; using FluentAssertions; using Microsoft.Extensions.Configuration; diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/DataHooks.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/DataHooks.cs index 6cb8e9e2f..375faaabe 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/DataHooks.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/DataHooks.cs @@ -9,9 +9,9 @@ using AdminWebsite.AcceptanceTests.Data; using AdminWebsite.AcceptanceTests.Helpers; using AdminWebsite.Services; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Requests.Enums; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Requests.Enums; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.Extensions.Caching.Memory; using TechTalk.SpecFlow; diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/RemoveDataHooks.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/RemoveDataHooks.cs index b5918af4b..95ed8cada 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/RemoveDataHooks.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Hooks/RemoveDataHooks.cs @@ -5,7 +5,7 @@ using AcceptanceTests.Common.Api.Hearings; using AcceptanceTests.Common.Api.Helpers; using AdminWebsite.AcceptanceTests.Helpers; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using TechTalk.SpecFlow; using VideoApi.Contract.Responses; diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/BookingDetailsSteps.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/BookingDetailsSteps.cs index 11d8595d8..d6e8294ed 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/BookingDetailsSteps.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/BookingDetailsSteps.cs @@ -1,14 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using AcceptanceTests.Common.Api.Helpers; +using System.Collections.Generic; using AcceptanceTests.Common.Driver.Drivers; using AcceptanceTests.Common.Driver.Helpers; using AcceptanceTests.Common.Test.Steps; using AdminWebsite.AcceptanceTests.Helpers; using AdminWebsite.AcceptanceTests.Pages; -using BookingsApi.Contract.Responses; using FluentAssertions; using TechTalk.SpecFlow; using TestApi.Contract.Dtos; diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/QuestionnaireSteps.cs b/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/QuestionnaireSteps.cs index 0d5cfc5a6..86838252c 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/QuestionnaireSteps.cs +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/Steps/QuestionnaireSteps.cs @@ -7,7 +7,7 @@ using AcceptanceTests.Common.Test.Steps; using AdminWebsite.AcceptanceTests.Helpers; using AdminWebsite.AcceptanceTests.Pages; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using TestApi.Contract.Dtos; using FluentAssertions; using TechTalk.SpecFlow; diff --git a/AdminWebsite/AdminWebsite.AcceptanceTests/packages.lock.json b/AdminWebsite/AdminWebsite.AcceptanceTests/packages.lock.json index 4b22911c6..607fe8e54 100644 --- a/AdminWebsite/AdminWebsite.AcceptanceTests/packages.lock.json +++ b/AdminWebsite/AdminWebsite.AcceptanceTests/packages.lock.json @@ -152,8 +152,8 @@ }, "BookingsApi.Client": { "type": "Transitive", - "resolved": "1.44.6", - "contentHash": "pr59SEWnlnkGyZmilLh+6JiUEZqLXn6iic5NVTEjO22VFs3Qij0RfZ2q+fotW2rk/tVcs0P2WGITt9kulBm5SQ==", + "resolved": "1.46.9", + "contentHash": "/WKAyKGdjSMt6I/1MnkH9+J8nqfmYqbRUtVSAOqvwjbYBpoZ1GZCqPMDoOcgDtNdGzQboo9wt2lQBa8snjhbpw==", "dependencies": { "Microsoft.AspNetCore.Mvc.Core": "2.2.5" } @@ -2632,7 +2632,7 @@ "adminwebsite": { "type": "Project", "dependencies": { - "BookingsApi.Client": "[1.44.6, )", + "BookingsApi.Client": "[1.46.9, )", "FluentValidation.AspNetCore": "[10.4.0, )", "LaunchDarkly.ServerSdk": "[7.0.3, )", "MicroElements.Swashbuckle.FluentValidation": "[5.7.0, )", diff --git a/AdminWebsite/AdminWebsite.IntegrationTests/Helper/ApiUriFactory.cs b/AdminWebsite/AdminWebsite.IntegrationTests/Helper/ApiUriFactory.cs index 159eda753..a15007b01 100644 --- a/AdminWebsite/AdminWebsite.IntegrationTests/Helper/ApiUriFactory.cs +++ b/AdminWebsite/AdminWebsite.IntegrationTests/Helper/ApiUriFactory.cs @@ -1,5 +1,5 @@ using System; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; namespace Testing.Common { diff --git a/AdminWebsite/AdminWebsite.IntegrationTests/packages.lock.json b/AdminWebsite/AdminWebsite.IntegrationTests/packages.lock.json index 0223259cc..525b66c36 100644 --- a/AdminWebsite/AdminWebsite.IntegrationTests/packages.lock.json +++ b/AdminWebsite/AdminWebsite.IntegrationTests/packages.lock.json @@ -93,8 +93,8 @@ }, "BookingsApi.Client": { "type": "Transitive", - "resolved": "1.44.6", - "contentHash": "pr59SEWnlnkGyZmilLh+6JiUEZqLXn6iic5NVTEjO22VFs3Qij0RfZ2q+fotW2rk/tVcs0P2WGITt9kulBm5SQ==", + "resolved": "1.46.9", + "contentHash": "/WKAyKGdjSMt6I/1MnkH9+J8nqfmYqbRUtVSAOqvwjbYBpoZ1GZCqPMDoOcgDtNdGzQboo9wt2lQBa8snjhbpw==", "dependencies": { "Microsoft.AspNetCore.Mvc.Core": "2.2.5" } @@ -2064,7 +2064,7 @@ "adminwebsite": { "type": "Project", "dependencies": { - "BookingsApi.Client": "[1.44.6, )", + "BookingsApi.Client": "[1.46.9, )", "FluentValidation.AspNetCore": "[10.4.0, )", "LaunchDarkly.ServerSdk": "[7.0.3, )", "MicroElements.Swashbuckle.FluentValidation": "[5.7.0, )", diff --git a/AdminWebsite/AdminWebsite.UnitTests/Attributes/HearingInputSanitizerAttributeTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Attributes/HearingInputSanitizerAttributeTest.cs index 5ea2add62..f53b6ea24 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Attributes/HearingInputSanitizerAttributeTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Attributes/HearingInputSanitizerAttributeTest.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; using AdminWebsite.Models; using AdminWebsite.UnitTests.Controllers; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.UnitTests.Attributes { @@ -114,9 +114,9 @@ private static ActionExecutingContext CreateBookNewHearingRequestContext(string { new CaseRequest{Name = text, Number = text} }, - Participants = new List + Participants = new List { - new BookingsApi.Contract.Requests.ParticipantRequest + new BookingsApi.Contract.V1.Requests.ParticipantRequest { Title = text, FirstName = text, diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/BookingListControllerTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/BookingListControllerTest.cs index e49f1e69e..49e11c01e 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/BookingListControllerTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/BookingListControllerTest.cs @@ -1,8 +1,8 @@ using AdminWebsite.Contracts.Requests; using AdminWebsite.Security; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.AspNetCore.Mvc; using Moq; @@ -18,7 +18,6 @@ public class BookingListControllerTest { private Mock _bookingsApiClient; private Mock _userIdentity; - private AdminWebsite.Controllers.BookingListController _controller; [SetUp] @@ -27,7 +26,8 @@ public void Setup() _bookingsApiClient = new Mock(); _userIdentity = new Mock(); - _controller = new AdminWebsite.Controllers.BookingListController(_bookingsApiClient.Object, + _controller = new AdminWebsite.Controllers.BookingListController( + _bookingsApiClient.Object, _userIdentity.Object, JavaScriptEncoder.Default); } @@ -61,7 +61,7 @@ public async Task Should_return_booking_list_if_cursor_is_not_null() .ReturnsAsync(new BookingsResponse()); _userIdentity.Setup(x => x.GetGroupDisplayNames()).Returns(new List { "type1", "type2" }); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(new List()); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(new List()); var request = new BookingSearchRequest { @@ -121,7 +121,7 @@ public async Task Should_return_ok_for_booking_list_with_null_types_in_database( { SetupTestCase(); List response = null; - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(response); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(response); var request = new BookingSearchRequest { @@ -141,7 +141,7 @@ public async Task Should_return_ok_for_booking_list_with_empty_list_of_types() SetupTestCase(); var response = new List(); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(response); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(response); var request = new BookingSearchRequest { @@ -173,7 +173,7 @@ public async Task } }; - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(response); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(response); var request = new BookingSearchRequest { @@ -199,7 +199,7 @@ public async Task Should_return_ok_for_booking_list_with_defined_types_list() _userIdentity.Setup(x => x.GetGroupDisplayNames()).Returns(new List { "type1", "type2" }); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(() => GetCaseTypesList()); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(() => GetCaseTypesList()); var request = new BookingSearchRequest { @@ -212,7 +212,7 @@ public async Task Should_return_ok_for_booking_list_with_defined_types_list() okResult.StatusCode.Should().Be(200); _userIdentity.Verify(x => x.IsAdministratorRole(), Times.Once); - _bookingsApiClient.Verify(s => s.GetCaseTypesAsync(), Times.Once); + _bookingsApiClient.Verify(s => s.GetCaseTypesAsync(true), Times.Once); _bookingsApiClient.Verify(x => x.GetHearingsByTypesAsync(It.IsAny()), Times.Once); } @@ -229,7 +229,7 @@ public async Task Should_return_ok_for_booking_list_and_exclude_repeated_types() _userIdentity.Setup(x => x.GetGroupDisplayNames()).Returns(new List { "type1", "type2", "type2" }); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(() => GetCaseTypesList()); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(() => GetCaseTypesList()); var request = new BookingSearchRequest { @@ -243,7 +243,7 @@ public async Task Should_return_ok_for_booking_list_and_exclude_repeated_types() okResult.StatusCode.Should().Be(200); _userIdentity.Verify(x => x.IsAdministratorRole(), Times.Once); - _bookingsApiClient.Verify(s => s.GetCaseTypesAsync(), Times.Once); + _bookingsApiClient.Verify(s => s.GetCaseTypesAsync(true), Times.Once); _bookingsApiClient.Verify(x => x.GetHearingsByTypesAsync(It.IsAny()), Times.Once); } @@ -252,7 +252,7 @@ public async Task Should_return_booking_list_when_admin_search_by_case_number() { SetupTestCase(); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -273,7 +273,7 @@ public async Task Should_return_booking_list_when_admin_search_by_venue_ids() { SetupTestCase(); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -293,7 +293,7 @@ public async Task Should_return_booking_list_when_admin_search_by_last_name() { SetupTestCase(); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -316,7 +316,7 @@ public async Task Should_return_booking_list_when_admin_search_by_case_types() { SetupTestCase(); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -339,7 +339,7 @@ public async Task Should_return_bookings_list_when_admin_search_by_start_date() var startDate = new DateTime(2022, 3, 25); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -364,7 +364,7 @@ public async Task Should_return_bookings_list_when_admin_search_by_end_date() var endDate = new DateTime(2022, 3, 25); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -389,7 +389,7 @@ public async Task Should_return_bookings_list_when_admin_search_by_start_and_end var startDate = new DateTime(2022, 3, 24); var endDate = new DateTime(2022, 3, 25); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -416,7 +416,7 @@ public async Task Should_return_bad_request_when_admin_search_with_start_date_af var startDate = new DateTime(2022, 3, 25); var endDate = new DateTime(2022, 3, 24); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { @@ -438,7 +438,7 @@ public async Task Should_return_booking_list_when_admin_search_by_multiple_crite { SetupTestCase(); - _bookingsApiClient.Setup(s => s.GetCaseTypesAsync()).ReturnsAsync(default(List)); + _bookingsApiClient.Setup(s => s.GetCaseTypesAsync(true)).ReturnsAsync(default(List)); var request = new BookingSearchRequest { diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/FeatureFlagControllerTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/FeatureFlagControllerTests.cs index b7ffa160f..da08c54af 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/FeatureFlagControllerTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/FeatureFlagControllerTests.cs @@ -1,7 +1,7 @@ using AdminWebsite.Controllers; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Configuration; +using BookingsApi.Contract.V1.Configuration; using FluentAssertions; using Moq; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HealthTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HealthTests.cs index 71a0e1731..3c0dfd3c0 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HealthTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HealthTests.cs @@ -77,7 +77,7 @@ public async Task Should_return_internal_server_error_result_when_bookings_api_n var exception = new AggregateException("kinly api error"); _bookingsApiClientMock - .Setup(x => x.GetCaseTypesAsync()) + .Setup(x => x.GetCaseTypesAsync(It.IsAny())) .ThrowsAsync(exception); var response = await GetResponseFromHealthCheck(HttpStatusCode.InternalServerError); @@ -91,7 +91,7 @@ public async Task Should_return_internal_server_error_result_when_non_booking_ap var exception = new UriFormatException("Test format is invalid"); _bookingsApiClientMock - .Setup(x => x.GetCaseTypesAsync()) + .Setup(x => x.GetCaseTypesAsync(It.IsAny())) .ThrowsAsync(exception); var response = await GetResponseFromHealthCheck(HttpStatusCode.InternalServerError); @@ -105,7 +105,7 @@ public async Task Should_return_booking_api_exception_when_booking_api_not_found var exception = new BookingsApiException("Bookings api error", 404, "response", null, new Exception()); _bookingsApiClientMock - .Setup(x => x.GetCaseTypesAsync()) + .Setup(x => x.GetCaseTypesAsync(It.IsAny())) .ThrowsAsync(exception); var response = await GetResponseFromHealthCheck(); diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/BookNewHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/BookNewHearingTests.cs index fee00cefe..d79a4fff1 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/BookNewHearingTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/BookNewHearingTests.cs @@ -11,18 +11,17 @@ using System.Threading.Tasks; using AdminWebsite.Configuration; using AdminWebsite.Contracts.Requests; +using AdminWebsite.Contracts.Responses; using AdminWebsite.Security; -using AdminWebsite.Services.Models; using AdminWebsite.UnitTests.Helper; using BookingsApi.Client; -using BookingsApi.Contract.Requests; using UserApi.Client; using UserApi.Contract.Requests; using UserApi.Contract.Responses; using Autofac.Extras.Moq; -using BookingsApi.Contract.Responses; using VideoApi.Contract.Responses; -using BookingsApi.Contract.Enums; +using BookingsApi.Contract.V1.Enums; +using V1 = BookingsApi.Contract.V1.Requests; namespace AdminWebsite.UnitTests.Controllers.HearingsController { @@ -74,7 +73,7 @@ public async Task Should_book_hearing_for_single_day() .WithParticipant("Judicial Office Holder", "fname4.lname4@hmcts.net") .WithParticipant("Staff Member","staff.member@hmcts.net") .WithParticipant("Judge", "judge.fudge@hmcts.net"); - _mocker.Mock().Setup(x => x.BookNewHearingAsync(bookingDetails)) + _mocker.Mock().Setup(x => x.BookNewHearingAsync(It.IsAny())) .ReturnsAsync(hearingDetailsResponse); @@ -87,15 +86,15 @@ public async Task Should_book_hearing_for_single_day() result.Result.Should().BeOfType(); var createdObjectResult = (CreatedResult) result.Result; createdObjectResult.StatusCode.Should().Be(201); - createdObjectResult.Value.Should().Be(hearingDetailsResponse); + createdObjectResult.Value.Should().BeEquivalentTo(hearingDetailsResponse); bookingDetails.Participants.Any(x => string.IsNullOrWhiteSpace(x.Username)).Should().BeFalse(); bookingDetails.CreatedBy.Should().Be(_expectedUserIdentityName); - _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); + _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); - _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.Is(y => y == bookingDetails)), Times.Once); + _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.IsAny()), Times.Once); } [Test] @@ -117,7 +116,7 @@ public async Task Should_book_hearing_without_judge() .WithParticipant("Judicial Office Holder", "fname4.lname4@hmcts.net") .WithParticipant("Staff Member", "staff.member@hmcts.net"); - _mocker.Mock().Setup(x => x.BookNewHearingAsync(bookingDetails)) + _mocker.Mock().Setup(x => x.BookNewHearingAsync(It.IsAny())) .ReturnsAsync(hearingDetailsResponse); _mocker.Mock().Setup(x => x.GetUserIdentityName()).Returns(_expectedUserIdentityName); @@ -129,15 +128,15 @@ public async Task Should_book_hearing_without_judge() result.Result.Should().BeOfType(); var createdObjectResult = (CreatedResult) result.Result; createdObjectResult.StatusCode.Should().Be(201); - createdObjectResult.Value.Should().Be(hearingDetailsResponse); + createdObjectResult.Value.Should().BeEquivalentTo(hearingDetailsResponse); bookingDetails.Participants.Any(x => string.IsNullOrWhiteSpace(x.Username)).Should().BeFalse(); bookingDetails.CreatedBy.Should().Be(_expectedUserIdentityName); - _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); + _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); - _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.Is(y => y == bookingDetails)), Times.Once); + _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.IsAny()), Times.Once); } [Test] @@ -159,7 +158,7 @@ public async Task Should_book_hearing_for_single_day_without_endpoints() .WithParticipant("Individual", "fname3.lname3@hmcts.net") .WithParticipant("Judicial Office Holder", "fname4.lname4@hmcts.net") .WithParticipant("Judge", "judge.fudge@hmcts.net"); - _mocker.Mock().Setup(x => x.BookNewHearingAsync(bookingDetails)) + _mocker.Mock().Setup(x => x.BookNewHearingAsync(It.IsAny())) .ReturnsAsync(hearingDetailsResponse); _mocker.Mock().Setup(x => x.GetUserIdentityName()).Returns(_expectedUserIdentityName); @@ -171,14 +170,14 @@ public async Task Should_book_hearing_for_single_day_without_endpoints() result.Result.Should().BeOfType(); var createdObjectResult = (CreatedResult) result.Result; createdObjectResult.StatusCode.Should().Be(201); - createdObjectResult.Value.Should().Be(hearingDetailsResponse); + createdObjectResult.Value.Should().BeEquivalentTo(hearingDetailsResponse); bookingDetails.CreatedBy.Should().Be(_expectedUserIdentityName); bookingDetails.Participants.Any(x => string.IsNullOrWhiteSpace(x.Username)).Should().BeFalse(); - _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Never); + _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Never); - _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.Is(y => y == bookingDetails)), Times.Once); + _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.IsAny()), Times.Once); } [Test] @@ -215,7 +214,8 @@ public async Task Should_book_hearing_for_multi_day() .WithParticipant("Judicial Office Holder", "fname4.lname4@hmcts.net") .WithParticipant("Judge", "judge.fudge@hmcts.net"); - _mocker.Mock().Setup(x => x.BookNewHearingAsync(bookingDetails)) + _mocker.Mock() + .Setup(x => x.BookNewHearingAsync(It.IsAny())) .ReturnsAsync(hearingDetailsResponse); // Act @@ -225,14 +225,14 @@ public async Task Should_book_hearing_for_multi_day() result.Result.Should().BeOfType(); var createdObjectResult = (CreatedResult) result.Result; createdObjectResult.StatusCode.Should().Be(201); - createdObjectResult.Value.Should().Be(hearingDetailsResponse); + createdObjectResult.Value.Should().BeEquivalentTo(hearingDetailsResponse); bookingDetails.CreatedBy.Should().Be(_expectedUserIdentityName); bookingDetails.Participants.Any(x => string.IsNullOrWhiteSpace(x.Username)).Should().BeFalse(); - _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); + _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); - _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.Is(y => y == bookingDetails)), Times.Once); + _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.IsAny()), Times.Once); } [Test] @@ -250,7 +250,7 @@ public async Task Should_catch_bookings_api_exceptions_and_return_bad_request_if _mocker.Mock().Setup(x => x.GetAdUserIdForUsername(It.IsAny())).ReturnsAsync(Guid.NewGuid().ToString()); - _mocker.Mock().Setup(x => x.BookNewHearingAsync(bookingDetails)) + _mocker.Mock().Setup(x => x.BookNewHearingAsync(It.IsAny())) .Throws(new BookingsApiException("", (int) HttpStatusCode.BadRequest, expectedExceptionResponse, null, null)); @@ -263,9 +263,9 @@ public async Task Should_catch_bookings_api_exceptions_and_return_bad_request_if badRequestObjectResult.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); badRequestObjectResult.Value.Should().Be(expectedExceptionResponse); - _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); + _mocker.Mock().Verify(x => x.AssignEndpointDefenceAdvocates(It.IsAny>(), It.Is>(x => x.SequenceEqual(bookingDetails.Participants.AsReadOnly()))), Times.Once); - _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.IsAny()), Times.Once); + _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.IsAny()), Times.Once); } [Test] @@ -284,7 +284,7 @@ public async Task Should_handle_failed_booking_request() hearingDetailsResponse.Status = BookingStatus.Failed; - _mocker.Mock().Setup(x => x.BookNewHearingAsync(bookingDetails)) + _mocker.Mock().Setup(x => x.BookNewHearingAsync(It.IsAny())) .ReturnsAsync(hearingDetailsResponse); _mocker.Mock().Setup(x => x.GetUserIdentityName()).Returns(_expectedUserIdentityName); @@ -297,46 +297,46 @@ public async Task Should_handle_failed_booking_request() ((ObjectResult)result.Result).StatusCode.Should().Be(201); - _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.Is(y => y == bookingDetails)), Times.Once); + _mocker.Mock().Verify(x => x.BookNewHearingAsync(It.IsAny()), Times.Once); } - private BookNewHearingRequest InitHearingForTest() + private BookingDetailsRequest InitHearingForTest() { // request with existing person, new user, existing user in AD but not in persons table - var bookNewHearingRequest = new BookNewHearingRequest + var bookNewHearingRequest = new BookingDetailsRequest { - Participants = new List + Participants = new List { - new BookingsApi.Contract.Requests.ParticipantRequest + new () { CaseRoleName = "CaseRole", ContactEmail = "contact1@hmcts.net", HearingRoleName = "HearingRole", DisplayName = "display name1", FirstName = "fname", MiddleNames = "", LastName = "lname1", Username = "username1@hmcts.net", OrganisationName = "", Representee = "", TelephoneNumber = "" }, - new BookingsApi.Contract.Requests.ParticipantRequest + new () { CaseRoleName = "CaseRole", ContactEmail = "contact2@hmcts.net", HearingRoleName = "HearingRole", DisplayName = "display name2", FirstName = "fname2", MiddleNames = "", LastName = "lname2", OrganisationName = "", Representee = "", TelephoneNumber = "", Username = "username2@hmcts.net" }, - new BookingsApi.Contract.Requests.ParticipantRequest + new () { CaseRoleName = "CaseRole", ContactEmail = "contact3@hmcts.net", HearingRoleName = "HearingRole", DisplayName = "display name3", FirstName = "fname3", MiddleNames = "", LastName = "lname3", OrganisationName = "", Representee = "", TelephoneNumber = "", Username = "username3@hmcts.net" }, - new BookingsApi.Contract.Requests.ParticipantRequest + new () { CaseRoleName = "Panel Member", ContactEmail = "contact4@hmcts.net", HearingRoleName = "HearingRole", DisplayName = "display name4", FirstName = "fname4", MiddleNames = "", LastName = "lname4", OrganisationName = "", Representee = "", TelephoneNumber = "", Username = "username4@hmcts.net" }, - new BookingsApi.Contract.Requests.ParticipantRequest + new () { CaseRoleName = "Judge", ContactEmail = "judge@hmcts.net", HearingRoleName = "Judge", DisplayName = "Judge Fudge", @@ -347,9 +347,9 @@ private BookNewHearingRequest InitHearingForTest() }, Endpoints = new List { - new EndpointRequest + new () {DisplayName = "displayname1", DefenceAdvocateContactEmail = "username1@hmcts.net"}, - new EndpointRequest + new () {DisplayName = "displayname2", DefenceAdvocateContactEmail = "fname2.lname2@hmcts.net"}, } }; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/CancelHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/CancelHearingTests.cs index 3c72dea5c..54debd334 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/CancelHearingTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/CancelHearingTests.cs @@ -9,10 +9,10 @@ using System.Collections.Generic; using System.Threading.Tasks; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Requests.Enums; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Requests.Enums; using Autofac.Extras.Moq; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using VideoApi.Contract.Responses; namespace AdminWebsite.UnitTests.Controllers.HearingsController diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/EditHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/EditHearingTests.cs index 0ebde95c5..cf1be05b7 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/EditHearingTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/EditHearingTests.cs @@ -21,18 +21,21 @@ using AdminWebsite.Services; using AdminWebsite.UnitTests.Helper; using BookingsApi.Client; -using BookingsApi.Contract.Configuration; -using BookingsApi.Contract.Enums; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Configuration; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; +using BookingsApi.Contract.V2.Enums; +using BookingsApi.Contract.V2.Responses; using NotificationApi.Client; using NotificationApi.Contract.Requests; using VideoApi.Client; using VideoApi.Contract.Consts; using VideoApi.Contract.Responses; -using CaseResponse = BookingsApi.Contract.Responses.CaseResponse; -using EndpointResponse = BookingsApi.Contract.Responses.EndpointResponse; -using LinkedParticipantResponse = BookingsApi.Contract.Responses.LinkedParticipantResponse; +using BookingStatus = BookingsApi.Contract.V1.Enums.BookingStatus; +using CaseResponse = BookingsApi.Contract.V1.Responses.CaseResponse; +using EndpointResponse = BookingsApi.Contract.V1.Responses.EndpointResponse; +using LinkedParticipantResponse = BookingsApi.Contract.V1.Responses.LinkedParticipantResponse; +using LinkedParticipantType = BookingsApi.Contract.V1.Enums.LinkedParticipantType; namespace AdminWebsite.UnitTests.Controllers.HearingsController { @@ -69,6 +72,7 @@ public class EditHearingTests private Guid _validId; private Mock _videoApiMock; private Mock _featureToggle; + private HearingDetailsResponseV2 _v2HearingDetailsResponse; [SetUp] public void Setup() @@ -102,7 +106,7 @@ public void Setup() _kinlyOptionsMock.Setup((op) => op.Value).Returns(_kinlyConfigurationMock.Object); _participantGroupLogger = new Mock>(); - _hearingsService = new HearingsService(_bookingsApiClient.Object, _participantGroupLogger.Object); + _hearingsService = new HearingsService(_bookingsApiClient.Object, _participantGroupLogger.Object, _featureToggle.Object); _bookingsApiClient.Setup(x => x.GetFeatureFlagAsync(It.Is(f => f == nameof(FeatureFlags.EJudFeature)))).ReturnsAsync(true); @@ -111,7 +115,8 @@ public void Setup() _editHearingRequestValidator.Object, new Mock>().Object, _hearingsService, - _conferencesServiceMock.Object); + _conferencesServiceMock.Object, + _featureToggle.Object); _validId = Guid.NewGuid(); _addNewParticipantRequest = new EditHearingRequest @@ -125,7 +130,7 @@ public void Setup() { new EditParticipantRequest { - ContactEmail = "new@hmcts.net", + ContactEmail = "new@domain.net.", FirstName = "Test_FirstName", LastName = "Test_LastName" } @@ -147,8 +152,8 @@ public void Setup() { Id = Guid.NewGuid(), UserRoleName = "Individual", - ContactEmail = "old@hmcts.net", - Username = "old@hmcts.net" + ContactEmail = "old@domain.net", + Username = "old@domain.net" } }, Cases = cases, @@ -156,11 +161,19 @@ public void Setup() ScheduledDateTime = DateTime.UtcNow.AddHours(3), OtherInformation = "" }; - - var participant1 = Guid.NewGuid(); - var participant2 = Guid.NewGuid(); - var participant3 = Guid.NewGuid(); - _existingHearingWithLinkedParticipants = new HearingDetailsResponse + var participantId1 = Guid.NewGuid(); + var participantId2 = Guid.NewGuid(); + var participantId3 = Guid.NewGuid(); + var participantId4 = Guid.NewGuid(); + var endpointGuid1 = Guid.NewGuid(); + var endpointGuid2 = Guid.NewGuid(); + var endpointGuid3 = Guid.NewGuid(); + var endpointGuid4 = Guid.NewGuid(); + var defenceAdvocate1 = "defenceAdvocate1"; + var defenceAdvocate2 = "defenceAdvocate2"; + var defenceAdvocate3 = "defenceAdvocate3"; + var defenceAdvocate4 = "defenceAdvocate4"; + _existingHearingWithLinkedParticipants = new HearingDetailsResponse() { Id = _validId, GroupId = _validId, @@ -171,52 +184,47 @@ public void Setup() { new ParticipantResponse { - Id = participant1, CaseRoleName = "judge", HearingRoleName = "hearingrole", + Id = participantId1, CaseRoleName = "judge", HearingRoleName = "hearingrole", ContactEmail = "judge.user@email.com", UserRoleName = "Judge", FirstName = "Judge", LinkedParticipants = new List() }, new ParticipantResponse { - Id = participant2, CaseRoleName = "caserole", HearingRoleName = "litigant in person", + Id = participantId2, CaseRoleName = "caserole", HearingRoleName = "litigant in person", ContactEmail = "individual.user@email.com", UserRoleName = "Individual", FirstName = "testuser1", LinkedParticipants = new List { new LinkedParticipantResponse - {Type = LinkedParticipantType.Interpreter, LinkedId = participant3} + {Type = LinkedParticipantType.Interpreter, LinkedId = participantId3} } }, new ParticipantResponse { - Id = participant3, CaseRoleName = "caserole", HearingRoleName = "interpreter", + Id = participantId3, CaseRoleName = "caserole", HearingRoleName = "interpreter", ContactEmail = "interpreter.user@email.com", UserRoleName = "Individual", FirstName = "testuser1", LinkedParticipants = new List { new LinkedParticipantResponse - {Type = LinkedParticipantType.Interpreter, LinkedId = participant2} + {Type = LinkedParticipantType.Interpreter, LinkedId = participantId2} } } }, ScheduledDateTime = DateTime.UtcNow.AddHours(3), OtherInformation = "" }; - - var guid1 = Guid.NewGuid(); - var guid2 = Guid.NewGuid(); - var guid3 = Guid.NewGuid(); - var guid4 = Guid.NewGuid(); _addEndpointToHearingRequest = new EditHearingRequest { Case = new EditCaseRequest { Name = "Case", Number = "123" }, Participants = new List(), Endpoints = new List { - new EditEndpointRequest { Id = null, DisplayName = "New Endpoint", DefenceAdvocateContactEmail = "username@hmcts.net" }, - new EditEndpointRequest { Id = guid1, DisplayName = "data1", DefenceAdvocateContactEmail = guid1.ToString() }, - new EditEndpointRequest { Id = guid2, DisplayName = "data2", DefenceAdvocateContactEmail = guid2.ToString() }, - new EditEndpointRequest { Id = guid3, DisplayName = "data3", DefenceAdvocateContactEmail = guid3.ToString() }, - new EditEndpointRequest { Id = guid4, DisplayName = "data4", DefenceAdvocateContactEmail = guid4.ToString() } + new EditEndpointRequest { Id = null, DisplayName = "New Endpoint", DefenceAdvocateContactEmail = "username@domain.net" }, + new EditEndpointRequest { Id = endpointGuid1, DisplayName = "data1", DefenceAdvocateContactEmail = defenceAdvocate1 }, + new EditEndpointRequest { Id = endpointGuid2, DisplayName = "data2", DefenceAdvocateContactEmail = defenceAdvocate2 }, + new EditEndpointRequest { Id = endpointGuid3, DisplayName = "data3", DefenceAdvocateContactEmail = defenceAdvocate3 }, + new EditEndpointRequest { Id = endpointGuid4, DisplayName = "data4", DefenceAdvocateContactEmail = defenceAdvocate4 } } }; @@ -226,12 +234,12 @@ public void Setup() Participants = new List() { new EditParticipantRequest() { - Id = guid1, + Id = participantId1, CaseRoleName = "judge", HearingRoleName = HearingRoleName.Judge, FirstName = "FirstName", LastName = "LastName", - ContactEmail = "judge@email.com", + ContactEmail = "judge@domain.com", DisplayName = "FirstName LastName", LinkedParticipants = new List(), OrganisationName = "Org1", @@ -243,11 +251,11 @@ public void Setup() }, Endpoints = new List { - new EditEndpointRequest { Id = null, DisplayName = "New Endpoint", DefenceAdvocateContactEmail = "username@hmcts.net" }, - new EditEndpointRequest { Id = guid1, DisplayName = "data1", DefenceAdvocateContactEmail = guid1.ToString() }, - new EditEndpointRequest { Id = guid2, DisplayName = "data2", DefenceAdvocateContactEmail = guid2.ToString() }, - new EditEndpointRequest { Id = guid3, DisplayName = "data3", DefenceAdvocateContactEmail = guid3.ToString() }, - new EditEndpointRequest { Id = guid4, DisplayName = "data4", DefenceAdvocateContactEmail = guid4.ToString() } + new EditEndpointRequest { Id = null, DisplayName = "New Endpoint", DefenceAdvocateContactEmail = "username@domain.net" }, + new EditEndpointRequest { Id = endpointGuid1, DisplayName = "data1", DefenceAdvocateContactEmail = defenceAdvocate1 }, + new EditEndpointRequest { Id = endpointGuid2, DisplayName = "data2", DefenceAdvocateContactEmail = defenceAdvocate2 }, + new EditEndpointRequest { Id = endpointGuid3, DisplayName = "data3", DefenceAdvocateContactEmail = defenceAdvocate3 }, + new EditEndpointRequest { Id = endpointGuid4, DisplayName = "data4", DefenceAdvocateContactEmail = defenceAdvocate4 } } }; @@ -260,10 +268,10 @@ public void Setup() }, Endpoints = new List { - new EditEndpointRequest { Id = guid1, DisplayName = "data1", DefenceAdvocateContactEmail = guid1.ToString() }, - new EditEndpointRequest { Id = guid2, DisplayName = "data2", DefenceAdvocateContactEmail = guid2.ToString() }, - new EditEndpointRequest { Id = guid3, DisplayName = "data3", DefenceAdvocateContactEmail = guid3.ToString() }, - new EditEndpointRequest { Id = guid4, DisplayName = "data4-edit", DefenceAdvocateContactEmail = guid4.ToString() } + new EditEndpointRequest { Id = endpointGuid1, DisplayName = "data1", DefenceAdvocateContactEmail = defenceAdvocate1 }, + new EditEndpointRequest { Id = endpointGuid2, DisplayName = "data2", DefenceAdvocateContactEmail = defenceAdvocate2 }, + new EditEndpointRequest { Id = endpointGuid3, DisplayName = "data3", DefenceAdvocateContactEmail = defenceAdvocate3 }, + new EditEndpointRequest { Id = endpointGuid4, DisplayName = "data4", DefenceAdvocateContactEmail = defenceAdvocate4 } } }; @@ -277,7 +285,7 @@ public void Setup() Participants = new List() { new EditParticipantRequest() { - Id = guid1, + Id = participantId1, CaseRoleName = "judge", HearingRoleName = HearingRoleName.Judge, FirstName = "FirstName", @@ -294,10 +302,10 @@ public void Setup() }, Endpoints = new List { - new EditEndpointRequest { Id = guid1, DisplayName = "data1", DefenceAdvocateContactEmail = guid1.ToString() }, - new EditEndpointRequest { Id = guid2, DisplayName = "data2", DefenceAdvocateContactEmail = guid2.ToString() }, - new EditEndpointRequest { Id = guid3, DisplayName = "data3", DefenceAdvocateContactEmail = guid3.ToString() }, - new EditEndpointRequest { Id = guid4, DisplayName = "data4-edit", DefenceAdvocateContactEmail = guid4.ToString() } + new EditEndpointRequest { Id = endpointGuid1, DisplayName = "data1", DefenceAdvocateContactEmail = defenceAdvocate1 }, + new EditEndpointRequest { Id = endpointGuid2, DisplayName = "data2", DefenceAdvocateContactEmail = defenceAdvocate2 }, + new EditEndpointRequest { Id = endpointGuid3, DisplayName = "data3", DefenceAdvocateContactEmail = defenceAdvocate3 }, + new EditEndpointRequest { Id = endpointGuid4, DisplayName = "data4-edit", DefenceAdvocateContactEmail = defenceAdvocate4 } } }; @@ -310,9 +318,9 @@ public void Setup() }, Endpoints = new List { - new EditEndpointRequest { Id = guid1, DisplayName = "data1", DefenceAdvocateContactEmail = guid1.ToString() }, - new EditEndpointRequest { Id = guid2, DisplayName = "data2", DefenceAdvocateContactEmail = guid2.ToString() }, - new EditEndpointRequest { Id = guid3, DisplayName = "data3", DefenceAdvocateContactEmail = guid3.ToString() } + new EditEndpointRequest { Id = endpointGuid1, DisplayName = "data1", DefenceAdvocateContactEmail = defenceAdvocate1 }, + new EditEndpointRequest { Id = endpointGuid2, DisplayName = "data2", DefenceAdvocateContactEmail = defenceAdvocate2 }, + new EditEndpointRequest { Id = endpointGuid3, DisplayName = "data3", DefenceAdvocateContactEmail = defenceAdvocate3 } } }; @@ -326,7 +334,7 @@ public void Setup() Participants = new List() { new EditParticipantRequest() { - Id = guid1, + Id = participantId1, CaseRoleName = "judge", HearingRoleName = HearingRoleName.Judge, FirstName = "FirstName", @@ -343,22 +351,28 @@ public void Setup() }, Endpoints = new List { - new EditEndpointRequest { Id = guid1, DisplayName = "data1", DefenceAdvocateContactEmail = guid1.ToString() }, - new EditEndpointRequest { Id = guid2, DisplayName = "data2", DefenceAdvocateContactEmail = guid2.ToString() }, - new EditEndpointRequest { Id = guid3, DisplayName = "data3", DefenceAdvocateContactEmail = guid3.ToString() } + new EditEndpointRequest { Id = endpointGuid1, DisplayName = "data1", DefenceAdvocateContactEmail = defenceAdvocate1 }, + new EditEndpointRequest { Id = endpointGuid2, DisplayName = "data2", DefenceAdvocateContactEmail = defenceAdvocate2 }, + new EditEndpointRequest { Id = endpointGuid3, DisplayName = "data3", DefenceAdvocateContactEmail = defenceAdvocate3 } } }; _existingHearingWithEndpointsOriginal = new HearingDetailsResponse { Id = _validId, - Participants = new List(), + Participants = new List + { + new ParticipantResponse { Id = participantId1, ContactEmail = defenceAdvocate1 }, + new ParticipantResponse { Id = participantId2, ContactEmail = defenceAdvocate2 }, + new ParticipantResponse { Id = participantId3, ContactEmail = defenceAdvocate3 }, + new ParticipantResponse { Id = participantId4, ContactEmail = defenceAdvocate4 } + }, Endpoints = new List { - new EndpointResponse { Id = guid1, DisplayName = "data1", Pin = "0000", Sip = "1111111111", DefenceAdvocateId = guid1 }, - new EndpointResponse { Id = guid2, DisplayName = "data2", Pin = "1111", Sip = "2222222222", DefenceAdvocateId = guid2 }, - new EndpointResponse { Id = guid3, DisplayName = "data3", Pin = "2222", Sip = "5544332234", DefenceAdvocateId = guid3 }, - new EndpointResponse { Id = guid4, DisplayName = "data4", Pin = "2222", Sip = "5544332234", DefenceAdvocateId = guid4 } + new EndpointResponse { Id = endpointGuid1, DisplayName = "data1", Pin = "0000", Sip = "1111111111", DefenceAdvocateId = participantId1 }, + new EndpointResponse { Id = endpointGuid2, DisplayName = "data2", Pin = "1111", Sip = "2222222222", DefenceAdvocateId = participantId2 }, + new EndpointResponse { Id = endpointGuid3, DisplayName = "data3", Pin = "2222", Sip = "5544332234", DefenceAdvocateId = participantId3 }, + new EndpointResponse { Id = endpointGuid4, DisplayName = "data4", Pin = "2222", Sip = "5544332234", DefenceAdvocateId = participantId4 } }, Cases = cases, CaseTypeName = "Unit Test", @@ -373,10 +387,14 @@ public void Setup() { new ParticipantResponse { - Id = participant1, CaseRoleName = "judge", HearingRoleName = HearingRoleName.Judge, + Id = Guid.NewGuid(), CaseRoleName = "judge", HearingRoleName = HearingRoleName.Judge, ContactEmail = "judge.user@email.com", UserRoleName = "Judge", FirstName = "Judge", LinkedParticipants = new List() - } + }, + new ParticipantResponse { Id = participantId1, ContactEmail = defenceAdvocate1 }, + new ParticipantResponse { Id = participantId2, ContactEmail = defenceAdvocate2 }, + new ParticipantResponse { Id = participantId3, ContactEmail = defenceAdvocate3 }, + new ParticipantResponse { Id = participantId4, ContactEmail = defenceAdvocate4 } }, Cases = cases, CaseTypeName = "Unit Test", @@ -394,7 +412,7 @@ public void Setup() { new EditParticipantRequest { - ContactEmail = "new@hmcts.net", + ContactEmail = "new@domain.net", FirstName = "Test_FirstName", LastName = "Test_LastName", HearingRoleName = HearingRoleName.Judge @@ -413,7 +431,7 @@ public void Setup() { new EditParticipantRequest { - Id = participant1, CaseRoleName = "judge", HearingRoleName = HearingRoleName.Judge, + Id = participantId1, CaseRoleName = "judge", HearingRoleName = HearingRoleName.Judge, ContactEmail = "judge.user@email.com", FirstName = "Judge" } }, @@ -425,6 +443,56 @@ public void Setup() _editHearingRequestValidator.Setup(x => x.Validate(It.IsAny())) .Returns(new ValidationResult()); + + _v2HearingDetailsResponse = new HearingDetailsResponseV2 + { + Id = _validId, + ScheduledDateTime = new DateTime(), + ServiceId = "ServiceId", + HearingTypeCode = "HearingTypeCode", + Participants = new List + { + new() + { + Id = Guid.NewGuid(), + UserRoleName = "Individual", + ContactEmail = "old@domain.net", + Username = "old@domain.net", + CaseRoleName = "caseRoleName", + } + }, + Cases = new List + { + new() + { + Name = "caseName", + Number = "caseNumber", + IsLeadCase = true, + } + }, + HearingRoomName = "hearingRoomName", + OtherInformation = "otherInformation", + CreatedDate = new DateTime(), + CreatedBy = "createdBy", + UpdatedBy = "updatedBy", + UpdatedDate = new DateTime(), + ConfirmedBy = "confirmedBy", + ConfirmedDate = new DateTime(), + Status = BookingStatusV2.Booked, + AudioRecordingRequired = true, + CancelReason = null, + Endpoints = new List() + { + new() + { + DefenceAdvocateId = Guid.NewGuid(), + DisplayName = "displayName", + Id = Guid.NewGuid(), + Pin = "pin", + Sip = "sip" + } + } + }; } [Test] @@ -520,18 +588,14 @@ public async Task Should_allow_updating_judge_other_information_prior_30_minutes var result = await _controller.EditHearing(_validId, _updateJudgeOtherInformationRequest); ((ObjectResult)result.Result).StatusCode.Should().Be(200); - _bookingsApiClient.Verify( - x => x.UpdateHearingParticipantsAsync(It.IsAny(), It.IsAny()), - Times.Once); + _bookingsApiClient.Verify(x => x.UpdateHearingParticipantsAsync(It.IsAny(), + It.IsAny()), Times.Once); _bookingsApiClient.Verify(x => x.UpdateHearingDetailsAsync(It.IsAny(), - It.Is(u => - !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), - Times.Once); + It.Is(u => !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), Times.Once); } [Test] - public async Task - Should_allow_edit_confirmed_hearing_up_until_30_minutes_before_starting() + public async Task Should_allow_edit_confirmed_hearing_up_until_30_minutes_before_starting() { _updatedExistingParticipantHearingOriginal.ScheduledDateTime = DateTime.UtcNow.AddHours(1); _addNewParticipantRequest.ScheduledDateTime = _updatedExistingParticipantHearingOriginal.ScheduledDateTime; @@ -545,12 +609,11 @@ public async Task ((OkObjectResult)result.Result).StatusCode.Should().Be(200); _bookingsApiClient.Verify( - x => x.UpdateHearingParticipantsAsync(It.IsAny(), It.IsAny()), - Times.Once); + x + => x.UpdateHearingParticipantsAsync(It.IsAny(), + It.IsAny()), Times.Once); _bookingsApiClient.Verify(x => x.UpdateHearingDetailsAsync(It.IsAny(), - It.Is(u => - !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), - Times.Once); + It.Is(u => !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), Times.Once); } [Test] @@ -576,7 +639,7 @@ public async Task Should_allow_only_participant_changes_if_hearing_starts_in_les _addNewParticipantRequest.Participants.Add(new EditParticipantRequest { - ContactEmail = "new2@hmcts.net", + ContactEmail = "new2@domain.net", FirstName = "Test2_FirstName", LastName = "Test2_LastName" }); @@ -677,8 +740,8 @@ public async Task Should_add_panel_members_for_a_hearing(string confirmedBy) _addNewParticipantRequest.Participants = new List {new EditParticipantRequest { HearingRoleName = RoleNames.PanelMember, - ContactEmail = "new.contactactemail@hmcts.net", - DisplayName = "new.displayName@hmcts.net", + ContactEmail = "new.contactactemail@domain.net", + DisplayName = "new.displayName@domain.net", CaseRoleName = RoleNames.PanelMember } }; @@ -726,8 +789,8 @@ public async Task Should_return_updated_hearing() updatedHearing.Participants.Add(new ParticipantResponse { Id = Guid.NewGuid(), - ContactEmail = "new@hmcts.net", - Username = "new@hmcts.net", + ContactEmail = "new@domain.net", + Username = "new@domain.net", UserRoleName = "Individual" }); @@ -736,13 +799,31 @@ public async Task Should_return_updated_hearing() .ReturnsAsync(updatedHearing) .ReturnsAsync(updatedHearing); var result = await _controller.EditHearing(_validId, _addNewParticipantRequest); - var hearing = (HearingDetailsResponse)((OkObjectResult)result.Result).Value; + var hearing = (AdminWebsite.Contracts.Responses.HearingDetailsResponse)((OkObjectResult)result.Result).Value; hearing.Id.Should().Be(_updatedExistingParticipantHearingOriginal.Id); _bookingsApiClient.Verify(x => x.UpdateHearingDetailsAsync(It.IsAny(), It.Is(u => !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), Times.Once); } + + [Test] + public async Task Should_return_updated_hearingV2() + { + _featureToggle.Setup(e => e.ReferenceDataToggle()).Returns(true); + var updatedHearing = _v2HearingDetailsResponse; + _bookingsApiClient.SetupSequence(x => x.GetHearingDetailsByIdV2Async(It.IsAny())) + .ReturnsAsync(updatedHearing) + .ReturnsAsync(updatedHearing) + .ReturnsAsync(updatedHearing); + var result = await _controller.EditHearing(_validId, _addNewParticipantRequest); + var hearing = (AdminWebsite.Contracts.Responses.HearingDetailsResponse)((OkObjectResult)result.Result).Value; + hearing.Id.Should().Be(updatedHearing.Id); + _bookingsApiClient.Verify(x => x.UpdateHearingDetailsAsync(It.IsAny(), + It.Is(u => + !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), + Times.Once); + } [Test] public async Task Should_pass_on_bad_request_from_bookings_api() @@ -771,15 +852,15 @@ public async Task Should_replace_judge_based_on_email() { FirstName = "Existing", LastName = "Judge", - ContactEmail = "existing@hmcts.net", - Username = "existing@hmcts.net", + ContactEmail = "existing@domain.net", + Username = "existing@domain.net", CaseRoleName = "Judge", UserRoleName = "Judge", HearingRoleName = "Judge", Id = existingJudgeId }); - const string newJudgeEmail = "new@hmcts.net"; + const string newJudgeEmail = "new@domain.net"; _addNewParticipantRequest.Participants.Add(new EditParticipantRequest { CaseRoleName = "Judge", @@ -794,8 +875,8 @@ public async Task Should_replace_judge_based_on_email() newPats.Add(new ParticipantResponse { Id = Guid.NewGuid(), - ContactEmail = "new@hmcts.net", - Username = "new@hmcts.net", + ContactEmail = "new@domain.net", + Username = "new@domain.net", UserRoleName = "Individual" }); newPats.Add(new ParticipantResponse @@ -873,12 +954,10 @@ public async Task Should_add_endpoint_if_new_endpoint_is_added_to_endpoint_list_ It.Is(u => !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), Times.Once); - _bookingsApiClient.Verify( - x => x.UpdateDisplayNameForEndpointAsync(It.IsAny(), It.IsAny(), - It.IsAny()), Times.Never); + _bookingsApiClient.Verify(x => x.UpdateDisplayNameForEndpointAsync( + It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); - _bookingsApiClient.Verify( - x => x.RemoveEndPointFromHearingAsync(It.IsAny(), It.IsAny()), Times.Never); + _bookingsApiClient.Verify(x => x.RemoveEndPointFromHearingAsync(It.IsAny(), It.IsAny()), Times.Never); } [Test] @@ -886,10 +965,9 @@ public async Task Should_update_endpoint_if_an_endpoint_is_updates_in_endpoint_l { _bookingsApiClient.Setup(x => x.GetHearingDetailsByIdAsync(It.IsAny())) .ReturnsAsync(_existingHearingWithEndpointsOriginal); - var result = await _controller.EditHearing(_validId, _editEndpointOnHearingRequest); + var result = await _controller.EditHearing(_validId, _editEndpointOnHearingRequestWithJudge); ((OkObjectResult)result.Result).StatusCode.Should().Be(200); - _bookingsApiClient.Verify( - x => x.AddEndPointToHearingAsync(It.IsAny(), It.IsAny()), Times.Never); + _bookingsApiClient.Verify(x => x.AddEndPointToHearingAsync(It.IsAny(), It.IsAny()), Times.Never); _bookingsApiClient.Verify(x => x.UpdateHearingDetailsAsync(It.IsAny(), It.Is(u => !u.Cases.IsNullOrEmpty() && u.QuestionnaireNotRequired == false)), Times.Once); @@ -1215,7 +1293,7 @@ public async Task Should_add_a_new_participant_and_link_to_existing_interpreter_ { ParticipantContactEmail = "interpreter.user@email.com", LinkedParticipantContactEmail = newUserContactEmail, - Type = LinkedParticipantType.Interpreter + Type = AdminWebsite.Contracts.Enums.LinkedParticipantType.Interpreter } } } @@ -1391,7 +1469,7 @@ public async Task Returns_Valid_When_Linked_Contact_Email_Is_Null_When_Adding_A_ new LinkedParticipant { LinkedId = partipant4, - Type = LinkedParticipantType.Interpreter, + Type = AdminWebsite.Contracts.Enums.LinkedParticipantType.Interpreter, LinkedParticipantContactEmail = null } } @@ -1419,7 +1497,7 @@ public async Task { // arrange var hearingId = _updatedExistingParticipantHearingOriginal.Id; - var newJudgeEmailOtherInfo = new OtherInformationDetails { JudgeEmail = "judgenew@hmcts.net" }; + var newJudgeEmailOtherInfo = new OtherInformationDetails { JudgeEmail = "judgene@domain.net" }; var updatedHearing = _updatedExistingParticipantHearingOriginal.Duplicate(); updatedHearing.Participants.Add(new ParticipantResponse { @@ -1484,7 +1562,7 @@ public async Task Should_handle_failed_booking_request_on_retry() var result = await _controller.EditHearing(_validId, request); - var response = ((ObjectResult)result.Result)?.Value as HearingDetailsResponse; + var response = ((ObjectResult)result.Result)?.Value as AdminWebsite.Contracts.Responses.HearingDetailsResponse; response.Status.Should().Be(BookingStatus.Failed); @@ -1509,7 +1587,7 @@ private EditHearingRequest FailedHearingRequest() { new EditParticipantRequest { - ContactEmail = "test@hmcts.net", + ContactEmail = "test@domain.net.", FirstName = "FirstName", LastName = "LastName", HearingRoleName = HearingRoleName.Judge diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetHearingTests.cs index dbffbf84a..7476a88b3 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetHearingTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetHearingTests.cs @@ -8,10 +8,14 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; +using AdminWebsite.Configuration; +using AdminWebsite.Contracts.Responses; using BookingsApi.Client; -using BookingsApi.Contract.Enums; -using BookingsApi.Contract.Responses; using Autofac.Extras.Moq; +using BookingsApi.Contract.V1.Enums; +using BookingsApi.Contract.V2.Enums; +using BookingsApi.Contract.V2.Responses; +using Moq.Language.Flow; using VideoApi.Contract.Responses; namespace AdminWebsite.UnitTests.Controllers.HearingsController @@ -21,13 +25,16 @@ public class GetHearingTests private AutoMock _mocker; private AdminWebsite.Controllers.HearingsController _controller; - private HearingDetailsResponse _vhExistingHearing; + private BookingsApi.Contract.V1.Responses.HearingDetailsResponse _vhExistingHearingV1; private Guid _guid; + private HearingDetailsResponseV2 _vhExistingHearingV2; + private Mock _featureToggle; [SetUp] public void Setup() { _mocker = AutoMock.GetLoose(); + _featureToggle = new Mock(); _mocker.Mock().Setup(cs => cs.GetConferenceDetailsByHearingId(It.IsAny(), false)) .ReturnsAsync(new ConferenceDetailsResponse { @@ -50,11 +57,11 @@ public void Setup() public void Initialise() { _guid = Guid.NewGuid(); - _vhExistingHearing = new HearingDetailsResponse + _vhExistingHearingV1 = new BookingsApi.Contract.V1.Responses.HearingDetailsResponse { - Cases = new List() + Cases = new List() { - new BookingsApi.Contract.Responses.CaseResponse + new BookingsApi.Contract.V1.Responses.CaseResponse {Name = "BBC vs ITV", Number = "TX/12345/2019", IsLeadCase = false} }, CaseTypeName = "Generic", @@ -65,22 +72,22 @@ public void Initialise() HearingVenueName = "Manchester Civil and Family Justice Centre", Id = _guid, OtherInformation = "Any other information about the hearing", - Participants = new List() + Participants = new List() { - new ParticipantResponse() + new () { CaseRoleName = "Judge", ContactEmail = "Judge.Lumb@hmcts.net", DisplayName = "Judge Lumb", FirstName = "Judge", HearingRoleName = "Judge", LastName = "Lumb", MiddleNames = string.Empty, TelephoneNumber = string.Empty, Title = "Judge", Username = "Judge.Lumb@hmcts.net" }, - new ParticipantResponse() + new () { CaseRoleName = "Applicant", ContactEmail = "test.applicant@hmcts.net", DisplayName = "Test Applicant", FirstName = "Test", HearingRoleName = "Litigant in person", LastName = "Applicant", MiddleNames = string.Empty, TelephoneNumber = string.Empty, Title = "Mr", Username = "Test.Applicant@hmcts.net" }, - new ParticipantResponse() + new () { CaseRoleName = "Respondent", ContactEmail = "test.respondent@hmcts.net", DisplayName = "Test Respondent", FirstName = "Test", HearingRoleName = "Representative", @@ -95,8 +102,58 @@ public void Initialise() UpdatedDate = DateTime.UtcNow }; + _vhExistingHearingV2 = new HearingDetailsResponseV2 + { + Id = _guid, + ScheduledDateTime = new DateTime(), + ServiceId = "ServiceId", + HearingTypeCode = "HearingTypeCode", + Participants = new List + { + new() + { + Id = Guid.NewGuid(), + UserRoleName = "Individual", + ContactEmail = "old@domain.net", + Username = "old@domain.net", + CaseRoleName = "caseRoleName", + } + }, + Cases = new List + { + new() + { + Name = "caseName", + Number = "caseNumber", + IsLeadCase = true, + } + }, + HearingRoomName = "hearingRoomName", + OtherInformation = "otherInformation", + CreatedDate = new DateTime(), + CreatedBy = "createdBy", + UpdatedBy = "updatedBy", + UpdatedDate = new DateTime(), + ConfirmedBy = "confirmedBy", + ConfirmedDate = new DateTime(), + Status = BookingStatusV2.Booked, + AudioRecordingRequired = true, + CancelReason = null, + Endpoints = new List() + { + new() + { + DefenceAdvocateId = Guid.NewGuid(), + DisplayName = "displayName", + Id = Guid.NewGuid(), + Pin = "pin", + Sip = "sip" + } + } + }; + _mocker.Mock().Setup(x => x.GetHearingDetailsByIdAsync(It.IsAny())) - .ReturnsAsync(_vhExistingHearing); + .ReturnsAsync(_vhExistingHearingV1); } [Test] @@ -104,7 +161,26 @@ public async Task Should_return_ok_status_if_hearing_id_is_valid() { // Arrange _mocker.Mock().Setup(x => x.GetHearingDetailsByIdAsync(It.IsAny())) - .ReturnsAsync(_vhExistingHearing); + .ReturnsAsync(_vhExistingHearingV1); + + // Act + var result = await _controller.GetHearingById(_guid); + + // Assert + var okRequestResult = (OkObjectResult) result; + okRequestResult.StatusCode.Should().Be(200); + + var hearing = (HearingDetailsResponse) ((OkObjectResult) result).Value; + hearing.Id.Should().Be(_vhExistingHearingV1.Id); + } + + [Test] + public async Task Should_return_ok_status_if_hearing_id_is_validV2() + { + // Arrange + _featureToggle.Setup(e => e.ReferenceDataToggle()).Returns(true); + _mocker.Mock().Setup(x => + x.GetHearingDetailsByIdV2Async(It.IsAny())).ReturnsAsync(_vhExistingHearingV2); // Act var result = await _controller.GetHearingById(_guid); @@ -114,7 +190,7 @@ public async Task Should_return_ok_status_if_hearing_id_is_valid() okRequestResult.StatusCode.Should().Be(200); var hearing = (HearingDetailsResponse) ((OkObjectResult) result).Value; - hearing.Id.Should().Be(_vhExistingHearing.Id); + hearing.Id.Should().Be(_vhExistingHearingV2.Id); } [Test] diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetStatusHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetStatusHearingTests.cs index 7946c065f..d227ab4f3 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetStatusHearingTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/GetStatusHearingTests.cs @@ -7,13 +7,14 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using AdminWebsite.Configuration; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Enums; -using BookingsApi.Contract.Responses; using VideoApi.Client; using VideoApi.Contract.Responses; using AdminWebsite.Security; +using BookingsApi.Contract.V1.Enums; +using BookingsApi.Contract.V1.Responses; using FluentValidation; using Microsoft.Extensions.Logging; @@ -26,6 +27,7 @@ public class GetStatusHearingTests private Mock _conferenceDetailsServiceMock; private Mock _hearingServiceMock; private HearingDetailsResponse _vhExistingHearing; + private Mock _featureFlag; private Guid _guid; private AutoMock _mocker; @@ -38,9 +40,14 @@ public void Setup() _bookingsApiClientMock = new Mock(); _conferenceDetailsServiceMock = new Mock(); _hearingServiceMock = new Mock(); - _controller = new AdminWebsite.Controllers.HearingsController(_bookingsApiClientMock.Object, new Mock().Object, - new Mock>().Object, new Mock>().Object, - _hearingServiceMock.Object, _conferenceDetailsServiceMock.Object); + _featureFlag = new Mock(); + _controller = new AdminWebsite.Controllers.HearingsController(_bookingsApiClientMock.Object, + new Mock().Object, + new Mock>().Object, + new Mock>().Object, + _hearingServiceMock.Object, + _conferenceDetailsServiceMock.Object, + _featureFlag.Object); Initialise(); @@ -51,9 +58,9 @@ public void Initialise() _guid = Guid.NewGuid(); _vhExistingHearing = new HearingDetailsResponse { - Cases = new List() + Cases = new List() { - new BookingsApi.Contract.Responses.CaseResponse + new BookingsApi.Contract.V1.Responses.CaseResponse {Name = "BBC vs ITV", Number = "TX/12345/2019", IsLeadCase = false} }, CaseTypeName = "Generic", diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/PostHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/PostHearingTests.cs index 0cc380db3..46375b9a9 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/PostHearingTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/PostHearingTests.cs @@ -13,19 +13,19 @@ using System.Net; using System.Threading.Tasks; using AdminWebsite.Configuration; +using AdminWebsite.Contracts.Enums; using AdminWebsite.Contracts.Requests; +using AdminWebsite.Contracts.Responses; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Requests.Enums; -using BookingsApi.Contract.Responses; -using LinkedParticipantRequest = BookingsApi.Contract.Requests.LinkedParticipantRequest; -using EndpointResponse = BookingsApi.Contract.Responses.EndpointResponse; -using LinkedParticipantResponse = BookingsApi.Contract.Responses.LinkedParticipantResponse; -using CaseResponse = BookingsApi.Contract.Responses.CaseResponse; -using LinkedParticipantType = BookingsApi.Contract.Enums.LinkedParticipantType; using Autofac.Extras.Moq; +using BookingsApi.Contract.V1.Configuration; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Requests.Enums; using VideoApi.Contract.Responses; -using BookingsApi.Contract.Configuration; +using EndpointRequest = AdminWebsite.Contracts.Requests.EndpointRequest; +using LinkedParticipantRequest = AdminWebsite.Contracts.Requests.LinkedParticipantRequest; +using ParticipantRequest = AdminWebsite.Contracts.Requests.ParticipantRequest; +using V1 = BookingsApi.Contract.V1; namespace AdminWebsite.UnitTests.Controllers.HearingsController { @@ -42,7 +42,7 @@ public void Setup() _mocker.Mock().Setup(cs => cs.GetConferenceDetailsByHearingId(It.IsAny(), false)) .ReturnsAsync(new ConferenceDetailsResponse { - MeetingRoom = new MeetingRoomResponse + MeetingRoom = new () { AdminUri = "AdminUri", JudgeUri = "JudgeUri", @@ -53,11 +53,11 @@ public void Setup() } }); _mocker.Mock().Setup(bs => bs.GetHearingDetailsByIdAsync(It.IsAny())) - .ReturnsAsync(new HearingDetailsResponse + .ReturnsAsync(new V1.Responses.HearingDetailsResponse { - Participants = new List + Participants = new List { - new ParticipantResponse {HearingRoleName = "Judge"} + new () {HearingRoleName = "Judge"} }, CaseTypeName = "Generic" }); @@ -70,18 +70,25 @@ public void Setup() public async Task Should_create_a_hearing_with_endpoints() { - var newHearingRequest = new BookNewHearingRequest + var newHearingRequest = new BookingDetailsRequest { - Participants = new List + Participants = new List { - new BookingsApi.Contract.Requests.ParticipantRequest + new () { - CaseRoleName = "CaseRole", ContactEmail = "contact1@hmcts.net", - HearingRoleName = "HearingRole", DisplayName = "display name1", - FirstName = "fname", MiddleNames = "", LastName = "lname1", Username = "username1@hmcts.net", - OrganisationName = "", Representee = "", TelephoneNumber = "" + CaseRoleName = "CaseRole", + ContactEmail = "contact1@hmcts.net", + HearingRoleName = "HearingRole", + DisplayName = "display name1", + FirstName = "fname", + MiddleNames = "", + LastName = "lname1", + Username = "username1@hmcts.net", + OrganisationName = "", + Representee = "", + TelephoneNumber = "" }, - new BookingsApi.Contract.Requests.ParticipantRequest + new () { CaseRoleName = "CaseRole", ContactEmail = "contact2@hmcts.net", HearingRoleName = "HearingRole", DisplayName = "display name2", @@ -92,10 +99,8 @@ public async Task Should_create_a_hearing_with_endpoints() }, Endpoints = new List { - new EndpointRequest - {DisplayName = "displayname1", DefenceAdvocateContactEmail = "username1@hmcts.net"}, - new EndpointRequest - {DisplayName = "displayname2", DefenceAdvocateContactEmail = "username2@hmcts.net"}, + new () {DisplayName = "displayname1", DefenceAdvocateContactEmail = "username1@hmcts.net"}, + new () {DisplayName = "displayname2", DefenceAdvocateContactEmail = "username2@hmcts.net"}, } }; @@ -109,7 +114,7 @@ public async Task Should_create_a_hearing_with_endpoints() .WithEndPoints(2) .WithParticipant("Representative", "username1@hmcts.net") .WithParticipant("Individual", "username2@hmcts.net"); - _mocker.Mock().Setup(x => x.BookNewHearingAsync(newHearingRequest)) + _mocker.Mock().Setup(x => x.BookNewHearingAsync(It.IsAny())) .ReturnsAsync(hearingDetailsResponse); _mocker.Mock().Setup(x => x.GetAdUserIdForUsername(It.IsAny())).ReturnsAsync(Guid.NewGuid().ToString()); @@ -124,24 +129,22 @@ public async Task Should_create_a_hearing_with_endpoints() public async Task Should_create_a_hearing_with_LinkedParticipants() { // request. - var newHearingRequest = new BookNewHearingRequest() + var newHearingRequest = new BookingDetailsRequest() { - Participants = new List + Participants = new List { - new BookingsApi.Contract.Requests.ParticipantRequest { CaseRoleName = "CaseRole", ContactEmail = "firstName1.lastName1@email.com", + new () { CaseRoleName = "CaseRole", ContactEmail = "firstName1.lastName1@email.com", DisplayName = "firstName1 lastName1", FirstName = "firstName1", HearingRoleName = "Litigant in person", LastName = "lastName1", MiddleNames = "", OrganisationName = "", Representee = "", TelephoneNumber = "1234567890", Title = "Mr.", Username = "firstName1.lastName1@email.net" }, - new BookingsApi.Contract.Requests.ParticipantRequest { CaseRoleName = "CaseRole", ContactEmail = "firstName2.lastName2@email.com", + new () { CaseRoleName = "CaseRole", ContactEmail = "firstName2.lastName2@email.com", DisplayName = "firstName2 lastName2", FirstName = "firstName2", HearingRoleName = "Interpreter", LastName = "lastName2", MiddleNames = "", OrganisationName = "", Representee = "", TelephoneNumber = "1234567890", Title = "Mr.", Username = "firstName2.lastName2@email.net" }, }, LinkedParticipants = new List { - new LinkedParticipantRequest { ParticipantContactEmail = "firstName1.lastName1@email.com", - LinkedParticipantContactEmail = "firstName2.lastName2@email.com", Type = LinkedParticipantType.Interpreter }, - new LinkedParticipantRequest { ParticipantContactEmail = "firstName2.lastName2@email.com", - LinkedParticipantContactEmail = "firstName1.lastName1@email.com", Type = LinkedParticipantType.Interpreter } + new () { ParticipantContactEmail = "firstName1.lastName1@email.com", LinkedParticipantContactEmail = "firstName2.lastName2@email.com", Type = LinkedParticipantType.Interpreter }, + new () { ParticipantContactEmail = "firstName2.lastName2@email.com", LinkedParticipantContactEmail = "firstName1.lastName1@email.com", Type = LinkedParticipantType.Interpreter } } }; @@ -150,21 +153,21 @@ public async Task Should_create_a_hearing_with_LinkedParticipants() BookingDetails = newHearingRequest }; // set response. - var linkedParticipant1 = new List() { new LinkedParticipantResponse() { LinkedId = Guid.NewGuid(), Type = LinkedParticipantType.Interpreter } }; - var participant1 = Builder.CreateNew().With(x => x.Id = Guid.NewGuid()) + var linkedParticipant1 = new List { new () { LinkedId = Guid.NewGuid(), Type = V1.Enums.LinkedParticipantType.Interpreter } }; + var participant1 = Builder.CreateNew().With(x => x.Id = Guid.NewGuid()) .With(x => x.UserRoleName = "Individual").With(x => x.Username = "firstName1.lastName1@email.net") .With(x => x.LinkedParticipants = linkedParticipant1) .Build(); - var linkedParticipant2 = new List() { new LinkedParticipantResponse() { LinkedId = Guid.NewGuid(), Type = LinkedParticipantType.Interpreter } }; - var participant2 = Builder.CreateNew().With(x => x.Id = Guid.NewGuid()) + var linkedParticipant2 = new List() { new () { LinkedId = Guid.NewGuid(), Type = V1.Enums.LinkedParticipantType.Interpreter } }; + var participant2 = Builder.CreateNew().With(x => x.Id = Guid.NewGuid()) .With(x => x.UserRoleName = "Individual").With(x => x.Username = "firstName1.lastName1@email.net") .With(x => x.LinkedParticipants = linkedParticipant2) .Build(); - var hearingDetailsResponse = Builder.CreateNew() - .With(x => x.Cases = Builder.CreateListOfSize(2).Build().ToList()) - .With(x => x.Endpoints = Builder.CreateListOfSize(2).Build().ToList()) - .With(x => x.Participants = new List { participant1, participant2 }).Build(); - _mocker.Mock().Setup(x => x.BookNewHearingAsync(newHearingRequest)) + var hearingDetailsResponse = Builder.CreateNew() + .With(x => x.Cases = Builder.CreateListOfSize(2).Build().ToList()) + .With(x => x.Endpoints = Builder.CreateListOfSize(2).Build().ToList()) + .With(x => x.Participants = new List { participant1, participant2 }).Build(); + _mocker.Mock().Setup(x => x.BookNewHearingAsync(It.IsAny())) .ReturnsAsync(hearingDetailsResponse); _mocker.Mock().Setup(x => x.GetAdUserIdForUsername(It.IsAny())).ReturnsAsync(Guid.NewGuid().ToString()); @@ -177,9 +180,9 @@ public async Task Should_create_a_hearing_with_LinkedParticipants() [Test] public async Task Should_pass_bad_request_from_bookings_api() { - var hearing = new BookNewHearingRequest + var hearing = new BookingDetailsRequest() { - Participants = new List() + Participants = new List() }; var bookingRequest = new BookHearingRequest @@ -197,9 +200,9 @@ public async Task Should_pass_bad_request_from_bookings_api() [Test] public void Should_throw_BookingsApiException() { - var hearing = new BookNewHearingRequest + var hearing = new BookingDetailsRequest() { - Participants = new List() + Participants = new List() }; var bookingRequest = new BookHearingRequest @@ -216,9 +219,9 @@ public void Should_throw_BookingsApiException() [Test] public void Should_throw_Exception() { - var hearing = new BookNewHearingRequest + var hearing = new BookingDetailsRequest { - Participants = new List() + Participants = new List() }; var bookingRequest = new BookHearingRequest @@ -281,7 +284,7 @@ public async Task Should_not_confirm_booking_status_if_no_judge_present() .Setup(x => x.UpdateBookingStatusAsync(It.IsAny(), It.IsAny())) .Verifiable(); //no judge in hearingDetails mock - _mocker.Mock().Setup(x => x.GetHearingDetailsByIdAsync(It.IsAny())).ReturnsAsync(It.IsAny()); + _mocker.Mock().Setup(x => x.GetHearingDetailsByIdAsync(It.IsAny())).ReturnsAsync(It.IsAny()); var response = await _controller.UpdateBookingStatus(Guid.NewGuid(), new UpdateBookingStatusRequest { Status = UpdateBookingStatus.Created }); @@ -319,11 +322,11 @@ public async Task Should_catch_BookingsApiException_by_updating_booking_status_a public async Task Should_clone_hearing() { var request = GetMultiHearingRequest(); - var groupedHearings = new List + var groupedHearings = new List { - new HearingDetailsResponse + new() { - Status = BookingsApi.Contract.Enums.BookingStatus.Booked, + Status = V1.Enums.BookingStatus.Booked, GroupId = Guid.NewGuid(), Id = Guid.NewGuid(), } @@ -351,13 +354,13 @@ public async Task Should_clone_and_confirm_hearing_for_large_booking() { var request = GetMultiHearingRequest(); var hearingGroupId = Guid.NewGuid(); - var groupedHearings = new List(); + var groupedHearings = new List(); var batchSize = 30; for (var i = 1; i <= batchSize; i++) { - groupedHearings.Add(new HearingDetailsResponse + groupedHearings.Add(new V1.Responses.HearingDetailsResponse { - Status = BookingsApi.Contract.Enums.BookingStatus.Booked, + Status = V1.Enums.BookingStatus.Booked, GroupId = hearingGroupId, Id = Guid.NewGuid() }); @@ -417,11 +420,11 @@ public async Task Should_catch_BookingsApiException_by_clone_hearing() public async Task Should_clone_hearings_on_weekends_when_start_or_end_date_are_on_weekends(DateTime startDate, DateTime endDate) { var request = new MultiHearingRequest { StartDate = startDate, EndDate = endDate}; - var groupedHearings = new List + var groupedHearings = new List { new() { - Status = BookingsApi.Contract.Enums.BookingStatus.Booked, + Status = V1.Enums.BookingStatus.Booked, GroupId = Guid.NewGuid(), Id = Guid.NewGuid(), } @@ -453,11 +456,11 @@ public async Task Should_not_clone_hearings_on_weekends_when_start_or_end_date_a var startDate = new DateTime(2022, 12, 15); var endDate = new DateTime(2022, 12, 20); var request = new MultiHearingRequest { StartDate = startDate, EndDate = endDate}; - var groupedHearings = new List + var groupedHearings = new List { new() { - Status = BookingsApi.Contract.Enums.BookingStatus.Booked, + Status = V1.Enums.BookingStatus.Booked, GroupId = Guid.NewGuid(), Id = Guid.NewGuid(), } @@ -491,16 +494,16 @@ public async Task Should_clone_hearings_using_hearing_dates() { var hearingDates = new List { - new DateTime(2023, 1, 6), - new DateTime(2023, 1, 7), - new DateTime(2023, 1, 8) + new (2023, 1, 6), + new (2023, 1, 7), + new (2023, 1, 8) }; var request = new MultiHearingRequest { HearingDates = hearingDates }; - var groupedHearings = new List + var groupedHearings = new List { new() { - Status = BookingsApi.Contract.Enums.BookingStatus.Booked, + Status = V1.Enums.BookingStatus.Booked, GroupId = Guid.NewGuid(), Id = Guid.NewGuid(), } @@ -512,9 +515,9 @@ public async Task Should_clone_hearings_using_hearing_dates() var expectedDates = new List { - new DateTime(2023, 1, 6), - new DateTime(2023, 1, 7), - new DateTime(2023, 1, 8) + new (2023, 1, 6), + new (2023, 1, 7), + new (2023, 1, 8) }; var response = await _controller.CloneHearing(Guid.NewGuid(), request); @@ -540,12 +543,11 @@ private Task> PostNewHearing() return PostWithParticipants(); } - private async Task> PostWithParticipants( - params BookingsApi.Contract.Requests.ParticipantRequest[] participants) + private async Task> PostWithParticipants(params ParticipantRequest[] participants) { - var hearing = new BookNewHearingRequest + var hearing = new BookingDetailsRequest { - Participants = new List(participants) + Participants = new List(participants) }; var bookingRequest = new BookHearingRequest diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/RebookHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/RebookHearingTests.cs new file mode 100644 index 000000000..3fd221bb0 --- /dev/null +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/RebookHearingTests.cs @@ -0,0 +1,67 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using AdminWebsite.UnitTests.Helper; +using Autofac.Extras.Moq; +using BookingsApi.Client; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; + +namespace AdminWebsite.UnitTests.Controllers.HearingsController +{ + public class RebookHearingTests + { + private AutoMock _mocker; + private AdminWebsite.Controllers.HearingsController _controller; + + [SetUp] + public void Setup() + { + _mocker = AutoMock.GetLoose(); + _controller = _mocker.Create(); + } + + [Test] + public async Task Should_return_no_content_when_successful() + { + var hearingId = Guid.NewGuid(); + _mocker.Mock() + .Setup(x => x.RebookHearingAsync(hearingId)) + .Verifiable(); + + var response = await _controller.RebookHearing(hearingId); + + response.Should().BeOfType(); + _mocker.Mock() + .Verify(x => x.RebookHearingAsync(hearingId), + Times.Once()); + + } + + [Test] + public async Task Should_pass_not_found_from_bookings_api() + { + var hearingId = Guid.NewGuid(); + _mocker.Mock().Setup(x => x.RebookHearingAsync(hearingId)) + .Throws(ClientException.ForBookingsAPI(HttpStatusCode.NotFound)); + + var response = await _controller.RebookHearing(hearingId); + + response.Should().BeOfType(); + } + + [Test] + public async Task Should_pass_bad_request_from_bookings_api() + { + var hearingId = Guid.NewGuid(); + _mocker.Mock().Setup(x => x.RebookHearingAsync(hearingId)) + .Throws(ClientException.ForBookingsAPI(HttpStatusCode.BadRequest)); + + var response = await _controller.RebookHearing(hearingId); + + response.Should().BeOfType(); + } + } +} diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/SearchForAudioRecordedHearingsTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/SearchForAudioRecordedHearingsTests.cs index b4aa2c4b8..004018400 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/SearchForAudioRecordedHearingsTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/SearchForAudioRecordedHearingsTests.cs @@ -1,13 +1,9 @@ using AdminWebsite.Models; -using AdminWebsite.Security; using AdminWebsite.Services; using AdminWebsite.UnitTests.Helper; using FluentAssertions; -using FluentValidation; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; using Moq; -using NotificationApi.Client; using NUnit.Framework; using System; using System.Collections.Generic; @@ -15,12 +11,9 @@ using System.Net; using System.Threading.Tasks; using BookingsApi.Client; -using BookingsApi.Contract.Enums; -using BookingsApi.Contract.Responses; -using VideoApi.Client; -using AdminWebsite.Configuration; +using BookingsApi.Contract.V1.Enums; +using BookingsApi.Contract.V1.Responses; using Autofac.Extras.Moq; -using Microsoft.Extensions.Options; using VideoApi.Contract.Responses; namespace AdminWebsite.UnitTests.Controllers.HearingsController @@ -62,9 +55,9 @@ public void InitialiseHearing() _guid = Guid.NewGuid(); _vhExistingHearing = new HearingDetailsResponse { - Cases = new List() + Cases = new List() { - new BookingsApi.Contract.Responses.CaseResponse() + new BookingsApi.Contract.V1.Responses.CaseResponse() {Name = "BBC vs ITV", Number = "TX/12345/2019", IsLeadCase = false} }, CaseTypeName = "Generic", diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/UpdateBookingStatusTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/UpdateBookingStatusTests.cs index 8bab348f7..b850c7221 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/UpdateBookingStatusTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/HearingsController/UpdateBookingStatusTests.cs @@ -10,9 +10,9 @@ using AdminWebsite.UnitTests.Helper; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Requests.Enums; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Requests.Enums; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JudiciaryAccountsControllerTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JudiciaryAccountsControllerTest.cs index 4e5674c36..b629e34af 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JudiciaryAccountsControllerTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JudiciaryAccountsControllerTest.cs @@ -13,8 +13,8 @@ using System.Text.Encodings.Web; using System.Threading.Tasks; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using System.Linq; using UserApi.Contract.Responses; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/AddNewJusticeUserTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/AddNewJusticeUserTests.cs index aa0c9761c..f54c93388 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/AddNewJusticeUserTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/AddNewJusticeUserTests.cs @@ -8,8 +8,8 @@ using AdminWebsite.Testing.Common.Builders; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using FizzWare.NBuilder; using FluentAssertions; using Microsoft.AspNetCore.Http; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/EditJusticeUserTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/EditJusticeUserTests.cs index 3fbb137a4..d872292e4 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/EditJusticeUserTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/EditJusticeUserTests.cs @@ -1,17 +1,13 @@ -using System; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; using AdminWebsite.Controllers; -using AdminWebsite.Models; -using AdminWebsite.Testing.Common.Builders; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using FizzWare.NBuilder; using FluentAssertions; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Moq; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/RestoreJusticeUserTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/RestoreJusticeUserTests.cs index 5748ce85e..dfb3a575e 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/RestoreJusticeUserTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/JusticeUserController/RestoreJusticeUserTests.cs @@ -5,14 +5,12 @@ using AdminWebsite.Controllers; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; using FizzWare.NBuilder; using FluentAssertions; using Microsoft.AspNetCore.Mvc; using Moq; using NUnit.Framework; -using VideoApi.Contract.Responses; namespace AdminWebsite.UnitTests.Controllers.JusticeUserController { diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/DeletePersonWithUsernameTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/DeletePersonWithUsernameTests.cs index 7bc71f495..18fc6ad5b 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/DeletePersonWithUsernameTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/DeletePersonWithUsernameTests.cs @@ -7,7 +7,7 @@ using AdminWebsite.Services; using AdminWebsite.UnitTests.Helper; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FizzWare.NBuilder; using FluentAssertions; using Microsoft.AspNetCore.Mvc; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/GetPersonForUpdateByContactEmailTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/GetPersonForUpdateByContactEmailTests.cs index a75dc8327..48eabeeb7 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/GetPersonForUpdateByContactEmailTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/GetPersonForUpdateByContactEmailTests.cs @@ -5,7 +5,7 @@ using AdminWebsite.Services; using AdminWebsite.UnitTests.Helper; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FizzWare.NBuilder; using FluentAssertions; using Microsoft.AspNetCore.Mvc; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/UpdatePersonDetailsTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/UpdatePersonDetailsTests.cs index 9a86f3da4..beba25eec 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/UpdatePersonDetailsTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonController/UpdatePersonDetailsTests.cs @@ -7,7 +7,7 @@ using AdminWebsite.Services; using AdminWebsite.UnitTests.Helper; using BookingsApi.Client; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; using FluentAssertions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonsControllerTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonsControllerTest.cs index ed6761521..fb1761506 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonsControllerTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/PersonsControllerTest.cs @@ -12,8 +12,8 @@ using AdminWebsite.Contracts.Responses; using AdminWebsite.Services; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using Microsoft.Extensions.Options; namespace AdminWebsite.UnitTests.Controllers diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/ReferenceDataControllerTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/ReferenceDataControllerTests.cs index 0986eccba..5d3626d26 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/ReferenceDataControllerTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/ReferenceDataControllerTests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using AdminWebsite.Configuration; using Autofac.Extras.Moq; using FizzWare.NBuilder; using FluentAssertions; @@ -11,8 +12,10 @@ using AdminWebsite.Models; using AdminWebsite.Security; using BookingsApi.Client; -using BookingsApi.Contract.Responses; -using HearingTypeResponse = BookingsApi.Contract.Responses.HearingTypeResponse; +using BookingsApi.Contract.Interfaces.Response; +using BookingsApi.Contract.V1.Responses; +using BookingsApi.Contract.V2.Responses; +using HearingTypeResponse = BookingsApi.Contract.V1.Responses.HearingTypeResponse; namespace AdminWebsite.UnitTests.Controllers { @@ -20,6 +23,7 @@ public class ReferenceDataControllerTests { private Mock _bookingsApiClientMock; private Mock _userIdentityMock; + private Mock _featureTogglesMock; private ReferenceDataController _controller; private AutoMock _mocker; @@ -29,6 +33,7 @@ public void Setup() _mocker = AutoMock.GetLoose(); _bookingsApiClientMock = _mocker.Mock(); _userIdentityMock = _mocker.Mock(); + _featureTogglesMock = _mocker.Mock(); _controller = _mocker.Create(); } @@ -36,7 +41,7 @@ public void Setup() public void Should_return_a_list_of_venues() { var hearingVenues = Builder.CreateListOfSize(2).Build().ToList(); - _bookingsApiClientMock.Setup(x => x.GetHearingVenuesAsync()).ReturnsAsync(hearingVenues); + _bookingsApiClientMock.Setup(x => x.GetHearingVenuesAsync(true)).ReturnsAsync(hearingVenues); var response = _controller.GetCourts(); var result = (OkObjectResult)response.Result.Result; @@ -47,25 +52,32 @@ public void Should_return_a_list_of_venues() public async Task Should_return_all_hearing_types() { // Arrange + var includeDeleted = true; _userIdentityMock.Setup(x => x.IsAdministratorRole()).Returns(true); _bookingsApiClientMock.Setup(x => - x.GetCaseTypesAsync()) + x.GetCaseTypesAsync(includeDeleted)) .ReturnsAsync(GetCaseTypesList()); // Act - var result = await _controller.GetHearingTypes(); + var result = await _controller.GetHearingTypes(includeDeleted); // Assert var okObjectResult = result.Result.Should().BeAssignableTo().Which; okObjectResult.Value.Should().BeEquivalentTo(GetHearingTypes()); - _bookingsApiClientMock.Verify(x => x.GetCaseTypesAsync(), Times.Once); + _bookingsApiClientMock.Verify(x => x.GetCaseTypesAsync(includeDeleted), Times.Once); } - [Test] - public async Task Should_return_participants_roles() + [TestCase(true)] + [TestCase(false)] + public async Task Should_return_participants_roles(bool refDataFeatureToggle) { - var listTypes = new List { new CaseRoleResponse { Name = "type1" } }; - SetTestCase(listTypes); + _featureTogglesMock.Setup(x => x.ReferenceDataToggle()).Returns(refDataFeatureToggle); + List listTypes; + if(refDataFeatureToggle) + listTypes = new List { new CaseRoleResponseV2 { Name = "type1" } }; + else + listTypes = new List { new CaseRoleResponse { Name = "type1" } }; + SetTestCase(listTypes, refDataFeatureToggle); var response = await _controller.GetParticipantRoles("type1"); response.Should().NotBeNull(); @@ -81,7 +93,7 @@ public async Task Should_return_participants_roles() [Test] public async Task Should_return_empty_list_of_participants_roles() { - var listTypes = new List(); + var listTypes = new List(); SetTestCase(listTypes); var response = await _controller.GetParticipantRoles("type1"); @@ -94,7 +106,7 @@ public async Task Should_return_empty_list_of_participants_roles() [Test] public async Task Should_return_empty_list_of_participants_roles_if_list_types_is_null() { - List listTypes = null; + List listTypes = null; SetTestCase(listTypes); var response = await _controller.GetParticipantRoles("type1"); @@ -104,13 +116,27 @@ public async Task Should_return_empty_list_of_participants_roles_if_list_types_i caseRoles.Count.Should().Be(0); } - private void SetTestCase(List listTypes) + private void SetTestCase(List listTypes, bool refDataToggle = false) { var listHearingRoles = new List { new HearingRoleResponse { Name = "type1", UserRole = "role1"} }; + var listHearingRoles2 = new List { new HearingRoleResponseV2 { Name = "type1", UserRole = "role1"} }; _userIdentityMock.Setup(x => x.GetAdministratorCaseTypes()).Returns(new List { "type1", "type2" }); - _bookingsApiClientMock.Setup(x => x.GetCaseRolesForCaseTypeAsync(It.IsAny())).ReturnsAsync(listTypes); - _bookingsApiClientMock.Setup(x => x.GetHearingRolesForCaseRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(listHearingRoles); + if (refDataToggle) + { + //v2 endpoints + var casetypeV2Response = listTypes?.Select(e => (CaseRoleResponseV2)e).ToList(); + _bookingsApiClientMock.Setup(x => x.GetCaseRolesForCaseServiceAsync(It.IsAny())).ReturnsAsync(casetypeV2Response); + _bookingsApiClientMock.Setup(x => x.GetHearingRolesForCaseRoleV2Async(It.IsAny(), It.IsAny())).ReturnsAsync(listHearingRoles2); + } + else + { + //V1 endpoints + var casetypeV1Response = listTypes?.Select(e => (CaseRoleResponse)e).ToList(); + _bookingsApiClientMock.Setup(x => x.GetCaseRolesForCaseTypeAsync(It.IsAny())).ReturnsAsync(casetypeV1Response); + _bookingsApiClientMock.Setup(x => x.GetHearingRolesForCaseRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(listHearingRoles); + + } } private List GetCaseTypesList() diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/StaffMemberControllerTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/StaffMemberControllerTest.cs index 8eceab32b..ca6a36363 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/StaffMemberControllerTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/StaffMemberControllerTest.cs @@ -1,8 +1,8 @@ using AdminWebsite.Controllers; using AdminWebsite.UnitTests.Helper; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.AspNetCore.Mvc; using Moq; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/SuitabilityControllerTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/SuitabilityControllerTest.cs index c4e1923e6..ceb19ac75 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/SuitabilityControllerTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/SuitabilityControllerTest.cs @@ -10,7 +10,7 @@ using System.Text.Encodings.Web; using System.Threading.Tasks; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.UnitTests.Controllers { diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/UserIdentityControllerTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/UserIdentityControllerTests.cs index 3cc0ab687..146e1d89b 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/UserIdentityControllerTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/UserIdentityControllerTests.cs @@ -6,7 +6,7 @@ using AdminWebsite.Models; using AdminWebsite.Testing.Common.Builders; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/AllocateHearingsToCsoTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/AllocateHearingsToCsoTests.cs index 8f86c1511..cc15c1baf 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/AllocateHearingsToCsoTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/AllocateHearingsToCsoTests.cs @@ -4,8 +4,8 @@ using AdminWebsite.Contracts.Responses; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using FizzWare.NBuilder; using FluentAssertions; using Microsoft.AspNetCore.Mvc; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocatedCsoForHearingTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocatedCsoForHearingTests.cs index ca2ac5e61..5fa306f89 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocatedCsoForHearingTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocatedCsoForHearingTests.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; -using AdminWebsite.Contracts.Responses; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocationHearingsTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocationHearingsTests.cs index 40dfeef38..54e1a4136 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocationHearingsTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetAllocationHearingsTests.cs @@ -4,8 +4,8 @@ using AdminWebsite.Contracts.Responses; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetUnallocatedHearingsTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetUnallocatedHearingsTests.cs index 119d39845..d7c62d7b6 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetUnallocatedHearingsTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkAllocationController/GetUnallocatedHearingsTests.cs @@ -3,12 +3,13 @@ using AdminWebsite.Contracts.Responses; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Moq; using NUnit.Framework; +using HearingDetailsResponse = BookingsApi.Contract.V1.Responses.HearingDetailsResponse; namespace AdminWebsite.UnitTests.Controllers.WorkAllocationController; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkHoursControllerTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkHoursControllerTests.cs index 0a8baac37..d424e8f3d 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkHoursControllerTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Controllers/WorkHoursControllerTests.cs @@ -2,14 +2,14 @@ using AdminWebsite.Controllers; using AdminWebsite.Models; using BookingsApi.Client; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; using Microsoft.AspNetCore.Mvc; using Moq; using NUnit.Framework; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; namespace AdminWebsite.UnitTests.Controllers @@ -30,9 +30,10 @@ public void Setup() _bookingsApiClientMock = new Mock(); _bookingsApiClientMock.Setup(x => x.SaveWorkHoursAsync(It.IsAny>())) .ReturnsAsync(_failedUsernames); - _bookingsApiClientMock.Setup(x => x.SaveNonWorkingHoursAsync(It.IsAny>())) + _bookingsApiClientMock + .Setup(x => x.SaveNonWorkingHoursAsync(It.IsAny>())) .ReturnsAsync(_failedUsernames); - _bookingsApiClientMock.Setup(x => x.DeleteVhoNonAvailabilityHoursAsync(It.IsAny())); + _bookingsApiClientMock.Setup(x => x.DeleteVhoNonAvailabilityHoursAsync(It.IsAny(), It.IsAny())); _controller = new WorkHoursController(_bookingsApiClientMock.Object); } @@ -66,7 +67,7 @@ public async Task UploadNonWorkingHours_should_call_api_and_return_failed_userna _bookingsApiClientMock.Verify(x => x.SaveNonWorkingHoursAsync(request), Times.Once); Assert.AreEqual(_failedUsernames, (response.Value as UploadNonWorkingHoursResponse).FailedUsernames); } - + [Test] public async Task Should_call_GetWorkhours_and_return_Ok() { @@ -82,17 +83,18 @@ public async Task Should_call_GetWorkhours_and_return_Ok() // Assert _bookingsApiClientMock.Verify(x => x.GetVhoWorkAvailabilityHoursAsync(username), Times.Once); response.Value.Should().BeOfType>(); - } - + } + [Test] public async Task Should_call_GetWorkhours_and_return_NotFound() { // Arrange - + var username = "test.user@hmcts.net"; _bookingsApiClientMock .Setup(e => e.GetVhoWorkAvailabilityHoursAsync(username)) - .Throws(new BookingsApiException("error",404,"",new Dictionary>(), new Exception())); + .Throws(new BookingsApiException("error", 404, "", new Dictionary>(), + new Exception())); // Act @@ -100,22 +102,23 @@ public async Task Should_call_GetWorkhours_and_return_NotFound() // Assert _bookingsApiClientMock.Verify(x => x.GetVhoWorkAvailabilityHoursAsync(username), Times.Once); - + response.Should().NotBeNull(); - var objectResult = (NotFoundObjectResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.NotFound); - } - + var objectResult = (NotFoundObjectResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.NotFound); + } + [Test] public async Task Should_call_GetWorkhours_and_return_BadRequest() { // Arrange - + var username = "test.user@hmcts.net"; _bookingsApiClientMock .Setup(e => e.GetVhoWorkAvailabilityHoursAsync(username)) - .Throws(new BookingsApiException("error",400,"",new Dictionary>(), new Exception())); + .Throws(new BookingsApiException("error", 400, "", new Dictionary>(), + new Exception())); // Act @@ -123,12 +126,13 @@ public async Task Should_call_GetWorkhours_and_return_BadRequest() // Assert _bookingsApiClientMock.Verify(x => x.GetVhoWorkAvailabilityHoursAsync(username), Times.Once); - + response.Should().NotBeNull(); - var objectResult = (BadRequestObjectResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); - } + var objectResult = (BadRequestObjectResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.BadRequest); + } + [Test] public async Task Should_call_GetNonAvailability_and_return_Ok() { @@ -144,17 +148,18 @@ public async Task Should_call_GetNonAvailability_and_return_Ok() // Assert _bookingsApiClientMock.Verify(x => x.GetVhoNonAvailabilityHoursAsync(username), Times.Once); response.Value.Should().BeOfType>(); - } - + } + [Test] public async Task Should_call_GetNonAvailability_and_return_NotFound() { // Arrange - + var username = "test.user@hmcts.net"; _bookingsApiClientMock .Setup(e => e.GetVhoNonAvailabilityHoursAsync(username)) - .Throws(new BookingsApiException("error",404,"",new Dictionary>(), new Exception())); + .Throws(new BookingsApiException("error", 404, "", new Dictionary>(), + new Exception())); // Act @@ -162,22 +167,23 @@ public async Task Should_call_GetNonAvailability_and_return_NotFound() // Assert _bookingsApiClientMock.Verify(x => x.GetVhoNonAvailabilityHoursAsync(username), Times.Once); - + response.Should().NotBeNull(); - var objectResult = (NotFoundObjectResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.NotFound); - } - + var objectResult = (NotFoundObjectResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.NotFound); + } + [Test] public async Task Should_call_GetNonAvailability_and_return_BadRequest() { // Arrange - + var username = "test.user@hmcts.net"; _bookingsApiClientMock .Setup(e => e.GetVhoNonAvailabilityHoursAsync(username)) - .Throws(new BookingsApiException("error",400,"",new Dictionary>(), new Exception())); + .Throws(new BookingsApiException("error", 400, "", new Dictionary>(), + new Exception())); // Act @@ -185,70 +191,79 @@ public async Task Should_call_GetNonAvailability_and_return_BadRequest() // Assert _bookingsApiClientMock.Verify(x => x.GetVhoNonAvailabilityHoursAsync(username), Times.Once); - + response.Should().NotBeNull(); - var objectResult = (BadRequestObjectResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); + var objectResult = (BadRequestObjectResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.BadRequest); } - + [Test] public async Task Should_call_DeleteNonAvailabilityWorkHours_and_return_BadRequest() { // Arrange - + var validationProblemDetails = new ValidationProblemDetails(new Dictionary + { + {"username", new[] {"Please provide a valid username"}}, + {"nonavailabilityId", new[] {"Please provide a valid nonavailabilityId"}} + }); + var apiException = new BookingsApiException("BadRequest", + (int) HttpStatusCode.BadRequest, + "Please provide a valid conference Id", null, validationProblemDetails, null); _bookingsApiClientMock - .Setup(e => e.DeleteVhoNonAvailabilityHoursAsync(1)) - .Throws(new BookingsApiException("error",400,"", null, new Exception())); + .Setup(e => e.DeleteVhoNonAvailabilityHoursAsync("badrequest@test.com", 1)) + .ThrowsAsync(apiException); // Act - var response = await _controller.DeleteNonAvailabilityWorkHours(1); + var response = await _controller.DeleteNonAvailabilityWorkHours("badrequest@test.com", 1); // Assert - _bookingsApiClientMock.Verify(x => x.DeleteVhoNonAvailabilityHoursAsync(1), Times.Once); - + _bookingsApiClientMock.Verify(x => x.DeleteVhoNonAvailabilityHoursAsync("badrequest@test.com", 1), + Times.Once); + response.Should().NotBeNull(); - var objectResult = (BadRequestObjectResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); + var objectResult = (BadRequestObjectResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.BadRequest); } - + [Test] public async Task Should_call_DeleteNonAvailabilityWorkHours_and_return_NotFound() { // Arrange - + _bookingsApiClientMock - .Setup(e => e.DeleteVhoNonAvailabilityHoursAsync(1)) - .Throws(new BookingsApiException("error",404,"", null, new Exception())); + .Setup(e => e.DeleteVhoNonAvailabilityHoursAsync("notfound@test.com", 1)) + .Throws(new BookingsApiException("error", 404, "", null, new Exception())); // Act - var response = await _controller.DeleteNonAvailabilityWorkHours(1); + var response = await _controller.DeleteNonAvailabilityWorkHours("notfound@test.com", 1); // Assert - _bookingsApiClientMock.Verify(x => x.DeleteVhoNonAvailabilityHoursAsync(1), Times.Once); - + _bookingsApiClientMock.Verify(x => x.DeleteVhoNonAvailabilityHoursAsync("notfound@test.com", 1), + Times.Once); + response.Should().NotBeNull(); - var objectResult = (NotFoundObjectResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.NotFound); + var objectResult = (NotFoundObjectResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.NotFound); } [Test] public async Task Should_call_DeleteNonAvailabilityWorkHours_and_return_Ok() { // Act - var response = await _controller.DeleteNonAvailabilityWorkHours(1); + var response = await _controller.DeleteNonAvailabilityWorkHours("ok@test.com", 1); // Assert - _bookingsApiClientMock.Verify(x => x.DeleteVhoNonAvailabilityHoursAsync(1), Times.Once); - + _bookingsApiClientMock.Verify(x => x.DeleteVhoNonAvailabilityHoursAsync("ok@test.com", 1), Times.Once); + response.Should().NotBeNull(); - var objectResult = (OkResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.OK); + var objectResult = (OkResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.OK); } [Test] @@ -277,12 +292,13 @@ public async Task UpdateNonAvailabilityWorkHours_should_return_no_content_when_u response.Should().NotBeNull(); - var objectResult = (NoContentResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.NoContent); + var objectResult = (NoContentResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.NoContent); } [Test] - public async Task UpdateNonAvailabilityWorkHours_should_return_bad_request_when_bookings_api_returns_bad_request() + public async Task + UpdateNonAvailabilityWorkHours_should_return_bad_request_when_bookings_api_returns_bad_request() { // Arrange var username = "test.user@hmcts.net"; @@ -300,20 +316,21 @@ public async Task UpdateNonAvailabilityWorkHours_should_return_bad_request_when_ }; _bookingsApiClientMock .Setup(e => e.UpdateVhoNonAvailabilityHoursAsync(username, request)) - .Throws(new BookingsApiException("error",400,"",new Dictionary>(), new Exception())); - + .Throws(new BookingsApiException("error", 400, "", new Dictionary>(), + new Exception())); + // Act var response = await _controller.UpdateNonAvailabilityWorkHours(username, request); - + // Assert _bookingsApiClientMock.Verify(x => x.UpdateVhoNonAvailabilityHoursAsync(username, request), Times.Once); response.Should().NotBeNull(); - var objectResult = (BadRequestObjectResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); + var objectResult = (BadRequestObjectResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.BadRequest); } - + [Test] public async Task UpdateNonAvailabilityWorkHours_should_return_not_found_when_bookings_api_returns_not_found() { @@ -333,7 +350,8 @@ public async Task UpdateNonAvailabilityWorkHours_should_return_not_found_when_bo }; _bookingsApiClientMock .Setup(e => e.UpdateVhoNonAvailabilityHoursAsync(username, request)) - .Throws(new BookingsApiException("error",404,"",new Dictionary>(), new Exception())); + .Throws(new BookingsApiException("error", 404, "", new Dictionary>(), + new Exception())); // Act var response = await _controller.UpdateNonAvailabilityWorkHours(username, request); @@ -343,8 +361,8 @@ public async Task UpdateNonAvailabilityWorkHours_should_return_not_found_when_bo response.Should().NotBeNull(); - var objectResult = (NotFoundResult)response; - objectResult.StatusCode.Should().Be((int)HttpStatusCode.NotFound); + var objectResult = (NotFoundResult) response; + objectResult.StatusCode.Should().Be((int) HttpStatusCode.NotFound); } } } \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite.UnitTests/Extensions/HearingDetailsResponseExtensionsTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Extensions/HearingDetailsResponseExtensionsTests.cs index 456974af5..04598e889 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Extensions/HearingDetailsResponseExtensionsTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Extensions/HearingDetailsResponseExtensionsTests.cs @@ -1,11 +1,11 @@ using AdminWebsite.Extensions; using AdminWebsite.Models; -using BookingsApi.Contract.Responses; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using System; using System.Collections.Generic; +using AdminWebsite.Contracts.Responses; using VideoApi.Contract.Enums; namespace AdminWebsite.UnitTests.Extensions diff --git a/AdminWebsite/AdminWebsite.UnitTests/Helper/HearingResponseBuilder.cs b/AdminWebsite/AdminWebsite.UnitTests/Helper/HearingResponseBuilder.cs index 116884db1..24d8fb957 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Helper/HearingResponseBuilder.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Helper/HearingResponseBuilder.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FizzWare.NBuilder; namespace AdminWebsite.UnitTests.Helper diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/AllocationHearingsResponseMapperTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/AllocationHearingsResponseMapperTests.cs index 88ccde3b9..87493bfc4 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/AllocationHearingsResponseMapperTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/AllocationHearingsResponseMapperTests.cs @@ -1,6 +1,6 @@ using System; using AdminWebsite.Mappers; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/BookingsHearingResponseMapperTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/BookingsHearingResponseMapperTests.cs new file mode 100644 index 000000000..a0b996e64 --- /dev/null +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/BookingsHearingResponseMapperTests.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using AdminWebsite.Mappers; +using BookingsApi.Contract.V1.Responses; +using FluentAssertions; +using NUnit.Framework; + +namespace AdminWebsite.UnitTests.Mappers; + +public class BookingsHearingResponseMapperTests +{ + [Test] + public void Should_map_all_properties_for_BookingsResponse_V1() + { + var source = new BookingsResponse + { + Limit = 1, + NextCursor = "nextCursor", + NextPageUrl = "nextPageUrl", + PrevPageUrl = "prevPageUrl", + Hearings = new List + { + new () + { + ScheduledDate = new DateTime(), + Hearings = new List + { + new () + { + HearingId = Guid.NewGuid(), + HearingNumber = "hearingNumber", + HearingName = "hearingName", + ScheduledDateTime = new DateTime(), + ScheduledDuration = 1, + CaseTypeName = "caseTypeName", + HearingTypeName = "hearingTypeName", + CourtRoom = "courtRoom", + CourtAddress = "courtAddress", + JudgeName = "judgeName", + CreatedBy = "createdBy", + CreatedDate = new DateTime(), + LastEditBy = "lastEditBy", + LastEditDate = new DateTime(), + ConfirmedBy = "confirmedBy", + ConfirmedDate = new DateTime(), + Status = BookingsApi.Contract.V1.Enums.BookingStatus.Created, + QuestionnaireNotRequired = true, + AudioRecordingRequired = true, + CancelReason = "cancelReason", + GroupId = Guid.NewGuid(), + CourtRoomAccount = "courtRoomAccount", + AllocatedTo = "allocatedTo" + } + } + } + } + }; + var result = source.Map(); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(source); + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/EditEndpointRequestMapperTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/EditEndpointRequestMapperTest.cs index ca2fc43dc..da67c174d 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/EditEndpointRequestMapperTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/EditEndpointRequestMapperTest.cs @@ -1,6 +1,6 @@ using System; +using AdminWebsite.Contracts.Responses; using AdminWebsite.Mappers; -using BookingsApi.Contract.Responses; using FluentAssertions; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingUpdateRequestMapperTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingUpdateRequestMapperTest.cs index 0273de9b7..621b509dc 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingUpdateRequestMapperTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingUpdateRequestMapperTest.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; +using AdminWebsite.Contracts.Enums; using AdminWebsite.Mappers; using AdminWebsite.Models; -using BookingsApi.Contract.Enums; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; using FluentAssertions; using NUnit.Framework; @@ -46,28 +46,5 @@ public void Should_map_properties_for_update_hearing_request() result.QuestionnaireNotRequired.Should().Be(_newParticipantRequest.QuestionnaireNotRequired); result.AudioRecordingRequired.Should().Be(_newParticipantRequest.AudioRecordingRequired); } - - [Test] - public void Should_map_property_AudioRecordingRequired_with_true_value_for_when_linkedParticipant_is_interpreter() - { - _newParticipantRequest.Participants = new List - { - new EditParticipantRequest - { - LinkedParticipants = new List - { - new LinkedParticipant - { - Id = Guid.NewGuid(), - LinkedId = Guid.NewGuid(), - ParticipantId = Guid.NewGuid(), - Type = LinkedParticipantType.Interpreter - } - } - } - }; - var result = HearingUpdateRequestMapper.MapTo(_newParticipantRequest, _username); - result.AudioRecordingRequired.Should().BeTrue(); - } } } diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingsForAudioFileSearchMapperTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingsForAudioFileSearchMapperTest.cs index fb2d77080..628c025f6 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingsForAudioFileSearchMapperTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/HearingsForAudioFileSearchMapperTest.cs @@ -1,6 +1,6 @@ using System; using AdminWebsite.Mappers; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/JudgeResponseMapperTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/JudgeResponseMapperTest.cs index 54194381c..bec410ad6 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/JudgeResponseMapperTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/JudgeResponseMapperTest.cs @@ -1,5 +1,5 @@ using AdminWebsite.Mappers; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/UnallocatedHearingsForVHOMapperTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/UnallocatedHearingsForVHOMapperTests.cs index 32bd9e9df..6db46995c 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/UnallocatedHearingsForVHOMapperTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/UnallocatedHearingsForVHOMapperTests.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using AdminWebsite.Mappers; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/UpdateParticipantRequestMapperTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/UpdateParticipantRequestMapperTest.cs index 1abd75a7d..2fb9e6018 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/UpdateParticipantRequestMapperTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/UpdateParticipantRequestMapperTest.cs @@ -1,6 +1,6 @@ using System; using AdminWebsite.Mappers; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using NUnit.Framework; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Mappers/UserResponseMapperTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Mappers/UserResponseMapperTest.cs index c1d44e191..f3bef66d2 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Mappers/UserResponseMapperTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Mappers/UserResponseMapperTest.cs @@ -1,6 +1,4 @@ -using System; -using AdminWebsite.Mappers; -using BookingsApi.Contract.Responses; +using AdminWebsite.Mappers; using FluentAssertions; using NUnit.Framework; using UserApi.Contract.Responses; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Security/UserServiceExceptionTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Security/UserServiceExceptionTest.cs index 0470d8a59..53dae6f7b 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Security/UserServiceExceptionTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Security/UserServiceExceptionTest.cs @@ -2,7 +2,7 @@ using NUnit.Framework; using System; using System.Runtime.Serialization; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.UnitTests.Security { diff --git a/AdminWebsite/AdminWebsite.UnitTests/Services/AppRoleServiceTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Services/AppRoleServiceTests.cs index d8944d44c..87458967c 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Services/AppRoleServiceTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Services/AppRoleServiceTests.cs @@ -8,8 +8,8 @@ using Autofac; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Requests.Enums; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests.Enums; +using BookingsApi.Contract.V1.Responses; using FluentAssertions; using Microsoft.Extensions.Caching.Memory; using Moq; diff --git a/AdminWebsite/AdminWebsite.UnitTests/Services/HearingServiceTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Services/HearingServiceTests.cs index aac1c347e..1dc1faa7d 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Services/HearingServiceTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Services/HearingServiceTests.cs @@ -9,18 +9,18 @@ using AdminWebsite.Services; using Autofac.Extras.Moq; using BookingsApi.Client; -using BookingsApi.Contract.Configuration; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Requests.Enums; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Configuration; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Requests.Enums; +using BookingsApi.Contract.V1.Responses; using FizzWare.NBuilder; using FluentAssertions; using Microsoft.Extensions.Options; using Moq; using NUnit.Framework; using VideoApi.Contract.Responses; -using CaseResponse = BookingsApi.Contract.Responses.CaseResponse; -using EndpointResponse = BookingsApi.Contract.Responses.EndpointResponse; +using CaseResponse = BookingsApi.Contract.V1.Responses.CaseResponse; +using EndpointResponse = BookingsApi.Contract.V1.Responses.EndpointResponse; namespace AdminWebsite.UnitTests.Services { @@ -128,9 +128,7 @@ public void Should_return_false_if_HearingRoomName_is_not_changed() { _editHearingRequest.HearingRoomName = "Updated HearingRoomName"; _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] @@ -138,20 +136,15 @@ public void Should_return_false_if_HearingVenueName_is_changed() { _editHearingRequest.HearingRoomName = "Updated HearingVenueName"; _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_false_if_OtherInformation_is_changed() { _editHearingRequest.OtherInformation = "Updated OtherInformation"; - _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] @@ -160,9 +153,7 @@ public void Should_return_false_if_ScheduledDuration_is_changed() _editHearingRequest.ScheduledDuration = _updatedExistingParticipantHearingOriginal.ScheduledDuration + 1; _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] @@ -172,8 +163,7 @@ public void Should_return_false_when_QuestionnaireNotRequired_is_changed() !_updatedExistingParticipantHearingOriginal.QuestionnaireNotRequired; _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] @@ -187,16 +177,14 @@ public void Should_return_true_when_endpoint_count_is_changed() }); _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_true_when_endpoint_displayName_is_changed() { _editHearingRequest.Endpoints.First().DisplayName = "test1"; - Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] @@ -210,32 +198,28 @@ public void Should_return_true_when_endpoint_removed() }); _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_true_when_endpoint_defenceAdvocateUsername_is_changed() { _updatedExistingParticipantHearingOriginal.Endpoints.First().DefenceAdvocateId = Guid.NewGuid(); - Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.True(_service.HasEndpointsBeenChanged(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_false_when_participant_removed() { _updatedExistingParticipantHearingOriginal.Participants.Add(new ParticipantResponse { Id = Guid.NewGuid() }); - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_true_when_participant_added() { _editHearingRequest.Participants.Add(new EditParticipantRequest { Id = Guid.NewGuid() }); - Assert.True(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.True(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] @@ -282,43 +266,35 @@ public void Should_have_one_added_participant() public void Should_return_false_if_participant_displayName_changed() { _editHearingRequest.Participants.First().DisplayName = "DisplayName changed"; - - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_false_if_participant_lastName_changed() { _editHearingRequest.Participants.First().LastName = "LastName changed"; - - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_throws_InvalidOperationException() { _updatedExistingParticipantHearingOriginal.Cases = new List(); - Assert.Throws(() => _service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.Throws(() => _service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_false_if_case_name_is_different() { _editHearingRequest.Case.Name = "Updated Case Name"; - - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public void Should_return_false_if_case_number_is_different() { _editHearingRequest.Case.Number = "Updated Number"; - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] @@ -326,15 +302,14 @@ public void Should_return_false_if_ScheduledDateTime_is_different() { _editHearingRequest.ScheduledDateTime = DateTime.Now; - Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, - _updatedExistingParticipantHearingOriginal)); + Assert.False(_service.IsAddingParticipantOnly(_editHearingRequest, _updatedExistingParticipantHearingOriginal.Map())); } [Test] public async Task Should_process_participants() { var existingParticipants = new List(); - var newParticipants = new List(); + var newParticipants = new List(); var removedParticipantIds = new List(); var linkedParticipants = new List(); @@ -367,7 +342,7 @@ public async Task Should_process_new_joh_participant_EJudFeature_Is_ON(string he var removedParticipantIds = new List(); // Act - var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing); + var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing.Map()); // Assert newParticipant.Should().NotBeNull(); @@ -390,7 +365,7 @@ public async Task Should_process_new_joh_participant_EJudFeature_Is_OFF(string h .Setup(x => x.GetFeatureFlagAsync(It.Is(f => f == nameof(FeatureFlags.EJudFeature)))).ReturnsAsync(false); // Act - var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing); + var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing.Map()); // Assert newParticipant.Should().NotBeNull(); @@ -412,7 +387,7 @@ public async Task Should_process_new_judge_participant_EJudFeature_Is_OFF() .Setup(x => x.GetFeatureFlagAsync(It.Is(f => f == nameof(FeatureFlags.EJudFeature)))).ReturnsAsync(false); // Act - var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing); + var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing.Map()); // Assert newParticipant.Should().NotBeNull(); @@ -440,7 +415,7 @@ public async Task Should_NOT_process_new_joh_participant_when_participant_is_in_ var removedParticipantIds = new List(); // Act - var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing); + var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing.Map()); // Assert newParticipant.Should().BeNull(); @@ -470,7 +445,7 @@ public async Task Should_process_new_joh_participant_when_participant_is_in_list }; // Act - var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing); + var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing.Map()); // Assert newParticipant.Should().NotBeNull(); @@ -491,7 +466,7 @@ public async Task Should_process_non_joh_participant() var removedParticipantIds = new List(); // Act - var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing); + var newParticipant = await _service.ProcessNewParticipant(_hearing.Id, participant, removedParticipantIds, _hearing.Map()); // Assert newParticipant.Should().NotBeNull(); @@ -515,7 +490,7 @@ public void IsUpdatingJudge_Should_return_correct_assertion(bool shouldUpdateJud .First(x => x.UserRoleName == "Judge") .ContactEmail = "Different.Judge@court.com"; //Act - var response = _service.IsUpdatingJudge(editHearing, hearing); + var response = _service.IsUpdatingJudge(editHearing, hearing.Map()); //Assert response.Should().Be(shouldUpdateJudge); } @@ -537,7 +512,7 @@ public void IsUpdatingJudge_should_be_correct_when_comparing_optional_contact_de if(shouldUpdateJudge) hearing.OtherInformation = "JudgePhone|loremIpsum2"; //Act - var response = _service.IsUpdatingJudge(editHearing, hearing); + var response = _service.IsUpdatingJudge(editHearing, hearing.Map()); //Assert response.Should().Be(shouldUpdateJudge); } @@ -557,7 +532,7 @@ public void IsUpdatingJudge_should_be_false_when_judge_isempty() hearing.Participants.Remove(hearing.Participants.Single(x => x.HearingRoleName == "Judge")); hearing.OtherInformation = "JudgePhone|loremIpsum"; //Act - var response = _service.IsUpdatingJudge(editHearing, hearing); + var response = _service.IsUpdatingJudge(editHearing, hearing.Map()); //Assert response.Should().Be(false); } @@ -577,7 +552,7 @@ public void IsUpdatingJudge_should_be_false_when_other_info_empty() hearing.Participants.Remove(hearing.Participants.Single(x => x.HearingRoleName == "Judge")); hearing.OtherInformation = string.Empty; //Act - var response = _service.IsUpdatingJudge(editHearing, hearing); + var response = _service.IsUpdatingJudge(editHearing, hearing.Map()); //Assert response.Should().Be(false); } diff --git a/AdminWebsite/AdminWebsite.UnitTests/Services/UserAccountServiceTests.cs b/AdminWebsite/AdminWebsite.UnitTests/Services/UserAccountServiceTests.cs index aceda9adc..df09b9459 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Services/UserAccountServiceTests.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Services/UserAccountServiceTests.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; using AdminWebsite.UnitTests.Helper; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using Microsoft.Extensions.Logging; using NotificationApi.Client; using NotificationApi.Contract; diff --git a/AdminWebsite/AdminWebsite.UnitTests/ParticipantRequest.cs b/AdminWebsite/AdminWebsite.UnitTests/TestParticipantRequest.cs similarity index 83% rename from AdminWebsite/AdminWebsite.UnitTests/ParticipantRequest.cs rename to AdminWebsite/AdminWebsite.UnitTests/TestParticipantRequest.cs index 1899e3394..2024a1f2c 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/ParticipantRequest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/TestParticipantRequest.cs @@ -1,8 +1,8 @@ namespace AdminWebsite.UnitTests { - internal class ParticipantRequest + internal class TestParticipantRequest { - public ParticipantRequest() + public TestParticipantRequest() { } diff --git a/AdminWebsite/AdminWebsite.UnitTests/Validators/CaseRequestValidationTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Validators/CaseRequestValidationTest.cs index 3859a98f5..3a9b6a5e5 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Validators/CaseRequestValidationTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Validators/CaseRequestValidationTest.cs @@ -2,7 +2,7 @@ using NUnit.Framework; using System; using System.Linq; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.UnitTests.Validators { diff --git a/AdminWebsite/AdminWebsite.UnitTests/Validators/ParticipantRequestValidationTest.cs b/AdminWebsite/AdminWebsite.UnitTests/Validators/ParticipantRequestValidationTest.cs index d6376d9c9..4a1c5afb1 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/Validators/ParticipantRequestValidationTest.cs +++ b/AdminWebsite/AdminWebsite.UnitTests/Validators/ParticipantRequestValidationTest.cs @@ -25,7 +25,7 @@ public void Should_validate_fields_with_length_greater_then_255_as_error() var longString = new String('a', 257); - var testRequest = new BookingsApi.Contract.Requests.ParticipantRequest + var testRequest = new BookingsApi.Contract.V1.Requests.ParticipantRequest { ContactEmail = longString, DisplayName = longString, @@ -45,7 +45,7 @@ public void Should_validate_fields_with_length_greater_then_255_as_error() public void Should_validate_fields_with_length_zero_as_error() { var shortString = ""; - var testRequest = new BookingsApi.Contract.Requests.ParticipantRequest + var testRequest = new BookingsApi.Contract.V1.Requests.ParticipantRequest { ContactEmail = shortString, DisplayName = shortString, @@ -60,7 +60,7 @@ public void Should_validate_fields_with_length_zero_as_error() [Test] public void Should_validate_participant_request() { - var testRequest = new BookingsApi.Contract.Requests.ParticipantRequest + var testRequest = new BookingsApi.Contract.V1.Requests.ParticipantRequest { ContactEmail = "aa@hmcts.net", FirstName = "Adam", diff --git a/AdminWebsite/AdminWebsite.UnitTests/packages.lock.json b/AdminWebsite/AdminWebsite.UnitTests/packages.lock.json index d91df46d0..61d76cf85 100644 --- a/AdminWebsite/AdminWebsite.UnitTests/packages.lock.json +++ b/AdminWebsite/AdminWebsite.UnitTests/packages.lock.json @@ -98,8 +98,8 @@ }, "BookingsApi.Client": { "type": "Transitive", - "resolved": "1.44.6", - "contentHash": "pr59SEWnlnkGyZmilLh+6JiUEZqLXn6iic5NVTEjO22VFs3Qij0RfZ2q+fotW2rk/tVcs0P2WGITt9kulBm5SQ==", + "resolved": "1.46.9", + "contentHash": "/WKAyKGdjSMt6I/1MnkH9+J8nqfmYqbRUtVSAOqvwjbYBpoZ1GZCqPMDoOcgDtNdGzQboo9wt2lQBa8snjhbpw==", "dependencies": { "Microsoft.AspNetCore.Mvc.Core": "2.2.5" } @@ -1938,7 +1938,7 @@ "adminwebsite": { "type": "Project", "dependencies": { - "BookingsApi.Client": "[1.44.6, )", + "BookingsApi.Client": "[1.46.9, )", "FluentValidation.AspNetCore": "[10.4.0, )", "LaunchDarkly.ServerSdk": "[7.0.3, )", "MicroElements.Swashbuckle.FluentValidation": "[5.7.0, )", diff --git a/AdminWebsite/AdminWebsite/AdminWebsite.csproj b/AdminWebsite/AdminWebsite/AdminWebsite.csproj index 937011500..86fb4b3e2 100644 --- a/AdminWebsite/AdminWebsite/AdminWebsite.csproj +++ b/AdminWebsite/AdminWebsite/AdminWebsite.csproj @@ -31,7 +31,7 @@ false - + diff --git a/AdminWebsite/AdminWebsite/Attributes/HearingInputSanitizerAttribute.cs b/AdminWebsite/AdminWebsite/Attributes/HearingInputSanitizerAttribute.cs index ca8c363f6..e692ad898 100644 --- a/AdminWebsite/AdminWebsite/Attributes/HearingInputSanitizerAttribute.cs +++ b/AdminWebsite/AdminWebsite/Attributes/HearingInputSanitizerAttribute.cs @@ -1,7 +1,7 @@ using AdminWebsite.Models; using Microsoft.AspNetCore.Mvc.Filters; using System.Text.RegularExpressions; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.Attributes { diff --git a/AdminWebsite/AdminWebsite/ClientApp/package-lock.json b/AdminWebsite/AdminWebsite/ClientApp/package-lock.json index 26788580c..e038a6445 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/package-lock.json +++ b/AdminWebsite/AdminWebsite/ClientApp/package-lock.json @@ -24,7 +24,7 @@ "@fortawesome/free-regular-svg-icons": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@hmcts/frontend": "^0.0.41-alpha", - "@microsoft/applicationinsights-web": "^2.6.1", + "@microsoft/applicationinsights-web": "^3.0.2", "@ministryofjustice/frontend": "^1.4.0", "@ng-select/ng-select": "^10.0.3", "angular-auth-oidc-client": "^15.0.3", @@ -73,7 +73,7 @@ "nswag": "^13.19.0", "pa11y": "^6.2.3", "prettier": "^2.8.8", - "puppeteer": "^20.6.0", + "puppeteer": "^21.1.0", "run-script-os": "^1.1.6", "sass": "^1.32.12", "typescript": "^4.9.4", @@ -3448,96 +3448,129 @@ "dev": true }, "node_modules/@microsoft/applicationinsights-analytics-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.6.1.tgz", - "integrity": "sha512-wRH67jZTPy6SP54ygAQsFXu5ZnfzGOoMkA6ll1pkhSC4hij7Cvzumr4PYkr2gIPBPxD354sLOjBL/lmOgBTc5g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-3.0.2.tgz", + "integrity": "sha512-vrgEiT6cKC2Yb0Y6rCp9CXjFStlRZLI/IhIiBEGYaUfzoytLxUj6F/AizUDYBuNQfE+CTYe0jNyqf+RJgEMkJQ==", "dependencies": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" + }, + "peerDependencies": { + "tslib": "*" } }, "node_modules/@microsoft/applicationinsights-channel-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.6.1.tgz", - "integrity": "sha512-oatERKW3eAjVNm5ej2NpRvBCCtPtiINIKxLiWVHv2SC2rzGrUnxNWFlUJojRT+u5ZXXsB51Ktw9gx8iHexnDVw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz", + "integrity": "sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw==", "dependencies": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" + }, + "peerDependencies": { + "tslib": "*" } }, "node_modules/@microsoft/applicationinsights-common": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-2.6.1.tgz", - "integrity": "sha512-kV/dI9UwTew3mq+3F3Tkl2dBn2C4+FOOG3S5cS7/SssVsUlvLrWXBrOOxfIJ7+EjQQ6ijcqlDus4Nz7Ms2Kk2Q==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz", + "integrity": "sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg==", "dependencies": { - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" + }, + "peerDependencies": { + "tslib": "*" } }, "node_modules/@microsoft/applicationinsights-core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.6.1.tgz", - "integrity": "sha512-SFnTx48BGkmz6P9GvXFeIZ641vnfrKo0hB74Hp9GR7UE3hqIDuomIBQS17unnh05T5w3PWKlDCGNpiCbJV6kzQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz", + "integrity": "sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ==", "dependencies": { - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" + }, + "peerDependencies": { + "tslib": "*" } }, "node_modules/@microsoft/applicationinsights-dependencies-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.6.1.tgz", - "integrity": "sha512-Y7R6BjzyB6NrkIBTT6FJrr2jKr8MiLxy264b1xUQHjry3Bwu+fsPJ7EETV61dkOEHs6IlWxAtikNCv8f3zQydw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-3.0.2.tgz", + "integrity": "sha512-b/YTonnbghg9DOFsLg4zdbYPafW8fPIzV+nZxfPPpxjA1LGvPhZz/zVx9YYWJg2RBXjojLQoJxLf1ro5eNGVig==", "dependencies": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" + }, + "peerDependencies": { + "tslib": "*" } }, "node_modules/@microsoft/applicationinsights-properties-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.6.1.tgz", - "integrity": "sha512-TQmKp9/j0yMGjUHBatRQ41E4S/1yTkJImh8csZxc4waMQmV9ITkNrDaC3bIPcrw+ASepI3QfP7sry+n7nvYLFw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-3.0.2.tgz", + "integrity": "sha512-PFqicp8q4Tc0hqfPjwfqKo12gEqTk1l4lMyUUIU7ugE1XOuDkZcMPha05KnZWKj+F4zQXJcetcAHoVkyoyCFQw==", "dependencies": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" + }, + "peerDependencies": { + "tslib": "*" } }, "node_modules/@microsoft/applicationinsights-shims": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-1.0.3.tgz", - "integrity": "sha512-+S17aqEkOYpyBpmclhgwcEplwnxSo5AxYBdRg38GBobI1GKPSpZfnLssLzcjJ6XZCS5tqB5xjyTZs6gHj7ZJWQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz", + "integrity": "sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==", + "dependencies": { + "@nevware21/ts-utils": ">= 0.9.4 < 2.x" + } }, "node_modules/@microsoft/applicationinsights-web": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web/-/applicationinsights-web-2.6.1.tgz", - "integrity": "sha512-jKF6hpPq3pzLqLSVxTMh7HU9tr/SPOFJN12pFYpNMU/rAMs/fgZsmFG/oBAzYTZxNilDTFljoblB66J9X+K6RQ==", - "dependencies": { - "@microsoft/applicationinsights-analytics-js": "2.6.1", - "@microsoft/applicationinsights-channel-js": "2.6.1", - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-dependencies-js": "2.6.1", - "@microsoft/applicationinsights-properties-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web/-/applicationinsights-web-3.0.2.tgz", + "integrity": "sha512-pf2zz/3mmGy1RoyaiLZwhHoE2mFZ+AWR3Zf7xPW7HjTG7dEE4BnovNyW3f9Eu6WWkcHUAHmS/ATzqvVlpB3W6A==", + "dependencies": { + "@microsoft/applicationinsights-analytics-js": "3.0.2", + "@microsoft/applicationinsights-channel-js": "3.0.2", + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-dependencies-js": "3.0.2", + "@microsoft/applicationinsights-properties-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" + }, + "peerDependencies": { + "tslib": "*" } }, "node_modules/@microsoft/dynamicproto-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.1.tgz", - "integrity": "sha512-SPY1PlXmg4FbJVItVdhDV+zigajPtSI8oZPrsKBEIzAF4FROuwWIq5C+RAF8VJshBqphcvU8Eoh4DrUEZOB31g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz", + "integrity": "sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg==", "dependencies": { - "findup-sync": "^4.0.0", - "nopt": "^5.0.0", - "pify": "^2.3.0" + "@nevware21/ts-utils": ">= 0.9.4 < 2.x" } }, "node_modules/@ministryofjustice/frontend": { @@ -3555,6 +3588,25 @@ "jquery": "^3.6.0" } }, + "node_modules/@nevware21/ts-async": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.2.6.tgz", + "integrity": "sha512-NCUqEZSbsy7LVtKlUScd/eTst6djkWauLlzoIPVKCOxalEBdO8lrgNRIm4Xy68JNudNN5faqa2WA12X8m0BVhA==", + "dependencies": { + "@nevware21/ts-utils": ">= 0.9.7 < 2.x" + }, + "peerDependencies": { + "typescript": ">=1" + } + }, + "node_modules/@nevware21/ts-utils": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.9.8.tgz", + "integrity": "sha512-kZ8s8hcn9jPVX/M7kSsBYrOGlHjqLahmxrG7QeKTk5paeVwfgKdvVCjj5Acb4UGb/ukU1G34U1Z3eb7bbVanyA==", + "peerDependencies": { + "typescript": ">=1" + } + }, "node_modules/@ng-select/ng-select": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-10.0.3.tgz", @@ -3843,16 +3895,16 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.1.tgz", - "integrity": "sha512-H43VosMzywHCcYcgv0GXXopvwnV21Ud9g2aXbPlQUJj1Xcz9V0wBwHeFz6saFhx/3VKisZfI1GEKEOhQCau7Vw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.7.0.tgz", + "integrity": "sha512-sl7zI0IkbQGak/+IE3VEEZab5SSOlI5F6558WvzWGC1n3+C722rfewC1ZIkcF9dsoGSsxhsONoseVlNQG4wWvQ==", "dev": true, "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", "progress": "2.0.3", - "proxy-agent": "6.2.1", - "tar-fs": "2.1.1", + "proxy-agent": "6.3.0", + "tar-fs": "3.0.4", "unbzip2-stream": "1.4.3", "yargs": "17.7.1" }, @@ -3861,14 +3913,6 @@ }, "engines": { "node": ">=16.3.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, "node_modules/@puppeteer/browsers/node_modules/cliui": { @@ -3885,6 +3929,28 @@ "node": ">=12" } }, + "node_modules/@puppeteer/browsers/node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dev": true, + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/@puppeteer/browsers/node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/@puppeteer/browsers/node_modules/yargs": { "version": "17.7.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", @@ -4000,6 +4066,12 @@ "node": ">= 10" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "node_modules/@types/applicationinsights-js": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/applicationinsights-js/-/applicationinsights-js-1.0.9.tgz", @@ -4852,7 +4924,8 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", @@ -4897,15 +4970,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", @@ -5288,6 +5352,12 @@ "node": ">=4" } }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", + "dev": true + }, "node_modules/babel-loader": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", @@ -5939,12 +6009,12 @@ } }, "node_modules/chromium-bidi": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.11.tgz", - "integrity": "sha512-p03ajLhlQ5gebw3cmbDBFmBc2wnJM5dnXS8Phu6mblGn/KQd76yOVL5VwE0VAisa7oazNfKGTaXlIZ8Q5Bb9OA==", + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.20.tgz", + "integrity": "sha512-ruHgVZFEv00mAQMz1tQjfjdG63jiPWrQPF6HLlX2ucqLqVTJoWngeBEKHaJ6n1swV/HSvgnBNbtTRIlcVyW3Fw==", "dev": true, "dependencies": { - "mitt": "3.0.0" + "mitt": "3.0.1" }, "peerDependencies": { "devtools-protocol": "*" @@ -6439,12 +6509,12 @@ } }, "node_modules/cross-fetch": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", - "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, "dependencies": { - "node-fetch": "^2.6.11" + "node-fetch": "^2.6.12" } }, "node_modules/css-loader": { @@ -6782,15 +6852,14 @@ } }, "node_modules/degenerator": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-4.0.2.tgz", - "integrity": "sha512-HKwIFvZROUMfH3qI3gBpD61BYh7q3c3GXD5UGZzoVNJwVSYgZKvYl1fRMXc9ozoTxl/VZxKJ5v/bA+19tywFiw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, "dependencies": { - "ast-types": "^0.13.2", - "escodegen": "^1.8.1", - "esprima": "^4.0.0", - "vm2": "^3.9.17" + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" }, "engines": { "node": ">= 14" @@ -6829,14 +6898,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/detect-node": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", @@ -6844,9 +6905,9 @@ "dev": true }, "node_modules/devtools-protocol": { - "version": "0.0.1135028", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1135028.tgz", - "integrity": "sha512-jEcNGrh6lOXNRJvZb9RjeevtZGrgugPKSMJZxfyxWQnhlKawMPhMtk/dfC+Z/6xNXExlzTKlY5LzIAK/fRpQIw==", + "version": "0.0.1159816", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1159816.tgz", + "integrity": "sha512-2cZlHxC5IlgkIWe2pSDmCrDiTzbSJWywjbDDnupOImEBcG31CQgBLV8wWE+5t+C4rimcjHsbzy7CBzf9oFjboA==", "dev": true }, "node_modules/di": { @@ -7360,64 +7421,33 @@ } }, "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "dependencies": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "estraverse": "^5.2.0", + "esutils": "^2.0.2" }, "bin": { "escodegen": "bin/escodegen.js", "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">=4.0" + "node": ">=6.0" }, "optionalDependencies": { "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=4.0" } }, "node_modules/escodegen/node_modules/source-map": { @@ -7430,18 +7460,6 @@ "node": ">=0.10.0" } }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint": { "version": "8.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", @@ -8083,17 +8101,6 @@ "node": ">=0.8.x" } }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -8282,6 +8289,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -8454,20 +8467,6 @@ "node": ">=8" } }, - "node_modules/findup-sync": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -8777,34 +8776,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -8995,17 +8966,6 @@ "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", "dev": true }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -9399,11 +9359,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, "node_modules/inquirer": { "version": "8.2.4", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", @@ -9943,14 +9898,6 @@ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", "dev": true }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -9984,7 +9931,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "node_modules/isobject": { "version": "3.0.1", @@ -11107,6 +11055,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, "dependencies": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -11304,9 +11253,9 @@ } }, "node_modules/mitt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", - "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "dev": true }, "node_modules/mkdirp": { @@ -11506,9 +11455,9 @@ "optional": true }, "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dev": true, "dependencies": { "whatwg-url": "^5.0.0" @@ -11633,20 +11582,6 @@ "node": ">=0.4.0" } }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/normalize-package-data": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", @@ -12356,17 +12291,18 @@ } }, "node_modules/pac-proxy-agent": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-6.0.3.tgz", - "integrity": "sha512-5Hr1KgPDoc21Vn3rsXBirwwDnF/iac1jN/zkpsOYruyT+ZgsUhUOgVwq3v9+ukjZd/yGm/0nzO1fDfl7rkGoHQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz", + "integrity": "sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA==", "dev": true, "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", - "pac-resolver": "^6.0.1", + "pac-resolver": "^7.0.0", "socks-proxy-agent": "^8.0.1" }, "engines": { @@ -12399,9 +12335,9 @@ } }, "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz", - "integrity": "sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", + "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -12426,13 +12362,13 @@ } }, "node_modules/pac-resolver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-6.0.1.tgz", - "integrity": "sha512-dg497MhVT7jZegPRuOScQ/z0aV/5WR0gTdRu1md+Irs9J9o+ls5jIuxjo1WfaTG+eQQkxyn5HMGvWK+w7EIBkQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", "dev": true, "dependencies": { - "degenerator": "^4.0.1", - "ip": "^1.1.5", + "degenerator": "^5.0.0", + "ip": "^1.1.8", "netmask": "^2.0.2" }, "engines": { @@ -12536,14 +12472,6 @@ "node": ">= 0.10" } }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -12648,14 +12576,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/piscina": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", @@ -12923,9 +12843,9 @@ } }, "node_modules/proxy-agent": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.2.1.tgz", - "integrity": "sha512-OIbBKlRAT+ycCm6wAYIzMwPejzRtjy8F3QiDX0eKOA3e4pe3U9F/IvzcHP42bmgQxVv97juG+J8/gx+JIeCX/Q==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", + "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -12933,7 +12853,7 @@ "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^6.0.3", + "pac-proxy-agent": "^7.0.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.1" }, @@ -12967,9 +12887,9 @@ } }, "node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz", - "integrity": "sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", + "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -13035,43 +12955,35 @@ } }, "node_modules/puppeteer": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-20.6.0.tgz", - "integrity": "sha512-D/kkEIpDFRqpLOcCoNNdXI+IUcoD1FmdlWteT4FFPOhNLC46urmItMfQDKSwk2NJoO38ncgCQe5XEQ3QHD+piA==", + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.1.0.tgz", + "integrity": "sha512-x0KfxVd7Hsefq8nzH1AAdSnYw5HEKI4QPeexBmx7nO29jDoEKNE+75G8zQ0E57ZOny/vAZZptCFdD3A7PkeESQ==", "dev": true, "hasInstallScript": true, "dependencies": { - "@puppeteer/browsers": "1.4.1", + "@puppeteer/browsers": "1.7.0", "cosmiconfig": "8.2.0", - "puppeteer-core": "20.6.0" + "puppeteer-core": "21.1.0" }, "engines": { "node": ">=16.3.0" } }, "node_modules/puppeteer-core": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.6.0.tgz", - "integrity": "sha512-vUE6VnqvOHX1ABssTxtzTJUzEJrTL49DmXflSvlRIcolzOISVni1niI5/oWsDxzyRVE9sfwe8QqFbsWozs5RPA==", + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.1.0.tgz", + "integrity": "sha512-ggfTj09jo81Y6M4DyNj80GrY6Pip+AtDUgGljqoSzP6FG5nz5Aju6Cs/X147fLgkJ4UKTb736U6cDp0ssLzN5Q==", "dev": true, "dependencies": { - "@puppeteer/browsers": "1.4.1", - "chromium-bidi": "0.4.11", - "cross-fetch": "3.1.6", + "@puppeteer/browsers": "1.7.0", + "chromium-bidi": "0.4.20", + "cross-fetch": "4.0.0", "debug": "4.3.4", - "devtools-protocol": "0.0.1135028", + "devtools-protocol": "0.0.1159816", "ws": "8.13.0" }, "engines": { "node": ">=16.3.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, "node_modules/puppeteer-core/node_modules/ws": { @@ -13175,6 +13087,12 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -13497,18 +13415,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -14347,6 +14253,16 @@ "node": ">=8.0" } }, + "node_modules/streamx": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", + "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -15144,22 +15060,6 @@ "node": ">= 0.8" } }, - "node_modules/vm2": { - "version": "3.9.19", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", - "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", - "dev": true, - "dependencies": { - "acorn": "^8.7.0", - "acorn-walk": "^8.2.0" - }, - "bin": { - "vm2": "bin/vm2" - }, - "engines": { - "node": ">=6.0" - } - }, "node_modules/void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -15473,6 +15373,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -17995,96 +17896,108 @@ "dev": true }, "@microsoft/applicationinsights-analytics-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.6.1.tgz", - "integrity": "sha512-wRH67jZTPy6SP54ygAQsFXu5ZnfzGOoMkA6ll1pkhSC4hij7Cvzumr4PYkr2gIPBPxD354sLOjBL/lmOgBTc5g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-3.0.2.tgz", + "integrity": "sha512-vrgEiT6cKC2Yb0Y6rCp9CXjFStlRZLI/IhIiBEGYaUfzoytLxUj6F/AizUDYBuNQfE+CTYe0jNyqf+RJgEMkJQ==", "requires": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" } }, "@microsoft/applicationinsights-channel-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.6.1.tgz", - "integrity": "sha512-oatERKW3eAjVNm5ej2NpRvBCCtPtiINIKxLiWVHv2SC2rzGrUnxNWFlUJojRT+u5ZXXsB51Ktw9gx8iHexnDVw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz", + "integrity": "sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw==", "requires": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" } }, "@microsoft/applicationinsights-common": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-2.6.1.tgz", - "integrity": "sha512-kV/dI9UwTew3mq+3F3Tkl2dBn2C4+FOOG3S5cS7/SssVsUlvLrWXBrOOxfIJ7+EjQQ6ijcqlDus4Nz7Ms2Kk2Q==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz", + "integrity": "sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg==", "requires": { - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" } }, "@microsoft/applicationinsights-core-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.6.1.tgz", - "integrity": "sha512-SFnTx48BGkmz6P9GvXFeIZ641vnfrKo0hB74Hp9GR7UE3hqIDuomIBQS17unnh05T5w3PWKlDCGNpiCbJV6kzQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz", + "integrity": "sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ==", "requires": { - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" } }, "@microsoft/applicationinsights-dependencies-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.6.1.tgz", - "integrity": "sha512-Y7R6BjzyB6NrkIBTT6FJrr2jKr8MiLxy264b1xUQHjry3Bwu+fsPJ7EETV61dkOEHs6IlWxAtikNCv8f3zQydw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-3.0.2.tgz", + "integrity": "sha512-b/YTonnbghg9DOFsLg4zdbYPafW8fPIzV+nZxfPPpxjA1LGvPhZz/zVx9YYWJg2RBXjojLQoJxLf1ro5eNGVig==", "requires": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" } }, "@microsoft/applicationinsights-properties-js": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.6.1.tgz", - "integrity": "sha512-TQmKp9/j0yMGjUHBatRQ41E4S/1yTkJImh8csZxc4waMQmV9ITkNrDaC3bIPcrw+ASepI3QfP7sry+n7nvYLFw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-3.0.2.tgz", + "integrity": "sha512-PFqicp8q4Tc0hqfPjwfqKo12gEqTk1l4lMyUUIU7ugE1XOuDkZcMPha05KnZWKj+F4zQXJcetcAHoVkyoyCFQw==", "requires": { - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" } }, "@microsoft/applicationinsights-shims": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-1.0.3.tgz", - "integrity": "sha512-+S17aqEkOYpyBpmclhgwcEplwnxSo5AxYBdRg38GBobI1GKPSpZfnLssLzcjJ6XZCS5tqB5xjyTZs6gHj7ZJWQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz", + "integrity": "sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==", + "requires": { + "@nevware21/ts-utils": ">= 0.9.4 < 2.x" + } }, "@microsoft/applicationinsights-web": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web/-/applicationinsights-web-2.6.1.tgz", - "integrity": "sha512-jKF6hpPq3pzLqLSVxTMh7HU9tr/SPOFJN12pFYpNMU/rAMs/fgZsmFG/oBAzYTZxNilDTFljoblB66J9X+K6RQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web/-/applicationinsights-web-3.0.2.tgz", + "integrity": "sha512-pf2zz/3mmGy1RoyaiLZwhHoE2mFZ+AWR3Zf7xPW7HjTG7dEE4BnovNyW3f9Eu6WWkcHUAHmS/ATzqvVlpB3W6A==", "requires": { - "@microsoft/applicationinsights-analytics-js": "2.6.1", - "@microsoft/applicationinsights-channel-js": "2.6.1", - "@microsoft/applicationinsights-common": "2.6.1", - "@microsoft/applicationinsights-core-js": "2.6.1", - "@microsoft/applicationinsights-dependencies-js": "2.6.1", - "@microsoft/applicationinsights-properties-js": "2.6.1", - "@microsoft/applicationinsights-shims": "1.0.3", - "@microsoft/dynamicproto-js": "^1.1.1" + "@microsoft/applicationinsights-analytics-js": "3.0.2", + "@microsoft/applicationinsights-channel-js": "3.0.2", + "@microsoft/applicationinsights-common": "3.0.2", + "@microsoft/applicationinsights-core-js": "3.0.2", + "@microsoft/applicationinsights-dependencies-js": "3.0.2", + "@microsoft/applicationinsights-properties-js": "3.0.2", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.2", + "@nevware21/ts-async": ">= 0.2.4 < 2.x", + "@nevware21/ts-utils": ">= 0.9.5 < 2.x" } }, "@microsoft/dynamicproto-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.1.tgz", - "integrity": "sha512-SPY1PlXmg4FbJVItVdhDV+zigajPtSI8oZPrsKBEIzAF4FROuwWIq5C+RAF8VJshBqphcvU8Eoh4DrUEZOB31g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz", + "integrity": "sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg==", "requires": { - "findup-sync": "^4.0.0", - "nopt": "^5.0.0", - "pify": "^2.3.0" + "@nevware21/ts-utils": ">= 0.9.4 < 2.x" } }, "@ministryofjustice/frontend": { @@ -18096,6 +18009,20 @@ "moment": "^2.27.0" } }, + "@nevware21/ts-async": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.2.6.tgz", + "integrity": "sha512-NCUqEZSbsy7LVtKlUScd/eTst6djkWauLlzoIPVKCOxalEBdO8lrgNRIm4Xy68JNudNN5faqa2WA12X8m0BVhA==", + "requires": { + "@nevware21/ts-utils": ">= 0.9.7 < 2.x" + } + }, + "@nevware21/ts-utils": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.9.8.tgz", + "integrity": "sha512-kZ8s8hcn9jPVX/M7kSsBYrOGlHjqLahmxrG7QeKTk5paeVwfgKdvVCjj5Acb4UGb/ukU1G34U1Z3eb7bbVanyA==", + "requires": {} + }, "@ng-select/ng-select": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-10.0.3.tgz", @@ -18296,16 +18223,16 @@ } }, "@puppeteer/browsers": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.1.tgz", - "integrity": "sha512-H43VosMzywHCcYcgv0GXXopvwnV21Ud9g2aXbPlQUJj1Xcz9V0wBwHeFz6saFhx/3VKisZfI1GEKEOhQCau7Vw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.7.0.tgz", + "integrity": "sha512-sl7zI0IkbQGak/+IE3VEEZab5SSOlI5F6558WvzWGC1n3+C722rfewC1ZIkcF9dsoGSsxhsONoseVlNQG4wWvQ==", "dev": true, "requires": { "debug": "4.3.4", "extract-zip": "2.0.1", "progress": "2.0.3", - "proxy-agent": "6.2.1", - "tar-fs": "2.1.1", + "proxy-agent": "6.3.0", + "tar-fs": "3.0.4", "unbzip2-stream": "1.4.3", "yargs": "17.7.1" }, @@ -18321,6 +18248,28 @@ "wrap-ansi": "^7.0.0" } }, + "tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dev": true, + "requires": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dev": true, + "requires": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "yargs": { "version": "17.7.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", @@ -18409,6 +18358,12 @@ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true }, + "@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "@types/applicationinsights-js": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/applicationinsights-js/-/applicationinsights-js-1.0.9.tgz", @@ -19083,7 +19038,8 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "accepts": { "version": "1.3.8", @@ -19115,12 +19071,6 @@ "dev": true, "requires": {} }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, "adjust-sourcemap-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", @@ -19394,6 +19344,12 @@ "integrity": "sha512-9AiDKFKUCWEQm1Kj4lcq7KFavLqSXdf2m/zJo+NVh4VXlW5iwXRJ6alkKmipCyYorsRnqsICH9XLubP1jBF+Og==", "dev": true }, + "b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", + "dev": true + }, "babel-loader": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", @@ -19876,12 +19832,12 @@ "dev": true }, "chromium-bidi": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.11.tgz", - "integrity": "sha512-p03ajLhlQ5gebw3cmbDBFmBc2wnJM5dnXS8Phu6mblGn/KQd76yOVL5VwE0VAisa7oazNfKGTaXlIZ8Q5Bb9OA==", + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.20.tgz", + "integrity": "sha512-ruHgVZFEv00mAQMz1tQjfjdG63jiPWrQPF6HLlX2ucqLqVTJoWngeBEKHaJ6n1swV/HSvgnBNbtTRIlcVyW3Fw==", "dev": true, "requires": { - "mitt": "3.0.0" + "mitt": "3.0.1" } }, "clean-stack": { @@ -20263,12 +20219,12 @@ } }, "cross-fetch": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", - "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, "requires": { - "node-fetch": "^2.6.11" + "node-fetch": "^2.6.12" } }, "css-loader": { @@ -20512,15 +20468,14 @@ } }, "degenerator": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-4.0.2.tgz", - "integrity": "sha512-HKwIFvZROUMfH3qI3gBpD61BYh7q3c3GXD5UGZzoVNJwVSYgZKvYl1fRMXc9ozoTxl/VZxKJ5v/bA+19tywFiw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, "requires": { - "ast-types": "^0.13.2", - "escodegen": "^1.8.1", - "esprima": "^4.0.0", - "vm2": "^3.9.17" + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" } }, "delegates": { @@ -20546,11 +20501,6 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" - }, "detect-node": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", @@ -20558,9 +20508,9 @@ "dev": true }, "devtools-protocol": { - "version": "0.0.1135028", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1135028.tgz", - "integrity": "sha512-jEcNGrh6lOXNRJvZb9RjeevtZGrgugPKSMJZxfyxWQnhlKawMPhMtk/dfC+Z/6xNXExlzTKlY5LzIAK/fRpQIw==", + "version": "0.0.1159816", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1159816.tgz", + "integrity": "sha512-2cZlHxC5IlgkIWe2pSDmCrDiTzbSJWywjbDDnupOImEBcG31CQgBLV8wWE+5t+C4rimcjHsbzy7CBzf9oFjboA==", "dev": true }, "di": { @@ -20964,46 +20914,21 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "requires": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", + "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "source-map": { @@ -21012,15 +20937,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } } } }, @@ -21491,14 +21407,6 @@ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -21648,6 +21556,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -21791,17 +21705,6 @@ "path-exists": "^4.0.0" } }, - "findup-sync": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" - } - }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -22020,28 +21923,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -22183,14 +22064,6 @@ "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", "dev": true }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "requires": { - "parse-passwd": "^1.0.0" - } - }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -22495,11 +22368,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, "inquirer": { "version": "8.2.4", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", @@ -22867,11 +22735,6 @@ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", "dev": true }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -22896,7 +22759,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "isobject": { "version": "3.0.1", @@ -23760,6 +23624,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -23900,9 +23765,9 @@ } }, "mitt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", - "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "dev": true }, "mkdirp": { @@ -24046,9 +23911,9 @@ "optional": true }, "node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dev": true, "requires": { "whatwg-url": "^5.0.0" @@ -24129,14 +23994,6 @@ "is": "^3.2.1" } }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "requires": { - "abbrev": "1" - } - }, "normalize-package-data": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", @@ -24660,17 +24517,18 @@ } }, "pac-proxy-agent": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-6.0.3.tgz", - "integrity": "sha512-5Hr1KgPDoc21Vn3rsXBirwwDnF/iac1jN/zkpsOYruyT+ZgsUhUOgVwq3v9+ukjZd/yGm/0nzO1fDfl7rkGoHQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz", + "integrity": "sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA==", "dev": true, "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", - "pac-resolver": "^6.0.1", + "pac-resolver": "^7.0.0", "socks-proxy-agent": "^8.0.1" }, "dependencies": { @@ -24694,9 +24552,9 @@ } }, "https-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz", - "integrity": "sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", + "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", "dev": true, "requires": { "agent-base": "^7.0.2", @@ -24717,13 +24575,13 @@ } }, "pac-resolver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-6.0.1.tgz", - "integrity": "sha512-dg497MhVT7jZegPRuOScQ/z0aV/5WR0gTdRu1md+Irs9J9o+ls5jIuxjo1WfaTG+eQQkxyn5HMGvWK+w7EIBkQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", "dev": true, "requires": { - "degenerator": "^4.0.1", - "ip": "^1.1.5", + "degenerator": "^5.0.0", + "ip": "^1.1.8", "netmask": "^2.0.2" }, "dependencies": { @@ -24804,11 +24662,6 @@ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" - }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -24895,11 +24748,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" - }, "piscina": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", @@ -25077,9 +24925,9 @@ } }, "proxy-agent": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.2.1.tgz", - "integrity": "sha512-OIbBKlRAT+ycCm6wAYIzMwPejzRtjy8F3QiDX0eKOA3e4pe3U9F/IvzcHP42bmgQxVv97juG+J8/gx+JIeCX/Q==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", + "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", "dev": true, "requires": { "agent-base": "^7.0.2", @@ -25087,7 +24935,7 @@ "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^6.0.3", + "pac-proxy-agent": "^7.0.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.1" }, @@ -25112,9 +24960,9 @@ } }, "https-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz", - "integrity": "sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", + "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", "dev": true, "requires": { "agent-base": "^7.0.2", @@ -25170,14 +25018,14 @@ "dev": true }, "puppeteer": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-20.6.0.tgz", - "integrity": "sha512-D/kkEIpDFRqpLOcCoNNdXI+IUcoD1FmdlWteT4FFPOhNLC46urmItMfQDKSwk2NJoO38ncgCQe5XEQ3QHD+piA==", + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.1.0.tgz", + "integrity": "sha512-x0KfxVd7Hsefq8nzH1AAdSnYw5HEKI4QPeexBmx7nO29jDoEKNE+75G8zQ0E57ZOny/vAZZptCFdD3A7PkeESQ==", "dev": true, "requires": { - "@puppeteer/browsers": "1.4.1", + "@puppeteer/browsers": "1.7.0", "cosmiconfig": "8.2.0", - "puppeteer-core": "20.6.0" + "puppeteer-core": "21.1.0" }, "dependencies": { "argparse": { @@ -25210,16 +25058,16 @@ } }, "puppeteer-core": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.6.0.tgz", - "integrity": "sha512-vUE6VnqvOHX1ABssTxtzTJUzEJrTL49DmXflSvlRIcolzOISVni1niI5/oWsDxzyRVE9sfwe8QqFbsWozs5RPA==", + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.1.0.tgz", + "integrity": "sha512-ggfTj09jo81Y6M4DyNj80GrY6Pip+AtDUgGljqoSzP6FG5nz5Aju6Cs/X147fLgkJ4UKTb736U6cDp0ssLzN5Q==", "dev": true, "requires": { - "@puppeteer/browsers": "1.4.1", - "chromium-bidi": "0.4.11", - "cross-fetch": "3.1.6", + "@puppeteer/browsers": "1.7.0", + "chromium-bidi": "0.4.20", + "cross-fetch": "4.0.0", "debug": "4.3.4", - "devtools-protocol": "0.0.1135028", + "devtools-protocol": "0.0.1159816", "ws": "8.13.0" }, "dependencies": { @@ -25253,6 +25101,12 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -25508,15 +25362,6 @@ "supports-preserve-symlinks-flag": "^1.0.0" } }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -26166,6 +26011,16 @@ "fs-extra": "^8.1.0" } }, + "streamx": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", + "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "dev": true, + "requires": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -26755,16 +26610,6 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, - "vm2": { - "version": "3.9.19", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", - "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", - "dev": true, - "requires": { - "acorn": "^8.7.0", - "acorn-walk": "^8.2.0" - } - }, "void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -26978,6 +26823,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, "requires": { "isexe": "^2.0.0" } diff --git a/AdminWebsite/AdminWebsite/ClientApp/package.json b/AdminWebsite/AdminWebsite/ClientApp/package.json index 7a1bc0f7f..809acc4a2 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/package.json +++ b/AdminWebsite/AdminWebsite/ClientApp/package.json @@ -37,7 +37,7 @@ "@fortawesome/free-regular-svg-icons": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@hmcts/frontend": "^0.0.41-alpha", - "@microsoft/applicationinsights-web": "^2.6.1", + "@microsoft/applicationinsights-web": "^3.0.2", "@ministryofjustice/frontend": "^1.4.0", "@ng-select/ng-select": "^10.0.3", "angular-auth-oidc-client": "^15.0.3", @@ -86,7 +86,7 @@ "nswag": "^13.19.0", "pa11y": "^6.2.3", "prettier": "^2.8.8", - "puppeteer": "^20.6.0", + "puppeteer": "^21.1.0", "run-script-os": "^1.1.6", "sass": "^1.32.12", "typescript": "^4.9.4", diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant-base/add-participant-base.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant-base/add-participant-base.component.ts index 8532b3b24..7fabd4d33 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant-base/add-participant-base.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant-base/add-participant-base.component.ts @@ -171,11 +171,7 @@ export abstract class AddParticipantBaseDirective extends BookingBaseComponent i if (this.form.valid && this.validEmail()) { this.disableCaseAndHearingRoles(); - if (this.editMode) { - this.displayNext(); - } else { - this.displayAdd(); - } + this.displayAdd(); } } @@ -219,16 +215,16 @@ export abstract class AddParticipantBaseDirective extends BookingBaseComponent i const formControlsObj = { party: this.participantDetails.case_role_name, role: this.participantDetails.hearing_role_name, - title: this.participantDetails.title === undefined ? this.constants.PleaseSelect : this.participantDetails.title, - firstName: this.participantDetails.first_name, - lastName: this.participantDetails.last_name, - email: this.participantDetails.email || '', - phone: this.participantDetails.phone || '', - displayName: this.participantDetails.display_name || '', - companyName: this.participantDetails.company || '', - companyNameIndividual: this.participantDetails.company || '', - representing: this.participantDetails.representee || '', - interpreterFor: this.setInterpretee(this.participantDetails) || this.constants.PleaseSelect + title: this.participantDetails.title ?? this.constants.PleaseSelect, + firstName: this.participantDetails.first_name.trim(), + lastName: this.participantDetails.last_name.trim(), + email: this.participantDetails.email.trim() || '', + phone: this.participantDetails.phone.trim() || '', + displayName: this.participantDetails.display_name?.trim() || '', + companyName: this.participantDetails.company?.trim() || '', + companyNameIndividual: this.participantDetails.company?.trim() || '', + representing: this.participantDetails.representee?.trim() || '', + interpreterFor: this.setInterpretee(this.participantDetails)?.trim() || this.constants.PleaseSelect }; if (this.participantDetails.hearing_role_name === Constants.HearingRoles.StaffMember) { delete formControlsObj['interpreterFor']; diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.html b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.html index b79e09113..13f687264 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.html +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.html @@ -213,7 +213,7 @@

Client details

-
+ -
+
Clear fields icon Clear details diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.spec.ts index b9b0a03e8..fc9298520 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.spec.ts @@ -1,7 +1,7 @@ -import { ComponentFixture, fakeAsync, flush, flushMicrotasks, TestBed, tick, waitForAsync } from '@angular/core/testing'; -import { AbstractControl, Validators } from '@angular/forms'; +import { ComponentFixture, fakeAsync, flush, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { AbstractControl } from '@angular/forms'; import { NavigationEnd, Router, RouterModule } from '@angular/router'; -import { Observable, of, Subject, Subscription } from 'rxjs'; +import { of, Subscription } from 'rxjs'; import { SharedModule } from 'src/app/shared/shared.module'; import { SearchServiceStub } from 'src/app/testing/stubs/service-service-stub'; import { Constants } from '../../common/constants'; @@ -26,6 +26,7 @@ import { TestingModule } from 'src/app/testing/testing.module'; import { By } from '@angular/platform-browser'; import { HearingRoles } from '../../common/model/hearing-roles.model'; import { FeatureFlagService } from '../../services/feature-flag.service'; +import { FeatureFlags, LaunchDarklyService } from 'src/app/services/launch-darkly.service'; let component: AddParticipantComponent; let fixture: ComponentFixture; @@ -168,6 +169,8 @@ function initHearingRequest(): HearingModel { newHearing.hearing_venue_id = -1; newHearing.scheduled_duration = 0; newHearing.participants = participants; + newHearing.case_type = 'Test Case Type'; + newHearing.case_type_service_id = 'AA1'; return newHearing; } @@ -184,18 +187,22 @@ function initExistHearingRequest(): HearingModel { return newHearing; } -const participant = new ParticipantModel(); -participant.email = 'email@hmcts.net'; -participant.first_name = 'Sam'; -participant.last_name = 'Green'; -participant.phone = '12345'; -participant.is_judge = false; -participant.display_name = 'Sam Green'; -participant.title = 'Mr'; -participant.hearing_role_name = 'Representative'; -participant.case_role_name = 'Applicant'; -participant.company = 'CN'; -participant.representee = 'test representee'; +let participant = new ParticipantModel(); + +function initParticipant() { + participant = new ParticipantModel(); + participant.email = 'email@hmcts.net'; + participant.first_name = 'Sam'; + participant.last_name = 'Green'; + participant.phone = '12345'; + participant.is_judge = false; + participant.display_name = 'Sam Green'; + participant.title = 'Mr'; + participant.hearing_role_name = 'Representative'; + participant.case_role_name = 'Applicant'; + participant.company = 'CN'; + participant.representee = 'test representee'; +} const routerSpy: jasmine.SpyObj = { events: of(new NavigationEnd(2, '/', '/')), @@ -204,9 +211,19 @@ const routerSpy: jasmine.SpyObj = { } as jasmine.SpyObj; let videoHearingsServiceSpy: jasmine.SpyObj; +videoHearingsServiceSpy = jasmine.createSpyObj([ + 'getParticipantRoles', + 'getCurrentRequest', + 'setBookingHasChanged', + 'updateHearingRequest', + 'cancelRequest', + 'isConferenceClosed', + 'isHearingAboutToStart' +]); let bookingServiceSpy: jasmine.SpyObj; let searchServiceSpy: jasmine.SpyObj; let featureFlagServiceSpy: jasmine.SpyObj; +const launchDarklyServiceSpy = jasmine.createSpyObj('LaunchDarklyService', ['getFlag']); const configServiceSpy = jasmine.createSpyObj('ConfigService', ['getClientSettings']); @@ -225,20 +242,15 @@ const searchService = { describe('AddParticipantComponent', () => { beforeEach(waitForAsync(() => { + initParticipant(); + const hearing = initHearingRequest(); - videoHearingsServiceSpy = jasmine.createSpyObj([ - 'getParticipantRoles', - 'getCurrentRequest', - 'setBookingHasChanged', - 'updateHearingRequest', - 'cancelRequest', - 'isConferenceClosed', - 'isHearingAboutToStart' - ]); videoHearingsServiceSpy.getParticipantRoles.and.returnValue(Promise.resolve(roleList)); videoHearingsServiceSpy.getCurrentRequest.and.returnValue(hearing); participantServiceSpy = jasmine.createSpyObj(['mapParticipantsRoles', 'checkDuplication', 'removeParticipant']); featureFlagServiceSpy.getFeatureFlagByName.and.returnValue(of(true)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.eJudFeature).and.returnValue(of(true)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.referenceData).and.returnValue(of(false)); participantServiceSpy.mapParticipantsRoles.and.returnValue(partyList); bookingServiceSpy = jasmine.createSpyObj(['isEditMode', 'resetEditMode']); bookingServiceSpy.isEditMode.and.returnValue(false); @@ -262,7 +274,7 @@ describe('AddParticipantComponent', () => { participantServiceSpy, routerSpy, bookingServiceSpy, - featureFlagServiceSpy, + launchDarklyServiceSpy, loggerSpy ); @@ -392,11 +404,15 @@ describe('AddParticipantComponent', () => { component.isRoleSelected = true; component.form.get('role').setValue('Representative'); + const originalFirstName = participant.first_name; + const originalLastName = participant.last_name; + participant.first_name = participant.first_name + ' '; + participant.last_name = participant.last_name + ' '; component.getParticipant(participant); expect(role.value).toBe(participant.hearing_role_name); expect(party.value).toBe(participant.case_role_name); - expect(firstName.value).toBe(participant.first_name); - expect(lastName.value).toBe(participant.last_name); + expect(firstName.value).toBe(originalFirstName); + expect(lastName.value).toBe(originalLastName); expect(email.value).toBe(participant.email); expect(phone.value).toBe(participant.phone); expect(title.value).toBe(participant.title); @@ -954,14 +970,14 @@ describe('AddParticipantComponent', () => { it('should return errorAlternativeEmail & errorJohAccountNotFound as false if called with notFoundEmailEvent as false', () => { component.errorAlternativeEmail = true; component.errorJohAccountNotFound = true; - component.subcribeForSeachEmailEvents(); + component.subscribeForSearchEmailEvents(); component.searchEmail.notFoundEmailEvent.next(false); expect(component.errorAlternativeEmail).toBeFalsy(); expect(component.errorJohAccountNotFound).toBeFalsy(); }); it('should have called Not Found Participant if Not Found Email Event has been called', () => { spyOn(component, 'notFoundParticipant'); - component.subcribeForSeachEmailEvents(); + component.subscribeForSearchEmailEvents(); component.searchEmail.notFoundEmailEvent.next(true); expect(component.notFoundParticipant).toHaveBeenCalledTimes(1); }); @@ -992,11 +1008,14 @@ describe('AddParticipantComponent edit mode', () => { { provide: BookingService, useValue: bookingServiceSpy }, { provide: Logger, useValue: loggerSpy }, { provide: FeatureFlagService, useValue: featureFlagServiceSpy }, - { provide: ConfigService, useValue: configServiceSpy } + { provide: ConfigService, useValue: configServiceSpy }, + { provide: LaunchDarklyService, useValue: launchDarklyServiceSpy } ] }).compileComponents(); featureFlagServiceSpy.getFeatureFlagByName.and.returnValue(of(true)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.eJudFeature).and.returnValue(of(true)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.referenceData).and.returnValue(of(false)); const hearing = initExistHearingRequest(); videoHearingsServiceSpy.getParticipantRoles.and.returnValue(Promise.resolve(roleList)); @@ -1026,6 +1045,10 @@ describe('AddParticipantComponent edit mode', () => { interpretee = component.form.controls['interpreterFor']; })); + afterEach(() => { + videoHearingsServiceSpy.getParticipantRoles.calls.reset(); + }); + it('should set errorJohAccountNotFound to true when no results found when searching EJudFeature flag is ON', () => { component.form.setValue({ party: 'Panel Member', @@ -1135,15 +1158,41 @@ describe('AddParticipantComponent edit mode', () => { expect(videoHearingsServiceSpy.getParticipantRoles).toHaveBeenCalled(); expect(component.showDetails).toBeTruthy(); expect(component.selectedParticipantEmail).toBe('test3@hmcts.net'); - expect(component.displayNextButton).toBeTruthy(); - expect(component.displayClearButton).toBeFalsy(); + expect(component.displayNextButton).toBeFalsy(); + expect(component.displayClearButton).toBeTruthy(); expect(component.displayAddButton).toBeFalsy(); - expect(component.displayUpdateButton).toBeFalsy(); + expect(component.displayUpdateButton).toBeTruthy(); }); tick(100); fixture.detectChanges(); })); + it('gets participant roles by case type service id when reference data flag is on', fakeAsync(async () => { + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.referenceData).and.returnValue(of(true)); + + component.ngOnInit(); + component.ngAfterViewInit(); + flush(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + expect(videoHearingsServiceSpy.getParticipantRoles).toHaveBeenCalledWith(component.hearing.case_type_service_id); + }); + })); + + it('gets participant roles by case type service id when reference data flag is off', fakeAsync(async () => { + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.referenceData).and.returnValue(of(false)); + + component.ngOnInit(); + component.ngAfterViewInit(); + flush(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + expect(videoHearingsServiceSpy.getParticipantRoles).toHaveBeenCalledWith(component.hearing.case_type); + }); + })); + it('should update participant and clear form', () => { component.showDetails = true; fixture.detectChanges(); @@ -1373,6 +1422,8 @@ describe('AddParticipantComponent edit mode no participants added', () => { bookingServiceSpy.isEditMode.and.returnValue(true); bookingServiceSpy.getParticipantEmail.and.returnValue(''); featureFlagServiceSpy.getFeatureFlagByName.and.returnValue(of(false)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.eJudFeature).and.returnValue(of(false)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.referenceData).and.returnValue(of(false)); TestBed.configureTestingModule({ imports: [SharedModule, RouterModule.forChild([]), BookingModule, PopupModule, TestingModule], @@ -1384,6 +1435,7 @@ describe('AddParticipantComponent edit mode no participants added', () => { { provide: BookingService, useValue: bookingServiceSpy }, { provide: Logger, useValue: loggerSpy }, { provide: FeatureFlagService, useValue: featureFlagServiceSpy }, + { provide: LaunchDarklyService, useValue: launchDarklyServiceSpy }, { provide: ConfigService, useValue: configServiceSpy } ] }).compileComponents(); @@ -1462,17 +1514,6 @@ describe('AddParticipantComponent edit mode no participants added', () => { expect(component.showDetails).toBeTruthy(); })); - it('should show update participant and clear details links when tries to edit a participant in hearing', fakeAsync(() => { - const debugElement = fixture.debugElement; - component.selectedParticipantEmail = 'test2@hmcts.net'; - fixture.detectChanges(); - const clearFormBtn = debugElement.query(By.css('#clearFormBtn')); - const updateFormBtn = debugElement.query(By.css('#updateParticipantBtn')); - tick(600); - expect(updateFormBtn).toBeTruthy(); - expect(clearFormBtn).toBeTruthy(); - })); - it('should show confirmation to remove participant', fakeAsync(() => { component.ngAfterContentInit(); component.ngAfterViewInit(); @@ -1616,6 +1657,8 @@ describe('AddParticipantComponent set representer', () => { bookingServiceSpy.isEditMode.and.returnValue(true); bookingServiceSpy.getParticipantEmail.and.returnValue(''); featureFlagServiceSpy.getFeatureFlagByName.and.returnValue(of(true)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.eJudFeature).and.returnValue(of(true)); + launchDarklyServiceSpy.getFlag.withArgs(FeatureFlags.referenceData).and.returnValue(of(false)); const searchServiceStab = jasmine.createSpyObj(['participantSearch']); @@ -1625,7 +1668,7 @@ describe('AddParticipantComponent set representer', () => { participantServiceSpy, { ...routerSpy, ...jasmine.createSpyObj(['navigate']) } as jasmine.SpyObj, bookingServiceSpy, - featureFlagServiceSpy, + launchDarklyServiceSpy, loggerSpy ); component.searchEmail = new SearchEmailComponent(searchServiceStab, configServiceSpy, loggerSpy, featureFlagServiceSpy); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.ts index ee2b17d9c..c0e5a6c45 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/add-participant/add-participant.component.ts @@ -1,6 +1,6 @@ import { AfterContentInit, AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Router } from '@angular/router'; -import { Observable, Subscription } from 'rxjs'; +import { combineLatest, Observable, Subject, Subscription } from 'rxjs'; import { PageUrls } from 'src/app/shared/page-url.constants'; import { Constants } from '../../common/constants'; import { SanitizeInputText } from '../../common/formatters/sanitize-input-text'; @@ -17,8 +17,8 @@ import { ParticipantListComponent } from '../participant'; import { HearingRoles } from '../../common/model/hearing-roles.model'; import { LinkedParticipantModel, LinkedParticipantType } from 'src/app/common/model/linked-participant.model'; import { Validators } from '@angular/forms'; -import { FeatureFlagService } from '../../services/feature-flag.service'; -import { first } from 'rxjs/operators'; +import { takeUntil } from 'rxjs/operators'; +import { FeatureFlags, LaunchDarklyService } from 'src/app/services/launch-darkly.service'; @Component({ selector: 'app-add-participant', @@ -45,6 +45,8 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme existingPerson: boolean; bookingHasParticipants: boolean; $subscriptions: Subscription[] = []; + referenceDataFeatureFlag = false; + destroyed$ = new Subject(); interpreteeList: ParticipantModel[] = []; showConfirmRemoveInterpretee = false; @@ -60,18 +62,22 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme private participantService: ParticipantService, protected router: Router, protected bookingService: BookingService, - protected featureFlagService: FeatureFlagService, + private launchDarklyService: LaunchDarklyService, protected logger: Logger ) { super(bookingService, router, videoHearingService, logger); this.titleList = searchService.TitleList; - featureFlagService - .getFeatureFlagByName('EJudFeature') - .pipe(first()) - .subscribe(result => (this.judiciaryRoles = result ? Constants.JudiciaryRoles : [])); } ngOnInit() { + const referenceDataFlag$ = this.launchDarklyService.getFlag(FeatureFlags.referenceData).pipe(takeUntil(this.destroyed$)); + const ejudFeatureFlag$ = this.launchDarklyService.getFlag(FeatureFlags.eJudFeature).pipe(takeUntil(this.destroyed$)); + + combineLatest([referenceDataFlag$, ejudFeatureFlag$]).subscribe(([referenceDataFlag, ejudFeatureFlag]) => { + this.referenceDataFeatureFlag = referenceDataFlag; + this.judiciaryRoles = ejudFeatureFlag ? Constants.JudiciaryRoles : []; + }); + this.checkForExistingRequest(); this.initialiseForm(); super.ngOnInit(); @@ -113,9 +119,10 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme setTimeout(() => { const self = this; + const caseTypeIdentifier = this.referenceDataFeatureFlag ? this.hearing.case_type_service_id : this.hearing.case_type; this.logger.debug(`${this.loggerPrefix} Getting participant roles.`); this.videoHearingService - .getParticipantRoles(this.hearing.case_type) + .getParticipantRoles(caseTypeIdentifier) .then((data: CaseAndHearingRolesResponse[]) => { self.setupRoles(data); if (self.editMode) { @@ -141,12 +148,12 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme if (this.editMode) { if (this.searchEmail && this.participantDetails) { this.setParticipantEmail(); - this.subcribeForSeachEmailEvents(); + this.subscribeForSearchEmailEvents(); } } } - subcribeForSeachEmailEvents() { + subscribeForSearchEmailEvents() { this.searchEmail.notFoundEmailEvent$.subscribe(notFound => { if (notFound) { this.notFoundParticipant(); @@ -171,18 +178,17 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme const self = this; this.$subscriptions.push( - this.form.valueChanges.subscribe(result => { + this.form.valueChanges.subscribe(() => { setTimeout(() => { if ( - (self.showDetails && - self.role.value === self.constants.PleaseSelect && - self.party.value === self.constants.PleaseSelect && - self.title.value === self.constants.PleaseSelect && - self.firstName.value === '' && - self.lastName.value === '' && - self.phone.value === '' && - self.displayName.value === '') || - self.editMode + self.showDetails && + self.role.value === self.constants.PleaseSelect && + self.party.value === self.constants.PleaseSelect && + self.title.value === self.constants.PleaseSelect && + self.firstName.value === '' && + self.lastName.value === '' && + self.phone.value === '' && + self.displayName.value === '' ) { self.displayNext(); } else if ( @@ -282,17 +288,15 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme } validateJudiciaryEmailAndRole() { - if (this.searchEmail && this.searchEmail.email.length) { + if (this.searchEmail?.email?.length) { this.searchService.searchJudiciaryEntries(this.searchEmail.email).subscribe(judiciaryEntries => { this.errorJudiciaryAccount = false; - if (judiciaryEntries && judiciaryEntries.length) { + if (judiciaryEntries?.length) { if (!this.judiciaryRoles.includes(this.role.value)) { this.setErrorForJudiciaryAccount(); } - } else { - if (this.judiciaryRoles.includes(this.role.value)) { - this.setErrorForJudiciaryAccount(); - } + } else if (this.judiciaryRoles.includes(this.role.value)) { + this.setErrorForJudiciaryAccount(); } }); } @@ -335,7 +339,7 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme this.hearing.participants.push(newParticipant); this.hearing.participants = [...this.hearing.participants]; - this.hearing = Object.assign({}, this.hearing); + this.hearing = { ...this.hearing }; this.populateInterpretedForList(); this.videoHearingService.updateHearingRequest(this.hearing); @@ -360,8 +364,7 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme username: newParticipant.username }); this.showConfirmationPopup = true; - const message = `You have already added ${newParticipant.first_name} ${newParticipant.last_name} to this hearing`; - this.confirmationMessage = message; + this.confirmationMessage = `You have already added ${newParticipant.first_name} ${newParticipant.last_name} to this hearing`; } } else { this.isShowErrorSummary = true; @@ -393,7 +396,7 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme } }); this.hearing.participants = [...this.hearing.participants]; - this.hearing = Object.assign({}, this.hearing); + this.hearing = { ...this.hearing }; this.clearForm(); this.participantDetails = null; this.form.markAsPristine(); @@ -417,7 +420,7 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme confirmRemoveParticipant() { if (this.selectedParticipantEmail) { const participant = this.hearing.participants.find(x => x.email.toLowerCase() === this.selectedParticipantEmail.toLowerCase()); - const title = participant && participant.title ? `${participant.title}` : ''; + const title = participant?.title ? `${participant.title}` : ''; this.removerFullName = participant ? `${title} ${participant.first_name} ${participant.last_name}` : ''; const anyParticipants = this.hearing.participants.filter(x => !x.is_judge); this.bookingHasParticipants = anyParticipants && anyParticipants.length > 1; @@ -442,7 +445,7 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme } this.participantService.removeParticipant(this.hearing, this.selectedParticipantEmail); this.removeLinkedParticipant(this.selectedParticipantEmail); - this.hearing = Object.assign({}, this.hearing); + this.hearing = { ...this.hearing }; this.videoHearingService.updateHearingRequest(this.hearing); this.videoHearingService.setBookingHasChanged(true); } @@ -471,10 +474,9 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme } private getUserRoleName(newParticipant: ParticipantModel): string { - const userRole = this.caseAndHearingRoles + return this.caseAndHearingRoles .find(c => c.name === newParticipant.case_role_name) ?.hearingRoles.find(h => h.name === newParticipant.hearing_role_name)?.userRole; - return userRole; } private addUpdateLinkedParticipant(newParticipant: ParticipantModel): LinkedParticipantModel[] { @@ -738,7 +740,7 @@ export class AddParticipantComponent extends AddParticipantBaseDirective impleme } this.participantService.removeParticipant(this.hearing, this.selectedParticipantEmail); this.removeLinkedParticipant(this.selectedParticipantEmail); - this.hearing = Object.assign({}, this.hearing); + this.hearing = { ...this.hearing }; this.videoHearingService.updateHearingRequest(this.hearing); this.videoHearingService.setBookingHasChanged(true); } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.spec.ts index 4fc839e42..29877c1dc 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.spec.ts @@ -87,6 +87,13 @@ describe('BreadcrumbComponent', () => { component.clickBreadcrumbs(step); expect(router.navigate).toHaveBeenCalledWith(['/assign-judge']); }); + + it('should init breadcrumb when the current item has not been set', () => { + component.currentItem = null; + const step = new BreadcrumbItemModel(2, false, 'Hearing schedule', '/assign-judge', false, false); + component.clickBreadcrumbs(step); + expect(router.navigate).toHaveBeenCalledWith(['/assign-judge']); + }); describe('when other checks fail', () => { const route = '/add-participants'; let step: BreadcrumbItemModel; diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.ts index a5fcb341e..7c088ea65 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/breadcrumb/breadcrumb.component.ts @@ -45,6 +45,9 @@ export class BreadcrumbComponent implements OnInit { if (!nextItem) { return; } + if (!this.currentItem) { + this.initBreadcrumb(); + } if (nextItem && nextItem.Id < this.currentItem.Id) { this.router.navigate([nextItem.Url]); return; diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.html b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.html index 2c1b82414..8d855f109 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.html +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.html @@ -64,11 +64,22 @@

Please complete
- + +
Please select a case type
@@ -76,11 +87,21 @@

Please complete
- + +
Please select a hearing type
@@ -113,9 +134,9 @@

Please complete
- +
- +
diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.spec.ts index 4a6e0b63e..d6f44e04c 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.spec.ts @@ -294,7 +294,7 @@ describe('CreateHearingComponent with existing request in session', () => { it('should repopulate form with existing request', fakeAsync(() => { expect(component.caseNumber.value).toBe(existingRequest.cases[0].number); expect(component.caseName.value).toBe(existingRequest.cases[0].name); - expect(component.hearingType.value).toBe(existingRequest.hearing_type_id); + expect(component.hearingType.value).toBe(existingRequest.hearing_type_name); })); it('should hide cancel and discard pop up confirmation', () => { diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.ts index 765ffbc4d..0988b29ef 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/create-hearing/create-hearing.component.ts @@ -11,7 +11,6 @@ import { ErrorService } from 'src/app/services/error.service'; import { PageUrls } from 'src/app/shared/page-url.constants'; import { Constants } from 'src/app/common/constants'; import { SanitizeInputText } from '../../common/formatters/sanitize-input-text'; -import { Subscription } from 'rxjs'; import { Logger } from 'src/app/services/logger'; @Component({ @@ -78,11 +77,7 @@ export class CreateHearingComponent extends BookingBaseComponent implements OnIn private setHearingTypeForExistingHearing() { if (this.hasSaved && this.filteredHearingTypes.length > 0) { - const selectedHearingTypes = this.filteredHearingTypes.filter(x => x.name === this.hearing.hearing_type_name); - if (!!selectedHearingTypes && selectedHearingTypes.length > 0) { - this.hearing.hearing_type_id = selectedHearingTypes[0].id; - this.form.get('hearingType').setValue(selectedHearingTypes[0].id); - } + this.form.get('hearingType').setValue(this.hearing.hearing_type_name); } } @@ -166,21 +161,9 @@ export class CreateHearingComponent extends BookingBaseComponent implements OnIn confirmCancelBooking() { this.logger.debug(`${this.loggerPrefix} Attempting to cancel booking.`); if (this.editMode) { - if (this.form.dirty || this.form.touched) { - this.logger.debug(`${this.loggerPrefix} In edit mode. Changes found. Confirm if changes should be discarded.`); - this.attemptingDiscardChanges = true; - } else { - this.logger.debug(`${this.loggerPrefix} In edit mode. No changes. Returning to summary.`); - this.router.navigate([PageUrls.Summary]); - } + this.cancelBookingInEditMode(); } else { - if (this.form.dirty || this.form.touched) { - this.logger.debug(`${this.loggerPrefix} New booking. Changes found. Confirm if changes should be discarded.`); - this.attemptingCancellation = true; - } else { - this.logger.debug(`${this.loggerPrefix} New booking. No changes found. Cancelling booking.`); - this.cancelBooking(); - } + this.cancelBookingInCreateMode(); } } @@ -207,22 +190,28 @@ export class CreateHearingComponent extends BookingBaseComponent implements OnIn this.hearing.cases[0] = hearingCase; this.hearing.case_type_id = this.isExistingHearing ? this.hearing.case_type_id : this.form.getRawValue().caseType; this.hearing.hearing_type_id = this.isExistingHearing ? this.hearing.hearing_type_id : this.form.getRawValue().hearingType; - this.hearing.hearing_type_name = this.availableHearingTypes.find(c => c.id === this.hearing.hearing_type_id).name; + const hearingType = this.availableHearingTypes.find(c => c.id === this.hearing.hearing_type_id); + // hearing type will be null if editing an expired hearing type + this.hearing.hearing_type_name = hearingType?.name ?? this.hearing.hearing_type_name; + this.hearing.hearing_type_code = hearingType?.code ?? this.hearing.hearing_type_code; this.hearing.questionnaire_not_required = false; + const hearingTypeGroup = this.availableHearingTypes.find(c => c.group === this.hearing.case_type); + // hearing type group will be null if editing an expired case type + this.hearing.case_type_service_id = hearingTypeGroup?.service_id ?? this.hearing.case_type_service_id; this.hearingService.updateHearingRequest(this.hearing); this.logger.debug(`${this.loggerPrefix} Updated hearing request details`, { hearing: this.hearing }); } private retrieveHearingTypes() { this.logger.debug(`${this.loggerPrefix} Retrieving hearing type`); - this.hearingService.getHearingTypes().subscribe( - (data: HearingTypeResponse[]) => { + this.hearingService.getHearingTypes().subscribe({ + next: (data: HearingTypeResponse[]) => { this.setupCaseTypeAndHearingTypes(data); this.filterHearingTypes(); this.setHearingTypeForExistingHearing(); }, - error => this.errorService.handleError(error) - ); + error: error => this.errorService.handleError(error) + }); } private setupCaseTypeAndHearingTypes(hearingTypes: HearingTypeResponse[]) { @@ -243,7 +232,7 @@ export class CreateHearingComponent extends BookingBaseComponent implements OnIn this.availableCaseTypes = this.availableHearingTypes .map(h => h.group) .filter((value, index, self) => self.indexOf(value) === index) - .sort(); + .sort((a, b) => a.localeCompare(b)); if (this.availableCaseTypes.length === 1) { this.selectedCaseType = this.availableCaseTypes[0]; @@ -270,6 +259,26 @@ export class CreateHearingComponent extends BookingBaseComponent implements OnIn this.hearingType.setValue(null); } + private cancelBookingInCreateMode() { + if (this.form.dirty || this.form.touched) { + this.logger.debug(`${this.loggerPrefix} New booking. Changes found. Confirm if changes should be discarded.`); + this.attemptingCancellation = true; + } else { + this.logger.debug(`${this.loggerPrefix} New booking. No changes found. Cancelling booking.`); + this.cancelBooking(); + } + } + + private cancelBookingInEditMode() { + if (this.form.dirty || this.form.touched) { + this.logger.debug(`${this.loggerPrefix} In edit mode. Changes found. Confirm if changes should be discarded.`); + this.attemptingDiscardChanges = true; + } else { + this.logger.debug(`${this.loggerPrefix} In edit mode. No changes. Returning to summary.`); + this.router.navigate([PageUrls.Summary]); + } + } + private dynamicSort(property) { let sortOrder = 1; if (property[0] === '-') { @@ -277,7 +286,10 @@ export class CreateHearingComponent extends BookingBaseComponent implements OnIn property = property.substr(1); } return function (a, b) { - const result = a[property] < b[property] ? -1 : a[property] > b[property] ? 1 : 0; + if (a[property] < b[property]) { + return -1 * sortOrder; + } + const result = a[property] > b[property] ? 1 : 0; return result * sortOrder; }; } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/hearing-schedule/hearing-schedule.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/hearing-schedule/hearing-schedule.component.ts index 5eb6391f2..c414902bb 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/hearing-schedule/hearing-schedule.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/hearing-schedule/hearing-schedule.component.ts @@ -30,6 +30,7 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On today = new Date(); canNavigate = true; selectedCourtName: string; + selectedCourtCode: string; isExistinHearing: boolean; endDateEarlierThanStartDate: boolean; isStartHoursInPast = false; @@ -65,8 +66,7 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On private checkForExistingRequest() { this.hearing = this.hearingService.getCurrentRequest(); this.isExistinHearing = this.hearing && !!this.hearing.hearing_type_name; - this.isBookedHearing = - this.hearing && this.hearing.hearing_id !== undefined && this.hearing.hearing_id !== null && this.hearing.hearing_id.length > 0; + this.isBookedHearing = this.hearing?.hearing_id?.length > 0; this.logger.debug(`${this.loggerPrefix} Checking for existing hearing`, { hearingExists: this.isExistinHearing, isBookedHearing: this.isBookedHearing, @@ -160,7 +160,9 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On this.courtAddressControl.valueChanges.subscribe(val => { const id = val; if (id !== null) { - this.selectedCourtName = this.availableCourts.find(c => c.id === id).name; + const venue = this.availableCourts.find(c => c.id === id); + this.selectedCourtName = venue.name; + this.selectedCourtCode = venue.code; } }); } @@ -335,8 +337,8 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On private retrieveCourts() { this.logger.debug(`${this.loggerPrefix} Retrieving courts.`); - this.refDataService.getCourts().subscribe( - (data: HearingVenueResponse[]) => { + this.refDataService.getCourts().subscribe({ + next: data => { this.availableCourts = data; this.logger.debug(`${this.loggerPrefix} Updating list of available courts.`, { courts: data.length }); const pleaseSelect = new HearingVenueResponse(); @@ -345,11 +347,11 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On this.availableCourts.unshift(pleaseSelect); this.setVenueForExistingHearing(); }, - error => { + error: error => { this.logger.error(`${this.loggerPrefix} Failed to get courts available.`, error); this.errorService.handleError(error); } - ); + }); } setVenueForExistingHearing() { @@ -357,6 +359,7 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On const selectedCourts = this.availableCourts.filter(x => x.name === this.hearing.court_name); if (selectedCourts && selectedCourts.length > 0) { this.selectedCourtName = selectedCourts[0].name; + this.selectedCourtCode = selectedCourts[0].code; this.form.get('courtAddress').setValue(selectedCourts[0].id); } } @@ -453,6 +456,7 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On this.hearing.hearing_venue_id = this.form.value.courtAddress; this.hearing.court_room = this.form.value.courtRoom; this.hearing.court_name = this.selectedCourtName; + this.hearing.court_code = this.selectedCourtCode; const hearingDate = new Date(this.form.value.hearingDate); hearingDate.setHours(this.form.value.hearingStartTimeHour, this.form.value.hearingStartTimeMinute); @@ -471,6 +475,7 @@ export class HearingScheduleComponent extends BookingBaseComponent implements On this.hearing.hearing_venue_id = this.form.value.courtAddress; this.hearing.court_room = this.form.value.courtRoom; this.hearing.court_name = this.selectedCourtName; + this.hearing.court_code = this.selectedCourtCode; const hearingDate = this.hearingDates[0]; hearingDate.setHours(this.form.value.hearingStartTimeHour, this.form.value.hearingStartTimeMinute); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/search-email/search-email.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/search-email/search-email.component.ts index 192a1351f..5d70ba7ca 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/search-email/search-email.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/search-email/search-email.component.ts @@ -4,7 +4,7 @@ import { Constants } from '../../common/constants'; import { SearchService } from '../../services/search.service'; import { ConfigService } from 'src/app/services/config.service'; import { Logger } from '../../services/logger'; -import { debounceTime, distinctUntilChanged, filter, first, map, switchMap, takeUntil, tap } from 'rxjs/operators'; +import { debounceTime, distinctUntilChanged, first, map, switchMap, tap } from 'rxjs/operators'; import { ParticipantModel } from 'src/app/common/model/participant.model'; import { FeatureFlagService } from '../../services/feature-flag.service'; @@ -72,6 +72,7 @@ export class SearchEmailComponent implements OnInit, OnDestroy { debounceTime(2000), distinctUntilChanged(), switchMap(term => { + // do not wait for valid email to be completed, partial search is allowed if (term.length > 2) { return this.searchService.participantSearch(term, this.hearingRoleParticipant, this.caseRole); } else { @@ -176,7 +177,7 @@ export class SearchEmailComponent implements OnInit, OnDestroy { } blurEmail() { - const userAlreadyExists = this.results && this.results.find(p => p.email === this.email) ? true : false; + const userAlreadyExists = this.results?.some(p => p.email === this.email); const emailIsValid = this.emailIsValid(); if (!this.results || this.results.length === 0 || (emailIsValid && !userAlreadyExists)) { @@ -198,7 +199,7 @@ export class SearchEmailComponent implements OnInit, OnDestroy { } populateParticipantInfo(email: string) { - if (this.results && this.results.length) { + if (this.results?.length) { const participant = this.results.find(p => p.email === email); if (participant) { this.selectItemClick(participant); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.html b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.html index 8f2238f8c..68399ecba 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.html +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.html @@ -88,10 +88,10 @@

Remove

-
+
link to endpoint - {{ getParticipantInfo(endpoint.defenceAdvocate) }} + {{ getDefenceAdvocateByContactEmail(endpoint.defenceAdvocate) }}
diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.spec.ts index c6b6cd77c..0c3e220f7 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.spec.ts @@ -29,6 +29,7 @@ import { ParticipantService } from '../services/participant.service'; import { SummaryComponent } from './summary.component'; import { FeatureFlagService } from '../../services/feature-flag.service'; import { ResponseTestData } from 'src/app/testing/data/response-test-data'; +import { BookingStatusService } from 'src/app/services/booking-status-service'; function initExistingHearingRequest(): HearingModel { const pat1 = new ParticipantModel(); @@ -115,6 +116,8 @@ videoHearingsServiceSpy = jasmine.createSpyObj('VideoHeari ]); const featureFlagSpy = jasmine.createSpyObj('FeatureFlagService', ['getFeatureFlagByName']); featureFlagSpy.getFeatureFlagByName.and.returnValue(of(true)); +const bookingStatusService = new BookingStatusService(videoHearingsServiceSpy); + describe('SummaryComponent with valid request', () => { let component: SummaryComponent; let fixture: ComponentFixture; @@ -139,7 +142,8 @@ describe('SummaryComponent with valid request', () => { { provide: Router, useValue: routerSpy }, { provide: Logger, useValue: loggerSpy }, { provide: RecordingGuardService, useValue: recordingGuardServiceSpy }, - { provide: FeatureFlagService, useValue: featureFlagSpy } + { provide: FeatureFlagService, useValue: featureFlagSpy }, + { provide: BookingStatusService, useValue: bookingStatusService } ], declarations: [ SummaryComponent, @@ -304,6 +308,18 @@ describe('SummaryComponent with valid request', () => { component.ngOnInit(); expect(component.hearing.audio_recording_required).toBe(false); }); + it('should set audio recording to false if case type is Crime Crown Court', () => { + component.hearing.case_type = component.constants.CaseTypes.CrimeCrownCourt; + component.ngOnInit(); + expect(component.hearing.audio_recording_required).toBe(false); + }); + it('should set audio recording to false if case type is Crime Crown Court and an interpreter is present', () => { + component.hearing.case_type = component.constants.CaseTypes.CrimeCrownCourt; + component.interpreterPresent = true; + component.isAudioRecordingRequired(); + component.ngOnInit(); + expect(component.hearing.audio_recording_required).toBe(false); + }); it('should display valid court address when room number is empty', () => { component.hearing.court_room = ''; component.ngOnInit(); @@ -568,7 +584,8 @@ describe('SummaryComponent with invalid request', () => { { provide: VideoHearingsService, useValue: videoHearingsServiceSpy }, { provide: Router, useValue: routerSpy }, { provide: Logger, useValue: loggerSpy }, - { provide: FeatureFlagService, useValue: featureFlagSpy } + { provide: FeatureFlagService, useValue: featureFlagSpy }, + { provide: BookingStatusService, useValue: bookingStatusService } ], imports: [RouterTestingModule], declarations: [ @@ -626,7 +643,8 @@ describe('SummaryComponent with existing request', () => { { provide: Router, useValue: routerSpy }, { provide: Logger, useValue: loggerSpy }, { provide: RecordingGuardService, useValue: recordingGuardServiceSpy }, - { provide: FeatureFlagService, useValue: featureFlagSpy } + { provide: FeatureFlagService, useValue: featureFlagSpy }, + { provide: BookingStatusService, useValue: bookingStatusService } ], imports: [RouterTestingModule], declarations: [ @@ -742,12 +760,14 @@ describe('SummaryComponent with existing request', () => { }); it('it should display the participant and representee', () => { component.hearing = initExistingHearingRequest(); - const result = component.getParticipantInfo('123123-123'); + const result = component.getDefenceAdvocateByContactEmail( + component.hearing.participants.find(x => x.id === '123123-123').contact_email + ); expect(result).toBe('solicitor 01, representing citizen 01'); }); it('it should display the participant and representee', () => { component.hearing = initExistingHearingRequest(); - const result = component.getParticipantInfo('123123-1231'); + const result = component.getDefenceAdvocateByContactEmail('madeup@doesnotexist.com'); expect(result).toBe(''); }); it('should remove an existing interpretee and interpreter', () => { @@ -825,7 +845,8 @@ describe('SummaryComponent with multi days request', () => { loggerSpy, recordingGuardServiceSpy, participantServiceSpy, - featureFlagServiceSpy + featureFlagServiceSpy, + bookingStatusService ); component.participantsListComponent = new ParticipantListComponent(loggerSpy, videoHearingsServiceSpy); component.removeInterpreterPopupComponent = new RemoveInterpreterPopupComponent(); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.ts index 4d8b27e4f..2fc4bea99 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/booking/summary/summary.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Router } from '@angular/router'; -import { Subscription, timer } from 'rxjs'; +import { Subscription } from 'rxjs'; import { EndpointModel } from 'src/app/common/model/endpoint.model'; import { HearingRoles } from 'src/app/common/model/hearing-roles.model'; import { ParticipantModel } from 'src/app/common/model/participant.model'; @@ -20,6 +20,7 @@ import { ParticipantService } from '../services/participant.service'; import { OtherInformationModel } from '../../common/model/other-information.model'; import { first } from 'rxjs/operators'; import { FeatureFlagService } from '../../services/feature-flag.service'; +import { BookingStatusService } from 'src/app/services/booking-status-service'; @Component({ selector: 'app-summary', @@ -74,7 +75,8 @@ export class SummaryComponent implements OnInit, OnDestroy { private logger: Logger, private recordingGuardService: RecordingGuardService, private participantService: ParticipantService, - private featureService: FeatureFlagService + private featureService: FeatureFlagService, + private bookingStatusService: BookingStatusService ) { this.attemptingCancellation = false; this.showErrorSaving = false; @@ -115,7 +117,10 @@ export class SummaryComponent implements OnInit, OnDestroy { isAudioRecordingRequired(): boolean { // CACD hearings should always have recordings set to off - if (this.caseType === this.constants.CaseTypes.CourtOfAppealCriminalDivision) { + if ( + this.caseType === this.constants.CaseTypes.CourtOfAppealCriminalDivision || + this.caseType === this.constants.CaseTypes.CrimeCrownCourt + ) { return false; } // Hearings with an interpreter should always have recording set to on @@ -127,7 +132,7 @@ export class SummaryComponent implements OnInit, OnDestroy { private confirmRemoveParticipant() { const participant = this.hearing.participants.find(x => x.email.toLowerCase() === this.selectedParticipantEmail.toLowerCase()); - const title = participant && participant.title ? `${participant.title}` : ''; + const title = participant?.title ? `${participant.title}` : ''; this.removerFullName = participant ? `${title} ${participant.first_name} ${participant.last_name}` : ''; const isInterpretee = @@ -167,7 +172,7 @@ export class SummaryComponent implements OnInit, OnDestroy { } this.hearing.participants.splice(indexOfParticipant, 1); this.removeLinkedParticipant(this.selectedParticipantEmail); - this.hearing = Object.assign({}, this.hearing); + this.hearing = { ...this.hearing }; this.hearingService.updateHearingRequest(this.hearing); this.hearingService.setBookingHasChanged(true); this.bookingService.removeParticipantEmail(); @@ -253,13 +258,8 @@ export class SummaryComponent implements OnInit, OnDestroy { const hearingDetailsResponse = await this.hearingService.saveHearing(this.hearing); if (this.judgeAssigned) { - // Poll Video-Api for booking confirmation - const schedule = timer(0, 5000).subscribe(async counter => { - const hearingStatusResponse = await this.hearingService.getStatus(hearingDetailsResponse.id); - if (hearingStatusResponse?.success || counter === 10) { - schedule.unsubscribe(); - await this.processBooking(hearingDetailsResponse, hearingStatusResponse); - } + this.bookingStatusService.pollForStatus(hearingDetailsResponse.id).subscribe(async response => { + await this.processBooking(hearingDetailsResponse, response); }); } else { await this.processMultiHearing(hearingDetailsResponse); @@ -347,8 +347,8 @@ export class SummaryComponent implements OnInit, OnDestroy { updateHearing() { this.$subscriptions.push( - this.hearingService.updateHearing(this.hearing).subscribe( - (hearingDetailsResponse: HearingDetailsResponse) => { + this.hearingService.updateHearing(this.hearing).subscribe({ + next: (hearingDetailsResponse: HearingDetailsResponse) => { this.showWaitSaving = false; this.hearingService.setBookingHasChanged(false); this.logger.info(`${this.loggerPrefix} Updated booking. Navigating to booking details.`, { @@ -363,14 +363,14 @@ export class SummaryComponent implements OnInit, OnDestroy { sessionStorage.setItem(this.newHearingSessionKey, hearingDetailsResponse.id); this.router.navigate([PageUrls.BookingConfirmation]); }, - error => { + error: error => { this.logger.error(`${this.loggerPrefix} Failed to update hearing with ID: ${this.hearing.hearing_id}.`, error, { hearing: this.hearing.hearing_id, payload: this.hearing }); this.setError(error); } - ) + }) ); } @@ -396,9 +396,9 @@ export class SummaryComponent implements OnInit, OnDestroy { }); } - getParticipantInfo(defenceAdvocate: string): string { + getDefenceAdvocateByContactEmail(defenceAdvocateConactEmail: string): string { let represents = ''; - const participant = this.hearing.participants.find(p => p.id === defenceAdvocate); + const participant = this.hearing.participants.find(p => p.contact_email === defenceAdvocateConactEmail); if (participant) { represents = participant.display_name + ', representing ' + participant.representee; } @@ -436,7 +436,7 @@ export class SummaryComponent implements OnInit, OnDestroy { } this.participantService.removeParticipant(this.hearing, this.selectedParticipantEmail); this.removeLinkedParticipant(this.selectedParticipantEmail); - this.hearing = Object.assign({}, this.hearing); + this.hearing = { ...this.hearing }; this.hearingService.updateHearingRequest(this.hearing); this.hearingService.setBookingHasChanged(true); this.bookingService.removeParticipantEmail(); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.html b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.html index 40d3ed818..0fbb2b543 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.html +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.html @@ -55,22 +55,13 @@

{{ hearing.HearingCaseNumber }} - diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.spec.ts index 8e5ea467a..cfdc3ce48 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.spec.ts @@ -13,6 +13,7 @@ import { AllocatedCsoResponse, BookingStatus, HearingDetailsResponse, + JusticeUserResponse, PhoneConferenceResponse, UpdateBookingStatus, UpdateBookingStatusRequest, @@ -24,6 +25,7 @@ import { UserIdentityService } from '../../services/user-identity.service'; import { VideoHearingsService } from '../../services/video-hearings.service'; import { PageUrls } from '../../shared/page-url.constants'; import { BookingDetailsComponent } from './booking-details.component'; +import { BookingStatusService } from 'src/app/services/booking-status-service'; let component: BookingDetailsComponent; let videoHearingServiceSpy: jasmine.SpyObj; @@ -140,7 +142,7 @@ export class BookingDetailsTestData { } const hearingResponse = new HearingDetailsResponse(); -const allocatedCsoResponse = new AllocatedCsoResponse(); +let allocatedCsoResponse = new AllocatedCsoResponse(); const caseModel = new CaseModel(); caseModel.name = 'X vs Y'; @@ -186,7 +188,9 @@ describe('BookingDetailsComponent', () => { 'getConferencePhoneNumber', 'isHearingAboutToStart', 'isConferenceClosed', - 'getAllocatedCsoForHearing' + 'getAllocatedCsoForHearing', + 'rebookHearing', + 'getStatus' ]); routerSpy = jasmine.createSpyObj('Router', ['navigate', 'navigateByUrl']); bookingServiceSpy = jasmine.createSpyObj('BookingService', [ @@ -201,8 +205,10 @@ describe('BookingDetailsComponent', () => { returnUrlServiceSpy = jasmine.createSpyObj('ReturnUrlService', ['popUrl', 'setUrl']); const defaultUpdateBookingStatusResponse = new UpdateBookingStatusResponse({ success: true, telephone_conference_id: '1234' }); + const bookingStatusService = new BookingStatusService(videoHearingServiceSpy); beforeEach(() => { + allocatedCsoResponse = new AllocatedCsoResponse({ cso: null, supports_work_allocation: true, hearing_id: hearingResponse.id }); videoHearingServiceSpy.getHearingById.and.returnValue(of(hearingResponse)); videoHearingServiceSpy.updateBookingStatus.and.returnValue(of(defaultUpdateBookingStatusResponse)); videoHearingServiceSpy.mapHearingDetailsResponseToHearingModel.and.returnValue(hearingModel); @@ -221,7 +227,8 @@ describe('BookingDetailsComponent', () => { bookingServiceSpy, bookingPersistServiceSpy, loggerSpy, - returnUrlServiceSpy + returnUrlServiceSpy, + bookingStatusService ); component.hearingId = '1'; }); @@ -249,8 +256,29 @@ describe('BookingDetailsComponent', () => { expect(component.booking.cases[0].number).toBe('XX3456234565'); expect(component.hearing.QuestionnaireNotRequired).toBeTruthy(); expect(component.hearing.AudioRecordingRequired).toBeTruthy(); + expect(component.hearing.AllocatedTo).toBe('Not Allocated'); discardPeriodicTasks(); })); + + it('should get allocated cso details', fakeAsync(() => { + const username = 'foo@test.com'; + allocatedCsoResponse.cso = new JusticeUserResponse({ username }); + videoHearingServiceSpy.getAllocatedCsoForHearing.and.returnValue(of(allocatedCsoResponse)); + component.ngOnInit(); + tick(); + expect(component.hearing.AllocatedTo).toBe(username); + discardPeriodicTasks(); + })); + + it('should set hearing AllocatedTo "Not Required" when venue does not support work allocation', fakeAsync(() => { + allocatedCsoResponse.supports_work_allocation = false; + videoHearingServiceSpy.getAllocatedCsoForHearing.and.returnValue(of(allocatedCsoResponse)); + component.ngOnInit(); + tick(); + expect(component.hearing.AllocatedTo).toBe('Not Required'); + discardPeriodicTasks(); + })); + it('should call service to map hearing response to HearingModel', () => { component.mapResponseToModel(new HearingDetailsResponse()); expect(videoHearingServiceSpy.mapHearingDetailsResponseToHearingModel).toHaveBeenCalled(); @@ -319,11 +347,6 @@ describe('BookingDetailsComponent', () => { component.setTimeObserver(); expect(component.isConfirmationTimeValid).toBeTruthy(); })); - it('should confirm booking', () => { - component.isVhOfficerAdmin = true; - component.confirmHearing(); - expect(videoHearingServiceSpy.getHearingById).toHaveBeenCalled(); - }); it('should show that user role is Vh office admin', () => { const profile = new UserProfileResponse({ is_vh_officer_administrator_role: true }); component.getUserRole(profile); @@ -334,15 +357,6 @@ describe('BookingDetailsComponent', () => { component.getUserRole(profile); expect(component.isVhOfficerAdmin).toBeFalsy(); }); - it('should not confirm booking if not the VH officer admin role', fakeAsync(() => { - component.ngOnInit(); - tick(1000); - const initialStatus = component.booking.status; - component.isVhOfficerAdmin = false; - component.confirmHearing(); - expect(component.booking.status).toBe(initialStatus); - discardPeriodicTasks(); - })); it('should persist status in the model', () => { component.booking = null; component.persistStatus(UpdateBookingStatus.Created); @@ -377,23 +391,6 @@ describe('BookingDetailsComponent', () => { component.navigateBack(); expect(routerSpy.navigateByUrl).toHaveBeenCalledWith(PageUrls.BookingsList); }); - it('should not show pop up if the confirm not failed', () => { - videoHearingServiceSpy.updateBookingStatus.and.returnValue(of(new UpdateBookingStatusResponse({ success: true }))); - component.isVhOfficerAdmin = true; - component.confirmHearing(); - expect(component.showConfirmingFailed).toBeFalsy(); - }); - it('should show pop up if the confirm failed', fakeAsync(() => { - component.ngOnInit(); - tick(1000); - videoHearingServiceSpy.updateBookingStatus.and.returnValue(of(new UpdateBookingStatusResponse({ success: false }))); - component.hearing.Status = ''; - component.isVhOfficerAdmin = true; - component.confirmHearing(); - tick(1000); - discardPeriodicTasks(); - expect(component.showConfirmingFailed).toBeTruthy(); - })); it('should hide pop up if the close confirm failed ok button was clicked', () => { component.showConfirmingFailed = true; component.closeConfirmFailed(); @@ -520,4 +517,69 @@ CY: 54321 (ID: 7777)`); expect(component.canRetryConfirmation).toBeTruthy(); }); + + describe('rebookHearing', () => { + beforeEach(() => { + videoHearingServiceSpy.rebookHearing.calls.reset(); + videoHearingServiceSpy.getStatus.calls.reset(); + component.isVhOfficerAdmin = true; + }); + + it('should update display when rebook hearing succeeds', fakeAsync(async () => { + const getStatusResponse = new UpdateBookingStatusResponse({ + success: true, + telephone_conference_id: '123' + }); + const conferencePhoneNumber = '1234'; + videoHearingServiceSpy.getStatus.and.returnValue(Promise.resolve(getStatusResponse)); + videoHearingServiceSpy.getConferencePhoneNumber.and.returnValue( + new Promise(resolve => { + resolve(conferencePhoneNumber); + }) + ); + + component.ngOnInit(); + await component.rebookHearing(); + tick(50000); + + expect(videoHearingServiceSpy.rebookHearing).toHaveBeenCalledWith(component.hearingId); + expect(videoHearingServiceSpy.getStatus).toHaveBeenCalledTimes(1); + expect(component.telephoneConferenceId).toBe(getStatusResponse.telephone_conference_id); + expect(component.conferencePhoneNumber).toBe(conferencePhoneNumber); + expect(component.conferencePhoneNumberWelsh).toBe(conferencePhoneNumber); + expect(component.booking.isConfirmed).toBeTruthy(); + expect(component.showConfirming).toBeFalsy(); + + discardPeriodicTasks(); + })); + + it('should update display when rebook hearing fails', fakeAsync(async () => { + const getStatusResponse = new UpdateBookingStatusResponse({ + success: false + }); + videoHearingServiceSpy.getStatus.and.returnValue(Promise.resolve(getStatusResponse)); + + component.ngOnInit(); + await component.rebookHearing(); + tick(60000); + + expect(videoHearingServiceSpy.rebookHearing).toHaveBeenCalledWith(component.hearingId); + expect(videoHearingServiceSpy.getStatus).toHaveBeenCalledTimes(11); + expect(component.showConfirmingFailed).toBeTruthy(); + expect(component.hearing.Status).toBe(UpdateBookingStatus.Failed); + expect(component.showConfirming).toBeFalsy(); + + discardPeriodicTasks(); + })); + + it('should not rebook hearing when user is not in the VH officer role', fakeAsync(async () => { + component.isVhOfficerAdmin = false; + + await component.rebookHearing(); + + expect(videoHearingServiceSpy.rebookHearing).toHaveBeenCalledTimes(0); + + discardPeriodicTasks(); + })); + }); }); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.ts index 7140a9f85..0077e6efa 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/booking-details/booking-details.component.ts @@ -14,12 +14,14 @@ import { HearingDetailsResponse, UpdateBookingStatus, UpdateBookingStatusRequest, + UpdateBookingStatusResponse, UserProfileResponse } from '../../services/clients/api-client'; import { Logger } from '../../services/logger'; import { UserIdentityService } from '../../services/user-identity.service'; import { VideoHearingsService } from '../../services/video-hearings.service'; import { PageUrls } from '../../shared/page-url.constants'; +import { BookingStatusService } from 'src/app/services/booking-status-service'; @Component({ selector: 'app-booking-details', @@ -59,7 +61,8 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { private bookingService: BookingService, private bookingPersistService: BookingPersistService, private logger: Logger, - private returnUrlService: ReturnUrlService + private returnUrlService: ReturnUrlService, + private bookingStatusService: BookingStatusService ) { this.showCancelBooking = false; this.showConfirming = false; @@ -96,7 +99,7 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { setSubscribers() { if (this.isConfirmationTimeValid) { - this.timeSubscription = this.$timeObserver.subscribe(x => { + this.timeSubscription = this.$timeObserver.subscribe(() => { this.setTimeObserver(); }); } @@ -137,7 +140,12 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { this.hearing.Endpoints = this.bookingDetailsService.mapBookingEndpoints(hearingResponse); this.videoHearingService .getAllocatedCsoForHearing(hearingResponse.id) - .subscribe(response => (this.hearing.AllocatedTo = response?.cso?.username ?? 'Unallocated')); + .subscribe( + response => + (this.hearing.AllocatedTo = response.supports_work_allocation + ? response?.cso?.username ?? 'Not Allocated' + : 'Not Required') + ); } mapResponseToModel(hearingResponse: HearingDetailsResponse): HearingModel { @@ -162,6 +170,7 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { } editHearing() { + this.bookingService.setEditMode(); this.router.navigate([PageUrls.Summary]); } @@ -169,10 +178,24 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { this.showCancelBooking = true; } - confirmHearing() { - if (this.isVhOfficerAdmin) { - this.updateHearingStatus(UpdateBookingStatus.Created, ''); + async rebookHearing() { + if (!this.isVhOfficerAdmin) { + this.logger.warn(`${this.loggerPrefix} Cannot rebook hearing - user is not a Vh Officer Admin`); + return; } + + this.showConfirming = true; + const hearingId = this.hearingId; + + await this.videoHearingService.rebookHearing(hearingId); + + this.bookingStatusService.pollForStatus(hearingId).subscribe(async response => { + let updateBookingStatus: UpdateBookingStatus = UpdateBookingStatus.Failed; + if (response?.success) { + updateBookingStatus = UpdateBookingStatus.Created; + } + await this.updateHearingStatusDisplay(response, updateBookingStatus); + }); } keepBooking() { @@ -194,20 +217,8 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { const updateBookingStatusResponse = await lastValueFrom( this.videoHearingService.updateBookingStatus(this.hearingId, updateBookingStatus) ); - if (updateBookingStatusResponse.success) { - this.telephoneConferenceId = updateBookingStatusResponse.telephone_conference_id; - this.conferencePhoneNumber = await this.videoHearingService.getConferencePhoneNumber(); - this.conferencePhoneNumberWelsh = await this.videoHearingService.getConferencePhoneNumber(true); - this.updateStatusHandler(status); - this.booking.isConfirmed = true; - } else { - this.showConfirmingFailed = true; - this.updateStatusHandler(UpdateBookingStatus.Failed); - } - this.showConfirming = false; - this.logger.info(`${this.loggerPrefix} Hearing status changed`, { hearingId: this.hearingId, status: status }); - this.logger.event(`${this.loggerPrefix} Hearing status changed`, { hearingId: this.hearingId, status: status }); + await this.updateHearingStatusDisplay(updateBookingStatusResponse, status); } catch (error) { if (status === UpdateBookingStatus.Cancelled) { this.showCancelBooking = false; @@ -221,6 +232,23 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { } } + async updateHearingStatusDisplay(statusResponse: UpdateBookingStatusResponse, status: UpdateBookingStatus) { + if (statusResponse.success) { + this.telephoneConferenceId = statusResponse.telephone_conference_id; + this.conferencePhoneNumber = await this.videoHearingService.getConferencePhoneNumber(); + this.conferencePhoneNumberWelsh = await this.videoHearingService.getConferencePhoneNumber(true); + this.updateStatusHandler(status); + this.booking.isConfirmed = true; + } else { + this.showConfirmingFailed = true; + this.updateStatusHandler(UpdateBookingStatus.Failed); + } + + this.showConfirming = false; + this.logger.info(`${this.loggerPrefix} Hearing status changed`, { hearingId: this.hearingId, status: statusResponse }); + this.logger.event(`${this.loggerPrefix} Hearing status changed`, { hearingId: this.hearingId, status: statusResponse }); + } + updateStatusHandler(status: UpdateBookingStatus) { if (status === UpdateBookingStatus.Cancelled) { this.showCancelBooking = false; @@ -231,14 +259,14 @@ export class BookingDetailsComponent implements OnInit, OnDestroy { return; } this.$subscriptions.push( - this.videoHearingService.getHearingById(this.hearingId).subscribe( - newData => { + this.videoHearingService.getHearingById(this.hearingId).subscribe({ + next: newData => { this.mapHearing(newData); }, - error => { + error: error => { this.logger.error(`${this.loggerPrefix} Error to get hearing Id: ${this.hearingId}`, error); } - ) + }) ); this.logger.info(`${this.loggerPrefix} updateStatusHandler --> Hearing status changed`, { hearingId: this.hearingId, diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.html b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.html index 819f62b1d..b5c11d629 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.html +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.html @@ -126,10 +126,10 @@

Video access points

{{ endpoint.displayName }}

-
+
link to endpoint - {{ getParticipantInfo(endpoint.defenceAdvocate) }} + {{ getDefenceAdvocateByContactEmail(endpoint.defenceAdvocate) }}
diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.spec.ts index 93d67f783..e36b9842a 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.spec.ts @@ -119,7 +119,7 @@ describe('HearingDetailsComponent', () => { ); participants.push(participant); component.participants = participants; - const result = component.getParticipantInfo('123-123'); + const result = component.getDefenceAdvocateByContactEmail(participant.Email); expect(result).toBe('display_name, representing representee'); }); it('it should display the participant and representee', () => { @@ -145,7 +145,7 @@ describe('HearingDetailsComponent', () => { ); participants.push(participant); component.participants = participants; - const result = component.getParticipantInfo('123-1234'); + const result = component.getDefenceAdvocateByContactEmail('madeup@doesnotexist.com'); expect(result).toBe(''); }); describe('feature flag turn on and off ', () => { diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.ts index 30f5cfe18..0744642ca 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/bookings-list/hearing-details/hearing-details.component.ts @@ -51,9 +51,9 @@ export class HearingDetailsComponent implements OnInit, OnDestroy { this.destroyed$.next(); } - getParticipantInfo(participantId: string): string { + getDefenceAdvocateByContactEmail(defenceAdvocateContactEmail: string): string { let represents = ''; - const participant = this.participants.find(p => p.ParticipantId === participantId); + const participant = this.participants.find(p => p.Email === defenceAdvocateContactEmail); if (participant) { represents = participant.DisplayName + ', representing ' + participant.Representee; } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/common/constants.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/common/constants.ts index bae7bafc8..929608f20 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/common/constants.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/common/constants.ts @@ -13,7 +13,7 @@ export const Constants = { TextInputPatternDisplayName: /^([-A-Za-z0-9 ',._])*$/, TextInputPatternName: /^(\w+(?:\w|['._-](?!['._-]))*\w+)$/, PostCodePattern: /^([a-zA-Z]{1,2}([0-9]{1,2}|[0-9][a-zA-Z])\s*[0-9][a-zA-Z]{2})$/, - EmailPattern: /^([!#-'*/-9=?A-Z^-~-]+(\.[!#-'*/-9=?A-Z^-~-]+)*)@([!#-'*/-9=?A-Z^-~-]+(\.[!#-'*/-9=?A-Z^-~-]+)+)$/, + EmailPattern: /^([!#-'*/-9=?A-Z^-~-][^&]+(\.[!#-'*/-9=?A-Z^-~-][^&]+)*)@([!#-'*/-9=?A-Z^-~-][^&]+(\.[!#-'*/-9=?A-Z^-~-][^&]+)+)$/, PhonePattern: /^([0-9() +-.])*$/, Judge: 'Judge', Citizen: 'Citizen', @@ -84,7 +84,7 @@ export const Constants = { UserRestored: 'Changes saved successfully.' }, OtherParticipantRoles: ['Staff Member', 'Observer', 'Panel Member', 'Winger'], - CaseTypes: { CourtOfAppealCriminalDivision: 'Court of Appeal Criminal Division' } + CaseTypes: { CourtOfAppealCriminalDivision: 'Court of Appeal Criminal Division', CrimeCrownCourt: 'Crime Crown Court' } }; /* diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/endpoint.model.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/endpoint.model.ts index dce7c6f74..1d5e4f7ab 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/endpoint.model.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/endpoint.model.ts @@ -3,6 +3,9 @@ export class EndpointModel { displayName?: string | undefined; sip?: string | undefined; pin?: string | undefined; + /** + * Defence advocate email address, not their ID + */ defenceAdvocate?: string | undefined; username?: string | undefined; contactEmail?: string | undefined; diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/hearing.model.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/hearing.model.ts index e319e311c..d5f4f477a 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/hearing.model.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/common/model/hearing.model.ts @@ -13,34 +13,37 @@ export class HearingModel { this.hearing_dates = []; this.hearing_id = ''; } - hearing_id?: string | undefined; - scheduled_date_time?: Date | undefined; - scheduled_duration?: number | undefined; - hearing_type_id?: number | undefined; - cases?: CaseModel[] | undefined; - participants?: ParticipantModel[] | undefined; - created_by?: string | undefined; - case_type?: string | undefined; - other_information?: string | undefined; - judge_email?: string | undefined; - judge_phone?: string | undefined; - court_room?: string | undefined; - hearing_venue_id?: number | undefined; - case_type_id?: number | undefined; - hearing_type_name?: string | undefined; - court_id?: number | undefined; - court_name?: string | undefined; - created_date?: Date | undefined; - updated_by?: string | undefined; - updated_date: Date | undefined; - status?: string | undefined; + hearing_id?: string; + scheduled_date_time?: Date; + scheduled_duration?: number; + hearing_type_id?: number; + cases?: CaseModel[]; + participants?: ParticipantModel[]; + created_by?: string; + case_type?: string; + case_type_service_id?: string; + other_information?: string; + judge_email?: string; + judge_phone?: string; + court_room?: string; + hearing_venue_id?: number; + case_type_id?: number; + hearing_type_name?: string; + hearing_type_code?: string; + court_id?: number; + court_name?: string; + court_code?: string; + created_date?: Date; + updated_by?: string; + updated_date: Date; + status?: string; questionnaire_not_required: boolean; audio_recording_required?: boolean; - endpoints?: EndpointModel[] | undefined; - multiDays?: boolean | undefined; - end_hearing_date_time?: Date | undefined; - telephone_conference_id?: string | undefined; - linked_participants?: LinkedParticipantModel[] | undefined; + endpoints?: EndpointModel[]; + multiDays?: boolean; + end_hearing_date_time?: Date; + telephone_conference_id?: string; + linked_participants?: LinkedParticipantModel[]; hearing_dates?: Date[]; isConfirmed?: boolean; } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/manage-team/manage-team.module.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/manage-team/manage-team.module.ts index 43d1f0d7f..0406fec98 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/manage-team/manage-team.module.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/manage-team/manage-team.module.ts @@ -18,6 +18,11 @@ import { ConfirmRestoreJusticeUserPopupComponent } from './pop-ups/confirm-resto ConfirmRestoreJusticeUserPopupComponent ], imports: [SharedModule, FontAwesomeModule, ManageTeamRoutingModule], - exports: [ManageTeamComponent] + exports: [ + ManageTeamComponent, + ConfirmDeleteHoursPopupComponent, + ConfirmDeleteJusticeUserPopupComponent, + ConfirmRestoreJusticeUserPopupComponent + ] }) export class ManageTeamModule {} diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/app-insights-logger.service.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/app-insights-logger.service.ts index 229bcc53d..da2723582 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/app-insights-logger.service.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/app-insights-logger.service.ts @@ -13,7 +13,7 @@ export class AppInsightsLogger implements LogAdapter { this.configService.getClientSettings().subscribe(settings => { this.appInsights = new ApplicationInsights({ config: { - instrumentationKey: settings.instrumentation_key + connectionString: settings.connection_string } }); this.appInsights.loadAppInsights(); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/booking-details.service.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/booking-details.service.ts index 6e5f60917..55c2d4ec9 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/booking-details.service.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/booking-details.service.ts @@ -81,12 +81,13 @@ export class BookingDetailsService { const endpoints: EndpointModel[] = []; if (hearingResponse.endpoints && hearingResponse.endpoints.length > 0) { hearingResponse.endpoints.forEach(e => { + const defenceAdvocate = hearingResponse.participants.find(p => p.id === e.defence_advocate_id); const epModel = new EndpointModel(); epModel.id = e.id; epModel.displayName = e.display_name; epModel.pin = e.pin; epModel.sip = e.sip; - epModel.defenceAdvocate = e.defence_advocate_id; + epModel.defenceAdvocate = defenceAdvocate?.contact_email; endpoints.push(epModel); }); } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/booking-status-service.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/booking-status-service.ts new file mode 100644 index 000000000..7196876ce --- /dev/null +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/booking-status-service.ts @@ -0,0 +1,32 @@ +import { Observable, timer } from 'rxjs'; +import { VideoHearingsService } from './video-hearings.service'; +import { UpdateBookingStatusResponse } from './clients/api-client'; +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class BookingStatusService { + constructor(private videoHearingService: VideoHearingsService) {} + + pollForStatus(hearingId: string): Observable { + const maxAttempts = 10; + const interval = 5000; + + return new Observable(subscriber => { + const schedule = timer(0, interval).subscribe(async (counter: number) => { + try { + const statusResponse = await this.videoHearingService.getStatus(hearingId); + if (statusResponse?.success || counter === maxAttempts) { + schedule.unsubscribe(); + subscriber.next(statusResponse); + subscriber.complete(); + } + } catch (error) { + schedule.unsubscribe(); + subscriber.error(error); + } + }); + }); + } +} diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/clients/api-client.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/clients/api-client.ts index 124cbac3e..1f0ee0ed9 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/clients/api-client.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/clients/api-client.ts @@ -1059,6 +1059,111 @@ export class BHClient extends ApiClientBase { return _observableOf(null as any); } + /** + * Rebook an existing hearing with a booking status of Failed + * @param hearingId Id of the hearing with a status of Failed + * @return No Content + */ + rebookHearing(hearingId: string): Observable { + let url_ = this.baseUrl + '/api/hearings/{hearingId}/conferences'; + if (hearingId === undefined || hearingId === null) throw new Error("The parameter 'hearingId' must be defined."); + url_ = url_.replace('{hearingId}', encodeURIComponent('' + hearingId)); + url_ = url_.replace(/[?&]$/, ''); + + let options_: any = { + observe: 'response', + responseType: 'blob', + headers: new HttpHeaders({}) + }; + + return _observableFrom(this.transformOptions(options_)) + .pipe( + _observableMergeMap(transformedOptions_ => { + return this.http.request('post', url_, transformedOptions_); + }) + ) + .pipe( + _observableMergeMap((response_: any) => { + return this.processRebookHearing(response_); + }) + ) + .pipe( + _observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processRebookHearing(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else return _observableThrow(response_) as any as Observable; + }) + ); + } + + protected processRebookHearing(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse + ? response.body + : (response as any).error instanceof Blob + ? (response as any).error + : undefined; + + let _headers: any = {}; + if (response.headers) { + for (let key of response.headers.keys()) { + _headers[key] = response.headers.get(key); + } + } + if (status === 500) { + return blobToText(responseBlob).pipe( + _observableMergeMap((_responseText: string) => { + let result500: any = null; + let resultData500 = _responseText === '' ? null : JSON.parse(_responseText, this.jsonParseReviver); + result500 = UnexpectedErrorResponse.fromJS(resultData500); + return throwException('Server Error', status, _responseText, _headers, result500); + }) + ); + } else if (status === 204) { + return blobToText(responseBlob).pipe( + _observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + }) + ); + } else if (status === 404) { + return blobToText(responseBlob).pipe( + _observableMergeMap((_responseText: string) => { + let result404: any = null; + let resultData404 = _responseText === '' ? null : JSON.parse(_responseText, this.jsonParseReviver); + result404 = ProblemDetails.fromJS(resultData404); + return throwException('Not Found', status, _responseText, _headers, result404); + }) + ); + } else if (status === 400) { + return blobToText(responseBlob).pipe( + _observableMergeMap((_responseText: string) => { + let result400: any = null; + let resultData400 = _responseText === '' ? null : JSON.parse(_responseText, this.jsonParseReviver); + result400 = ValidationProblemDetails.fromJS(resultData400); + return throwException('Bad Request', status, _responseText, _headers, result400); + }) + ); + } else if (status === 401) { + return blobToText(responseBlob).pipe( + _observableMergeMap((_responseText: string) => { + return throwException('Unauthorized', status, _responseText, _headers); + }) + ); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe( + _observableMergeMap((_responseText: string) => { + return throwException('An unexpected server error occurred.', status, _responseText, _headers); + }) + ); + } + return _observableOf(null as any); + } + /** * Clone hearings with the details of a given hearing on given dates * @param hearingId Original hearing to clone @@ -3138,10 +3243,13 @@ export class BHClient extends ApiClientBase { /** * Gets a list hearing types + * @param includeDeleted (optional) * @return Success */ - getHearingTypes(): Observable { - let url_ = this.baseUrl + '/api/reference/types'; + getHearingTypes(includeDeleted: boolean | undefined): Observable { + let url_ = this.baseUrl + '/api/reference/types?'; + if (includeDeleted === null) throw new Error("The parameter 'includeDeleted' cannot be null."); + else if (includeDeleted !== undefined) url_ += 'includeDeleted=' + encodeURIComponent('' + includeDeleted) + '&'; url_ = url_.replace(/[?&]$/, ''); let options_: any = { @@ -3241,13 +3349,13 @@ export class BHClient extends ApiClientBase { /** * Get available participant roles - * @param caseTypeName (optional) + * @param caseTypeParameter (optional) * @return Success */ - getParticipantRoles(caseTypeName: string | undefined): Observable { + getParticipantRoles(caseTypeParameter: string | undefined): Observable { let url_ = this.baseUrl + '/api/reference/participantroles?'; - if (caseTypeName === null) throw new Error("The parameter 'caseTypeName' cannot be null."); - else if (caseTypeName !== undefined) url_ += 'caseTypeName=' + encodeURIComponent('' + caseTypeName) + '&'; + if (caseTypeParameter === null) throw new Error("The parameter 'caseTypeParameter' cannot be null."); + else if (caseTypeParameter !== undefined) url_ += 'caseTypeParameter=' + encodeURIComponent('' + caseTypeParameter) + '&'; url_ = url_.replace(/[?&]$/, ''); let options_: any = { @@ -5180,13 +5288,15 @@ export class BHClient extends ApiClientBase { } /** - * @param id (optional) * @return Success */ - deleteNonAvailabilityWorkHours(id: number | undefined): Observable { - let url_ = this.baseUrl + '/api/workhours/NonAvailability?'; - if (id === null) throw new Error("The parameter 'id' cannot be null."); - else if (id !== undefined) url_ += 'id=' + encodeURIComponent('' + id) + '&'; + deleteNonAvailabilityWorkHours(username: string, nonAvailabilityId: number): Observable { + let url_ = this.baseUrl + '/api/workhours/NonAvailability/{username}/{nonAvailabilityId}'; + if (username === undefined || username === null) throw new Error("The parameter 'username' must be defined."); + url_ = url_.replace('{username}', encodeURIComponent('' + username)); + if (nonAvailabilityId === undefined || nonAvailabilityId === null) + throw new Error("The parameter 'nonAvailabilityId' must be defined."); + url_ = url_.replace('{nonAvailabilityId}', encodeURIComponent('' + nonAvailabilityId)); url_ = url_.replace(/[?&]$/, ''); let options_: any = { @@ -5278,11 +5388,22 @@ export class BHClient extends ApiClientBase { } } +export enum BookingStatus { + Booked = 'Booked', + Created = 'Created', + Cancelled = 'Cancelled', + Failed = 'Failed' +} + export enum JudgeAccountType { Courtroom = 'Courtroom', Judiciary = 'Judiciary' } +export enum LinkedParticipantType { + Interpreter = 'Interpreter' +} + /** Create a new Justice User */ export class AddNewJusticeUserRequest implements IAddNewJusticeUserRequest { /** The user's first name */ @@ -5353,7 +5474,7 @@ export interface IAddNewJusticeUserRequest { } export class BookHearingRequest implements IBookHearingRequest { - booking_details?: BookNewHearingRequest; + booking_details?: BookingDetailsRequest; is_multi_day?: boolean; multi_hearing_details?: MultiHearingRequest; other_information_details?: string | undefined; @@ -5368,7 +5489,7 @@ export class BookHearingRequest implements IBookHearingRequest { init(_data?: any) { if (_data) { - this.booking_details = _data['booking_details'] ? BookNewHearingRequest.fromJS(_data['booking_details']) : undefined; + this.booking_details = _data['booking_details'] ? BookingDetailsRequest.fromJS(_data['booking_details']) : undefined; this.is_multi_day = _data['is_multi_day']; this.multi_hearing_details = _data['multi_hearing_details'] ? MultiHearingRequest.fromJS(_data['multi_hearing_details']) @@ -5395,12 +5516,130 @@ export class BookHearingRequest implements IBookHearingRequest { } export interface IBookHearingRequest { - booking_details?: BookNewHearingRequest; + booking_details?: BookingDetailsRequest; is_multi_day?: boolean; multi_hearing_details?: MultiHearingRequest; other_information_details?: string | undefined; } +export class BookingDetailsRequest implements IBookingDetailsRequest { + scheduled_date_time?: Date; + scheduled_duration?: number; + hearing_venue_name?: string | undefined; + case_type_name?: string | undefined; + hearing_type_name?: string | undefined; + cases?: CaseRequest[] | undefined; + participants?: ParticipantRequest[] | undefined; + hearing_room_name?: string | undefined; + other_information?: string | undefined; + created_by?: string | undefined; + questionnaire_not_required?: boolean; + audio_recording_required?: boolean; + is_multi_day_hearing?: boolean; + endpoints?: EndpointRequest[] | undefined; + linked_participants?: LinkedParticipantRequest[] | undefined; + + constructor(data?: IBookingDetailsRequest) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + } + } + if (!data) { + this.is_multi_day_hearing = false; + } + } + + init(_data?: any) { + if (_data) { + this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; + this.scheduled_duration = _data['scheduled_duration']; + this.hearing_venue_name = _data['hearing_venue_name']; + this.case_type_name = _data['case_type_name']; + this.hearing_type_name = _data['hearing_type_name']; + if (Array.isArray(_data['cases'])) { + this.cases = [] as any; + for (let item of _data['cases']) this.cases!.push(CaseRequest.fromJS(item)); + } + if (Array.isArray(_data['participants'])) { + this.participants = [] as any; + for (let item of _data['participants']) this.participants!.push(ParticipantRequest.fromJS(item)); + } + this.hearing_room_name = _data['hearing_room_name']; + this.other_information = _data['other_information']; + this.created_by = _data['created_by']; + this.questionnaire_not_required = _data['questionnaire_not_required']; + this.audio_recording_required = _data['audio_recording_required']; + this.is_multi_day_hearing = _data['is_multi_day_hearing'] !== undefined ? _data['is_multi_day_hearing'] : false; + if (Array.isArray(_data['endpoints'])) { + this.endpoints = [] as any; + for (let item of _data['endpoints']) this.endpoints!.push(EndpointRequest.fromJS(item)); + } + if (Array.isArray(_data['linked_participants'])) { + this.linked_participants = [] as any; + for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipantRequest.fromJS(item)); + } + } + } + + static fromJS(data: any): BookingDetailsRequest { + data = typeof data === 'object' ? data : {}; + let result = new BookingDetailsRequest(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; + data['scheduled_duration'] = this.scheduled_duration; + data['hearing_venue_name'] = this.hearing_venue_name; + data['case_type_name'] = this.case_type_name; + data['hearing_type_name'] = this.hearing_type_name; + if (Array.isArray(this.cases)) { + data['cases'] = []; + for (let item of this.cases) data['cases'].push(item.toJSON()); + } + if (Array.isArray(this.participants)) { + data['participants'] = []; + for (let item of this.participants) data['participants'].push(item.toJSON()); + } + data['hearing_room_name'] = this.hearing_room_name; + data['other_information'] = this.other_information; + data['created_by'] = this.created_by; + data['questionnaire_not_required'] = this.questionnaire_not_required; + data['audio_recording_required'] = this.audio_recording_required; + data['is_multi_day_hearing'] = this.is_multi_day_hearing; + if (Array.isArray(this.endpoints)) { + data['endpoints'] = []; + for (let item of this.endpoints) data['endpoints'].push(item.toJSON()); + } + if (Array.isArray(this.linked_participants)) { + data['linked_participants'] = []; + for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); + } + return data; + } +} + +export interface IBookingDetailsRequest { + scheduled_date_time?: Date; + scheduled_duration?: number; + hearing_venue_name?: string | undefined; + case_type_name?: string | undefined; + hearing_type_name?: string | undefined; + cases?: CaseRequest[] | undefined; + participants?: ParticipantRequest[] | undefined; + hearing_room_name?: string | undefined; + other_information?: string | undefined; + created_by?: string | undefined; + questionnaire_not_required?: boolean; + audio_recording_required?: boolean; + is_multi_day_hearing?: boolean; + endpoints?: EndpointRequest[] | undefined; + linked_participants?: LinkedParticipantRequest[] | undefined; +} + export class BookingSearchRequest implements IBookingSearchRequest { cursor?: string | undefined; limit?: number; @@ -5494,12 +5733,12 @@ export interface IBookingSearchRequest { noAllocated?: boolean; } -export class UpdateAccountDetailsRequest implements IUpdateAccountDetailsRequest { - first_name?: string | undefined; - last_name?: string | undefined; - current_username?: string | undefined; +export class CaseRequest implements ICaseRequest { + number?: string | undefined; + name?: string | undefined; + is_lead_case?: boolean; - constructor(data?: IUpdateAccountDetailsRequest) { + constructor(data?: ICaseRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5509,34 +5748,238 @@ export class UpdateAccountDetailsRequest implements IUpdateAccountDetailsRequest init(_data?: any) { if (_data) { - this.first_name = _data['first_name']; - this.last_name = _data['last_name']; - this.current_username = _data['current_username']; + this.number = _data['number']; + this.name = _data['name']; + this.is_lead_case = _data['is_lead_case']; } } - static fromJS(data: any): UpdateAccountDetailsRequest { + static fromJS(data: any): CaseRequest { data = typeof data === 'object' ? data : {}; - let result = new UpdateAccountDetailsRequest(); + let result = new CaseRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['first_name'] = this.first_name; - data['last_name'] = this.last_name; - data['current_username'] = this.current_username; + data['number'] = this.number; + data['name'] = this.name; + data['is_lead_case'] = this.is_lead_case; return data; } } -export interface IUpdateAccountDetailsRequest { - first_name?: string | undefined; - last_name?: string | undefined; - current_username?: string | undefined; -} - +export interface ICaseRequest { + number?: string | undefined; + name?: string | undefined; + is_lead_case?: boolean; +} + +export class EndpointRequest implements IEndpointRequest { + display_name?: string | undefined; + defence_advocate_contact_email?: string | undefined; + + constructor(data?: IEndpointRequest) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + } + } + } + + init(_data?: any) { + if (_data) { + this.display_name = _data['display_name']; + this.defence_advocate_contact_email = _data['defence_advocate_contact_email']; + } + } + + static fromJS(data: any): EndpointRequest { + data = typeof data === 'object' ? data : {}; + let result = new EndpointRequest(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data['display_name'] = this.display_name; + data['defence_advocate_contact_email'] = this.defence_advocate_contact_email; + return data; + } +} + +export interface IEndpointRequest { + display_name?: string | undefined; + defence_advocate_contact_email?: string | undefined; +} + +export class LinkedParticipantRequest implements ILinkedParticipantRequest { + participant_contact_email?: string | undefined; + linked_participant_contact_email?: string | undefined; + type?: LinkedParticipantType; + + constructor(data?: ILinkedParticipantRequest) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + } + } + } + + init(_data?: any) { + if (_data) { + this.participant_contact_email = _data['participant_contact_email']; + this.linked_participant_contact_email = _data['linked_participant_contact_email']; + this.type = _data['type']; + } + } + + static fromJS(data: any): LinkedParticipantRequest { + data = typeof data === 'object' ? data : {}; + let result = new LinkedParticipantRequest(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data['participant_contact_email'] = this.participant_contact_email; + data['linked_participant_contact_email'] = this.linked_participant_contact_email; + data['type'] = this.type; + return data; + } +} + +export interface ILinkedParticipantRequest { + participant_contact_email?: string | undefined; + linked_participant_contact_email?: string | undefined; + type?: LinkedParticipantType; +} + +export class ParticipantRequest implements IParticipantRequest { + title?: string | undefined; + first_name?: string | undefined; + middle_names?: string | undefined; + last_name?: string | undefined; + contact_email?: string | undefined; + telephone_number?: string | undefined; + username?: string | undefined; + display_name?: string | undefined; + case_role_name?: string | undefined; + hearing_role_name?: string | undefined; + representee?: string | undefined; + organisation_name?: string | undefined; + + constructor(data?: IParticipantRequest) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + } + } + } + + init(_data?: any) { + if (_data) { + this.title = _data['title']; + this.first_name = _data['first_name']; + this.middle_names = _data['middle_names']; + this.last_name = _data['last_name']; + this.contact_email = _data['contact_email']; + this.telephone_number = _data['telephone_number']; + this.username = _data['username']; + this.display_name = _data['display_name']; + this.case_role_name = _data['case_role_name']; + this.hearing_role_name = _data['hearing_role_name']; + this.representee = _data['representee']; + this.organisation_name = _data['organisation_name']; + } + } + + static fromJS(data: any): ParticipantRequest { + data = typeof data === 'object' ? data : {}; + let result = new ParticipantRequest(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data['title'] = this.title; + data['first_name'] = this.first_name; + data['middle_names'] = this.middle_names; + data['last_name'] = this.last_name; + data['contact_email'] = this.contact_email; + data['telephone_number'] = this.telephone_number; + data['username'] = this.username; + data['display_name'] = this.display_name; + data['case_role_name'] = this.case_role_name; + data['hearing_role_name'] = this.hearing_role_name; + data['representee'] = this.representee; + data['organisation_name'] = this.organisation_name; + return data; + } +} + +export interface IParticipantRequest { + title?: string | undefined; + first_name?: string | undefined; + middle_names?: string | undefined; + last_name?: string | undefined; + contact_email?: string | undefined; + telephone_number?: string | undefined; + username?: string | undefined; + display_name?: string | undefined; + case_role_name?: string | undefined; + hearing_role_name?: string | undefined; + representee?: string | undefined; + organisation_name?: string | undefined; +} + +export class UpdateAccountDetailsRequest implements IUpdateAccountDetailsRequest { + first_name?: string | undefined; + last_name?: string | undefined; + current_username?: string | undefined; + + constructor(data?: IUpdateAccountDetailsRequest) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + } + } + } + + init(_data?: any) { + if (_data) { + this.first_name = _data['first_name']; + this.last_name = _data['last_name']; + this.current_username = _data['current_username']; + } + } + + static fromJS(data: any): UpdateAccountDetailsRequest { + data = typeof data === 'object' ? data : {}; + let result = new UpdateAccountDetailsRequest(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data['first_name'] = this.first_name; + data['last_name'] = this.last_name; + data['current_username'] = this.current_username; + return data; + } +} + +export interface IUpdateAccountDetailsRequest { + first_name?: string | undefined; + last_name?: string | undefined; + current_username?: string | undefined; +} + export class AllocationHearingsResponse implements IAllocationHearingsResponse { /** The hearing id */ hearing_id?: string; @@ -5622,34 +6065,11 @@ export interface IAllocationHearingsResponse { concurrent_hearings_count?: number | undefined; } -/** Configuration to initialise the UI application */ -export class ClientSettingsResponse implements IClientSettingsResponse { - /** The Azure Tenant Id */ - tenant_id?: string | undefined; - /** The UI Client Id */ - client_id?: string | undefined; - /** The UI Resource Id, can be used as an alternative id to ClientId for authentication */ - resource_id?: string | undefined; - /** The Uri to redirect back to after a successful login */ - redirect_uri?: string | undefined; - /** The Uri to redirect back to after a successful logout */ - post_logout_redirect_uri?: string | undefined; - /** The Application Insight Instrumentation Key */ - instrumentation_key?: string | undefined; - /** The reform email */ - test_username_stem?: string | undefined; - /** To join the conference phone number */ - conference_phone_number?: string | undefined; - /** To join the conference phone number - welsh */ - conference_phone_number_welsh?: string | undefined; - /** The date to switch on option to join by phone */ - join_by_phone_from_date?: string | undefined; - /** The Uri to video web url */ - video_web_url?: string | undefined; - /** The LaunchDarkly Client ID */ - readonly launch_darkly_client_id?: string | undefined; +export class BookingsByDateResponse implements IBookingsByDateResponse { + scheduled_date?: Date; + hearings?: BookingsHearingResponse[] | undefined; - constructor(data?: IClientSettingsResponse) { + constructor(data?: IBookingsByDateResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5659,80 +6079,64 @@ export class ClientSettingsResponse implements IClientSettingsResponse { init(_data?: any) { if (_data) { - this.tenant_id = _data['tenant_id']; - this.client_id = _data['client_id']; - this.resource_id = _data['resource_id']; - this.redirect_uri = _data['redirect_uri']; - this.post_logout_redirect_uri = _data['post_logout_redirect_uri']; - this.instrumentation_key = _data['instrumentation_key']; - this.test_username_stem = _data['test_username_stem']; - this.conference_phone_number = _data['conference_phone_number']; - this.conference_phone_number_welsh = _data['conference_phone_number_welsh']; - this.join_by_phone_from_date = _data['join_by_phone_from_date']; - this.video_web_url = _data['video_web_url']; - (this).launch_darkly_client_id = _data['launch_darkly_client_id']; + this.scheduled_date = _data['scheduled_date'] ? new Date(_data['scheduled_date'].toString()) : undefined; + if (Array.isArray(_data['hearings'])) { + this.hearings = [] as any; + for (let item of _data['hearings']) this.hearings!.push(BookingsHearingResponse.fromJS(item)); + } } } - static fromJS(data: any): ClientSettingsResponse { + static fromJS(data: any): BookingsByDateResponse { data = typeof data === 'object' ? data : {}; - let result = new ClientSettingsResponse(); + let result = new BookingsByDateResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['tenant_id'] = this.tenant_id; - data['client_id'] = this.client_id; - data['resource_id'] = this.resource_id; - data['redirect_uri'] = this.redirect_uri; - data['post_logout_redirect_uri'] = this.post_logout_redirect_uri; - data['instrumentation_key'] = this.instrumentation_key; - data['test_username_stem'] = this.test_username_stem; - data['conference_phone_number'] = this.conference_phone_number; - data['conference_phone_number_welsh'] = this.conference_phone_number_welsh; - data['join_by_phone_from_date'] = this.join_by_phone_from_date; - data['video_web_url'] = this.video_web_url; - data['launch_darkly_client_id'] = this.launch_darkly_client_id; + data['scheduled_date'] = this.scheduled_date ? this.scheduled_date.toISOString() : undefined; + if (Array.isArray(this.hearings)) { + data['hearings'] = []; + for (let item of this.hearings) data['hearings'].push(item.toJSON()); + } return data; } } -/** Configuration to initialise the UI application */ -export interface IClientSettingsResponse { - /** The Azure Tenant Id */ - tenant_id?: string | undefined; - /** The UI Client Id */ - client_id?: string | undefined; - /** The UI Resource Id, can be used as an alternative id to ClientId for authentication */ - resource_id?: string | undefined; - /** The Uri to redirect back to after a successful login */ - redirect_uri?: string | undefined; - /** The Uri to redirect back to after a successful logout */ - post_logout_redirect_uri?: string | undefined; - /** The Application Insight Instrumentation Key */ - instrumentation_key?: string | undefined; - /** The reform email */ - test_username_stem?: string | undefined; - /** To join the conference phone number */ - conference_phone_number?: string | undefined; - /** To join the conference phone number - welsh */ - conference_phone_number_welsh?: string | undefined; - /** The date to switch on option to join by phone */ - join_by_phone_from_date?: string | undefined; - /** The Uri to video web url */ - video_web_url?: string | undefined; - /** The LaunchDarkly Client ID */ - launch_darkly_client_id?: string | undefined; +export interface IBookingsByDateResponse { + scheduled_date?: Date; + hearings?: BookingsHearingResponse[] | undefined; } -export class DateForUnallocatedHearings implements IDateForUnallocatedHearings { - count?: number; - date_start?: Date; - date_end?: Date | undefined; +export class BookingsHearingResponse implements IBookingsHearingResponse { + hearing_id?: string; + hearing_number?: string | undefined; + hearing_name?: string | undefined; + scheduled_date_time?: Date; + scheduled_duration?: number; + case_type_name?: string | undefined; + hearing_type_name?: string | undefined; + court_room?: string | undefined; + court_address?: string | undefined; + judge_name?: string | undefined; + created_by?: string | undefined; + created_date?: Date; + last_edit_by?: string | undefined; + last_edit_date?: Date | undefined; + confirmed_by?: string | undefined; + confirmed_date?: Date | undefined; + hearing_date?: Date; + status?: BookingStatus2; + questionnaire_not_required?: boolean; + audio_recording_required?: boolean; + cancel_reason?: string | undefined; + group_id?: string | undefined; + court_room_account?: string | undefined; + allocated_to?: string | undefined; - constructor(data?: IDateForUnallocatedHearings) { + constructor(data?: IBookingsHearingResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5742,46 +6146,105 @@ export class DateForUnallocatedHearings implements IDateForUnallocatedHearings { init(_data?: any) { if (_data) { - this.count = _data['count']; - this.date_start = _data['date_start'] ? new Date(_data['date_start'].toString()) : undefined; - this.date_end = _data['date_end'] ? new Date(_data['date_end'].toString()) : undefined; + this.hearing_id = _data['hearing_id']; + this.hearing_number = _data['hearing_number']; + this.hearing_name = _data['hearing_name']; + this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; + this.scheduled_duration = _data['scheduled_duration']; + this.case_type_name = _data['case_type_name']; + this.hearing_type_name = _data['hearing_type_name']; + this.court_room = _data['court_room']; + this.court_address = _data['court_address']; + this.judge_name = _data['judge_name']; + this.created_by = _data['created_by']; + this.created_date = _data['created_date'] ? new Date(_data['created_date'].toString()) : undefined; + this.last_edit_by = _data['last_edit_by']; + this.last_edit_date = _data['last_edit_date'] ? new Date(_data['last_edit_date'].toString()) : undefined; + this.confirmed_by = _data['confirmed_by']; + this.confirmed_date = _data['confirmed_date'] ? new Date(_data['confirmed_date'].toString()) : undefined; + this.hearing_date = _data['hearing_date'] ? new Date(_data['hearing_date'].toString()) : undefined; + this.status = _data['status']; + this.questionnaire_not_required = _data['questionnaire_not_required']; + this.audio_recording_required = _data['audio_recording_required']; + this.cancel_reason = _data['cancel_reason']; + this.group_id = _data['group_id']; + this.court_room_account = _data['court_room_account']; + this.allocated_to = _data['allocated_to']; } } - static fromJS(data: any): DateForUnallocatedHearings { + static fromJS(data: any): BookingsHearingResponse { data = typeof data === 'object' ? data : {}; - let result = new DateForUnallocatedHearings(); + let result = new BookingsHearingResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['count'] = this.count; - data['date_start'] = this.date_start ? this.date_start.toISOString() : undefined; - data['date_end'] = this.date_end ? this.date_end.toISOString() : undefined; + data['hearing_id'] = this.hearing_id; + data['hearing_number'] = this.hearing_number; + data['hearing_name'] = this.hearing_name; + data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; + data['scheduled_duration'] = this.scheduled_duration; + data['case_type_name'] = this.case_type_name; + data['hearing_type_name'] = this.hearing_type_name; + data['court_room'] = this.court_room; + data['court_address'] = this.court_address; + data['judge_name'] = this.judge_name; + data['created_by'] = this.created_by; + data['created_date'] = this.created_date ? this.created_date.toISOString() : undefined; + data['last_edit_by'] = this.last_edit_by; + data['last_edit_date'] = this.last_edit_date ? this.last_edit_date.toISOString() : undefined; + data['confirmed_by'] = this.confirmed_by; + data['confirmed_date'] = this.confirmed_date ? this.confirmed_date.toISOString() : undefined; + data['hearing_date'] = this.hearing_date ? this.hearing_date.toISOString() : undefined; + data['status'] = this.status; + data['questionnaire_not_required'] = this.questionnaire_not_required; + data['audio_recording_required'] = this.audio_recording_required; + data['cancel_reason'] = this.cancel_reason; + data['group_id'] = this.group_id; + data['court_room_account'] = this.court_room_account; + data['allocated_to'] = this.allocated_to; return data; } } -export interface IDateForUnallocatedHearings { - count?: number; - date_start?: Date; - date_end?: Date | undefined; +export interface IBookingsHearingResponse { + hearing_id?: string; + hearing_number?: string | undefined; + hearing_name?: string | undefined; + scheduled_date_time?: Date; + scheduled_duration?: number; + case_type_name?: string | undefined; + hearing_type_name?: string | undefined; + court_room?: string | undefined; + court_address?: string | undefined; + judge_name?: string | undefined; + created_by?: string | undefined; + created_date?: Date; + last_edit_by?: string | undefined; + last_edit_date?: Date | undefined; + confirmed_by?: string | undefined; + confirmed_date?: Date | undefined; + hearing_date?: Date; + status?: BookingStatus2; + questionnaire_not_required?: boolean; + audio_recording_required?: boolean; + cancel_reason?: string | undefined; + group_id?: string | undefined; + court_room_account?: string | undefined; + allocated_to?: string | undefined; } -/** Defines a type of hearing based on case */ -export class HearingTypeResponse implements IHearingTypeResponse { - /** The short code for the type */ - code?: string | undefined; - /** Which case type it belongs to */ - group?: string | undefined; - /** Unique identifier for this type of hearing */ - id?: number | undefined; - /** Hearing type display name */ - name?: string | undefined; +export class BookingsResponse implements IBookingsResponse { + next_cursor?: string | undefined; + limit?: number; + prev_page_url?: string | undefined; + next_page_url?: string | undefined; + hearings?: BookingsByDateResponse[] | undefined; - constructor(data?: IHearingTypeResponse) { + constructor(data?: IBookingsResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5791,57 +6254,52 @@ export class HearingTypeResponse implements IHearingTypeResponse { init(_data?: any) { if (_data) { - this.code = _data['code']; - this.group = _data['group']; - this.id = _data['id']; - this.name = _data['name']; + this.next_cursor = _data['next_cursor']; + this.limit = _data['limit']; + this.prev_page_url = _data['prev_page_url']; + this.next_page_url = _data['next_page_url']; + if (Array.isArray(_data['hearings'])) { + this.hearings = [] as any; + for (let item of _data['hearings']) this.hearings!.push(BookingsByDateResponse.fromJS(item)); + } } } - static fromJS(data: any): HearingTypeResponse { + static fromJS(data: any): BookingsResponse { data = typeof data === 'object' ? data : {}; - let result = new HearingTypeResponse(); + let result = new BookingsResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['code'] = this.code; - data['group'] = this.group; - data['id'] = this.id; - data['name'] = this.name; + data['next_cursor'] = this.next_cursor; + data['limit'] = this.limit; + data['prev_page_url'] = this.prev_page_url; + data['next_page_url'] = this.next_page_url; + if (Array.isArray(this.hearings)) { + data['hearings'] = []; + for (let item of this.hearings) data['hearings'].push(item.toJSON()); + } return data; } } -/** Defines a type of hearing based on case */ -export interface IHearingTypeResponse { - /** The short code for the type */ - code?: string | undefined; - /** Which case type it belongs to */ - group?: string | undefined; - /** Unique identifier for this type of hearing */ - id?: number | undefined; - /** Hearing type display name */ - name?: string | undefined; +export interface IBookingsResponse { + next_cursor?: string | undefined; + limit?: number; + prev_page_url?: string | undefined; + next_page_url?: string | undefined; + hearings?: BookingsByDateResponse[] | undefined; } -/** A judge existing in the system */ -export class JudgeResponse implements IJudgeResponse { - /** Judge first name */ - first_name?: string | undefined; - /** Judge last name */ - last_name?: string | undefined; - /** Judge display name as in the identity system */ - display_name?: string | undefined; - /** Judge username/email */ - email?: string | undefined; - /** Judge contact email */ - contact_email?: string | undefined; - account_type?: JudgeAccountType; +export class CaseResponse implements ICaseResponse { + number?: string | undefined; + name?: string | undefined; + is_lead_case?: boolean; - constructor(data?: IJudgeResponse) { + constructor(data?: ICaseResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5851,57 +6309,62 @@ export class JudgeResponse implements IJudgeResponse { init(_data?: any) { if (_data) { - this.first_name = _data['first_name']; - this.last_name = _data['last_name']; - this.display_name = _data['display_name']; - this.email = _data['email']; - this.contact_email = _data['contact_email']; - this.account_type = _data['account_type']; + this.number = _data['number']; + this.name = _data['name']; + this.is_lead_case = _data['is_lead_case']; } } - static fromJS(data: any): JudgeResponse { + static fromJS(data: any): CaseResponse { data = typeof data === 'object' ? data : {}; - let result = new JudgeResponse(); + let result = new CaseResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['first_name'] = this.first_name; - data['last_name'] = this.last_name; - data['display_name'] = this.display_name; - data['email'] = this.email; - data['contact_email'] = this.contact_email; - data['account_type'] = this.account_type; + data['number'] = this.number; + data['name'] = this.name; + data['is_lead_case'] = this.is_lead_case; return data; } } -/** A judge existing in the system */ -export interface IJudgeResponse { - /** Judge first name */ - first_name?: string | undefined; - /** Judge last name */ - last_name?: string | undefined; - /** Judge display name as in the identity system */ - display_name?: string | undefined; - /** Judge username/email */ - email?: string | undefined; - /** Judge contact email */ - contact_email?: string | undefined; - account_type?: JudgeAccountType; +export interface ICaseResponse { + number?: string | undefined; + name?: string | undefined; + is_lead_case?: boolean; } -/** A public holiday */ -export class PublicHolidayResponse implements IPublicHolidayResponse { - /** Name of a public holiday */ - name?: string | undefined; - /** Date of a public holiday */ - date?: Date; +/** Configuration to initialise the UI application */ +export class ClientSettingsResponse implements IClientSettingsResponse { + /** The Azure Tenant Id */ + tenant_id?: string | undefined; + /** The UI Client Id */ + client_id?: string | undefined; + /** The UI Resource Id, can be used as an alternative id to ClientId for authentication */ + resource_id?: string | undefined; + /** The Uri to redirect back to after a successful login */ + redirect_uri?: string | undefined; + /** The Uri to redirect back to after a successful logout */ + post_logout_redirect_uri?: string | undefined; + /** The Application Insights Connection String */ + connection_string?: string | undefined; + /** The reform email */ + test_username_stem?: string | undefined; + /** To join the conference phone number */ + conference_phone_number?: string | undefined; + /** To join the conference phone number - welsh */ + conference_phone_number_welsh?: string | undefined; + /** The date to switch on option to join by phone */ + join_by_phone_from_date?: string | undefined; + /** The Uri to video web url */ + video_web_url?: string | undefined; + /** The LaunchDarkly Client ID */ + readonly launch_darkly_client_id?: string | undefined; - constructor(data?: IPublicHolidayResponse) { + constructor(data?: IClientSettingsResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5911,41 +6374,80 @@ export class PublicHolidayResponse implements IPublicHolidayResponse { init(_data?: any) { if (_data) { - this.name = _data['name']; - this.date = _data['date'] ? new Date(_data['date'].toString()) : undefined; + this.tenant_id = _data['tenant_id']; + this.client_id = _data['client_id']; + this.resource_id = _data['resource_id']; + this.redirect_uri = _data['redirect_uri']; + this.post_logout_redirect_uri = _data['post_logout_redirect_uri']; + this.connection_string = _data['connection_string']; + this.test_username_stem = _data['test_username_stem']; + this.conference_phone_number = _data['conference_phone_number']; + this.conference_phone_number_welsh = _data['conference_phone_number_welsh']; + this.join_by_phone_from_date = _data['join_by_phone_from_date']; + this.video_web_url = _data['video_web_url']; + (this).launch_darkly_client_id = _data['launch_darkly_client_id']; } } - static fromJS(data: any): PublicHolidayResponse { + static fromJS(data: any): ClientSettingsResponse { data = typeof data === 'object' ? data : {}; - let result = new PublicHolidayResponse(); + let result = new ClientSettingsResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['name'] = this.name; - data['date'] = this.date ? this.date.toISOString() : undefined; + data['tenant_id'] = this.tenant_id; + data['client_id'] = this.client_id; + data['resource_id'] = this.resource_id; + data['redirect_uri'] = this.redirect_uri; + data['post_logout_redirect_uri'] = this.post_logout_redirect_uri; + data['connection_string'] = this.connection_string; + data['test_username_stem'] = this.test_username_stem; + data['conference_phone_number'] = this.conference_phone_number; + data['conference_phone_number_welsh'] = this.conference_phone_number_welsh; + data['join_by_phone_from_date'] = this.join_by_phone_from_date; + data['video_web_url'] = this.video_web_url; + data['launch_darkly_client_id'] = this.launch_darkly_client_id; return data; } } -/** A public holiday */ -export interface IPublicHolidayResponse { - /** Name of a public holiday */ - name?: string | undefined; - /** Date of a public holiday */ - date?: Date; +/** Configuration to initialise the UI application */ +export interface IClientSettingsResponse { + /** The Azure Tenant Id */ + tenant_id?: string | undefined; + /** The UI Client Id */ + client_id?: string | undefined; + /** The UI Resource Id, can be used as an alternative id to ClientId for authentication */ + resource_id?: string | undefined; + /** The Uri to redirect back to after a successful login */ + redirect_uri?: string | undefined; + /** The Uri to redirect back to after a successful logout */ + post_logout_redirect_uri?: string | undefined; + /** The Application Insights Connection String */ + connection_string?: string | undefined; + /** The reform email */ + test_username_stem?: string | undefined; + /** To join the conference phone number */ + conference_phone_number?: string | undefined; + /** To join the conference phone number - welsh */ + conference_phone_number_welsh?: string | undefined; + /** The date to switch on option to join by phone */ + join_by_phone_from_date?: string | undefined; + /** The Uri to video web url */ + video_web_url?: string | undefined; + /** The LaunchDarkly Client ID */ + launch_darkly_client_id?: string | undefined; } -export class UnallocatedHearingsForVhoResponse implements IUnallocatedHearingsForVhoResponse { - today?: DateForUnallocatedHearings; - tomorrow?: DateForUnallocatedHearings; - next7_days?: DateForUnallocatedHearings; - next30_days?: DateForUnallocatedHearings; +export class DateForUnallocatedHearings implements IDateForUnallocatedHearings { + count?: number; + date_start?: Date; + date_end?: Date | undefined; - constructor(data?: IUnallocatedHearingsForVhoResponse) { + constructor(data?: IDateForUnallocatedHearings) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5955,41 +6457,42 @@ export class UnallocatedHearingsForVhoResponse implements IUnallocatedHearingsFo init(_data?: any) { if (_data) { - this.today = _data['today'] ? DateForUnallocatedHearings.fromJS(_data['today']) : undefined; - this.tomorrow = _data['tomorrow'] ? DateForUnallocatedHearings.fromJS(_data['tomorrow']) : undefined; - this.next7_days = _data['next7_days'] ? DateForUnallocatedHearings.fromJS(_data['next7_days']) : undefined; - this.next30_days = _data['next30_days'] ? DateForUnallocatedHearings.fromJS(_data['next30_days']) : undefined; + this.count = _data['count']; + this.date_start = _data['date_start'] ? new Date(_data['date_start'].toString()) : undefined; + this.date_end = _data['date_end'] ? new Date(_data['date_end'].toString()) : undefined; } } - static fromJS(data: any): UnallocatedHearingsForVhoResponse { + static fromJS(data: any): DateForUnallocatedHearings { data = typeof data === 'object' ? data : {}; - let result = new UnallocatedHearingsForVhoResponse(); + let result = new DateForUnallocatedHearings(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['today'] = this.today ? this.today.toJSON() : undefined; - data['tomorrow'] = this.tomorrow ? this.tomorrow.toJSON() : undefined; - data['next7_days'] = this.next7_days ? this.next7_days.toJSON() : undefined; - data['next30_days'] = this.next30_days ? this.next30_days.toJSON() : undefined; + data['count'] = this.count; + data['date_start'] = this.date_start ? this.date_start.toISOString() : undefined; + data['date_end'] = this.date_end ? this.date_end.toISOString() : undefined; return data; } } -export interface IUnallocatedHearingsForVhoResponse { - today?: DateForUnallocatedHearings; - tomorrow?: DateForUnallocatedHearings; - next7_days?: DateForUnallocatedHearings; - next30_days?: DateForUnallocatedHearings; +export interface IDateForUnallocatedHearings { + count?: number; + date_start?: Date; + date_end?: Date | undefined; } -export class UnexpectedErrorResponse implements IUnexpectedErrorResponse { - error_message?: string | undefined; +export class EndpointResponse implements IEndpointResponse { + id?: string; + display_name?: string | undefined; + sip?: string | undefined; + pin?: string | undefined; + defence_advocate_id?: string | undefined; - constructor(data?: IUnexpectedErrorResponse) { + constructor(data?: IEndpointResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -5999,34 +6502,77 @@ export class UnexpectedErrorResponse implements IUnexpectedErrorResponse { init(_data?: any) { if (_data) { - this.error_message = _data['error_message']; + this.id = _data['id']; + this.display_name = _data['display_name']; + this.sip = _data['sip']; + this.pin = _data['pin']; + this.defence_advocate_id = _data['defence_advocate_id']; } } - static fromJS(data: any): UnexpectedErrorResponse { + static fromJS(data: any): EndpointResponse { data = typeof data === 'object' ? data : {}; - let result = new UnexpectedErrorResponse(); + let result = new EndpointResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['error_message'] = this.error_message; + data['id'] = this.id; + data['display_name'] = this.display_name; + data['sip'] = this.sip; + data['pin'] = this.pin; + data['defence_advocate_id'] = this.defence_advocate_id; return data; } } -export interface IUnexpectedErrorResponse { - error_message?: string | undefined; +export interface IEndpointResponse { + id?: string; + display_name?: string | undefined; + sip?: string | undefined; + pin?: string | undefined; + defence_advocate_id?: string | undefined; } -export class UserProfileResponse implements IUserProfileResponse { - is_vh_officer_administrator_role?: boolean; - is_vh_team_leader?: boolean; - is_case_administrator?: boolean; +export class HearingDetailsResponse implements IHearingDetailsResponse { + id?: string; + scheduled_date_time?: Date; + scheduled_duration?: number; + /** V1 only */ + hearing_venue_name?: string | undefined; + /** V2 only */ + hearing_venue_code?: string | undefined; + /** V1 only */ + case_type_name?: string | undefined; + /** V2 only */ + service_id?: string | undefined; + /** V1 only */ + hearing_type_name?: string | undefined; + /** V2 only */ + hearing_type_code?: string | undefined; + cases?: CaseResponse[] | undefined; + participants?: ParticipantResponse[] | undefined; + /** V1 only */ + telephone_participants?: TelephoneParticipantResponse[] | undefined; + hearing_room_name?: string | undefined; + other_information?: string | undefined; + created_date?: Date; + created_by?: string | undefined; + updated_by?: string | undefined; + updated_date?: Date; + confirmed_by?: string | undefined; + confirmed_date?: Date | undefined; + status?: BookingStatus; + /** V1 only */ + questionnaire_not_required?: boolean; + audio_recording_required?: boolean; + cancel_reason?: string | undefined; + endpoints?: EndpointResponse[] | undefined; + group_id?: string | undefined; - constructor(data?: IUserProfileResponse) { + constructor(data?: IHearingDetailsResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6036,78 +6582,150 @@ export class UserProfileResponse implements IUserProfileResponse { init(_data?: any) { if (_data) { - this.is_vh_officer_administrator_role = _data['is_vh_officer_administrator_role']; - this.is_vh_team_leader = _data['is_vh_team_leader']; - this.is_case_administrator = _data['is_case_administrator']; - } - } - - static fromJS(data: any): UserProfileResponse { - data = typeof data === 'object' ? data : {}; - let result = new UserProfileResponse(); - result.init(data); - return result; - } - - toJSON(data?: any) { - data = typeof data === 'object' ? data : {}; - data['is_vh_officer_administrator_role'] = this.is_vh_officer_administrator_role; - data['is_vh_team_leader'] = this.is_vh_team_leader; - data['is_case_administrator'] = this.is_case_administrator; - return data; - } -} - -export interface IUserProfileResponse { - is_vh_officer_administrator_role?: boolean; - is_vh_team_leader?: boolean; - is_case_administrator?: boolean; -} - -export class ApplicationVersion implements IApplicationVersion { - file_version?: string | undefined; - information_version?: string | undefined; - - constructor(data?: IApplicationVersion) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + this.id = _data['id']; + this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; + this.scheduled_duration = _data['scheduled_duration']; + this.hearing_venue_name = _data['hearing_venue_name']; + this.hearing_venue_code = _data['hearing_venue_code']; + this.case_type_name = _data['case_type_name']; + this.service_id = _data['service_id']; + this.hearing_type_name = _data['hearing_type_name']; + this.hearing_type_code = _data['hearing_type_code']; + if (Array.isArray(_data['cases'])) { + this.cases = [] as any; + for (let item of _data['cases']) this.cases!.push(CaseResponse.fromJS(item)); } + if (Array.isArray(_data['participants'])) { + this.participants = [] as any; + for (let item of _data['participants']) this.participants!.push(ParticipantResponse.fromJS(item)); + } + if (Array.isArray(_data['telephone_participants'])) { + this.telephone_participants = [] as any; + for (let item of _data['telephone_participants']) + this.telephone_participants!.push(TelephoneParticipantResponse.fromJS(item)); + } + this.hearing_room_name = _data['hearing_room_name']; + this.other_information = _data['other_information']; + this.created_date = _data['created_date'] ? new Date(_data['created_date'].toString()) : undefined; + this.created_by = _data['created_by']; + this.updated_by = _data['updated_by']; + this.updated_date = _data['updated_date'] ? new Date(_data['updated_date'].toString()) : undefined; + this.confirmed_by = _data['confirmed_by']; + this.confirmed_date = _data['confirmed_date'] ? new Date(_data['confirmed_date'].toString()) : undefined; + this.status = _data['status']; + this.questionnaire_not_required = _data['questionnaire_not_required']; + this.audio_recording_required = _data['audio_recording_required']; + this.cancel_reason = _data['cancel_reason']; + if (Array.isArray(_data['endpoints'])) { + this.endpoints = [] as any; + for (let item of _data['endpoints']) this.endpoints!.push(EndpointResponse.fromJS(item)); + } + this.group_id = _data['group_id']; } } - init(_data?: any) { - if (_data) { - this.file_version = _data['file_version']; - this.information_version = _data['information_version']; - } - } - - static fromJS(data: any): ApplicationVersion { + static fromJS(data: any): HearingDetailsResponse { data = typeof data === 'object' ? data : {}; - let result = new ApplicationVersion(); + let result = new HearingDetailsResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['file_version'] = this.file_version; - data['information_version'] = this.information_version; + data['id'] = this.id; + data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; + data['scheduled_duration'] = this.scheduled_duration; + data['hearing_venue_name'] = this.hearing_venue_name; + data['hearing_venue_code'] = this.hearing_venue_code; + data['case_type_name'] = this.case_type_name; + data['service_id'] = this.service_id; + data['hearing_type_name'] = this.hearing_type_name; + data['hearing_type_code'] = this.hearing_type_code; + if (Array.isArray(this.cases)) { + data['cases'] = []; + for (let item of this.cases) data['cases'].push(item.toJSON()); + } + if (Array.isArray(this.participants)) { + data['participants'] = []; + for (let item of this.participants) data['participants'].push(item.toJSON()); + } + if (Array.isArray(this.telephone_participants)) { + data['telephone_participants'] = []; + for (let item of this.telephone_participants) data['telephone_participants'].push(item.toJSON()); + } + data['hearing_room_name'] = this.hearing_room_name; + data['other_information'] = this.other_information; + data['created_date'] = this.created_date ? this.created_date.toISOString() : undefined; + data['created_by'] = this.created_by; + data['updated_by'] = this.updated_by; + data['updated_date'] = this.updated_date ? this.updated_date.toISOString() : undefined; + data['confirmed_by'] = this.confirmed_by; + data['confirmed_date'] = this.confirmed_date ? this.confirmed_date.toISOString() : undefined; + data['status'] = this.status; + data['questionnaire_not_required'] = this.questionnaire_not_required; + data['audio_recording_required'] = this.audio_recording_required; + data['cancel_reason'] = this.cancel_reason; + if (Array.isArray(this.endpoints)) { + data['endpoints'] = []; + for (let item of this.endpoints) data['endpoints'].push(item.toJSON()); + } + data['group_id'] = this.group_id; return data; } } -export interface IApplicationVersion { - file_version?: string | undefined; - information_version?: string | undefined; +export interface IHearingDetailsResponse { + id?: string; + scheduled_date_time?: Date; + scheduled_duration?: number; + /** V1 only */ + hearing_venue_name?: string | undefined; + /** V2 only */ + hearing_venue_code?: string | undefined; + /** V1 only */ + case_type_name?: string | undefined; + /** V2 only */ + service_id?: string | undefined; + /** V1 only */ + hearing_type_name?: string | undefined; + /** V2 only */ + hearing_type_code?: string | undefined; + cases?: CaseResponse[] | undefined; + participants?: ParticipantResponse[] | undefined; + /** V1 only */ + telephone_participants?: TelephoneParticipantResponse[] | undefined; + hearing_room_name?: string | undefined; + other_information?: string | undefined; + created_date?: Date; + created_by?: string | undefined; + updated_by?: string | undefined; + updated_date?: Date; + confirmed_by?: string | undefined; + confirmed_date?: Date | undefined; + status?: BookingStatus; + /** V1 only */ + questionnaire_not_required?: boolean; + audio_recording_required?: boolean; + cancel_reason?: string | undefined; + endpoints?: EndpointResponse[] | undefined; + group_id?: string | undefined; } -export class CaseAndHearingRolesResponse implements ICaseAndHearingRolesResponse { +/** Defines a type of hearing based on case */ +export class HearingTypeResponse implements IHearingTypeResponse { + /** The short code for the type */ + code?: string | undefined; + /** Which case type it belongs to */ + group?: string | undefined; + /** Unique identifier for this type of hearing */ + id?: number | undefined; + /** Hearing type display name */ name?: string | undefined; - hearing_roles?: HearingRole[] | undefined; + /** The service id for the type */ + service_id?: string | undefined; - constructor(data?: ICaseAndHearingRolesResponse) { + constructor(data?: IHearingTypeResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6117,42 +6735,61 @@ export class CaseAndHearingRolesResponse implements ICaseAndHearingRolesResponse init(_data?: any) { if (_data) { + this.code = _data['code']; + this.group = _data['group']; + this.id = _data['id']; this.name = _data['name']; - if (Array.isArray(_data['hearing_roles'])) { - this.hearing_roles = [] as any; - for (let item of _data['hearing_roles']) this.hearing_roles!.push(HearingRole.fromJS(item)); - } + this.service_id = _data['service_id']; } } - static fromJS(data: any): CaseAndHearingRolesResponse { + static fromJS(data: any): HearingTypeResponse { data = typeof data === 'object' ? data : {}; - let result = new CaseAndHearingRolesResponse(); + let result = new HearingTypeResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; + data['code'] = this.code; + data['group'] = this.group; + data['id'] = this.id; data['name'] = this.name; - if (Array.isArray(this.hearing_roles)) { - data['hearing_roles'] = []; - for (let item of this.hearing_roles) data['hearing_roles'].push(item.toJSON()); - } + data['service_id'] = this.service_id; return data; } } -export interface ICaseAndHearingRolesResponse { +/** Defines a type of hearing based on case */ +export interface IHearingTypeResponse { + /** The short code for the type */ + code?: string | undefined; + /** Which case type it belongs to */ + group?: string | undefined; + /** Unique identifier for this type of hearing */ + id?: number | undefined; + /** Hearing type display name */ name?: string | undefined; - hearing_roles?: HearingRole[] | undefined; + /** The service id for the type */ + service_id?: string | undefined; } -export class CvpForAudioFileResponse implements ICvpForAudioFileResponse { - file_name?: string | undefined; - sas_token_uri?: string | undefined; +/** A judge existing in the system */ +export class JudgeResponse implements IJudgeResponse { + /** Judge first name */ + first_name?: string | undefined; + /** Judge last name */ + last_name?: string | undefined; + /** Judge display name as in the identity system */ + display_name?: string | undefined; + /** Judge username/email */ + email?: string | undefined; + /** Judge contact email */ + contact_email?: string | undefined; + account_type?: JudgeAccountType; - constructor(data?: ICvpForAudioFileResponse) { + constructor(data?: IJudgeResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6162,39 +6799,54 @@ export class CvpForAudioFileResponse implements ICvpForAudioFileResponse { init(_data?: any) { if (_data) { - this.file_name = _data['file_name']; - this.sas_token_uri = _data['sas_token_uri']; + this.first_name = _data['first_name']; + this.last_name = _data['last_name']; + this.display_name = _data['display_name']; + this.email = _data['email']; + this.contact_email = _data['contact_email']; + this.account_type = _data['account_type']; } } - static fromJS(data: any): CvpForAudioFileResponse { + static fromJS(data: any): JudgeResponse { data = typeof data === 'object' ? data : {}; - let result = new CvpForAudioFileResponse(); + let result = new JudgeResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['file_name'] = this.file_name; - data['sas_token_uri'] = this.sas_token_uri; + data['first_name'] = this.first_name; + data['last_name'] = this.last_name; + data['display_name'] = this.display_name; + data['email'] = this.email; + data['contact_email'] = this.contact_email; + data['account_type'] = this.account_type; return data; } } -export interface ICvpForAudioFileResponse { - file_name?: string | undefined; - sas_token_uri?: string | undefined; +/** A judge existing in the system */ +export interface IJudgeResponse { + /** Judge first name */ + first_name?: string | undefined; + /** Judge last name */ + last_name?: string | undefined; + /** Judge display name as in the identity system */ + display_name?: string | undefined; + /** Judge username/email */ + email?: string | undefined; + /** Judge contact email */ + contact_email?: string | undefined; + account_type?: JudgeAccountType; } -/** Case request */ -export class EditCaseRequest implements IEditCaseRequest { - /** The case number */ - number!: string; - /** The case name */ - name!: string; +export class LinkedParticipantResponse implements ILinkedParticipantResponse { + linked_id?: string; + type?: LinkedParticipantType; - constructor(data?: IEditCaseRequest) { + constructor(data?: ILinkedParticipantResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6204,61 +6856,82 @@ export class EditCaseRequest implements IEditCaseRequest { init(_data?: any) { if (_data) { - this.number = _data['number']; - this.name = _data['name']; + this.linked_id = _data['linked_id']; + this.type = _data['type']; } } - static fromJS(data: any): EditCaseRequest { + static fromJS(data: any): LinkedParticipantResponse { data = typeof data === 'object' ? data : {}; - let result = new EditCaseRequest(); + let result = new LinkedParticipantResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['number'] = this.number; - data['name'] = this.name; + data['linked_id'] = this.linked_id; + data['type'] = this.type; return data; } } -/** Case request */ -export interface IEditCaseRequest { - /** The case number */ - number: string; - /** The case name */ - name: string; +export interface ILinkedParticipantResponse { + linked_id?: string; + type?: LinkedParticipantType; } -export class EditEndpointRequest implements IEditEndpointRequest { - /** Endpoint Id. */ - id?: string | undefined; - /** The display name for the endpoint */ +export class ParticipantResponse implements IParticipantResponse { + id?: string; display_name?: string | undefined; - /** The username of the participant */ - defence_advocate_contact_email?: string | undefined; - - constructor(data?: IEditEndpointRequest) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; - } - } + case_role_name?: string | undefined; + hearing_role_name?: string | undefined; + user_role_name?: string | undefined; + title?: string | undefined; + first_name?: string | undefined; + middle_names?: string | undefined; + last_name?: string | undefined; + contact_email?: string | undefined; + telephone_number?: string | undefined; + username?: string | undefined; + organisation?: string | undefined; + representee?: string | undefined; + linked_participants?: LinkedParticipantResponse[] | undefined; + + constructor(data?: IParticipantResponse) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + } + } } init(_data?: any) { if (_data) { this.id = _data['id']; this.display_name = _data['display_name']; - this.defence_advocate_contact_email = _data['defence_advocate_contact_email']; + this.case_role_name = _data['case_role_name']; + this.hearing_role_name = _data['hearing_role_name']; + this.user_role_name = _data['user_role_name']; + this.title = _data['title']; + this.first_name = _data['first_name']; + this.middle_names = _data['middle_names']; + this.last_name = _data['last_name']; + this.contact_email = _data['contact_email']; + this.telephone_number = _data['telephone_number']; + this.username = _data['username']; + this.organisation = _data['organisation']; + this.representee = _data['representee']; + if (Array.isArray(_data['linked_participants'])) { + this.linked_participants = [] as any; + for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipantResponse.fromJS(item)); + } } } - static fromJS(data: any): EditEndpointRequest { + static fromJS(data: any): ParticipantResponse { data = typeof data === 'object' ? data : {}; - let result = new EditEndpointRequest(); + let result = new ParticipantResponse(); result.init(data); return result; } @@ -6267,167 +6940,102 @@ export class EditEndpointRequest implements IEditEndpointRequest { data = typeof data === 'object' ? data : {}; data['id'] = this.id; data['display_name'] = this.display_name; - data['defence_advocate_contact_email'] = this.defence_advocate_contact_email; + data['case_role_name'] = this.case_role_name; + data['hearing_role_name'] = this.hearing_role_name; + data['user_role_name'] = this.user_role_name; + data['title'] = this.title; + data['first_name'] = this.first_name; + data['middle_names'] = this.middle_names; + data['last_name'] = this.last_name; + data['contact_email'] = this.contact_email; + data['telephone_number'] = this.telephone_number; + data['username'] = this.username; + data['organisation'] = this.organisation; + data['representee'] = this.representee; + if (Array.isArray(this.linked_participants)) { + data['linked_participants'] = []; + for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); + } return data; } } -export interface IEditEndpointRequest { - /** Endpoint Id. */ - id?: string | undefined; - /** The display name for the endpoint */ +export interface IParticipantResponse { + id?: string; display_name?: string | undefined; - /** The username of the participant */ - defence_advocate_contact_email?: string | undefined; + case_role_name?: string | undefined; + hearing_role_name?: string | undefined; + user_role_name?: string | undefined; + title?: string | undefined; + first_name?: string | undefined; + middle_names?: string | undefined; + last_name?: string | undefined; + contact_email?: string | undefined; + telephone_number?: string | undefined; + username?: string | undefined; + organisation?: string | undefined; + representee?: string | undefined; + linked_participants?: LinkedParticipantResponse[] | undefined; } -/** Request for updating an existing hearing */ -export class EditHearingRequest implements IEditHearingRequest { - /** The date and time for a hearing */ - scheduled_date_time?: Date; - /** The duration of a hearing (number of minutes) */ - scheduled_duration?: number; - /** The name of the hearing venue */ - hearing_venue_name?: string | undefined; - /** The hearing room name at the hearing venue */ - hearing_room_name?: string | undefined; - case!: EditCaseRequest; - /** List of participants in hearing */ - participants!: EditParticipantRequest[] | undefined; - telephone_participants?: EditTelephoneParticipantRequest[] | undefined; - /** Any other information about the hearing */ - other_information?: string | undefined; - /** QuestionnaireNotRequired */ - questionnaire_not_required?: boolean; - /** Gets or sets audio recording required flag */ - audio_recording_required?: boolean; - /** List of endpoints for the hearing */ - endpoints?: EditEndpointRequest[] | undefined; +/** A public holiday */ +export class PublicHolidayResponse implements IPublicHolidayResponse { + /** Name of a public holiday */ + name?: string | undefined; + /** Date of a public holiday */ + date?: Date; - constructor(data?: IEditHearingRequest) { + constructor(data?: IPublicHolidayResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; } } - if (!data) { - this.case = new EditCaseRequest(); - } } init(_data?: any) { if (_data) { - this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; - this.scheduled_duration = _data['scheduled_duration']; - this.hearing_venue_name = _data['hearing_venue_name']; - this.hearing_room_name = _data['hearing_room_name']; - this.case = _data['case'] ? EditCaseRequest.fromJS(_data['case']) : new EditCaseRequest(); - if (Array.isArray(_data['participants'])) { - this.participants = [] as any; - for (let item of _data['participants']) this.participants!.push(EditParticipantRequest.fromJS(item)); - } - if (Array.isArray(_data['telephone_participants'])) { - this.telephone_participants = [] as any; - for (let item of _data['telephone_participants']) - this.telephone_participants!.push(EditTelephoneParticipantRequest.fromJS(item)); - } - this.other_information = _data['other_information']; - this.questionnaire_not_required = _data['questionnaire_not_required']; - this.audio_recording_required = _data['audio_recording_required']; - if (Array.isArray(_data['endpoints'])) { - this.endpoints = [] as any; - for (let item of _data['endpoints']) this.endpoints!.push(EditEndpointRequest.fromJS(item)); - } + this.name = _data['name']; + this.date = _data['date'] ? new Date(_data['date'].toString()) : undefined; } } - static fromJS(data: any): EditHearingRequest { + static fromJS(data: any): PublicHolidayResponse { data = typeof data === 'object' ? data : {}; - let result = new EditHearingRequest(); + let result = new PublicHolidayResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; - data['scheduled_duration'] = this.scheduled_duration; - data['hearing_venue_name'] = this.hearing_venue_name; - data['hearing_room_name'] = this.hearing_room_name; - data['case'] = this.case ? this.case.toJSON() : undefined; - if (Array.isArray(this.participants)) { - data['participants'] = []; - for (let item of this.participants) data['participants'].push(item.toJSON()); - } - if (Array.isArray(this.telephone_participants)) { - data['telephone_participants'] = []; - for (let item of this.telephone_participants) data['telephone_participants'].push(item.toJSON()); - } - data['other_information'] = this.other_information; - data['questionnaire_not_required'] = this.questionnaire_not_required; - data['audio_recording_required'] = this.audio_recording_required; - if (Array.isArray(this.endpoints)) { - data['endpoints'] = []; - for (let item of this.endpoints) data['endpoints'].push(item.toJSON()); - } + data['name'] = this.name; + data['date'] = this.date ? this.date.toISOString() : undefined; return data; } } -/** Request for updating an existing hearing */ -export interface IEditHearingRequest { - /** The date and time for a hearing */ - scheduled_date_time?: Date; - /** The duration of a hearing (number of minutes) */ - scheduled_duration?: number; - /** The name of the hearing venue */ - hearing_venue_name?: string | undefined; - /** The hearing room name at the hearing venue */ - hearing_room_name?: string | undefined; - case: EditCaseRequest; - /** List of participants in hearing */ - participants: EditParticipantRequest[] | undefined; - telephone_participants?: EditTelephoneParticipantRequest[] | undefined; - /** Any other information about the hearing */ - other_information?: string | undefined; - /** QuestionnaireNotRequired */ - questionnaire_not_required?: boolean; - /** Gets or sets audio recording required flag */ - audio_recording_required?: boolean; - /** List of endpoints for the hearing */ - endpoints?: EditEndpointRequest[] | undefined; +/** A public holiday */ +export interface IPublicHolidayResponse { + /** Name of a public holiday */ + name?: string | undefined; + /** Date of a public holiday */ + date?: Date; } -/** Participant request */ -export class EditParticipantRequest implements IEditParticipantRequest { - /** Participant Id. */ - id?: string | undefined; - /** Participant Title. */ - title?: string | undefined; - /** Participant first name. */ - first_name!: string; - /** Participant middle name. */ - middle_names?: string | undefined; - /** Participant last name. */ - last_name!: string; - /** Participant Contact Email */ - contact_email!: string; - /** Participant Telephone number */ - telephone_number?: string | undefined; - /** Participant Display Name */ - display_name!: string; - /** The name of the participant's case role */ +export class TelephoneParticipantResponse implements ITelephoneParticipantResponse { + id?: string; case_role_name?: string | undefined; - /** The name of the participant's hearing role */ hearing_role_name?: string | undefined; - /** The representee of a representative */ + first_name?: string | undefined; + last_name?: string | undefined; + contact_email?: string | undefined; + telephone_number?: string | undefined; + mobile_number?: string | undefined; representee?: string | undefined; - /** Organisation name */ - organisation_name?: string | undefined; - /** List of linked participants */ - linked_participants?: LinkedParticipant[] | undefined; + linked_participants?: LinkedParticipantResponse[] | undefined; - constructor(data?: IEditParticipantRequest) { + constructor(data?: ITelephoneParticipantResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6438,27 +7046,24 @@ export class EditParticipantRequest implements IEditParticipantRequest { init(_data?: any) { if (_data) { this.id = _data['id']; - this.title = _data['title']; + this.case_role_name = _data['case_role_name']; + this.hearing_role_name = _data['hearing_role_name']; this.first_name = _data['first_name']; - this.middle_names = _data['middle_names']; this.last_name = _data['last_name']; this.contact_email = _data['contact_email']; this.telephone_number = _data['telephone_number']; - this.display_name = _data['display_name']; - this.case_role_name = _data['case_role_name']; - this.hearing_role_name = _data['hearing_role_name']; + this.mobile_number = _data['mobile_number']; this.representee = _data['representee']; - this.organisation_name = _data['organisation_name']; if (Array.isArray(_data['linked_participants'])) { this.linked_participants = [] as any; - for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipant.fromJS(item)); + for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipantResponse.fromJS(item)); } } } - static fromJS(data: any): EditParticipantRequest { + static fromJS(data: any): TelephoneParticipantResponse { data = typeof data === 'object' ? data : {}; - let result = new EditParticipantRequest(); + let result = new TelephoneParticipantResponse(); result.init(data); return result; } @@ -6466,17 +7071,14 @@ export class EditParticipantRequest implements IEditParticipantRequest { toJSON(data?: any) { data = typeof data === 'object' ? data : {}; data['id'] = this.id; - data['title'] = this.title; + data['case_role_name'] = this.case_role_name; + data['hearing_role_name'] = this.hearing_role_name; data['first_name'] = this.first_name; - data['middle_names'] = this.middle_names; data['last_name'] = this.last_name; data['contact_email'] = this.contact_email; data['telephone_number'] = this.telephone_number; - data['display_name'] = this.display_name; - data['case_role_name'] = this.case_role_name; - data['hearing_role_name'] = this.hearing_role_name; + data['mobile_number'] = this.mobile_number; data['representee'] = this.representee; - data['organisation_name'] = this.organisation_name; if (Array.isArray(this.linked_participants)) { data['linked_participants'] = []; for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); @@ -6485,60 +7087,26 @@ export class EditParticipantRequest implements IEditParticipantRequest { } } -/** Participant request */ -export interface IEditParticipantRequest { - /** Participant Id. */ - id?: string | undefined; - /** Participant Title. */ - title?: string | undefined; - /** Participant first name. */ - first_name: string; - /** Participant middle name. */ - middle_names?: string | undefined; - /** Participant last name. */ - last_name: string; - /** Participant Contact Email */ - contact_email: string; - /** Participant Telephone number */ - telephone_number?: string | undefined; - /** Participant Display Name */ - display_name: string; - /** The name of the participant's case role */ - case_role_name?: string | undefined; - /** The name of the participant's hearing role */ - hearing_role_name?: string | undefined; - /** The representee of a representative */ - representee?: string | undefined; - /** Organisation name */ - organisation_name?: string | undefined; - /** List of linked participants */ - linked_participants?: LinkedParticipant[] | undefined; -} - -/** Participant request */ -export class EditTelephoneParticipantRequest implements IEditTelephoneParticipantRequest { - /** Participant Id */ +export interface ITelephoneParticipantResponse { id?: string; - /** The name of the participant's case role */ case_role_name?: string | undefined; - /** The name of the participant's hearing role */ hearing_role_name?: string | undefined; - /** Participant first name. */ first_name?: string | undefined; - /** Participant last name. */ last_name?: string | undefined; - /** Participant contact email */ contact_email?: string | undefined; - /** Participant telephone number */ telephone_number?: string | undefined; - /** Participant telephone number */ mobile_number?: string | undefined; - /** Gets or sets the person name that Representative represents. */ representee?: string | undefined; - /** The participant linked to this participant response */ - linked_participants?: LinkedParticipant[] | undefined; + linked_participants?: LinkedParticipantResponse[] | undefined; +} - constructor(data?: IEditTelephoneParticipantRequest) { +export class UnallocatedHearingsForVhoResponse implements IUnallocatedHearingsForVhoResponse { + today?: DateForUnallocatedHearings; + tomorrow?: DateForUnallocatedHearings; + next7_days?: DateForUnallocatedHearings; + next30_days?: DateForUnallocatedHearings; + + constructor(data?: IUnallocatedHearingsForVhoResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6548,78 +7116,41 @@ export class EditTelephoneParticipantRequest implements IEditTelephoneParticipan init(_data?: any) { if (_data) { - this.id = _data['id']; - this.case_role_name = _data['case_role_name']; - this.hearing_role_name = _data['hearing_role_name']; - this.first_name = _data['first_name']; - this.last_name = _data['last_name']; - this.contact_email = _data['contact_email']; - this.telephone_number = _data['telephone_number']; - this.mobile_number = _data['mobile_number']; - this.representee = _data['representee']; - if (Array.isArray(_data['linked_participants'])) { - this.linked_participants = [] as any; - for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipant.fromJS(item)); - } + this.today = _data['today'] ? DateForUnallocatedHearings.fromJS(_data['today']) : undefined; + this.tomorrow = _data['tomorrow'] ? DateForUnallocatedHearings.fromJS(_data['tomorrow']) : undefined; + this.next7_days = _data['next7_days'] ? DateForUnallocatedHearings.fromJS(_data['next7_days']) : undefined; + this.next30_days = _data['next30_days'] ? DateForUnallocatedHearings.fromJS(_data['next30_days']) : undefined; } } - static fromJS(data: any): EditTelephoneParticipantRequest { + static fromJS(data: any): UnallocatedHearingsForVhoResponse { data = typeof data === 'object' ? data : {}; - let result = new EditTelephoneParticipantRequest(); + let result = new UnallocatedHearingsForVhoResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['case_role_name'] = this.case_role_name; - data['hearing_role_name'] = this.hearing_role_name; - data['first_name'] = this.first_name; - data['last_name'] = this.last_name; - data['contact_email'] = this.contact_email; - data['telephone_number'] = this.telephone_number; - data['mobile_number'] = this.mobile_number; - data['representee'] = this.representee; - if (Array.isArray(this.linked_participants)) { - data['linked_participants'] = []; - for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); - } + data['today'] = this.today ? this.today.toJSON() : undefined; + data['tomorrow'] = this.tomorrow ? this.tomorrow.toJSON() : undefined; + data['next7_days'] = this.next7_days ? this.next7_days.toJSON() : undefined; + data['next30_days'] = this.next30_days ? this.next30_days.toJSON() : undefined; return data; } } -/** Participant request */ -export interface IEditTelephoneParticipantRequest { - /** Participant Id */ - id?: string; - /** The name of the participant's case role */ - case_role_name?: string | undefined; - /** The name of the participant's hearing role */ - hearing_role_name?: string | undefined; - /** Participant first name. */ - first_name?: string | undefined; - /** Participant last name. */ - last_name?: string | undefined; - /** Participant contact email */ - contact_email?: string | undefined; - /** Participant telephone number */ - telephone_number?: string | undefined; - /** Participant telephone number */ - mobile_number?: string | undefined; - /** Gets or sets the person name that Representative represents. */ - representee?: string | undefined; - /** The participant linked to this participant response */ - linked_participants?: LinkedParticipant[] | undefined; +export interface IUnallocatedHearingsForVhoResponse { + today?: DateForUnallocatedHearings; + tomorrow?: DateForUnallocatedHearings; + next7_days?: DateForUnallocatedHearings; + next30_days?: DateForUnallocatedHearings; } -export class HealthCheck implements IHealthCheck { - successful?: boolean; +export class UnexpectedErrorResponse implements IUnexpectedErrorResponse { error_message?: string | undefined; - data?: { [key: string]: any } | undefined; - constructor(data?: IHealthCheck) { + constructor(data?: IUnexpectedErrorResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6629,52 +7160,34 @@ export class HealthCheck implements IHealthCheck { init(_data?: any) { if (_data) { - this.successful = _data['successful']; this.error_message = _data['error_message']; - if (_data['data']) { - this.data = {} as any; - for (let key in _data['data']) { - if (_data['data'].hasOwnProperty(key)) (this.data)![key] = _data['data'][key]; - } - } } } - static fromJS(data: any): HealthCheck { + static fromJS(data: any): UnexpectedErrorResponse { data = typeof data === 'object' ? data : {}; - let result = new HealthCheck(); + let result = new UnexpectedErrorResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['successful'] = this.successful; data['error_message'] = this.error_message; - if (this.data) { - data['data'] = {}; - for (let key in this.data) { - if (this.data.hasOwnProperty(key)) (data['data'])[key] = (this.data)[key]; - } - } return data; } } -export interface IHealthCheck { - successful?: boolean; +export interface IUnexpectedErrorResponse { error_message?: string | undefined; - data?: { [key: string]: any } | undefined; } -export class HealthCheckResponse implements IHealthCheckResponse { - bookings_api_health?: HealthCheck; - user_api_health?: HealthCheck; - video_api_health?: HealthCheck; - notification_api_health?: HealthCheck; - app_version?: ApplicationVersion; +export class UserProfileResponse implements IUserProfileResponse { + is_vh_officer_administrator_role?: boolean; + is_vh_team_leader?: boolean; + is_case_administrator?: boolean; - constructor(data?: IHealthCheckResponse) { + constructor(data?: IUserProfileResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6684,46 +7197,39 @@ export class HealthCheckResponse implements IHealthCheckResponse { init(_data?: any) { if (_data) { - this.bookings_api_health = _data['bookings_api_health'] ? HealthCheck.fromJS(_data['bookings_api_health']) : undefined; - this.user_api_health = _data['user_api_health'] ? HealthCheck.fromJS(_data['user_api_health']) : undefined; - this.video_api_health = _data['video_api_health'] ? HealthCheck.fromJS(_data['video_api_health']) : undefined; - this.notification_api_health = _data['notification_api_health'] - ? HealthCheck.fromJS(_data['notification_api_health']) - : undefined; - this.app_version = _data['app_version'] ? ApplicationVersion.fromJS(_data['app_version']) : undefined; + this.is_vh_officer_administrator_role = _data['is_vh_officer_administrator_role']; + this.is_vh_team_leader = _data['is_vh_team_leader']; + this.is_case_administrator = _data['is_case_administrator']; } } - static fromJS(data: any): HealthCheckResponse { + static fromJS(data: any): UserProfileResponse { data = typeof data === 'object' ? data : {}; - let result = new HealthCheckResponse(); + let result = new UserProfileResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['bookings_api_health'] = this.bookings_api_health ? this.bookings_api_health.toJSON() : undefined; - data['user_api_health'] = this.user_api_health ? this.user_api_health.toJSON() : undefined; - data['video_api_health'] = this.video_api_health ? this.video_api_health.toJSON() : undefined; - data['notification_api_health'] = this.notification_api_health ? this.notification_api_health.toJSON() : undefined; - data['app_version'] = this.app_version ? this.app_version.toJSON() : undefined; + data['is_vh_officer_administrator_role'] = this.is_vh_officer_administrator_role; + data['is_vh_team_leader'] = this.is_vh_team_leader; + data['is_case_administrator'] = this.is_case_administrator; return data; } } -export interface IHealthCheckResponse { - bookings_api_health?: HealthCheck; - user_api_health?: HealthCheck; - video_api_health?: HealthCheck; - notification_api_health?: HealthCheck; - app_version?: ApplicationVersion; +export interface IUserProfileResponse { + is_vh_officer_administrator_role?: boolean; + is_vh_team_leader?: boolean; + is_case_administrator?: boolean; } -export class HearingAudioRecordingResponse implements IHearingAudioRecordingResponse { - audio_file_links?: string[] | undefined; +export class ApplicationVersion implements IApplicationVersion { + file_version?: string | undefined; + information_version?: string | undefined; - constructor(data?: IHearingAudioRecordingResponse) { + constructor(data?: IApplicationVersion) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6733,39 +7239,36 @@ export class HearingAudioRecordingResponse implements IHearingAudioRecordingResp init(_data?: any) { if (_data) { - if (Array.isArray(_data['audio_file_links'])) { - this.audio_file_links = [] as any; - for (let item of _data['audio_file_links']) this.audio_file_links!.push(item); - } + this.file_version = _data['file_version']; + this.information_version = _data['information_version']; } } - static fromJS(data: any): HearingAudioRecordingResponse { + static fromJS(data: any): ApplicationVersion { data = typeof data === 'object' ? data : {}; - let result = new HearingAudioRecordingResponse(); + let result = new ApplicationVersion(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - if (Array.isArray(this.audio_file_links)) { - data['audio_file_links'] = []; - for (let item of this.audio_file_links) data['audio_file_links'].push(item); - } + data['file_version'] = this.file_version; + data['information_version'] = this.information_version; return data; } } -export interface IHearingAudioRecordingResponse { - audio_file_links?: string[] | undefined; +export interface IApplicationVersion { + file_version?: string | undefined; + information_version?: string | undefined; } -export class HearingRole implements IHearingRole { +export class CaseAndHearingRolesResponse implements ICaseAndHearingRolesResponse { name?: string | undefined; - user_role?: string | undefined; + hearing_roles?: HearingRole[] | undefined; - constructor(data?: IHearingRole) { + constructor(data?: ICaseAndHearingRolesResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6776,13 +7279,16 @@ export class HearingRole implements IHearingRole { init(_data?: any) { if (_data) { this.name = _data['name']; - this.user_role = _data['user_role']; + if (Array.isArray(_data['hearing_roles'])) { + this.hearing_roles = [] as any; + for (let item of _data['hearing_roles']) this.hearing_roles!.push(HearingRole.fromJS(item)); + } } } - static fromJS(data: any): HearingRole { + static fromJS(data: any): CaseAndHearingRolesResponse { data = typeof data === 'object' ? data : {}; - let result = new HearingRole(); + let result = new CaseAndHearingRolesResponse(); result.init(data); return result; } @@ -6790,35 +7296,24 @@ export class HearingRole implements IHearingRole { toJSON(data?: any) { data = typeof data === 'object' ? data : {}; data['name'] = this.name; - data['user_role'] = this.user_role; + if (Array.isArray(this.hearing_roles)) { + data['hearing_roles'] = []; + for (let item of this.hearing_roles) data['hearing_roles'].push(item.toJSON()); + } return data; } } -export interface IHearingRole { +export interface ICaseAndHearingRolesResponse { name?: string | undefined; - user_role?: string | undefined; + hearing_roles?: HearingRole[] | undefined; } -export class HearingsForAudioFileSearchResponse implements IHearingsForAudioFileSearchResponse { - /** Hearing Id */ - id?: string; - /** The date and time for a hearing */ - scheduled_date_time?: Date; - /** The name of the hearing venue */ - hearing_venue_name?: string | undefined; - /** The case number */ - case_number?: string | undefined; - /** The case name */ - case_name?: string | undefined; - /** The courtroom account */ - courtroom_account?: string | undefined; - /** The courtroom account */ - courtroom_account_name?: string | undefined; - /** The hearing room name at the hearing venue */ - hearing_room_name?: string | undefined; +export class CvpForAudioFileResponse implements ICvpForAudioFileResponse { + file_name?: string | undefined; + sas_token_uri?: string | undefined; - constructor(data?: IHearingsForAudioFileSearchResponse) { + constructor(data?: ICvpForAudioFileResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6828,66 +7323,39 @@ export class HearingsForAudioFileSearchResponse implements IHearingsForAudioFile init(_data?: any) { if (_data) { - this.id = _data['id']; - this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; - this.hearing_venue_name = _data['hearing_venue_name']; - this.case_number = _data['case_number']; - this.case_name = _data['case_name']; - this.courtroom_account = _data['courtroom_account']; - this.courtroom_account_name = _data['courtroom_account_name']; - this.hearing_room_name = _data['hearing_room_name']; + this.file_name = _data['file_name']; + this.sas_token_uri = _data['sas_token_uri']; } } - static fromJS(data: any): HearingsForAudioFileSearchResponse { + static fromJS(data: any): CvpForAudioFileResponse { data = typeof data === 'object' ? data : {}; - let result = new HearingsForAudioFileSearchResponse(); + let result = new CvpForAudioFileResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; - data['hearing_venue_name'] = this.hearing_venue_name; - data['case_number'] = this.case_number; - data['case_name'] = this.case_name; - data['courtroom_account'] = this.courtroom_account; - data['courtroom_account_name'] = this.courtroom_account_name; - data['hearing_room_name'] = this.hearing_room_name; + data['file_name'] = this.file_name; + data['sas_token_uri'] = this.sas_token_uri; return data; } } -export interface IHearingsForAudioFileSearchResponse { - /** Hearing Id */ - id?: string; - /** The date and time for a hearing */ - scheduled_date_time?: Date; - /** The name of the hearing venue */ - hearing_venue_name?: string | undefined; - /** The case number */ - case_number?: string | undefined; - /** The case name */ - case_name?: string | undefined; - /** The courtroom account */ - courtroom_account?: string | undefined; - /** The courtroom account */ - courtroom_account_name?: string | undefined; - /** The hearing room name at the hearing venue */ - hearing_room_name?: string | undefined; +export interface ICvpForAudioFileResponse { + file_name?: string | undefined; + sas_token_uri?: string | undefined; } -export class LinkedParticipant implements ILinkedParticipant { - id?: string; - participant_id?: string; - linked_id?: string; - type?: LinkedParticipantType; - participant_contact_email?: string | undefined; - linked_participant_contact_email?: string | undefined; +/** Case request */ +export class EditCaseRequest implements IEditCaseRequest { + /** The case number */ + number!: string; + /** The case name */ + name!: string; - constructor(data?: ILinkedParticipant) { + constructor(data?: IEditCaseRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6897,50 +7365,43 @@ export class LinkedParticipant implements ILinkedParticipant { init(_data?: any) { if (_data) { - this.id = _data['id']; - this.participant_id = _data['participant_id']; - this.linked_id = _data['linked_id']; - this.type = _data['type']; - this.participant_contact_email = _data['participant_contact_email']; - this.linked_participant_contact_email = _data['linked_participant_contact_email']; + this.number = _data['number']; + this.name = _data['name']; } } - static fromJS(data: any): LinkedParticipant { + static fromJS(data: any): EditCaseRequest { data = typeof data === 'object' ? data : {}; - let result = new LinkedParticipant(); + let result = new EditCaseRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['participant_id'] = this.participant_id; - data['linked_id'] = this.linked_id; - data['type'] = this.type; - data['participant_contact_email'] = this.participant_contact_email; - data['linked_participant_contact_email'] = this.linked_participant_contact_email; + data['number'] = this.number; + data['name'] = this.name; return data; } } -export interface ILinkedParticipant { - id?: string; - participant_id?: string; - linked_id?: string; - type?: LinkedParticipantType; - participant_contact_email?: string | undefined; - linked_participant_contact_email?: string | undefined; +/** Case request */ +export interface IEditCaseRequest { + /** The case number */ + number: string; + /** The case name */ + name: string; } -export class MultiHearingRequest implements IMultiHearingRequest { - start_date?: Date; - end_date?: Date; - hearing_dates?: Date[] | undefined; - is_individual_dates?: boolean; +export class EditEndpointRequest implements IEditEndpointRequest { + /** Endpoint Id. */ + id?: string | undefined; + /** The display name for the endpoint */ + display_name?: string | undefined; + /** The username of the participant */ + defence_advocate_contact_email?: string | undefined; - constructor(data?: IMultiHearingRequest) { + constructor(data?: IEditEndpointRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -6950,166 +7411,184 @@ export class MultiHearingRequest implements IMultiHearingRequest { init(_data?: any) { if (_data) { - this.start_date = _data['start_date'] ? new Date(_data['start_date'].toString()) : undefined; - this.end_date = _data['end_date'] ? new Date(_data['end_date'].toString()) : undefined; - if (Array.isArray(_data['hearing_dates'])) { - this.hearing_dates = [] as any; - for (let item of _data['hearing_dates']) this.hearing_dates!.push(new Date(item)); - } - this.is_individual_dates = _data['is_individual_dates']; + this.id = _data['id']; + this.display_name = _data['display_name']; + this.defence_advocate_contact_email = _data['defence_advocate_contact_email']; } } - static fromJS(data: any): MultiHearingRequest { + static fromJS(data: any): EditEndpointRequest { data = typeof data === 'object' ? data : {}; - let result = new MultiHearingRequest(); + let result = new EditEndpointRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['start_date'] = this.start_date ? this.start_date.toISOString() : undefined; - data['end_date'] = this.end_date ? this.end_date.toISOString() : undefined; - if (Array.isArray(this.hearing_dates)) { - data['hearing_dates'] = []; - for (let item of this.hearing_dates) data['hearing_dates'].push(item.toISOString()); - } - data['is_individual_dates'] = this.is_individual_dates; + data['id'] = this.id; + data['display_name'] = this.display_name; + data['defence_advocate_contact_email'] = this.defence_advocate_contact_email; return data; } } -export interface IMultiHearingRequest { - start_date?: Date; - end_date?: Date; - hearing_dates?: Date[] | undefined; - is_individual_dates?: boolean; +export interface IEditEndpointRequest { + /** Endpoint Id. */ + id?: string | undefined; + /** The display name for the endpoint */ + display_name?: string | undefined; + /** The username of the participant */ + defence_advocate_contact_email?: string | undefined; } -export class PhoneConferenceResponse implements IPhoneConferenceResponse { - telephone_conference_id?: string | undefined; +/** Request for updating an existing hearing */ +export class EditHearingRequest implements IEditHearingRequest { + /** The date and time for a hearing */ + scheduled_date_time?: Date; + /** The duration of a hearing (number of minutes) */ + scheduled_duration?: number; + /** The name of the hearing venue */ + hearing_venue_name?: string | undefined; + /** The hearing room name at the hearing venue */ + hearing_room_name?: string | undefined; + case!: EditCaseRequest; + /** List of participants in hearing */ + participants!: EditParticipantRequest[] | undefined; + telephone_participants?: EditTelephoneParticipantRequest[] | undefined; + /** Any other information about the hearing */ + other_information?: string | undefined; + /** QuestionnaireNotRequired */ + questionnaire_not_required?: boolean; + /** Gets or sets audio recording required flag */ + audio_recording_required?: boolean; + /** List of endpoints for the hearing */ + endpoints?: EditEndpointRequest[] | undefined; - constructor(data?: IPhoneConferenceResponse) { + constructor(data?: IEditHearingRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; } } + if (!data) { + this.case = new EditCaseRequest(); + } } init(_data?: any) { if (_data) { - this.telephone_conference_id = _data['telephone_conference_id']; + this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; + this.scheduled_duration = _data['scheduled_duration']; + this.hearing_venue_name = _data['hearing_venue_name']; + this.hearing_room_name = _data['hearing_room_name']; + this.case = _data['case'] ? EditCaseRequest.fromJS(_data['case']) : new EditCaseRequest(); + if (Array.isArray(_data['participants'])) { + this.participants = [] as any; + for (let item of _data['participants']) this.participants!.push(EditParticipantRequest.fromJS(item)); + } + if (Array.isArray(_data['telephone_participants'])) { + this.telephone_participants = [] as any; + for (let item of _data['telephone_participants']) + this.telephone_participants!.push(EditTelephoneParticipantRequest.fromJS(item)); + } + this.other_information = _data['other_information']; + this.questionnaire_not_required = _data['questionnaire_not_required']; + this.audio_recording_required = _data['audio_recording_required']; + if (Array.isArray(_data['endpoints'])) { + this.endpoints = [] as any; + for (let item of _data['endpoints']) this.endpoints!.push(EditEndpointRequest.fromJS(item)); + } } } - static fromJS(data: any): PhoneConferenceResponse { + static fromJS(data: any): EditHearingRequest { data = typeof data === 'object' ? data : {}; - let result = new PhoneConferenceResponse(); + let result = new EditHearingRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['telephone_conference_id'] = this.telephone_conference_id; - return data; - } -} - -export interface IPhoneConferenceResponse { - telephone_conference_id?: string | undefined; -} - -export class UpdateBookingStatusResponse implements IUpdateBookingStatusResponse { - success?: boolean; - message?: string | undefined; - telephone_conference_id?: string | undefined; - - constructor(data?: IUpdateBookingStatusResponse) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; - } + data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; + data['scheduled_duration'] = this.scheduled_duration; + data['hearing_venue_name'] = this.hearing_venue_name; + data['hearing_room_name'] = this.hearing_room_name; + data['case'] = this.case ? this.case.toJSON() : undefined; + if (Array.isArray(this.participants)) { + data['participants'] = []; + for (let item of this.participants) data['participants'].push(item.toJSON()); } - } - - init(_data?: any) { - if (_data) { - this.success = _data['success']; - this.message = _data['message']; - this.telephone_conference_id = _data['telephone_conference_id']; + if (Array.isArray(this.telephone_participants)) { + data['telephone_participants'] = []; + for (let item of this.telephone_participants) data['telephone_participants'].push(item.toJSON()); + } + data['other_information'] = this.other_information; + data['questionnaire_not_required'] = this.questionnaire_not_required; + data['audio_recording_required'] = this.audio_recording_required; + if (Array.isArray(this.endpoints)) { + data['endpoints'] = []; + for (let item of this.endpoints) data['endpoints'].push(item.toJSON()); } - } - - static fromJS(data: any): UpdateBookingStatusResponse { - data = typeof data === 'object' ? data : {}; - let result = new UpdateBookingStatusResponse(); - result.init(data); - return result; - } - - toJSON(data?: any) { - data = typeof data === 'object' ? data : {}; - data['success'] = this.success; - data['message'] = this.message; - data['telephone_conference_id'] = this.telephone_conference_id; return data; } } -export interface IUpdateBookingStatusResponse { - success?: boolean; - message?: string | undefined; - telephone_conference_id?: string | undefined; -} - -export class UploadNonWorkingHoursResponse implements IUploadNonWorkingHoursResponse { - failed_usernames?: string[] | undefined; - - constructor(data?: IUploadNonWorkingHoursResponse) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; - } - } - } - - init(_data?: any) { - if (_data) { - if (Array.isArray(_data['failed_usernames'])) { - this.failed_usernames = [] as any; - for (let item of _data['failed_usernames']) this.failed_usernames!.push(item); - } - } - } - - static fromJS(data: any): UploadNonWorkingHoursResponse { - data = typeof data === 'object' ? data : {}; - let result = new UploadNonWorkingHoursResponse(); - result.init(data); - return result; - } - - toJSON(data?: any) { - data = typeof data === 'object' ? data : {}; - if (Array.isArray(this.failed_usernames)) { - data['failed_usernames'] = []; - for (let item of this.failed_usernames) data['failed_usernames'].push(item); - } - return data; - } -} - -export interface IUploadNonWorkingHoursResponse { - failed_usernames?: string[] | undefined; +/** Request for updating an existing hearing */ +export interface IEditHearingRequest { + /** The date and time for a hearing */ + scheduled_date_time?: Date; + /** The duration of a hearing (number of minutes) */ + scheduled_duration?: number; + /** The name of the hearing venue */ + hearing_venue_name?: string | undefined; + /** The hearing room name at the hearing venue */ + hearing_room_name?: string | undefined; + case: EditCaseRequest; + /** List of participants in hearing */ + participants: EditParticipantRequest[] | undefined; + telephone_participants?: EditTelephoneParticipantRequest[] | undefined; + /** Any other information about the hearing */ + other_information?: string | undefined; + /** QuestionnaireNotRequired */ + questionnaire_not_required?: boolean; + /** Gets or sets audio recording required flag */ + audio_recording_required?: boolean; + /** List of endpoints for the hearing */ + endpoints?: EditEndpointRequest[] | undefined; } -export class UploadWorkHoursResponse implements IUploadWorkHoursResponse { - failed_usernames?: string[] | undefined; +/** Participant request */ +export class EditParticipantRequest implements IEditParticipantRequest { + /** Participant Id. */ + id?: string | undefined; + /** Participant Title. */ + title?: string | undefined; + /** Participant first name. */ + first_name!: string; + /** Participant middle name. */ + middle_names?: string | undefined; + /** Participant last name. */ + last_name!: string; + /** Participant Contact Email */ + contact_email!: string; + /** Participant Telephone number */ + telephone_number?: string | undefined; + /** Participant Display Name */ + display_name!: string; + /** The name of the participant's case role */ + case_role_name?: string | undefined; + /** The name of the participant's hearing role */ + hearing_role_name?: string | undefined; + /** The representee of a representative */ + representee?: string | undefined; + /** Organisation name */ + organisation_name?: string | undefined; + /** List of linked participants */ + linked_participants?: LinkedParticipant[] | undefined; - constructor(data?: IUploadWorkHoursResponse) { + constructor(data?: IEditParticipantRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7119,143 +7598,151 @@ export class UploadWorkHoursResponse implements IUploadWorkHoursResponse { init(_data?: any) { if (_data) { - if (Array.isArray(_data['failed_usernames'])) { - this.failed_usernames = [] as any; - for (let item of _data['failed_usernames']) this.failed_usernames!.push(item); + this.id = _data['id']; + this.title = _data['title']; + this.first_name = _data['first_name']; + this.middle_names = _data['middle_names']; + this.last_name = _data['last_name']; + this.contact_email = _data['contact_email']; + this.telephone_number = _data['telephone_number']; + this.display_name = _data['display_name']; + this.case_role_name = _data['case_role_name']; + this.hearing_role_name = _data['hearing_role_name']; + this.representee = _data['representee']; + this.organisation_name = _data['organisation_name']; + if (Array.isArray(_data['linked_participants'])) { + this.linked_participants = [] as any; + for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipant.fromJS(item)); } } } - static fromJS(data: any): UploadWorkHoursResponse { + static fromJS(data: any): EditParticipantRequest { data = typeof data === 'object' ? data : {}; - let result = new UploadWorkHoursResponse(); + let result = new EditParticipantRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - if (Array.isArray(this.failed_usernames)) { - data['failed_usernames'] = []; - for (let item of this.failed_usernames) data['failed_usernames'].push(item); + data['id'] = this.id; + data['title'] = this.title; + data['first_name'] = this.first_name; + data['middle_names'] = this.middle_names; + data['last_name'] = this.last_name; + data['contact_email'] = this.contact_email; + data['telephone_number'] = this.telephone_number; + data['display_name'] = this.display_name; + data['case_role_name'] = this.case_role_name; + data['hearing_role_name'] = this.hearing_role_name; + data['representee'] = this.representee; + data['organisation_name'] = this.organisation_name; + if (Array.isArray(this.linked_participants)) { + data['linked_participants'] = []; + for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); } return data; } } -export interface IUploadWorkHoursResponse { - failed_usernames?: string[] | undefined; -} - -export enum BookingStatus { - Booked = 'Booked', - Created = 'Created', - Cancelled = 'Cancelled', - Failed = 'Failed' -} - -export enum LinkedParticipantType { - Interpreter = 'Interpreter' +/** Participant request */ +export interface IEditParticipantRequest { + /** Participant Id. */ + id?: string | undefined; + /** Participant Title. */ + title?: string | undefined; + /** Participant first name. */ + first_name: string; + /** Participant middle name. */ + middle_names?: string | undefined; + /** Participant last name. */ + last_name: string; + /** Participant Contact Email */ + contact_email: string; + /** Participant Telephone number */ + telephone_number?: string | undefined; + /** Participant Display Name */ + display_name: string; + /** The name of the participant's case role */ + case_role_name?: string | undefined; + /** The name of the participant's hearing role */ + hearing_role_name?: string | undefined; + /** The representee of a representative */ + representee?: string | undefined; + /** Organisation name */ + organisation_name?: string | undefined; + /** List of linked participants */ + linked_participants?: LinkedParticipant[] | undefined; } -export class BookNewHearingRequest implements IBookNewHearingRequest { - scheduled_date_time?: Date; - scheduled_duration?: number; - hearing_venue_name?: string | undefined; - case_type_name?: string | undefined; - case_type_service_id?: string | undefined; - hearing_type_name?: string | undefined; - cases?: CaseRequest[] | undefined; - participants?: ParticipantRequest[] | undefined; - hearing_room_name?: string | undefined; - other_information?: string | undefined; - created_by?: string | undefined; - questionnaire_not_required?: boolean; - audio_recording_required?: boolean; - hearing_type_code?: string | undefined; - is_multi_day_hearing?: boolean; - endpoints?: EndpointRequest[] | undefined; - linked_participants?: LinkedParticipantRequest[] | undefined; +/** Participant request */ +export class EditTelephoneParticipantRequest implements IEditTelephoneParticipantRequest { + /** Participant Id */ + id?: string; + /** The name of the participant's case role */ + case_role_name?: string | undefined; + /** The name of the participant's hearing role */ + hearing_role_name?: string | undefined; + /** Participant first name. */ + first_name?: string | undefined; + /** Participant last name. */ + last_name?: string | undefined; + /** Participant contact email */ + contact_email?: string | undefined; + /** Participant telephone number */ + telephone_number?: string | undefined; + /** Participant telephone number */ + mobile_number?: string | undefined; + /** Gets or sets the person name that Representative represents. */ + representee?: string | undefined; + /** The participant linked to this participant response */ + linked_participants?: LinkedParticipant[] | undefined; - constructor(data?: IBookNewHearingRequest) { + constructor(data?: IEditTelephoneParticipantRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; } } - if (!data) { - this.is_multi_day_hearing = false; - } } init(_data?: any) { if (_data) { - this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; - this.scheduled_duration = _data['scheduled_duration']; - this.hearing_venue_name = _data['hearing_venue_name']; - this.case_type_name = _data['case_type_name']; - this.case_type_service_id = _data['case_type_service_id']; - this.hearing_type_name = _data['hearing_type_name']; - if (Array.isArray(_data['cases'])) { - this.cases = [] as any; - for (let item of _data['cases']) this.cases!.push(CaseRequest.fromJS(item)); - } - if (Array.isArray(_data['participants'])) { - this.participants = [] as any; - for (let item of _data['participants']) this.participants!.push(ParticipantRequest.fromJS(item)); - } - this.hearing_room_name = _data['hearing_room_name']; - this.other_information = _data['other_information']; - this.created_by = _data['created_by']; - this.questionnaire_not_required = _data['questionnaire_not_required']; - this.audio_recording_required = _data['audio_recording_required']; - this.hearing_type_code = _data['hearing_type_code']; - this.is_multi_day_hearing = _data['is_multi_day_hearing'] !== undefined ? _data['is_multi_day_hearing'] : false; - if (Array.isArray(_data['endpoints'])) { - this.endpoints = [] as any; - for (let item of _data['endpoints']) this.endpoints!.push(EndpointRequest.fromJS(item)); - } + this.id = _data['id']; + this.case_role_name = _data['case_role_name']; + this.hearing_role_name = _data['hearing_role_name']; + this.first_name = _data['first_name']; + this.last_name = _data['last_name']; + this.contact_email = _data['contact_email']; + this.telephone_number = _data['telephone_number']; + this.mobile_number = _data['mobile_number']; + this.representee = _data['representee']; if (Array.isArray(_data['linked_participants'])) { this.linked_participants = [] as any; - for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipantRequest.fromJS(item)); + for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipant.fromJS(item)); } } } - static fromJS(data: any): BookNewHearingRequest { + static fromJS(data: any): EditTelephoneParticipantRequest { data = typeof data === 'object' ? data : {}; - let result = new BookNewHearingRequest(); + let result = new EditTelephoneParticipantRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; - data['scheduled_duration'] = this.scheduled_duration; - data['hearing_venue_name'] = this.hearing_venue_name; - data['case_type_name'] = this.case_type_name; - data['case_type_service_id'] = this.case_type_service_id; - data['hearing_type_name'] = this.hearing_type_name; - if (Array.isArray(this.cases)) { - data['cases'] = []; - for (let item of this.cases) data['cases'].push(item.toJSON()); - } - if (Array.isArray(this.participants)) { - data['participants'] = []; - for (let item of this.participants) data['participants'].push(item.toJSON()); - } - data['hearing_room_name'] = this.hearing_room_name; - data['other_information'] = this.other_information; - data['created_by'] = this.created_by; - data['questionnaire_not_required'] = this.questionnaire_not_required; - data['audio_recording_required'] = this.audio_recording_required; - data['hearing_type_code'] = this.hearing_type_code; - data['is_multi_day_hearing'] = this.is_multi_day_hearing; - if (Array.isArray(this.endpoints)) { - data['endpoints'] = []; - for (let item of this.endpoints) data['endpoints'].push(item.toJSON()); - } + data['id'] = this.id; + data['case_role_name'] = this.case_role_name; + data['hearing_role_name'] = this.hearing_role_name; + data['first_name'] = this.first_name; + data['last_name'] = this.last_name; + data['contact_email'] = this.contact_email; + data['telephone_number'] = this.telephone_number; + data['mobile_number'] = this.mobile_number; + data['representee'] = this.representee; if (Array.isArray(this.linked_participants)) { data['linked_participants'] = []; for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); @@ -7264,32 +7751,36 @@ export class BookNewHearingRequest implements IBookNewHearingRequest { } } -export interface IBookNewHearingRequest { - scheduled_date_time?: Date; - scheduled_duration?: number; - hearing_venue_name?: string | undefined; - case_type_name?: string | undefined; - case_type_service_id?: string | undefined; - hearing_type_name?: string | undefined; - cases?: CaseRequest[] | undefined; - participants?: ParticipantRequest[] | undefined; - hearing_room_name?: string | undefined; - other_information?: string | undefined; - created_by?: string | undefined; - questionnaire_not_required?: boolean; - audio_recording_required?: boolean; - hearing_type_code?: string | undefined; - is_multi_day_hearing?: boolean; - endpoints?: EndpointRequest[] | undefined; - linked_participants?: LinkedParticipantRequest[] | undefined; +/** Participant request */ +export interface IEditTelephoneParticipantRequest { + /** Participant Id */ + id?: string; + /** The name of the participant's case role */ + case_role_name?: string | undefined; + /** The name of the participant's hearing role */ + hearing_role_name?: string | undefined; + /** Participant first name. */ + first_name?: string | undefined; + /** Participant last name. */ + last_name?: string | undefined; + /** Participant contact email */ + contact_email?: string | undefined; + /** Participant telephone number */ + telephone_number?: string | undefined; + /** Participant telephone number */ + mobile_number?: string | undefined; + /** Gets or sets the person name that Representative represents. */ + representee?: string | undefined; + /** The participant linked to this participant response */ + linked_participants?: LinkedParticipant[] | undefined; } -export class CaseRequest implements ICaseRequest { - number?: string | undefined; - name?: string | undefined; - is_lead_case?: boolean; +export class HealthCheck implements IHealthCheck { + successful?: boolean; + error_message?: string | undefined; + data?: { [key: string]: any } | undefined; - constructor(data?: ICaseRequest) { + constructor(data?: IHealthCheck) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7299,40 +7790,52 @@ export class CaseRequest implements ICaseRequest { init(_data?: any) { if (_data) { - this.number = _data['number']; - this.name = _data['name']; - this.is_lead_case = _data['is_lead_case']; + this.successful = _data['successful']; + this.error_message = _data['error_message']; + if (_data['data']) { + this.data = {} as any; + for (let key in _data['data']) { + if (_data['data'].hasOwnProperty(key)) (this.data)![key] = _data['data'][key]; + } + } } } - static fromJS(data: any): CaseRequest { + static fromJS(data: any): HealthCheck { data = typeof data === 'object' ? data : {}; - let result = new CaseRequest(); + let result = new HealthCheck(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['number'] = this.number; - data['name'] = this.name; - data['is_lead_case'] = this.is_lead_case; + data['successful'] = this.successful; + data['error_message'] = this.error_message; + if (this.data) { + data['data'] = {}; + for (let key in this.data) { + if (this.data.hasOwnProperty(key)) (data['data'])[key] = (this.data)[key]; + } + } return data; } } -export interface ICaseRequest { - number?: string | undefined; - name?: string | undefined; - is_lead_case?: boolean; +export interface IHealthCheck { + successful?: boolean; + error_message?: string | undefined; + data?: { [key: string]: any } | undefined; } -export class EditJusticeUserRequest implements IEditJusticeUserRequest { - id?: string; - username?: string | undefined; - roles?: JusticeUserRole[] | undefined; +export class HealthCheckResponse implements IHealthCheckResponse { + bookings_api_health?: HealthCheck; + user_api_health?: HealthCheck; + video_api_health?: HealthCheck; + notification_api_health?: HealthCheck; + app_version?: ApplicationVersion; - constructor(data?: IEditJusticeUserRequest) { + constructor(data?: IHealthCheckResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7342,45 +7845,46 @@ export class EditJusticeUserRequest implements IEditJusticeUserRequest { init(_data?: any) { if (_data) { - this.id = _data['id']; - this.username = _data['username']; - if (Array.isArray(_data['roles'])) { - this.roles = [] as any; - for (let item of _data['roles']) this.roles!.push(item); - } + this.bookings_api_health = _data['bookings_api_health'] ? HealthCheck.fromJS(_data['bookings_api_health']) : undefined; + this.user_api_health = _data['user_api_health'] ? HealthCheck.fromJS(_data['user_api_health']) : undefined; + this.video_api_health = _data['video_api_health'] ? HealthCheck.fromJS(_data['video_api_health']) : undefined; + this.notification_api_health = _data['notification_api_health'] + ? HealthCheck.fromJS(_data['notification_api_health']) + : undefined; + this.app_version = _data['app_version'] ? ApplicationVersion.fromJS(_data['app_version']) : undefined; } } - static fromJS(data: any): EditJusticeUserRequest { + static fromJS(data: any): HealthCheckResponse { data = typeof data === 'object' ? data : {}; - let result = new EditJusticeUserRequest(); + let result = new HealthCheckResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['username'] = this.username; - if (Array.isArray(this.roles)) { - data['roles'] = []; - for (let item of this.roles) data['roles'].push(item); - } + data['bookings_api_health'] = this.bookings_api_health ? this.bookings_api_health.toJSON() : undefined; + data['user_api_health'] = this.user_api_health ? this.user_api_health.toJSON() : undefined; + data['video_api_health'] = this.video_api_health ? this.video_api_health.toJSON() : undefined; + data['notification_api_health'] = this.notification_api_health ? this.notification_api_health.toJSON() : undefined; + data['app_version'] = this.app_version ? this.app_version.toJSON() : undefined; return data; } } -export interface IEditJusticeUserRequest { - id?: string; - username?: string | undefined; - roles?: JusticeUserRole[] | undefined; +export interface IHealthCheckResponse { + bookings_api_health?: HealthCheck; + user_api_health?: HealthCheck; + video_api_health?: HealthCheck; + notification_api_health?: HealthCheck; + app_version?: ApplicationVersion; } -export class EndpointRequest implements IEndpointRequest { - display_name?: string | undefined; - defence_advocate_contact_email?: string | undefined; +export class HearingAudioRecordingResponse implements IHearingAudioRecordingResponse { + audio_file_links?: string[] | undefined; - constructor(data?: IEndpointRequest) { + constructor(data?: IHearingAudioRecordingResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7390,56 +7894,39 @@ export class EndpointRequest implements IEndpointRequest { init(_data?: any) { if (_data) { - this.display_name = _data['display_name']; - this.defence_advocate_contact_email = _data['defence_advocate_contact_email']; + if (Array.isArray(_data['audio_file_links'])) { + this.audio_file_links = [] as any; + for (let item of _data['audio_file_links']) this.audio_file_links!.push(item); + } } } - static fromJS(data: any): EndpointRequest { + static fromJS(data: any): HearingAudioRecordingResponse { data = typeof data === 'object' ? data : {}; - let result = new EndpointRequest(); + let result = new HearingAudioRecordingResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['display_name'] = this.display_name; - data['defence_advocate_contact_email'] = this.defence_advocate_contact_email; + if (Array.isArray(this.audio_file_links)) { + data['audio_file_links'] = []; + for (let item of this.audio_file_links) data['audio_file_links'].push(item); + } return data; } } -export interface IEndpointRequest { - display_name?: string | undefined; - defence_advocate_contact_email?: string | undefined; -} - -export enum JusticeUserRole { - CaseAdmin = 'CaseAdmin', - Vho = 'Vho', - Clerk = 'Clerk', - Judge = 'Judge', - Individual = 'Individual', - Representative = 'Representative', - JudicialOfficeHolder = 'JudicialOfficeHolder', - StaffMember = 'StaffMember', - VhTeamLead = 'VhTeamLead' -} - -export enum UpdateBookingStatus { - Booked = 'Booked', - Created = 'Created', - Cancelled = 'Cancelled', - Failed = 'Failed' +export interface IHearingAudioRecordingResponse { + audio_file_links?: string[] | undefined; } -export class LinkedParticipantRequest implements ILinkedParticipantRequest { - participant_contact_email?: string | undefined; - linked_participant_contact_email?: string | undefined; - type?: LinkedParticipantType; +export class HearingRole implements IHearingRole { + name?: string | undefined; + user_role?: string | undefined; - constructor(data?: ILinkedParticipantRequest) { + constructor(data?: IHearingRole) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7449,40 +7936,50 @@ export class LinkedParticipantRequest implements ILinkedParticipantRequest { init(_data?: any) { if (_data) { - this.participant_contact_email = _data['participant_contact_email']; - this.linked_participant_contact_email = _data['linked_participant_contact_email']; - this.type = _data['type']; + this.name = _data['name']; + this.user_role = _data['user_role']; } } - static fromJS(data: any): LinkedParticipantRequest { + static fromJS(data: any): HearingRole { data = typeof data === 'object' ? data : {}; - let result = new LinkedParticipantRequest(); + let result = new HearingRole(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['participant_contact_email'] = this.participant_contact_email; - data['linked_participant_contact_email'] = this.linked_participant_contact_email; - data['type'] = this.type; + data['name'] = this.name; + data['user_role'] = this.user_role; return data; } } -export interface ILinkedParticipantRequest { - participant_contact_email?: string | undefined; - linked_participant_contact_email?: string | undefined; - type?: LinkedParticipantType; +export interface IHearingRole { + name?: string | undefined; + user_role?: string | undefined; } -export class NonWorkingHours implements INonWorkingHours { - id?: number; - start_time?: Date; - end_time?: Date; +export class HearingsForAudioFileSearchResponse implements IHearingsForAudioFileSearchResponse { + /** Hearing Id */ + id?: string; + /** The date and time for a hearing */ + scheduled_date_time?: Date; + /** The name of the hearing venue */ + hearing_venue_name?: string | undefined; + /** The case number */ + case_number?: string | undefined; + /** The case name */ + case_name?: string | undefined; + /** The courtroom account */ + courtroom_account?: string | undefined; + /** The courtroom account */ + courtroom_account_name?: string | undefined; + /** The hearing room name at the hearing venue */ + hearing_room_name?: string | undefined; - constructor(data?: INonWorkingHours) { + constructor(data?: IHearingsForAudioFileSearchResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7493,14 +7990,19 @@ export class NonWorkingHours implements INonWorkingHours { init(_data?: any) { if (_data) { this.id = _data['id']; - this.start_time = _data['start_time'] ? new Date(_data['start_time'].toString()) : undefined; - this.end_time = _data['end_time'] ? new Date(_data['end_time'].toString()) : undefined; + this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; + this.hearing_venue_name = _data['hearing_venue_name']; + this.case_number = _data['case_number']; + this.case_name = _data['case_name']; + this.courtroom_account = _data['courtroom_account']; + this.courtroom_account_name = _data['courtroom_account_name']; + this.hearing_room_name = _data['hearing_room_name']; } } - static fromJS(data: any): NonWorkingHours { + static fromJS(data: any): HearingsForAudioFileSearchResponse { data = typeof data === 'object' ? data : {}; - let result = new NonWorkingHours(); + let result = new HearingsForAudioFileSearchResponse(); result.init(data); return result; } @@ -7508,33 +8010,45 @@ export class NonWorkingHours implements INonWorkingHours { toJSON(data?: any) { data = typeof data === 'object' ? data : {}; data['id'] = this.id; - data['start_time'] = this.start_time ? this.start_time.toISOString() : undefined; - data['end_time'] = this.end_time ? this.end_time.toISOString() : undefined; + data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; + data['hearing_venue_name'] = this.hearing_venue_name; + data['case_number'] = this.case_number; + data['case_name'] = this.case_name; + data['courtroom_account'] = this.courtroom_account; + data['courtroom_account_name'] = this.courtroom_account_name; + data['hearing_room_name'] = this.hearing_room_name; return data; } } -export interface INonWorkingHours { - id?: number; - start_time?: Date; - end_time?: Date; +export interface IHearingsForAudioFileSearchResponse { + /** Hearing Id */ + id?: string; + /** The date and time for a hearing */ + scheduled_date_time?: Date; + /** The name of the hearing venue */ + hearing_venue_name?: string | undefined; + /** The case number */ + case_number?: string | undefined; + /** The case name */ + case_name?: string | undefined; + /** The courtroom account */ + courtroom_account?: string | undefined; + /** The courtroom account */ + courtroom_account_name?: string | undefined; + /** The hearing room name at the hearing venue */ + hearing_room_name?: string | undefined; } -export class ParticipantRequest implements IParticipantRequest { - title?: string | undefined; - first_name?: string | undefined; - middle_names?: string | undefined; - last_name?: string | undefined; - contact_email?: string | undefined; - telephone_number?: string | undefined; - username?: string | undefined; - display_name?: string | undefined; - case_role_name?: string | undefined; - hearing_role_name?: string | undefined; - representee?: string | undefined; - organisation_name?: string | undefined; +export class LinkedParticipant implements ILinkedParticipant { + id?: string; + participant_id?: string; + linked_id?: string; + type?: LinkedParticipantType; + participant_contact_email?: string | undefined; + linked_participant_contact_email?: string | undefined; - constructor(data?: IParticipantRequest) { + constructor(data?: ILinkedParticipant) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7544,66 +8058,50 @@ export class ParticipantRequest implements IParticipantRequest { init(_data?: any) { if (_data) { - this.title = _data['title']; - this.first_name = _data['first_name']; - this.middle_names = _data['middle_names']; - this.last_name = _data['last_name']; - this.contact_email = _data['contact_email']; - this.telephone_number = _data['telephone_number']; - this.username = _data['username']; - this.display_name = _data['display_name']; - this.case_role_name = _data['case_role_name']; - this.hearing_role_name = _data['hearing_role_name']; - this.representee = _data['representee']; - this.organisation_name = _data['organisation_name']; + this.id = _data['id']; + this.participant_id = _data['participant_id']; + this.linked_id = _data['linked_id']; + this.type = _data['type']; + this.participant_contact_email = _data['participant_contact_email']; + this.linked_participant_contact_email = _data['linked_participant_contact_email']; } } - static fromJS(data: any): ParticipantRequest { + static fromJS(data: any): LinkedParticipant { data = typeof data === 'object' ? data : {}; - let result = new ParticipantRequest(); + let result = new LinkedParticipant(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['title'] = this.title; - data['first_name'] = this.first_name; - data['middle_names'] = this.middle_names; - data['last_name'] = this.last_name; - data['contact_email'] = this.contact_email; - data['telephone_number'] = this.telephone_number; - data['username'] = this.username; - data['display_name'] = this.display_name; - data['case_role_name'] = this.case_role_name; - data['hearing_role_name'] = this.hearing_role_name; - data['representee'] = this.representee; - data['organisation_name'] = this.organisation_name; + data['id'] = this.id; + data['participant_id'] = this.participant_id; + data['linked_id'] = this.linked_id; + data['type'] = this.type; + data['participant_contact_email'] = this.participant_contact_email; + data['linked_participant_contact_email'] = this.linked_participant_contact_email; return data; } } -export interface IParticipantRequest { - title?: string | undefined; - first_name?: string | undefined; - middle_names?: string | undefined; - last_name?: string | undefined; - contact_email?: string | undefined; - telephone_number?: string | undefined; - username?: string | undefined; - display_name?: string | undefined; - case_role_name?: string | undefined; - hearing_role_name?: string | undefined; - representee?: string | undefined; - organisation_name?: string | undefined; +export interface ILinkedParticipant { + id?: string; + participant_id?: string; + linked_id?: string; + type?: LinkedParticipantType; + participant_contact_email?: string | undefined; + linked_participant_contact_email?: string | undefined; } -export class RestoreJusticeUserRequest implements IRestoreJusticeUserRequest { - id?: string; - username?: string | undefined; +export class MultiHearingRequest implements IMultiHearingRequest { + start_date?: Date; + end_date?: Date; + hearing_dates?: Date[] | undefined; + is_individual_dates?: boolean; - constructor(data?: IRestoreJusticeUserRequest) { + constructor(data?: IMultiHearingRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7613,37 +8111,47 @@ export class RestoreJusticeUserRequest implements IRestoreJusticeUserRequest { init(_data?: any) { if (_data) { - this.id = _data['id']; - this.username = _data['username']; + this.start_date = _data['start_date'] ? new Date(_data['start_date'].toString()) : undefined; + this.end_date = _data['end_date'] ? new Date(_data['end_date'].toString()) : undefined; + if (Array.isArray(_data['hearing_dates'])) { + this.hearing_dates = [] as any; + for (let item of _data['hearing_dates']) this.hearing_dates!.push(new Date(item)); + } + this.is_individual_dates = _data['is_individual_dates']; } } - static fromJS(data: any): RestoreJusticeUserRequest { + static fromJS(data: any): MultiHearingRequest { data = typeof data === 'object' ? data : {}; - let result = new RestoreJusticeUserRequest(); + let result = new MultiHearingRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['username'] = this.username; + data['start_date'] = this.start_date ? this.start_date.toISOString() : undefined; + data['end_date'] = this.end_date ? this.end_date.toISOString() : undefined; + if (Array.isArray(this.hearing_dates)) { + data['hearing_dates'] = []; + for (let item of this.hearing_dates) data['hearing_dates'].push(item.toISOString()); + } + data['is_individual_dates'] = this.is_individual_dates; return data; } } -export interface IRestoreJusticeUserRequest { - id?: string; - username?: string | undefined; +export interface IMultiHearingRequest { + start_date?: Date; + end_date?: Date; + hearing_dates?: Date[] | undefined; + is_individual_dates?: boolean; } -export class UpdateBookingStatusRequest implements IUpdateBookingStatusRequest { - updated_by?: string | undefined; - status?: UpdateBookingStatus; - cancel_reason?: string | undefined; +export class PhoneConferenceResponse implements IPhoneConferenceResponse { + telephone_conference_id?: string | undefined; - constructor(data?: IUpdateBookingStatusRequest) { + constructor(data?: IPhoneConferenceResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7653,39 +8161,34 @@ export class UpdateBookingStatusRequest implements IUpdateBookingStatusRequest { init(_data?: any) { if (_data) { - this.updated_by = _data['updated_by']; - this.status = _data['status']; - this.cancel_reason = _data['cancel_reason']; + this.telephone_conference_id = _data['telephone_conference_id']; } } - static fromJS(data: any): UpdateBookingStatusRequest { + static fromJS(data: any): PhoneConferenceResponse { data = typeof data === 'object' ? data : {}; - let result = new UpdateBookingStatusRequest(); + let result = new PhoneConferenceResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['updated_by'] = this.updated_by; - data['status'] = this.status; - data['cancel_reason'] = this.cancel_reason; + data['telephone_conference_id'] = this.telephone_conference_id; return data; } } -export interface IUpdateBookingStatusRequest { - updated_by?: string | undefined; - status?: UpdateBookingStatus; - cancel_reason?: string | undefined; +export interface IPhoneConferenceResponse { + telephone_conference_id?: string | undefined; } -export class UpdateHearingAllocationToCsoRequest implements IUpdateHearingAllocationToCsoRequest { - hearings?: string[] | undefined; - cso_id?: string; +export class UpdateBookingStatusResponse implements IUpdateBookingStatusResponse { + success?: boolean; + message?: string | undefined; + telephone_conference_id?: string | undefined; - constructor(data?: IUpdateHearingAllocationToCsoRequest) { + constructor(data?: IUpdateBookingStatusResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7695,41 +8198,38 @@ export class UpdateHearingAllocationToCsoRequest implements IUpdateHearingAlloca init(_data?: any) { if (_data) { - if (Array.isArray(_data['hearings'])) { - this.hearings = [] as any; - for (let item of _data['hearings']) this.hearings!.push(item); - } - this.cso_id = _data['cso_id']; + this.success = _data['success']; + this.message = _data['message']; + this.telephone_conference_id = _data['telephone_conference_id']; } } - static fromJS(data: any): UpdateHearingAllocationToCsoRequest { + static fromJS(data: any): UpdateBookingStatusResponse { data = typeof data === 'object' ? data : {}; - let result = new UpdateHearingAllocationToCsoRequest(); + let result = new UpdateBookingStatusResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - if (Array.isArray(this.hearings)) { - data['hearings'] = []; - for (let item of this.hearings) data['hearings'].push(item); - } - data['cso_id'] = this.cso_id; + data['success'] = this.success; + data['message'] = this.message; + data['telephone_conference_id'] = this.telephone_conference_id; return data; } } -export interface IUpdateHearingAllocationToCsoRequest { - hearings?: string[] | undefined; - cso_id?: string; +export interface IUpdateBookingStatusResponse { + success?: boolean; + message?: string | undefined; + telephone_conference_id?: string | undefined; } -export class UpdateNonWorkingHoursRequest implements IUpdateNonWorkingHoursRequest { - hours?: NonWorkingHours[] | undefined; +export class UploadNonWorkingHoursResponse implements IUploadNonWorkingHoursResponse { + failed_usernames?: string[] | undefined; - constructor(data?: IUpdateNonWorkingHoursRequest) { + constructor(data?: IUploadNonWorkingHoursResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7739,40 +8239,38 @@ export class UpdateNonWorkingHoursRequest implements IUpdateNonWorkingHoursReque init(_data?: any) { if (_data) { - if (Array.isArray(_data['hours'])) { - this.hours = [] as any; - for (let item of _data['hours']) this.hours!.push(NonWorkingHours.fromJS(item)); + if (Array.isArray(_data['failed_usernames'])) { + this.failed_usernames = [] as any; + for (let item of _data['failed_usernames']) this.failed_usernames!.push(item); } } } - static fromJS(data: any): UpdateNonWorkingHoursRequest { + static fromJS(data: any): UploadNonWorkingHoursResponse { data = typeof data === 'object' ? data : {}; - let result = new UpdateNonWorkingHoursRequest(); + let result = new UploadNonWorkingHoursResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - if (Array.isArray(this.hours)) { - data['hours'] = []; - for (let item of this.hours) data['hours'].push(item.toJSON()); + if (Array.isArray(this.failed_usernames)) { + data['failed_usernames'] = []; + for (let item of this.failed_usernames) data['failed_usernames'].push(item); } return data; } } -export interface IUpdateNonWorkingHoursRequest { - hours?: NonWorkingHours[] | undefined; +export interface IUploadNonWorkingHoursResponse { + failed_usernames?: string[] | undefined; } -export class UploadNonWorkingHoursRequest implements IUploadNonWorkingHoursRequest { - username?: string | undefined; - end_time?: Date; - start_time?: Date; +export class UploadWorkHoursResponse implements IUploadWorkHoursResponse { + failed_usernames?: string[] | undefined; - constructor(data?: IUploadNonWorkingHoursRequest) { + constructor(data?: IUploadWorkHoursResponse) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7782,39 +8280,47 @@ export class UploadNonWorkingHoursRequest implements IUploadNonWorkingHoursReque init(_data?: any) { if (_data) { - this.username = _data['username']; - this.end_time = _data['end_time'] ? new Date(_data['end_time'].toString()) : undefined; - this.start_time = _data['start_time'] ? new Date(_data['start_time'].toString()) : undefined; + if (Array.isArray(_data['failed_usernames'])) { + this.failed_usernames = [] as any; + for (let item of _data['failed_usernames']) this.failed_usernames!.push(item); + } } } - static fromJS(data: any): UploadNonWorkingHoursRequest { + static fromJS(data: any): UploadWorkHoursResponse { data = typeof data === 'object' ? data : {}; - let result = new UploadNonWorkingHoursRequest(); + let result = new UploadWorkHoursResponse(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['username'] = this.username; - data['end_time'] = this.end_time ? this.end_time.toISOString() : undefined; - data['start_time'] = this.start_time ? this.start_time.toISOString() : undefined; + if (Array.isArray(this.failed_usernames)) { + data['failed_usernames'] = []; + for (let item of this.failed_usernames) data['failed_usernames'].push(item); + } return data; } } -export interface IUploadNonWorkingHoursRequest { - username?: string | undefined; - end_time?: Date; - start_time?: Date; +export interface IUploadWorkHoursResponse { + failed_usernames?: string[] | undefined; } -export class UploadWorkHoursRequest implements IUploadWorkHoursRequest { +export enum BookingStatus2 { + Booked = 'Booked', + Created = 'Created', + Cancelled = 'Cancelled', + Failed = 'Failed' +} + +export class EditJusticeUserRequest implements IEditJusticeUserRequest { + id?: string; username?: string | undefined; - working_hours?: WorkingHours[] | undefined; + roles?: JusticeUserRole[] | undefined; - constructor(data?: IUploadWorkHoursRequest) { + constructor(data?: IEditJusticeUserRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7824,45 +8330,65 @@ export class UploadWorkHoursRequest implements IUploadWorkHoursRequest { init(_data?: any) { if (_data) { + this.id = _data['id']; this.username = _data['username']; - if (Array.isArray(_data['working_hours'])) { - this.working_hours = [] as any; - for (let item of _data['working_hours']) this.working_hours!.push(WorkingHours.fromJS(item)); + if (Array.isArray(_data['roles'])) { + this.roles = [] as any; + for (let item of _data['roles']) this.roles!.push(item); } } } - static fromJS(data: any): UploadWorkHoursRequest { + static fromJS(data: any): EditJusticeUserRequest { data = typeof data === 'object' ? data : {}; - let result = new UploadWorkHoursRequest(); + let result = new EditJusticeUserRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; + data['id'] = this.id; data['username'] = this.username; - if (Array.isArray(this.working_hours)) { - data['working_hours'] = []; - for (let item of this.working_hours) data['working_hours'].push(item.toJSON()); + if (Array.isArray(this.roles)) { + data['roles'] = []; + for (let item of this.roles) data['roles'].push(item); } return data; } } -export interface IUploadWorkHoursRequest { +export interface IEditJusticeUserRequest { + id?: string; username?: string | undefined; - working_hours?: WorkingHours[] | undefined; + roles?: JusticeUserRole[] | undefined; } -export class WorkingHours implements IWorkingHours { - day_of_week_id?: number; - end_time_hour?: number | undefined; - end_time_minutes?: number | undefined; - start_time_hour?: number | undefined; - start_time_minutes?: number | undefined; +export enum JusticeUserRole { + CaseAdmin = 'CaseAdmin', + Vho = 'Vho', + Clerk = 'Clerk', + Judge = 'Judge', + Individual = 'Individual', + Representative = 'Representative', + JudicialOfficeHolder = 'JudicialOfficeHolder', + StaffMember = 'StaffMember', + VhTeamLead = 'VhTeamLead' +} - constructor(data?: IWorkingHours) { +export enum UpdateBookingStatus { + Booked = 'Booked', + Created = 'Created', + Cancelled = 'Cancelled', + Failed = 'Failed' +} + +export class NonWorkingHours implements INonWorkingHours { + id?: number; + start_time?: Date; + end_time?: Date; + + constructor(data?: INonWorkingHours) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7872,45 +8398,39 @@ export class WorkingHours implements IWorkingHours { init(_data?: any) { if (_data) { - this.day_of_week_id = _data['day_of_week_id']; - this.end_time_hour = _data['end_time_hour']; - this.end_time_minutes = _data['end_time_minutes']; - this.start_time_hour = _data['start_time_hour']; - this.start_time_minutes = _data['start_time_minutes']; + this.id = _data['id']; + this.start_time = _data['start_time'] ? new Date(_data['start_time'].toString()) : undefined; + this.end_time = _data['end_time'] ? new Date(_data['end_time'].toString()) : undefined; } } - static fromJS(data: any): WorkingHours { + static fromJS(data: any): NonWorkingHours { data = typeof data === 'object' ? data : {}; - let result = new WorkingHours(); + let result = new NonWorkingHours(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['day_of_week_id'] = this.day_of_week_id; - data['end_time_hour'] = this.end_time_hour; - data['end_time_minutes'] = this.end_time_minutes; - data['start_time_hour'] = this.start_time_hour; - data['start_time_minutes'] = this.start_time_minutes; + data['id'] = this.id; + data['start_time'] = this.start_time ? this.start_time.toISOString() : undefined; + data['end_time'] = this.end_time ? this.end_time.toISOString() : undefined; return data; } } -export interface IWorkingHours { - day_of_week_id?: number; - end_time_hour?: number | undefined; - end_time_minutes?: number | undefined; - start_time_hour?: number | undefined; - start_time_minutes?: number | undefined; +export interface INonWorkingHours { + id?: number; + start_time?: Date; + end_time?: Date; } -export class AllocatedCsoResponse implements IAllocatedCsoResponse { - hearing_id?: string; - cso?: JusticeUserResponse; +export class RestoreJusticeUserRequest implements IRestoreJusticeUserRequest { + id?: string; + username?: string | undefined; - constructor(data?: IAllocatedCsoResponse) { + constructor(data?: IRestoreJusticeUserRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7920,36 +8440,37 @@ export class AllocatedCsoResponse implements IAllocatedCsoResponse { init(_data?: any) { if (_data) { - this.hearing_id = _data['hearing_id']; - this.cso = _data['cso'] ? JusticeUserResponse.fromJS(_data['cso']) : undefined; + this.id = _data['id']; + this.username = _data['username']; } } - static fromJS(data: any): AllocatedCsoResponse { + static fromJS(data: any): RestoreJusticeUserRequest { data = typeof data === 'object' ? data : {}; - let result = new AllocatedCsoResponse(); + let result = new RestoreJusticeUserRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['hearing_id'] = this.hearing_id; - data['cso'] = this.cso ? this.cso.toJSON() : undefined; + data['id'] = this.id; + data['username'] = this.username; return data; } } -export interface IAllocatedCsoResponse { - hearing_id?: string; - cso?: JusticeUserResponse; +export interface IRestoreJusticeUserRequest { + id?: string; + username?: string | undefined; } -export class BookingsByDateResponse implements IBookingsByDateResponse { - scheduled_date?: Date; - hearings?: BookingsHearingResponse[] | undefined; +export class UpdateBookingStatusRequest implements IUpdateBookingStatusRequest { + updated_by?: string | undefined; + status?: UpdateBookingStatus; + cancel_reason?: string | undefined; - constructor(data?: IBookingsByDateResponse) { + constructor(data?: IUpdateBookingStatusRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -7959,64 +8480,39 @@ export class BookingsByDateResponse implements IBookingsByDateResponse { init(_data?: any) { if (_data) { - this.scheduled_date = _data['scheduled_date'] ? new Date(_data['scheduled_date'].toString()) : undefined; - if (Array.isArray(_data['hearings'])) { - this.hearings = [] as any; - for (let item of _data['hearings']) this.hearings!.push(BookingsHearingResponse.fromJS(item)); - } + this.updated_by = _data['updated_by']; + this.status = _data['status']; + this.cancel_reason = _data['cancel_reason']; } } - static fromJS(data: any): BookingsByDateResponse { + static fromJS(data: any): UpdateBookingStatusRequest { data = typeof data === 'object' ? data : {}; - let result = new BookingsByDateResponse(); + let result = new UpdateBookingStatusRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['scheduled_date'] = this.scheduled_date ? this.scheduled_date.toISOString() : undefined; - if (Array.isArray(this.hearings)) { - data['hearings'] = []; - for (let item of this.hearings) data['hearings'].push(item.toJSON()); - } + data['updated_by'] = this.updated_by; + data['status'] = this.status; + data['cancel_reason'] = this.cancel_reason; return data; } } -export interface IBookingsByDateResponse { - scheduled_date?: Date; - hearings?: BookingsHearingResponse[] | undefined; +export interface IUpdateBookingStatusRequest { + updated_by?: string | undefined; + status?: UpdateBookingStatus; + cancel_reason?: string | undefined; } -export class BookingsHearingResponse implements IBookingsHearingResponse { - hearing_id?: string; - hearing_number?: string | undefined; - hearing_name?: string | undefined; - scheduled_date_time?: Date; - scheduled_duration?: number; - case_type_name?: string | undefined; - hearing_type_name?: string | undefined; - court_room?: string | undefined; - court_address?: string | undefined; - judge_name?: string | undefined; - created_by?: string | undefined; - created_date?: Date; - last_edit_by?: string | undefined; - last_edit_date?: Date | undefined; - confirmed_by?: string | undefined; - confirmed_date?: Date | undefined; - readonly hearing_date?: Date; - status?: BookingStatus; - questionnaire_not_required?: boolean; - audio_recording_required?: boolean; - cancel_reason?: string | undefined; - group_id?: string | undefined; - court_room_account?: string | undefined; - allocated_to?: string | undefined; +export class UpdateHearingAllocationToCsoRequest implements IUpdateHearingAllocationToCsoRequest { + hearings?: string[] | undefined; + cso_id?: string; - constructor(data?: IBookingsHearingResponse) { + constructor(data?: IUpdateHearingAllocationToCsoRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -8026,105 +8522,41 @@ export class BookingsHearingResponse implements IBookingsHearingResponse { init(_data?: any) { if (_data) { - this.hearing_id = _data['hearing_id']; - this.hearing_number = _data['hearing_number']; - this.hearing_name = _data['hearing_name']; - this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; - this.scheduled_duration = _data['scheduled_duration']; - this.case_type_name = _data['case_type_name']; - this.hearing_type_name = _data['hearing_type_name']; - this.court_room = _data['court_room']; - this.court_address = _data['court_address']; - this.judge_name = _data['judge_name']; - this.created_by = _data['created_by']; - this.created_date = _data['created_date'] ? new Date(_data['created_date'].toString()) : undefined; - this.last_edit_by = _data['last_edit_by']; - this.last_edit_date = _data['last_edit_date'] ? new Date(_data['last_edit_date'].toString()) : undefined; - this.confirmed_by = _data['confirmed_by']; - this.confirmed_date = _data['confirmed_date'] ? new Date(_data['confirmed_date'].toString()) : undefined; - (this).hearing_date = _data['hearing_date'] ? new Date(_data['hearing_date'].toString()) : undefined; - this.status = _data['status']; - this.questionnaire_not_required = _data['questionnaire_not_required']; - this.audio_recording_required = _data['audio_recording_required']; - this.cancel_reason = _data['cancel_reason']; - this.group_id = _data['group_id']; - this.court_room_account = _data['court_room_account']; - this.allocated_to = _data['allocated_to']; + if (Array.isArray(_data['hearings'])) { + this.hearings = [] as any; + for (let item of _data['hearings']) this.hearings!.push(item); + } + this.cso_id = _data['cso_id']; } } - static fromJS(data: any): BookingsHearingResponse { + static fromJS(data: any): UpdateHearingAllocationToCsoRequest { data = typeof data === 'object' ? data : {}; - let result = new BookingsHearingResponse(); + let result = new UpdateHearingAllocationToCsoRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['hearing_id'] = this.hearing_id; - data['hearing_number'] = this.hearing_number; - data['hearing_name'] = this.hearing_name; - data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; - data['scheduled_duration'] = this.scheduled_duration; - data['case_type_name'] = this.case_type_name; - data['hearing_type_name'] = this.hearing_type_name; - data['court_room'] = this.court_room; - data['court_address'] = this.court_address; - data['judge_name'] = this.judge_name; - data['created_by'] = this.created_by; - data['created_date'] = this.created_date ? this.created_date.toISOString() : undefined; - data['last_edit_by'] = this.last_edit_by; - data['last_edit_date'] = this.last_edit_date ? this.last_edit_date.toISOString() : undefined; - data['confirmed_by'] = this.confirmed_by; - data['confirmed_date'] = this.confirmed_date ? this.confirmed_date.toISOString() : undefined; - data['hearing_date'] = this.hearing_date ? this.hearing_date.toISOString() : undefined; - data['status'] = this.status; - data['questionnaire_not_required'] = this.questionnaire_not_required; - data['audio_recording_required'] = this.audio_recording_required; - data['cancel_reason'] = this.cancel_reason; - data['group_id'] = this.group_id; - data['court_room_account'] = this.court_room_account; - data['allocated_to'] = this.allocated_to; + if (Array.isArray(this.hearings)) { + data['hearings'] = []; + for (let item of this.hearings) data['hearings'].push(item); + } + data['cso_id'] = this.cso_id; return data; } } -export interface IBookingsHearingResponse { - hearing_id?: string; - hearing_number?: string | undefined; - hearing_name?: string | undefined; - scheduled_date_time?: Date; - scheduled_duration?: number; - case_type_name?: string | undefined; - hearing_type_name?: string | undefined; - court_room?: string | undefined; - court_address?: string | undefined; - judge_name?: string | undefined; - created_by?: string | undefined; - created_date?: Date; - last_edit_by?: string | undefined; - last_edit_date?: Date | undefined; - confirmed_by?: string | undefined; - confirmed_date?: Date | undefined; - hearing_date?: Date; - status?: BookingStatus; - questionnaire_not_required?: boolean; - audio_recording_required?: boolean; - cancel_reason?: string | undefined; - group_id?: string | undefined; - court_room_account?: string | undefined; - allocated_to?: string | undefined; +export interface IUpdateHearingAllocationToCsoRequest { + hearings?: string[] | undefined; + cso_id?: string; } -export class BookingsResponse implements IBookingsResponse { - hearings?: BookingsByDateResponse[] | undefined; - next_cursor?: string | undefined; - limit?: number; - prev_page_url?: string | undefined; - next_page_url?: string | undefined; +export class UpdateNonWorkingHoursRequest implements IUpdateNonWorkingHoursRequest { + hours?: NonWorkingHours[] | undefined; - constructor(data?: IBookingsResponse) { + constructor(data?: IUpdateNonWorkingHoursRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -8134,52 +8566,40 @@ export class BookingsResponse implements IBookingsResponse { init(_data?: any) { if (_data) { - if (Array.isArray(_data['hearings'])) { - this.hearings = [] as any; - for (let item of _data['hearings']) this.hearings!.push(BookingsByDateResponse.fromJS(item)); + if (Array.isArray(_data['hours'])) { + this.hours = [] as any; + for (let item of _data['hours']) this.hours!.push(NonWorkingHours.fromJS(item)); } - this.next_cursor = _data['next_cursor']; - this.limit = _data['limit']; - this.prev_page_url = _data['prev_page_url']; - this.next_page_url = _data['next_page_url']; } } - static fromJS(data: any): BookingsResponse { + static fromJS(data: any): UpdateNonWorkingHoursRequest { data = typeof data === 'object' ? data : {}; - let result = new BookingsResponse(); + let result = new UpdateNonWorkingHoursRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - if (Array.isArray(this.hearings)) { - data['hearings'] = []; - for (let item of this.hearings) data['hearings'].push(item.toJSON()); + if (Array.isArray(this.hours)) { + data['hours'] = []; + for (let item of this.hours) data['hours'].push(item.toJSON()); } - data['next_cursor'] = this.next_cursor; - data['limit'] = this.limit; - data['prev_page_url'] = this.prev_page_url; - data['next_page_url'] = this.next_page_url; return data; } } -export interface IBookingsResponse { - hearings?: BookingsByDateResponse[] | undefined; - next_cursor?: string | undefined; - limit?: number; - prev_page_url?: string | undefined; - next_page_url?: string | undefined; +export interface IUpdateNonWorkingHoursRequest { + hours?: NonWorkingHours[] | undefined; } -export class CaseResponse implements ICaseResponse { - number?: string | undefined; - name?: string | undefined; - is_lead_case?: boolean; +export class UploadNonWorkingHoursRequest implements IUploadNonWorkingHoursRequest { + username?: string | undefined; + end_time?: Date; + start_time?: Date; - constructor(data?: ICaseResponse) { + constructor(data?: IUploadNonWorkingHoursRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -8189,42 +8609,39 @@ export class CaseResponse implements ICaseResponse { init(_data?: any) { if (_data) { - this.number = _data['number']; - this.name = _data['name']; - this.is_lead_case = _data['is_lead_case']; + this.username = _data['username']; + this.end_time = _data['end_time'] ? new Date(_data['end_time'].toString()) : undefined; + this.start_time = _data['start_time'] ? new Date(_data['start_time'].toString()) : undefined; } } - static fromJS(data: any): CaseResponse { + static fromJS(data: any): UploadNonWorkingHoursRequest { data = typeof data === 'object' ? data : {}; - let result = new CaseResponse(); + let result = new UploadNonWorkingHoursRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['number'] = this.number; - data['name'] = this.name; - data['is_lead_case'] = this.is_lead_case; + data['username'] = this.username; + data['end_time'] = this.end_time ? this.end_time.toISOString() : undefined; + data['start_time'] = this.start_time ? this.start_time.toISOString() : undefined; return data; } } -export interface ICaseResponse { - number?: string | undefined; - name?: string | undefined; - is_lead_case?: boolean; +export interface IUploadNonWorkingHoursRequest { + username?: string | undefined; + end_time?: Date; + start_time?: Date; } -export class EndpointResponse implements IEndpointResponse { - id?: string; - display_name?: string | undefined; - sip?: string | undefined; - pin?: string | undefined; - defence_advocate_id?: string | undefined; +export class UploadWorkHoursRequest implements IUploadWorkHoursRequest { + username?: string | undefined; + working_hours?: WorkingHours[] | undefined; - constructor(data?: IEndpointResponse) { + constructor(data?: IUploadWorkHoursRequest) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -8234,66 +8651,45 @@ export class EndpointResponse implements IEndpointResponse { init(_data?: any) { if (_data) { - this.id = _data['id']; - this.display_name = _data['display_name']; - this.sip = _data['sip']; - this.pin = _data['pin']; - this.defence_advocate_id = _data['defence_advocate_id']; + this.username = _data['username']; + if (Array.isArray(_data['working_hours'])) { + this.working_hours = [] as any; + for (let item of _data['working_hours']) this.working_hours!.push(WorkingHours.fromJS(item)); + } } } - static fromJS(data: any): EndpointResponse { + static fromJS(data: any): UploadWorkHoursRequest { data = typeof data === 'object' ? data : {}; - let result = new EndpointResponse(); + let result = new UploadWorkHoursRequest(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['display_name'] = this.display_name; - data['sip'] = this.sip; - data['pin'] = this.pin; - data['defence_advocate_id'] = this.defence_advocate_id; + data['username'] = this.username; + if (Array.isArray(this.working_hours)) { + data['working_hours'] = []; + for (let item of this.working_hours) data['working_hours'].push(item.toJSON()); + } return data; } } -export interface IEndpointResponse { - id?: string; - display_name?: string | undefined; - sip?: string | undefined; - pin?: string | undefined; - defence_advocate_id?: string | undefined; +export interface IUploadWorkHoursRequest { + username?: string | undefined; + working_hours?: WorkingHours[] | undefined; } -export class HearingDetailsResponse implements IHearingDetailsResponse { - id?: string; - scheduled_date_time?: Date; - scheduled_duration?: number; - hearing_venue_name?: string | undefined; - case_type_name?: string | undefined; - hearing_type_name?: string | undefined; - cases?: CaseResponse[] | undefined; - participants?: ParticipantResponse[] | undefined; - telephone_participants?: TelephoneParticipantResponse[] | undefined; - hearing_room_name?: string | undefined; - other_information?: string | undefined; - created_date?: Date; - created_by?: string | undefined; - updated_by?: string | undefined; - updated_date?: Date; - confirmed_by?: string | undefined; - confirmed_date?: Date | undefined; - status?: BookingStatus; - questionnaire_not_required?: boolean; - audio_recording_required?: boolean; - cancel_reason?: string | undefined; - endpoints?: EndpointResponse[] | undefined; - group_id?: string | undefined; +export class WorkingHours implements IWorkingHours { + day_of_week_id?: number; + end_time_hour?: number | undefined; + end_time_minutes?: number | undefined; + start_time_hour?: number | undefined; + start_time_minutes?: number | undefined; - constructor(data?: IHearingDetailsResponse) { + constructor(data?: IWorkingHours) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; @@ -8303,122 +8699,87 @@ export class HearingDetailsResponse implements IHearingDetailsResponse { init(_data?: any) { if (_data) { - this.id = _data['id']; - this.scheduled_date_time = _data['scheduled_date_time'] ? new Date(_data['scheduled_date_time'].toString()) : undefined; - this.scheduled_duration = _data['scheduled_duration']; - this.hearing_venue_name = _data['hearing_venue_name']; - this.case_type_name = _data['case_type_name']; - this.hearing_type_name = _data['hearing_type_name']; - if (Array.isArray(_data['cases'])) { - this.cases = [] as any; - for (let item of _data['cases']) this.cases!.push(CaseResponse.fromJS(item)); - } - if (Array.isArray(_data['participants'])) { - this.participants = [] as any; - for (let item of _data['participants']) this.participants!.push(ParticipantResponse.fromJS(item)); - } - if (Array.isArray(_data['telephone_participants'])) { - this.telephone_participants = [] as any; - for (let item of _data['telephone_participants']) - this.telephone_participants!.push(TelephoneParticipantResponse.fromJS(item)); - } - this.hearing_room_name = _data['hearing_room_name']; - this.other_information = _data['other_information']; - this.created_date = _data['created_date'] ? new Date(_data['created_date'].toString()) : undefined; - this.created_by = _data['created_by']; - this.updated_by = _data['updated_by']; - this.updated_date = _data['updated_date'] ? new Date(_data['updated_date'].toString()) : undefined; - this.confirmed_by = _data['confirmed_by']; - this.confirmed_date = _data['confirmed_date'] ? new Date(_data['confirmed_date'].toString()) : undefined; - this.status = _data['status']; - this.questionnaire_not_required = _data['questionnaire_not_required']; - this.audio_recording_required = _data['audio_recording_required']; - this.cancel_reason = _data['cancel_reason']; - if (Array.isArray(_data['endpoints'])) { - this.endpoints = [] as any; - for (let item of _data['endpoints']) this.endpoints!.push(EndpointResponse.fromJS(item)); - } - this.group_id = _data['group_id']; + this.day_of_week_id = _data['day_of_week_id']; + this.end_time_hour = _data['end_time_hour']; + this.end_time_minutes = _data['end_time_minutes']; + this.start_time_hour = _data['start_time_hour']; + this.start_time_minutes = _data['start_time_minutes']; } } - static fromJS(data: any): HearingDetailsResponse { + static fromJS(data: any): WorkingHours { data = typeof data === 'object' ? data : {}; - let result = new HearingDetailsResponse(); + let result = new WorkingHours(); result.init(data); return result; } toJSON(data?: any) { data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['scheduled_date_time'] = this.scheduled_date_time ? this.scheduled_date_time.toISOString() : undefined; - data['scheduled_duration'] = this.scheduled_duration; - data['hearing_venue_name'] = this.hearing_venue_name; - data['case_type_name'] = this.case_type_name; - data['hearing_type_name'] = this.hearing_type_name; - if (Array.isArray(this.cases)) { - data['cases'] = []; - for (let item of this.cases) data['cases'].push(item.toJSON()); - } - if (Array.isArray(this.participants)) { - data['participants'] = []; - for (let item of this.participants) data['participants'].push(item.toJSON()); - } - if (Array.isArray(this.telephone_participants)) { - data['telephone_participants'] = []; - for (let item of this.telephone_participants) data['telephone_participants'].push(item.toJSON()); + data['day_of_week_id'] = this.day_of_week_id; + data['end_time_hour'] = this.end_time_hour; + data['end_time_minutes'] = this.end_time_minutes; + data['start_time_hour'] = this.start_time_hour; + data['start_time_minutes'] = this.start_time_minutes; + return data; + } +} + +export interface IWorkingHours { + day_of_week_id?: number; + end_time_hour?: number | undefined; + end_time_minutes?: number | undefined; + start_time_hour?: number | undefined; + start_time_minutes?: number | undefined; +} + +export class AllocatedCsoResponse implements IAllocatedCsoResponse { + hearing_id?: string; + cso?: JusticeUserResponse; + supports_work_allocation?: boolean; + + constructor(data?: IAllocatedCsoResponse) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; + } } - data['hearing_room_name'] = this.hearing_room_name; - data['other_information'] = this.other_information; - data['created_date'] = this.created_date ? this.created_date.toISOString() : undefined; - data['created_by'] = this.created_by; - data['updated_by'] = this.updated_by; - data['updated_date'] = this.updated_date ? this.updated_date.toISOString() : undefined; - data['confirmed_by'] = this.confirmed_by; - data['confirmed_date'] = this.confirmed_date ? this.confirmed_date.toISOString() : undefined; - data['status'] = this.status; - data['questionnaire_not_required'] = this.questionnaire_not_required; - data['audio_recording_required'] = this.audio_recording_required; - data['cancel_reason'] = this.cancel_reason; - if (Array.isArray(this.endpoints)) { - data['endpoints'] = []; - for (let item of this.endpoints) data['endpoints'].push(item.toJSON()); + } + + init(_data?: any) { + if (_data) { + this.hearing_id = _data['hearing_id']; + this.cso = _data['cso'] ? JusticeUserResponse.fromJS(_data['cso']) : undefined; + this.supports_work_allocation = _data['supports_work_allocation']; } - data['group_id'] = this.group_id; + } + + static fromJS(data: any): AllocatedCsoResponse { + data = typeof data === 'object' ? data : {}; + let result = new AllocatedCsoResponse(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data['hearing_id'] = this.hearing_id; + data['cso'] = this.cso ? this.cso.toJSON() : undefined; + data['supports_work_allocation'] = this.supports_work_allocation; return data; } } -export interface IHearingDetailsResponse { - id?: string; - scheduled_date_time?: Date; - scheduled_duration?: number; - hearing_venue_name?: string | undefined; - case_type_name?: string | undefined; - hearing_type_name?: string | undefined; - cases?: CaseResponse[] | undefined; - participants?: ParticipantResponse[] | undefined; - telephone_participants?: TelephoneParticipantResponse[] | undefined; - hearing_room_name?: string | undefined; - other_information?: string | undefined; - created_date?: Date; - created_by?: string | undefined; - updated_by?: string | undefined; - updated_date?: Date; - confirmed_by?: string | undefined; - confirmed_date?: Date | undefined; - status?: BookingStatus; - questionnaire_not_required?: boolean; - audio_recording_required?: boolean; - cancel_reason?: string | undefined; - endpoints?: EndpointResponse[] | undefined; - group_id?: string | undefined; +export interface IAllocatedCsoResponse { + hearing_id?: string; + cso?: JusticeUserResponse; + supports_work_allocation?: boolean; } export class HearingVenueResponse implements IHearingVenueResponse { id?: number; name?: string | undefined; + code?: string | undefined; constructor(data?: IHearingVenueResponse) { if (data) { @@ -8432,6 +8793,7 @@ export class HearingVenueResponse implements IHearingVenueResponse { if (_data) { this.id = _data['id']; this.name = _data['name']; + this.code = _data['code']; } } @@ -8446,6 +8808,7 @@ export class HearingVenueResponse implements IHearingVenueResponse { data = typeof data === 'object' ? data : {}; data['id'] = this.id; data['name'] = this.name; + data['code'] = this.code; return data; } } @@ -8453,6 +8816,7 @@ export class HearingVenueResponse implements IHearingVenueResponse { export interface IHearingVenueResponse { id?: number; name?: string | undefined; + code?: string | undefined; } export class HearingsByUsernameForDeletionResponse implements IHearingsByUsernameForDeletionResponse { @@ -8587,142 +8951,6 @@ export interface IJusticeUserResponse { deleted?: boolean; } -export class LinkedParticipantResponse implements ILinkedParticipantResponse { - linked_id?: string; - type?: LinkedParticipantType; - - constructor(data?: ILinkedParticipantResponse) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; - } - } - } - - init(_data?: any) { - if (_data) { - this.linked_id = _data['linked_id']; - this.type = _data['type']; - } - } - - static fromJS(data: any): LinkedParticipantResponse { - data = typeof data === 'object' ? data : {}; - let result = new LinkedParticipantResponse(); - result.init(data); - return result; - } - - toJSON(data?: any) { - data = typeof data === 'object' ? data : {}; - data['linked_id'] = this.linked_id; - data['type'] = this.type; - return data; - } -} - -export interface ILinkedParticipantResponse { - linked_id?: string; - type?: LinkedParticipantType; -} - -export class ParticipantResponse implements IParticipantResponse { - id?: string; - display_name?: string | undefined; - case_role_name?: string | undefined; - hearing_role_name?: string | undefined; - user_role_name?: string | undefined; - title?: string | undefined; - first_name?: string | undefined; - middle_names?: string | undefined; - last_name?: string | undefined; - contact_email?: string | undefined; - telephone_number?: string | undefined; - username?: string | undefined; - organisation?: string | undefined; - representee?: string | undefined; - linked_participants?: LinkedParticipantResponse[] | undefined; - - constructor(data?: IParticipantResponse) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; - } - } - } - - init(_data?: any) { - if (_data) { - this.id = _data['id']; - this.display_name = _data['display_name']; - this.case_role_name = _data['case_role_name']; - this.hearing_role_name = _data['hearing_role_name']; - this.user_role_name = _data['user_role_name']; - this.title = _data['title']; - this.first_name = _data['first_name']; - this.middle_names = _data['middle_names']; - this.last_name = _data['last_name']; - this.contact_email = _data['contact_email']; - this.telephone_number = _data['telephone_number']; - this.username = _data['username']; - this.organisation = _data['organisation']; - this.representee = _data['representee']; - if (Array.isArray(_data['linked_participants'])) { - this.linked_participants = [] as any; - for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipantResponse.fromJS(item)); - } - } - } - - static fromJS(data: any): ParticipantResponse { - data = typeof data === 'object' ? data : {}; - let result = new ParticipantResponse(); - result.init(data); - return result; - } - - toJSON(data?: any) { - data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['display_name'] = this.display_name; - data['case_role_name'] = this.case_role_name; - data['hearing_role_name'] = this.hearing_role_name; - data['user_role_name'] = this.user_role_name; - data['title'] = this.title; - data['first_name'] = this.first_name; - data['middle_names'] = this.middle_names; - data['last_name'] = this.last_name; - data['contact_email'] = this.contact_email; - data['telephone_number'] = this.telephone_number; - data['username'] = this.username; - data['organisation'] = this.organisation; - data['representee'] = this.representee; - if (Array.isArray(this.linked_participants)) { - data['linked_participants'] = []; - for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); - } - return data; - } -} - -export interface IParticipantResponse { - id?: string; - display_name?: string | undefined; - case_role_name?: string | undefined; - hearing_role_name?: string | undefined; - user_role_name?: string | undefined; - title?: string | undefined; - first_name?: string | undefined; - middle_names?: string | undefined; - last_name?: string | undefined; - contact_email?: string | undefined; - telephone_number?: string | undefined; - username?: string | undefined; - organisation?: string | undefined; - representee?: string | undefined; - linked_participants?: LinkedParticipantResponse[] | undefined; -} - export class ParticipantSuitabilityAnswerResponse implements IParticipantSuitabilityAnswerResponse { participant_id?: string; case_number?: string | undefined; @@ -8965,83 +9193,6 @@ export interface ISuitabilityAnswersResponse { next_page_url?: string | undefined; } -export class TelephoneParticipantResponse implements ITelephoneParticipantResponse { - id?: string; - case_role_name?: string | undefined; - hearing_role_name?: string | undefined; - first_name?: string | undefined; - last_name?: string | undefined; - contact_email?: string | undefined; - telephone_number?: string | undefined; - mobile_number?: string | undefined; - representee?: string | undefined; - linked_participants?: LinkedParticipantResponse[] | undefined; - - constructor(data?: ITelephoneParticipantResponse) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) (this)[property] = (data)[property]; - } - } - } - - init(_data?: any) { - if (_data) { - this.id = _data['id']; - this.case_role_name = _data['case_role_name']; - this.hearing_role_name = _data['hearing_role_name']; - this.first_name = _data['first_name']; - this.last_name = _data['last_name']; - this.contact_email = _data['contact_email']; - this.telephone_number = _data['telephone_number']; - this.mobile_number = _data['mobile_number']; - this.representee = _data['representee']; - if (Array.isArray(_data['linked_participants'])) { - this.linked_participants = [] as any; - for (let item of _data['linked_participants']) this.linked_participants!.push(LinkedParticipantResponse.fromJS(item)); - } - } - } - - static fromJS(data: any): TelephoneParticipantResponse { - data = typeof data === 'object' ? data : {}; - let result = new TelephoneParticipantResponse(); - result.init(data); - return result; - } - - toJSON(data?: any) { - data = typeof data === 'object' ? data : {}; - data['id'] = this.id; - data['case_role_name'] = this.case_role_name; - data['hearing_role_name'] = this.hearing_role_name; - data['first_name'] = this.first_name; - data['last_name'] = this.last_name; - data['contact_email'] = this.contact_email; - data['telephone_number'] = this.telephone_number; - data['mobile_number'] = this.mobile_number; - data['representee'] = this.representee; - if (Array.isArray(this.linked_participants)) { - data['linked_participants'] = []; - for (let item of this.linked_participants) data['linked_participants'].push(item.toJSON()); - } - return data; - } -} - -export interface ITelephoneParticipantResponse { - id?: string; - case_role_name?: string | undefined; - hearing_role_name?: string | undefined; - first_name?: string | undefined; - last_name?: string | undefined; - contact_email?: string | undefined; - telephone_number?: string | undefined; - mobile_number?: string | undefined; - representee?: string | undefined; - linked_participants?: LinkedParticipantResponse[] | undefined; -} - export class VhoNonAvailabilityWorkHoursResponse implements IVhoNonAvailabilityWorkHoursResponse { id?: number; end_time?: Date; diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/launch-darkly.service.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/launch-darkly.service.ts index 070096ad5..36f67d397 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/launch-darkly.service.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/launch-darkly.service.ts @@ -9,7 +9,8 @@ export const FeatureFlags = { vhoWorkAllocation: 'vho-work-allocation', eJudFeature: 'EJudFeature', dom1Integration: 'dom1', - hrsIntegration: 'hrs-integration' + hrsIntegration: 'hrs-integration', + referenceData: 'reference-data' }; @Injectable({ diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/recording-guard.service.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/recording-guard.service.ts index 80bf32959..d1428c693 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/recording-guard.service.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/recording-guard.service.ts @@ -5,7 +5,7 @@ import { ParticipantModel } from '../common/model/participant.model'; providedIn: 'root' }) export class RecordingGuardService { - excludedCaseTypes: string[] = ['Court of Appeal Criminal Division']; + excludedCaseTypes: string[] = ['Court of Appeal Criminal Division', 'Crime Crown Court']; mandatoryRecordingRoles: string[] = ['Interpreter']; switchOffRecording(caseType: string): boolean { diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.spec.ts index 139adc064..bc9934661 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.spec.ts @@ -36,7 +36,8 @@ describe('Video hearing service', () => { 'getTelephoneConferenceIdById', 'getConfigSettings', 'getUserList', - 'getAllocationForHearing' + 'getAllocationForHearing', + 'rebookHearing' ]); service = new VideoHearingsService(clientApiSpy); }); @@ -420,7 +421,7 @@ describe('Video hearing service', () => { endpoint.display_name = 'endpoint 001'; endpoints.push(endpoint); - const model = service.mapEndpointResponseToEndpointModel(endpoints); + const model = service.mapEndpointResponseToEndpointModel(endpoints, []); expect(model[0].displayName).toEqual(endpoint.display_name); }); @@ -517,6 +518,13 @@ describe('Video hearing service', () => { expect(model[0].linkedParticipantId).toEqual(linkedParticipant.linked_id); }); + it('should rebook hearing', async () => { + clientApiSpy.rebookHearing.and.returnValue(of(null)); + + await service.rebookHearing('hearingId'); + expect(clientApiSpy.rebookHearing).toHaveBeenCalled(); + }); + describe('isConferenceClosed', () => { it('should return false if booking status booked and telephone conference Id is empty', () => { const model = new HearingModel(); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.ts index a05986966..cce43e26a 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/services/video-hearings.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { firstValueFrom, lastValueFrom, Observable } from 'rxjs'; import { BHClient, - BookNewHearingRequest, + BookingDetailsRequest, CaseAndHearingRolesResponse, CaseRequest, CaseResponse, @@ -107,8 +107,8 @@ export class VideoHearingsService { sessionStorage.removeItem(this.vhoNonAvailabiltiesHaveChangesKey); } - getHearingTypes(): Observable { - return this.bhClient.getHearingTypes(); + getHearingTypes(includeDeleted: boolean = false): Observable { + return this.bhClient.getHearingTypes(includeDeleted); } getCurrentRequest(): HearingModel { @@ -185,6 +185,10 @@ export class VideoHearingsService { return await lastValueFrom(this.bhClient.cloneHearing(hearingId, request)); } + rebookHearing(hearingId: string): Promise { + return lastValueFrom(this.bhClient.rebookHearing(hearingId)); + } + updateHearing(booking: HearingModel): Observable { const hearingRequest = this.mapExistingHearing(booking); return this.bhClient.editHearing(booking.hearing_id, hearingRequest); @@ -268,8 +272,8 @@ export class VideoHearingsService { return editEndpoint; } - mapHearing(newRequest: HearingModel): BookNewHearingRequest { - const newHearingRequest = new BookNewHearingRequest(); + mapHearing(newRequest: HearingModel): BookingDetailsRequest { + const newHearingRequest = new BookingDetailsRequest(); newHearingRequest.cases = this.mapCases(newRequest); newHearingRequest.case_type_name = newRequest.case_type; newHearingRequest.hearing_type_name = newRequest.hearing_type_name; @@ -305,7 +309,7 @@ export class VideoHearingsService { hearing.questionnaire_not_required = response.questionnaire_not_required; hearing.status = response.status; hearing.audio_recording_required = response.audio_recording_required; - hearing.endpoints = this.mapEndpointResponseToEndpointModel(response.endpoints); + hearing.endpoints = this.mapEndpointResponseToEndpointModel(response.endpoints, response.participants); hearing.isConfirmed = Boolean(response.confirmed_date); return hearing; } @@ -419,17 +423,18 @@ export class VideoHearingsService { return linkedParticipants; } - mapEndpointResponseToEndpointModel(response: EndpointResponse[]): EndpointModel[] { + mapEndpointResponseToEndpointModel(response: EndpointResponse[], participants: ParticipantResponse[]): EndpointModel[] { const endpoints: EndpointModel[] = []; let endpoint: EndpointModel; if (response && response.length > 0) { response.forEach(e => { + const defenceAdvocate = participants.find(p => p.id === e.defence_advocate_id); endpoint = new EndpointModel(); endpoint.id = e.id; endpoint.displayName = e.display_name; endpoint.pin = e.pin; endpoint.sip = e.sip; - endpoint.defenceAdvocate = e.defence_advocate_id; + endpoint.defenceAdvocate = defenceAdvocate?.contact_email; endpoints.push(endpoint); }); } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/shared/menus/case-types-menu/case-types-menu.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/shared/menus/case-types-menu/case-types-menu.component.ts index aeefca3c7..48ec422d1 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/shared/menus/case-types-menu/case-types-menu.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/shared/menus/case-types-menu/case-types-menu.component.ts @@ -33,19 +33,19 @@ export class CaseTypesMenuComponent extends MenuBase { loadItems(): void { const distinct = (value, index, array) => array.indexOf(value) === index; - this.videoHearingService.getHearingTypes().subscribe( - (data: HearingTypeResponse[]) => { + this.videoHearingService.getHearingTypes(true).subscribe({ + next: (data: HearingTypeResponse[]) => { this.caseTypes = this.items = [ ...Array.from( data .map(item => item.group) .filter(distinct) - .sort() + .sort((a, b) => a.localeCompare(b)) ) ]; this.logger.debug(`${this.loggerPrefix} Updating list of case-types.`, { caseTypes: data.length }); }, - error => this.handleListError(error, 'case types') - ); + error: error => this.handleListError(error, 'case types') + }); } } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/allocate-hearings/allocate-hearings.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/allocate-hearings/allocate-hearings.component.ts index 6cfef2414..b4998e7a2 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/allocate-hearings/allocate-hearings.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/allocate-hearings/allocate-hearings.component.ts @@ -105,11 +105,11 @@ export class AllocateHearingsComponent implements OnInit { }); const distinct = (value, index, array) => array.indexOf(value) === index; - this.videoHearingService.getHearingTypes().subscribe((data: HearingTypeResponse[]) => { + this.videoHearingService.getHearingTypes(true).subscribe((data: HearingTypeResponse[]) => { this.caseTypesSelectOptions = data .map(item => item.group) .filter(distinct) - .sort() + .sort((a, b) => a.localeCompare(b)) .map(group => ({ entityId: group, label: group })); }); } @@ -241,13 +241,13 @@ export class AllocateHearingsComponent implements OnInit { confirmAllocation() { this.clearHearingUpdatedMessage(); const selectedCso = this.selectAllocateCso?.selected as SelectOption; - this.allocateService.allocateCsoToHearings(this.allocationHearingViewModel.selectedHearingIds, selectedCso.entityId).subscribe( - result => this.updateTableWithAllocatedCso(result), - () => { + this.allocateService.allocateCsoToHearings(this.allocationHearingViewModel.selectedHearingIds, selectedCso.entityId).subscribe({ + next: result => this.updateTableWithAllocatedCso(result), + error: () => { this.updateMessageAndDisplay('One or more hearings could not be allocated successfully.'); this.searchForHearings(true); } - ); + }); } toggleAll(checkAll: boolean) { diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.spec.ts index f382ae1e6..f0b722eba 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.spec.ts @@ -328,13 +328,16 @@ describe('EditWorkHoursComponent', () => { describe('filter by future date', () => { it('should show vho future data ', () => { - component.result = [ - new VhoNonAvailabilityWorkHoursResponse({ id: 0, start_time: new Date('2022/10/24'), end_time: new Date('2022/10/24') }), - new VhoNonAvailabilityWorkHoursResponse({ id: 1, start_time: new Date('2022/10/25'), end_time: new Date('2022/10/29') }), - new VhoNonAvailabilityWorkHoursResponse({ id: 2, start_time: new Date('2023/10/30'), end_time: new Date('2023/10/31') }) + component.todayDate = new Date('2022/07/25'); + const input = [ + new VhoNonAvailabilityWorkHoursResponse({ id: 0, start_time: new Date('2021/07/30'), end_time: new Date('2022/07/30') }), + new VhoNonAvailabilityWorkHoursResponse({ id: 1, start_time: new Date('2022/07/25'), end_time: new Date('2022/07/26') }), + new VhoNonAvailabilityWorkHoursResponse({ id: 2, start_time: new Date('2022/06/25'), end_time: new Date('2022/06/25') }) ]; - fixture.detectChanges(); - expect(component.filterByFutureDate).toBeTruthy(); + const result = component.filterByFutureDate(input); + expect(result.length).toBe(2); + expect(result).toContain(input[0]); + expect(result).toContain(input[1]); }); }); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.ts index 8c69f5969..50a72f7f5 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/edit-work-hours.component.ts @@ -202,6 +202,6 @@ export class EditWorkHoursComponent implements OnInit { this.dataChange.emit($event); } public filterByFutureDate(value: VhoNonAvailabilityWorkHoursResponse[]) { - return value?.filter(d => d.start_time >= this.todayDate); + return value?.filter(d => d.end_time >= this.todayDate); } } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.spec.ts index 139cece94..09e127748 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.spec.ts @@ -996,6 +996,19 @@ describe('VhoNonAvailabilityWorkHoursTableComponent', () => { // assert expect(component.displayMessage).toBeFalsy(); }); + + it('it should display a message when non-availability hour row deleted', () => { + component.nonWorkHours = [new EditVhoNonAvailabilityWorkHoursModel()]; + component.addNewNonAvailabilityRow(); + const slot = component.nonWorkHours[component.nonWorkHours.length - 1]; + + component.delete(slot); + component.onDeletionAnswer(true); + fixture.detectChanges(); + // assert + expect(component.displayMessage).toBeTruthy(); + expect(component.message).toBe(VhoWorkHoursNonAvailabilityTableComponent.DeleteRowMessageNonAvailabilityHours); + }); }); describe('handleContinue', () => { diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.ts index 9184b8f7d..362dbd949 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/edit-work-hours/vho-work-hours-non-availability-table/vho-work-hours-non-availability-table.component.ts @@ -70,6 +70,7 @@ export class VhoWorkHoursNonAvailabilityTableComponent implements OnInit, CanDea public static readonly ErrorEndTimeRequired = 'End time is required'; public static readonly WarningRecordLimitExeeded = 'Showing only 20 Records, For more records please use filter by date'; public static readonly WarningNoWorkingHoursForVho = 'There are no non-availability hours uploaded for this team member'; + public static readonly DeleteRowMessageNonAvailabilityHours = 'Non-availability hours deleted successfully'; private static DateTimeErrors = { start_date: VhoWorkHoursNonAvailabilityTableComponent.ErrorStartDateRequired, @@ -365,11 +366,13 @@ export class VhoWorkHoursNonAvailabilityTableComponent implements OnInit, CanDea onDeletionAnswer($event: boolean) { this.displayConfirmPopup = false; + if ($event) { - this.bhClient.deleteNonAvailabilityWorkHours(this.slotToDelete.id).subscribe({ + this.bhClient.deleteNonAvailabilityWorkHours(this.userName, this.slotToDelete.id).subscribe({ next: () => { this.logger.info(`${this.loggerPrefix} Non Working hours deleted`); this.removeSlot(); + this.showMessage(VhoWorkHoursNonAvailabilityTableComponent.DeleteRowMessageNonAvailabilityHours); }, error: error => { this.logger.error(`${this.loggerPrefix} Working hours could not be saved`, error); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.spec.ts index 8e5f8cfa3..665af8e92 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.spec.ts @@ -89,6 +89,38 @@ describe('WorkHoursFileProcessorService', () => { expect(result.fileValidationErrors.length).toBe(1); expect(result.fileValidationErrors[0]).toContain('duplicate team member found'); }); + + it('should show invalid row error when too few values provided', () => { + const input = + 'Username,Monday,,Tuesday,,Wednesday,,Thursday,,Friday,Saturday,Sunday\n' + + ',Start,End,Start,End,Start,End,Start,End,Start,End,Start,End,Start,End\n' + + 'first.second@xyz.com,9:00,17:00,09:00,17:30,9:30,18:00,08:00,18:00,9:00,17:00\n' + + 'first.second.2@xyz.com,9:00,17:00,09:00,17:30,9:30,18:00,08:00,18:00,9:00,17:00'; + + const result = service.processWorkHours(input); + expect(result.fileValidationErrors.length).toBe(2); + result.fileValidationErrors.forEach(error => { + expect(error).toContain( + 'Invalid row detected. Please ensure that the structure of the row matches the provided template, with blank values if a user does not work on a particular day.' + ); + }); + }); + + it('should show invalid row error when too many values provided', () => { + const input = + 'Username,Monday,,Tuesday,,Wednesday,,Thursday,,Friday,Saturday,Sunday\n' + + ',Start,End,Start,End,Start,End,Start,End,Start,End,Start,End,Start,End\n' + + 'first.second@xyz.com,,9:00,17:00,09:00,17:30,9:30,18:00,08:00,18:00,9:00,17:00,,,,\n' + + 'first.second.2@xyz.com,,,9:00,17:00,09:00,17:30,9:30,18:00,08:00,18:00,9:00,17:00,,,,'; + + const result = service.processWorkHours(input); + expect(result.fileValidationErrors.length).toBe(2); + result.fileValidationErrors.forEach(error => { + expect(error).toContain( + 'Invalid row detected. Please ensure that the structure of the row matches the provided template, with blank values if a user does not work on a particular day.' + ); + }); + }); }); describe('processNonWorkHour', () => { diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.ts index 8e46789f6..394d7eeed 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/services/work-hours-file-processor.service.ts @@ -19,6 +19,8 @@ export class WorkHoursFileProcessorService { private incorrectDelimiterErrorMessage = 'Incorrect delimiter used. Please use a colon to separate the hours and minutes.'; private duplicateUserErrorMessage = 'duplicate team member found.'; + private invalidRow = + 'Invalid row detected. Please ensure that the structure of the row matches the provided template, with blank values if a user does not work on a particular day.'; constructor(private bhClient: BHClient) {} @@ -52,6 +54,12 @@ export class WorkHoursFileProcessorService { } const actualRow = index + 3; + const expectedValueCount = 15; + if (values.length !== expectedValueCount) { + workingHoursFileValidationErrors.push(`Row ${actualRow} - ${this.invalidRow}`); + return; + } + const uploadWorkHoursRequest = new UploadWorkHoursRequest(); uploadWorkHoursRequest.username = values[0]; diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.html b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.html index 9c99bf581..d9034a1f3 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.html +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.html @@ -31,7 +31,14 @@ type="file" accept=".CSV" /> - +
- +
diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.spec.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.spec.ts index 5f5d9ad2b..d6d951ff8 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.spec.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.spec.ts @@ -70,6 +70,31 @@ describe('UploadWorkHoursComponent', () => { expect(resetErrorsSpy).toHaveBeenCalled(); }); + it('should disable upload button for work hours if file is invalid', () => { + const resetErrorsSpy = spyOn(component, 'resetWorkingHoursMessages'); + workHoursProcessorSpy.isFileFormatValild.and.returnValue(false); + const file = new File([''], 'filename.xlsx', { type: 'xlsx' }); + + component.handleFileInput(file, FileType.UploadWorkingHours); + + expect(component.disableWorkHoursButton).toBe(true); + expect(resetErrorsSpy).toHaveBeenCalled(); + expect(component.workingHoursFileValidationErrors.length).toBeGreaterThan(0); + }); + + it('should disable upload button for non work hours if file is invalid', () => { + const resetErrorsSpy = spyOn(component, 'resetNonWorkingHoursMessages'); + component.disableNonWorkHoursButton = false; + workHoursProcessorSpy.isFileFormatValild.and.returnValue(false); + const file = new File([''], 'filename.xlsx', { type: 'xlsx' }); + + component.handleFileInput(file, FileType.UploadNonWorkingHours); + + expect(component.disableNonWorkHoursButton).toBe(true); + expect(resetErrorsSpy).toHaveBeenCalled(); + expect(component.nonWorkingHoursFileValidationErrors.length).toBeGreaterThan(0); + }); + it('should not assign non-working hours file if file is null', () => { const resetErrorsSpy = spyOn(component, 'resetNonWorkingHoursMessages'); const file = new File([''], 'filename.csv', { type: 'text/csv' }); @@ -82,6 +107,8 @@ describe('UploadWorkHoursComponent', () => { }); it(`should set errors when maximum working hours file size is exceeded`, () => { + component.disableWorkHoursButton = false; + const resetErrorsSpy = spyOn(component, 'resetWorkingHoursMessages'); const file = new File([''], 'filename.csv', { type: 'text/csv' }); Object.defineProperty(file, 'size', { value: 2000001 }); workHoursProcessorSpy.isFileTooBig.and.returnValue(true); @@ -89,9 +116,13 @@ describe('UploadWorkHoursComponent', () => { component.handleFileInput(file, FileType.UploadWorkingHours); expect(component.workingHoursFileValidationErrors[0]).toBe('File cannot be larger than 200kb'); + expect(component.disableWorkHoursButton).toBe(true); + expect(resetErrorsSpy).toHaveBeenCalled(); }); it(`should set errors when maximum non-working hours file size is exceeded`, () => { + component.disableNonWorkHoursButton = false; + const resetErrorsSpy = spyOn(component, 'resetNonWorkingHoursMessages'); const file = new File([''], 'filename.csv', { type: 'text/csv' }); Object.defineProperty(file, 'size', { value: 2000001 }); workHoursProcessorSpy.isFileTooBig.and.returnValue(true); @@ -99,6 +130,8 @@ describe('UploadWorkHoursComponent', () => { component.handleFileInput(file, FileType.UploadNonWorkingHours); expect(component.nonWorkingHoursFileValidationErrors[0]).toBe('File cannot be larger than 200kb'); + expect(component.disableNonWorkHoursButton).toBe(true); + expect(resetErrorsSpy).toHaveBeenCalled(); }); }); diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.ts b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.ts index de9733b56..e7599140e 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.ts +++ b/AdminWebsite/AdminWebsite/ClientApp/src/app/work-allocation/upload-work-hours/upload-work-hours.component.ts @@ -22,6 +22,8 @@ export class UploadWorkHoursComponent { public workingHoursFile: File | null = null; public nonWorkingHoursFile: File | null = null; + public disableNonWorkHoursButton: boolean; + public disableWorkHoursButton: boolean; constructor(private workHoursProcessor: WorkHoursFileProcessorService) {} @@ -33,22 +35,18 @@ export class UploadWorkHoursComponent { if (!this.workHoursProcessor.isFileFormatValild(file)) { const message = `File format is not supported, Supported file format is .CSV`; - if (fileType === FileType.UploadNonWorkingHours) { - this.nonWorkingHoursFileValidationErrors.push(message); - } else { - this.workingHoursFileValidationErrors.push(message); - } + this.handleFileInputError(fileType, message); return; + } else { + this.reenableUploadButton(fileType); } if (this.workHoursProcessor.isFileTooBig(file)) { const message = `File cannot be larger than ${this.workHoursProcessor.maxFileUploadSize / 1000}kb`; - if (fileType === FileType.UploadNonWorkingHours) { - this.nonWorkingHoursFileValidationErrors.push(message); - } else { - this.workingHoursFileValidationErrors.push(message); - } + this.handleFileInputError(fileType, message); return; + } else { + this.reenableUploadButton(fileType); } if (fileType === FileType.UploadWorkingHours) { @@ -143,4 +141,24 @@ export class UploadWorkHoursComponent { const reader = this.readFile(this.nonWorkingHoursFile); reader.onload = e => this.readNonWorkAvailability(e.target.result as string); } + + private handleFileInputError(fileType: FileType, message: string) { + if (fileType === FileType.UploadNonWorkingHours) { + this.disableNonWorkHoursButton = true; + this.resetNonWorkingHoursMessages(); + this.nonWorkingHoursFileValidationErrors.push(message); + } else { + this.disableWorkHoursButton = true; + this.resetWorkingHoursMessages(); + this.workingHoursFileValidationErrors.push(message); + } + } + + private reenableUploadButton(fileType: FileType) { + if (fileType === FileType.UploadWorkingHours) { + this.disableWorkHoursButton = false; + } else { + this.disableNonWorkHoursButton = false; + } + } } diff --git a/AdminWebsite/AdminWebsite/ClientApp/src/tslint.json b/AdminWebsite/AdminWebsite/ClientApp/src/tslint.json index 1f6d71571..68e1466fa 100644 --- a/AdminWebsite/AdminWebsite/ClientApp/src/tslint.json +++ b/AdminWebsite/AdminWebsite/ClientApp/src/tslint.json @@ -1,5 +1,5 @@ { - "extends": "../tslint.json", + "extends": "../tsconfig.json", "linterOptions": { "exclude": ["**/api-client.ts"] }, diff --git a/AdminWebsite/AdminWebsite/Configuration/ApplicationInsightsConfiguration.cs b/AdminWebsite/AdminWebsite/Configuration/ApplicationInsightsConfiguration.cs index e67bd39be..18c5f14ad 100644 --- a/AdminWebsite/AdminWebsite/Configuration/ApplicationInsightsConfiguration.cs +++ b/AdminWebsite/AdminWebsite/Configuration/ApplicationInsightsConfiguration.cs @@ -6,5 +6,6 @@ public class ApplicationInsightsConfiguration /// Application insights instrumentation key to specify target of logging /// public string InstrumentationKey { get; set; } + public string ConnectionString { get; set; } } } diff --git a/AdminWebsite/AdminWebsite/Configuration/FeatureToggles.cs b/AdminWebsite/AdminWebsite/Configuration/FeatureToggles.cs index 200bdb6d0..21e7b8aa2 100644 --- a/AdminWebsite/AdminWebsite/Configuration/FeatureToggles.cs +++ b/AdminWebsite/AdminWebsite/Configuration/FeatureToggles.cs @@ -10,6 +10,7 @@ public interface IFeatureToggles { public bool BookAndConfirmToggle(); public bool Dom1Enabled(); + public bool ReferenceDataToggle(); } public class FeatureToggles : IFeatureToggles @@ -19,6 +20,7 @@ public class FeatureToggles : IFeatureToggles private const string LdUser = "vh-admin-web"; private const string BookAndConfirmToggleKey = "Book_and_Confirm"; private const string Dom1EnabledToggleKey = "dom1"; + private const string ReferenceDataToggleKey = "reference-data"; public FeatureToggles(string sdkKey, string environmentName) { @@ -47,5 +49,15 @@ public bool Dom1Enabled() return _ldClient.BoolVariation(Dom1EnabledToggleKey, _context); } + + public bool ReferenceDataToggle() + { + if (!_ldClient.Initialized) + { + throw new InvalidOperationException("LaunchDarkly client not initialized"); + } + + return _ldClient.BoolVariation(ReferenceDataToggleKey, _context); + } } } \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Enums/BookingStatus.cs b/AdminWebsite/AdminWebsite/Contracts/Enums/BookingStatus.cs new file mode 100644 index 000000000..67db5110b --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Enums/BookingStatus.cs @@ -0,0 +1,8 @@ +namespace AdminWebsite.Contracts.Enums; +public enum BookingStatus +{ + Booked = 1, + Created = 2, + Cancelled = 3, + Failed = 4 +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Enums/LinkedParticipantType.cs b/AdminWebsite/AdminWebsite/Contracts/Enums/LinkedParticipantType.cs new file mode 100644 index 000000000..05660fdaa --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Enums/LinkedParticipantType.cs @@ -0,0 +1,6 @@ +namespace AdminWebsite.Contracts.Enums; + +public enum LinkedParticipantType +{ + Interpreter = 1, +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/AddNewJusticeUserRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/AddNewJusticeUserRequest.cs index 7a7bc6099..eeeb69ed4 100644 --- a/AdminWebsite/AdminWebsite/Contracts/Requests/AddNewJusticeUserRequest.cs +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/AddNewJusticeUserRequest.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using BookingsApi.Contract.Requests.Enums; +using BookingsApi.Contract.V1.Requests.Enums; namespace AdminWebsite.Contracts.Requests; diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/BookHearingRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/BookHearingRequest.cs index 603d86456..339ad812e 100644 --- a/AdminWebsite/AdminWebsite/Contracts/Requests/BookHearingRequest.cs +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/BookHearingRequest.cs @@ -1,11 +1,10 @@ using AdminWebsite.Models; -using BookingsApi.Contract.Requests; namespace AdminWebsite.Contracts.Requests { public class BookHearingRequest { - public BookNewHearingRequest BookingDetails { get; set; } + public BookingDetailsRequest BookingDetails { get; set; } public bool IsMultiDay { get; set; } public MultiHearingRequest MultiHearingDetails { get; set; } public string OtherInformationDetails { get; set; } diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/BookingDetailsRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/BookingDetailsRequest.cs new file mode 100644 index 000000000..dbb0ca897 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/BookingDetailsRequest.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace AdminWebsite.Contracts.Requests; + +public class BookingDetailsRequest +{ + public DateTime ScheduledDateTime { get; set; } + public int ScheduledDuration { get; set; } + public string HearingVenueName { get; set; } + public string CaseTypeName { get; set; } + public string HearingTypeName { get; set; } + public List Cases { get; set; } + public List Participants { get; set; } + public string HearingRoomName { get; set; } + public string OtherInformation { get; set; } + public string CreatedBy { get; set; } + public bool QuestionnaireNotRequired { get; set; } + public bool AudioRecordingRequired { get; set; } + [DefaultValue(false)] + public bool IsMultiDayHearing { get; set; } + public List Endpoints { get; set; } + public List LinkedParticipants { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/BookingSearchRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/BookingSearchRequest.cs index fc5eded3b..0e7453ed9 100644 --- a/AdminWebsite/AdminWebsite/Contracts/Requests/BookingSearchRequest.cs +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/BookingSearchRequest.cs @@ -1,11 +1,17 @@ -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; +using Newtonsoft.Json; namespace AdminWebsite.Contracts.Requests { public class BookingSearchRequest { + public BookingSearchRequest() + { + CaseTypes = new List(); + SelectedUsers = new List(); + VenueIds = new List(); + } private const int DefaultLimit = 100; [JsonProperty("cursor")] @@ -18,27 +24,27 @@ public class BookingSearchRequest public string CaseNumber { get; set; } = string.Empty; [JsonProperty("venueIds")] - public List VenueIds { get; set; } = null; + public List VenueIds { get; set; } [JsonProperty("caseTypes")] - public List CaseTypes { get; set; } = null; + public List CaseTypes { get; set; } [JsonProperty("selectedUsers")] - public List SelectedUsers { get; set; } = null; + public List SelectedUsers { get; set; } [JsonProperty("startDate")] - public DateTime? StartDate { get; set; } = null; + public DateTime? StartDate { get; set; } [JsonProperty("endDate")] - public DateTime? EndDate { get; set; } = null; + public DateTime? EndDate { get; set; } [JsonProperty("lastName")] public string LastName { get; set; } = string.Empty; [JsonProperty("noJudge")] - public bool Nojudge { get; set; } = false; + public bool Nojudge { get; set; } [JsonProperty("noAllocated")] - public bool NoAllocated { get; set; } = false; + public bool NoAllocated { get; set; } } } diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/CaseRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/CaseRequest.cs new file mode 100644 index 000000000..ea7e60ace --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/CaseRequest.cs @@ -0,0 +1,8 @@ +namespace AdminWebsite.Contracts.Requests; + +public class CaseRequest +{ + public string Number { get; set; } + public string Name { get; set; } + public bool IsLeadCase { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/EndpointRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/EndpointRequest.cs new file mode 100644 index 000000000..182bf4932 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/EndpointRequest.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; + +namespace AdminWebsite.Contracts.Requests; + +public class EndpointRequest +{ + [StringLength(255, ErrorMessage = "Display name max length is 255 characters")] + [RegularExpression("^([-A-Za-z0-9 \',._])*$")] + public string DisplayName { get; set; } + public string DefenceAdvocateContactEmail { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/LinkedParticipantRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/LinkedParticipantRequest.cs new file mode 100644 index 000000000..5098472f7 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/LinkedParticipantRequest.cs @@ -0,0 +1,10 @@ +using AdminWebsite.Contracts.Enums; + +namespace AdminWebsite.Contracts.Requests; + +public class LinkedParticipantRequest +{ + public string ParticipantContactEmail { get; set; } + public string LinkedParticipantContactEmail { get; set; } + public LinkedParticipantType Type { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Requests/ParticipantRequest.cs b/AdminWebsite/AdminWebsite/Contracts/Requests/ParticipantRequest.cs new file mode 100644 index 000000000..e831b67d2 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Requests/ParticipantRequest.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; + +namespace AdminWebsite.Contracts.Requests; + +public class ParticipantRequest +{ + public string Title { get; set; } + public string FirstName { get; set; } + public string MiddleNames { get; set; } + public string LastName { get; set; } + public string ContactEmail { get; set; } + public string TelephoneNumber { get; set; } + public string Username { get; set; } + [StringLength(255, ErrorMessage = "Display name max length is 255 characters")] + [RegularExpression("^([-A-Za-z0-9 \',._])*$")] + public string DisplayName { get; set; } + public string CaseRoleName { get; set; } + public string HearingRoleName { get; set; } + public string Representee { get; set; } + public string OrganisationName { get; set; } +} diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/BookingsHearingResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/BookingsHearingResponse.cs new file mode 100644 index 000000000..bddde7ff1 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/BookingsHearingResponse.cs @@ -0,0 +1,32 @@ +using System; +using BookingsApi.Contract.V1.Enums; + +namespace AdminWebsite.Contracts.Responses; + +public class BookingsHearingResponse +{ + public Guid HearingId { get; set; } + public string HearingNumber { get; set; } + public string HearingName { get; set; } + public DateTime ScheduledDateTime { get; set; } + public int ScheduledDuration { get; set; } + public string CaseTypeName { get; set; } + public string HearingTypeName { get; set; } + public string CourtRoom { get; set; } + public string CourtAddress { get; set; } + public string JudgeName { get; set; } + public string CreatedBy { get; set; } + public DateTime CreatedDate { get; set; } + public string LastEditBy { get; set; } + public DateTime? LastEditDate { get; set; } + public string ConfirmedBy { get; set; } + public DateTime? ConfirmedDate { get; set; } + public DateTime HearingDate { get; set; } + public BookingStatus Status { get; set; } + public bool QuestionnaireNotRequired { get; set; } + public bool AudioRecordingRequired { get; set; } + public string CancelReason { get; set; } + public Guid? GroupId { get; set; } + public string CourtRoomAccount { get; set; } + public string AllocatedTo { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/BookingsResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/BookingsResponse.cs new file mode 100644 index 000000000..05d96b232 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/BookingsResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace AdminWebsite.Contracts.Responses; + +public class BookingsResponse +{ + public string NextCursor { get; set; } + public int Limit { get; set; } + public string PrevPageUrl { get; set; } + public string NextPageUrl { get; set; } + public List Hearings { get; set; } +} +public class BookingsByDateResponse +{ + public DateTime ScheduledDate { get; set; } + public List Hearings { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/CaseResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/CaseResponse.cs new file mode 100644 index 000000000..899621914 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/CaseResponse.cs @@ -0,0 +1,8 @@ +namespace AdminWebsite.Contracts.Responses; + +public class CaseResponse +{ + public string Number { get; set; } + public string Name { get; set; } + public bool IsLeadCase { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/ClientSettingsResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/ClientSettingsResponse.cs index ccfca0d58..b94a0f405 100644 --- a/AdminWebsite/AdminWebsite/Contracts/Responses/ClientSettingsResponse.cs +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/ClientSettingsResponse.cs @@ -31,9 +31,9 @@ public class ClientSettingsResponse public string PostLogoutRedirectUri { get; set; } /// - /// The Application Insight Instrumentation Key + /// The Application Insights Connection String /// - public string InstrumentationKey { get; set; } + public string ConnectionString { get; set; } /// /// The reform email diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/EndpointResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/EndpointResponse.cs new file mode 100644 index 000000000..451777e4a --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/EndpointResponse.cs @@ -0,0 +1,11 @@ +using System; + +namespace AdminWebsite.Contracts.Responses; +public class EndpointResponse +{ + public Guid Id { get; set; } + public string DisplayName { get; set; } + public string Sip { get; set; } + public string Pin { get; set; } + public Guid? DefenceAdvocateId { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/HearingDetailsResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/HearingDetailsResponse.cs new file mode 100644 index 000000000..2799e595a --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/HearingDetailsResponse.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using AdminWebsite.Contracts.Enums; + +namespace AdminWebsite.Contracts.Responses; + +public class HearingDetailsResponse +{ + public Guid Id { get; set; } + public DateTime ScheduledDateTime { get; set; } + public int ScheduledDuration { get; set; } + /// + /// V1 only + /// + public string HearingVenueName { get; set; } + /// + /// V2 only + /// + public string HearingVenueCode { get; set; } + /// + /// V1 only + /// + public string CaseTypeName { get; set; } + /// + /// V2 only + /// + public string ServiceId { get; set; } + /// + /// V1 only + /// + public string HearingTypeName { get; set; } + /// + /// V2 only + /// + public string HearingTypeCode { get; set; } + public List Cases { get; set; } + public List Participants { get; set; } + /// + /// V1 only + /// + public List TelephoneParticipants { get; set; } + public string HearingRoomName { get; set; } + public string OtherInformation { get; set; } + public DateTime CreatedDate { get; set; } + public string CreatedBy { get; set; } + public string UpdatedBy { get; set; } + public DateTime UpdatedDate { get; set; } + public string ConfirmedBy { get; set; } + public DateTime? ConfirmedDate { get; set; } + public BookingStatus Status { get; set; } + /// + /// V1 only + /// + public bool QuestionnaireNotRequired { get; set; } + public bool AudioRecordingRequired { get; set; } + public string CancelReason { get; set; } + public List Endpoints { get; set; } + public Guid? GroupId { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/HearingTypeResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/HearingTypeResponse.cs index 2db9decc0..2078684b4 100644 --- a/AdminWebsite/AdminWebsite/Contracts/Responses/HearingTypeResponse.cs +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/HearingTypeResponse.cs @@ -24,5 +24,10 @@ public class HearingTypeResponse /// Hearing type display name /// public string Name { get; set; } + + /// + /// The service id for the type + /// + public string ServiceId { get; set; } } } diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/LinkedParticipantResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/LinkedParticipantResponse.cs new file mode 100644 index 000000000..18d6b59df --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/LinkedParticipantResponse.cs @@ -0,0 +1,10 @@ +using System; +using AdminWebsite.Contracts.Enums; + +namespace AdminWebsite.Contracts.Responses; + +public class LinkedParticipantResponse +{ + public Guid LinkedId { get; set; } + public LinkedParticipantType Type { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/ParticipantResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/ParticipantResponse.cs new file mode 100644 index 000000000..a995ef1a8 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/ParticipantResponse.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace AdminWebsite.Contracts.Responses; + +public class ParticipantResponse +{ + public Guid Id { get; set; } + public string DisplayName { get; set; } + public string CaseRoleName { get; set; } + public string HearingRoleName { get; set; } + public string UserRoleName { get; set; } + public string Title { get; set; } + public string FirstName { get; set; } + public string MiddleNames { get; set; } + public string LastName { get; set; } + public string ContactEmail { get; set; } + public string TelephoneNumber { get; set; } + public string Username { get; set; } + public string Organisation { get; set; } + public string Representee { get; set; } + public List LinkedParticipants { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Contracts/Responses/TelephoneParticipantResponse.cs b/AdminWebsite/AdminWebsite/Contracts/Responses/TelephoneParticipantResponse.cs new file mode 100644 index 000000000..59369f2f7 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Contracts/Responses/TelephoneParticipantResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace AdminWebsite.Contracts.Responses; + +public class TelephoneParticipantResponse +{ + public Guid Id { get; set; } + public string CaseRoleName { get; set; } + public string HearingRoleName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string ContactEmail { get; set; } + public string TelephoneNumber { get; set; } + public string MobileNumber { get; set; } + public string Representee { get; set; } + public List LinkedParticipants { get; set; } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Controllers/BookingListController.cs b/AdminWebsite/AdminWebsite/Controllers/BookingListController.cs index 3a986ba37..20bce1f96 100644 --- a/AdminWebsite/AdminWebsite/Controllers/BookingListController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/BookingListController.cs @@ -1,8 +1,6 @@ using AdminWebsite.Contracts.Requests; using AdminWebsite.Security; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; using System.Collections.Generic; @@ -10,6 +8,9 @@ using System.Net; using System.Text.Encodings.Web; using System.Threading.Tasks; +using AdminWebsite.Contracts.Responses; +using AdminWebsite.Mappers; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.Controllers { @@ -88,7 +89,7 @@ public async Task GetBookingsList([FromBody]BookingSearchRequest r NoAllocated = request.NoAllocated }); - return Ok(bookingsResponse); + return Ok(bookingsResponse.Map()); } catch (BookingsApiException e) { @@ -104,12 +105,12 @@ public async Task GetBookingsList([FromBody]BookingSearchRequest r private async Task> GetCaseTypesId(IEnumerable caseTypes) { var typeIds = new List(); - var types = await _bookingsApiClient.GetCaseTypesAsync(); + var types = await _bookingsApiClient.GetCaseTypesAsync(includeDeleted:true); if (types != null && types.Any()) foreach (var item in caseTypes) { var caseType = types.FirstOrDefault(s => s.Name == item); - if (caseType != null && typeIds.All(s => s != caseType.Id)) + if (caseType != null && typeIds.TrueForAll(s => s != caseType.Id)) { typeIds.Add(caseType.Id); } diff --git a/AdminWebsite/AdminWebsite/Controllers/ConfigSettingsController.cs b/AdminWebsite/AdminWebsite/Controllers/ConfigSettingsController.cs index 718cb630b..ab1aed582 100644 --- a/AdminWebsite/AdminWebsite/Controllers/ConfigSettingsController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/ConfigSettingsController.cs @@ -51,7 +51,7 @@ public ActionResult Get() { var clientSettings = new ClientSettingsResponse { - InstrumentationKey = _applicationInsightsConfiguration.InstrumentationKey, + ConnectionString = _applicationInsightsConfiguration.ConnectionString, TestUsernameStem = _testUserSecrets.TestUsernameStem, ConferencePhoneNumber = _kinlyConfiguration.ConferencePhoneNumber, ConferencePhoneNumberWelsh = _kinlyConfiguration.ConferencePhoneNumberWelsh, diff --git a/AdminWebsite/AdminWebsite/Controllers/HealthCheckController.cs b/AdminWebsite/AdminWebsite/Controllers/HealthCheckController.cs index 2be1f93ec..e2aaa4fdc 100644 --- a/AdminWebsite/AdminWebsite/Controllers/HealthCheckController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/HealthCheckController.cs @@ -74,7 +74,7 @@ public async Task Health() try { - await _bookingsApiClient.GetCaseTypesAsync(); + await _bookingsApiClient.GetCaseTypesAsync(includeDeleted:false); } catch (BookingsApiException baEx) { diff --git a/AdminWebsite/AdminWebsite/Controllers/HearingsController.cs b/AdminWebsite/AdminWebsite/Controllers/HearingsController.cs index 168a6df5b..c8a7e9bf7 100644 --- a/AdminWebsite/AdminWebsite/Controllers/HearingsController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/HearingsController.cs @@ -4,6 +4,7 @@ using System.Net; using System.Threading.Tasks; using AdminWebsite.Attributes; +using AdminWebsite.Configuration; using AdminWebsite.Contracts.Enums; using AdminWebsite.Contracts.Requests; using AdminWebsite.Extensions; @@ -13,16 +14,17 @@ using AdminWebsite.Security; using AdminWebsite.Services; using BookingsApi.Client; -using BookingsApi.Contract.Enums; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; using FluentValidation; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Swashbuckle.AspNetCore.Annotations; using VideoApi.Client; -using VideoApi.Contract.Consts; +using HearingDetailsResponse = AdminWebsite.Contracts.Responses.HearingDetailsResponse; +using LinkedParticipantRequest = AdminWebsite.Contracts.Requests.LinkedParticipantRequest; +using LinkedParticipantType = BookingsApi.Contract.V1.Enums.LinkedParticipantType; +using ParticipantRequest = BookingsApi.Contract.V1.Requests.ParticipantRequest; namespace AdminWebsite.Controllers { @@ -38,6 +40,7 @@ public class HearingsController : ControllerBase private readonly IValidator _editHearingRequestValidator; private readonly IHearingsService _hearingsService; private readonly IConferenceDetailsService _conferenceDetailsService; + private readonly IFeatureToggles _featureToggles; private readonly ILogger _logger; private readonly IUserIdentity _userIdentity; private const int StartingSoonMinutesThreshold = 30; @@ -51,7 +54,8 @@ public HearingsController(IBookingsApiClient bookingsApiClient, IValidator editHearingRequestValidator, ILogger logger, IHearingsService hearingsService, - IConferenceDetailsService conferenceDetailsService) + IConferenceDetailsService conferenceDetailsService, + IFeatureToggles featureToggles) { _bookingsApiClient = bookingsApiClient; _userIdentity = userIdentity; @@ -59,6 +63,7 @@ public HearingsController(IBookingsApiClient bookingsApiClient, _logger = logger; _hearingsService = hearingsService; _conferenceDetailsService = conferenceDetailsService; + _featureToggles = featureToggles; } #pragma warning restore S107 /// @@ -86,11 +91,14 @@ public async Task> Post([FromBody] BookHear } newBookingRequest.CreatedBy = _userIdentity.GetUserIdentityName(); + + var newBookingRequestV1 = newBookingRequest.MapToV1(); _logger.LogInformation("BookNewHearing - Attempting to send booking request to Booking API"); - var hearingDetailsResponse = await _bookingsApiClient.BookNewHearingAsync(newBookingRequest); + var hearingDetailsResponse = await _bookingsApiClient.BookNewHearingAsync(newBookingRequestV1); + _logger.LogInformation("BookNewHearing - Successfully booked hearing {Hearing}", hearingDetailsResponse.Id); - return Created("",hearingDetailsResponse); + return Created("",hearingDetailsResponse.Map()); } catch (BookingsApiException e) { @@ -108,6 +116,35 @@ public async Task> Post([FromBody] BookHear } } + /// + /// Rebook an existing hearing with a booking status of Failed + /// + /// Id of the hearing with a status of Failed + /// + [HttpPost("{hearingId}/conferences")] + [SwaggerOperation(OperationId = "RebookHearing")] + [ProducesResponseType((int)HttpStatusCode.NoContent)] + [ProducesResponseType((int)HttpStatusCode.NotFound)] + [ProducesResponseType(typeof(ValidationProblemDetails), (int)HttpStatusCode.BadRequest)] + public async Task RebookHearing(Guid hearingId) + { + try + { + await _bookingsApiClient.RebookHearingAsync(hearingId); + + return NoContent(); + } + catch (BookingsApiException e) + { + _logger.LogError(e, + "There was a problem rebooking the hearing. Status Code {StatusCode} - Message {Message}", + e.StatusCode, e.Response); + if (e.StatusCode == (int)HttpStatusCode.NotFound) return NotFound(e.Response); + if (e.StatusCode == (int)HttpStatusCode.BadRequest) return BadRequest(e.Response); + throw; + } + } + /// /// Clone hearings with the details of a given hearing on given dates /// @@ -205,7 +242,18 @@ public async Task> EditHearing(Guid hearing HearingDetailsResponse originalHearing; try { - originalHearing = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId); + + if (_featureToggles.ReferenceDataToggle()) + { + var response = await _bookingsApiClient.GetHearingDetailsByIdV2Async(hearingId); + originalHearing = response.Map(); + } + else + { + + var response = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId); + originalHearing = response.Map(); + } } catch (BookingsApiException e) { @@ -236,8 +284,18 @@ public async Task> EditHearing(Guid hearing ModelState.AddModelError(nameof(hearingId), errorMessage); return BadRequest(ModelState); } + HearingDetailsResponse updatedHearing; + if (_featureToggles.ReferenceDataToggle()) + { + var updatedHearing2 = await _bookingsApiClient.GetHearingDetailsByIdV2Async(hearingId); + updatedHearing = updatedHearing2.Map(); + } + else + { + var updatedHearing1 = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId); + updatedHearing = updatedHearing1.Map(); + } - var updatedHearing = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId); //Save hearing details var updateHearingRequest = HearingUpdateRequestMapper.MapTo(request, _userIdentity.GetUserIdentityName()); await _bookingsApiClient.UpdateHearingDetailsAsync(hearingId, updateHearingRequest); @@ -270,13 +328,18 @@ private async Task UpdateParticipants(Guid hearingId, EditHearingRequest request newParticipants.Add(newParticipant); var linkedParticipants = ExtractLinkedParticipants(request, originalHearing, removedParticipantIds, existingParticipants, newParticipants); + var linkedParticipantsV1 = linkedParticipants.Select(lp => lp.MapToV1()).ToList(); - await _hearingsService.ProcessParticipants(hearingId, existingParticipants, newParticipants, removedParticipantIds.ToList(), linkedParticipants.ToList()); + await _hearingsService.ProcessParticipants(hearingId, existingParticipants, newParticipants, removedParticipantIds.ToList(), linkedParticipantsV1); await _hearingsService.ProcessEndpoints(hearingId, request, originalHearing, newParticipants); } - private static List ExtractLinkedParticipants(EditHearingRequest request, HearingDetailsResponse originalHearing, - List removedParticipantIds, List existingParticipants, List newParticipants) + private static List ExtractLinkedParticipants( + EditHearingRequest request, + HearingDetailsResponse originalHearing, + List removedParticipantIds, + List existingParticipants, + List newParticipants) { var linkedParticipants = new List(); var participantsWithLinks = request.Participants @@ -288,12 +351,11 @@ private static List ExtractLinkedParticipants(EditHear for (int i = 0; i < participantsWithLinks.Count; i++) { var participantWithLinks = participantsWithLinks[i]; - var linkedParticipantRequest = new LinkedParticipantRequest + var linkedParticipantRequest = new LinkedParticipantRequest() { LinkedParticipantContactEmail = participantWithLinks.LinkedParticipants[0].LinkedParticipantContactEmail, - ParticipantContactEmail = participantWithLinks.LinkedParticipants[0].ParticipantContactEmail ?? - participantWithLinks.ContactEmail, - Type = participantWithLinks.LinkedParticipants[0].Type + ParticipantContactEmail = participantWithLinks.LinkedParticipants[0].ParticipantContactEmail ?? participantWithLinks.ContactEmail, + Type = (Contracts.Enums.LinkedParticipantType) participantWithLinks.LinkedParticipants[0].Type }; // If the participant link is not new and already existed, then the ParticipantContactEmail will be null. We find it here and populate it. @@ -357,7 +419,17 @@ public async Task GetHearingById(Guid hearingId) { try { - var hearingResponse = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId); + HearingDetailsResponse hearingResponse; + if (_featureToggles.ReferenceDataToggle()) + { + var response = await _bookingsApiClient.GetHearingDetailsByIdV2Async(hearingId); + hearingResponse = response.Map(); + } + else + { + var response = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId); + hearingResponse = response.Map(); + } return Ok(hearingResponse); } catch (BookingsApiException e) @@ -413,7 +485,7 @@ public async Task GetHearingConferenceStatus(Guid hearingId) VideoApi.Contract.Responses.ConferenceDetailsResponse conferenceDetailsResponse; var response = await _bookingsApiClient.GetBookingStatusByIdAsync(hearingId); - if (response == BookingStatus.Created) + if ((BookingStatus)response == BookingStatus.Created) { try { @@ -464,14 +536,13 @@ public async Task GetHearingConferenceStatus(Guid hearingId) [ProducesResponseType(typeof(UpdateBookingStatusResponse), (int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] - public async Task UpdateBookingStatus(Guid hearingId, - UpdateBookingStatusRequest updateBookingStatusRequest) + public async Task UpdateBookingStatus(Guid hearingId, UpdateBookingStatusRequest updateBookingStatusRequest) { try { var hearing = await _bookingsApiClient.GetHearingDetailsByIdAsync(hearingId); var judgeExists = hearing?.Participants?.Any(p => p.HearingRoleName == RoleNames.Judge) ?? false; - if (!judgeExists && updateBookingStatusRequest.Status == BookingsApi.Contract.Requests.Enums.UpdateBookingStatus.Created) + if (!judgeExists && updateBookingStatusRequest.Status == BookingsApi.Contract.V1.Requests.Enums.UpdateBookingStatus.Created) return BadRequest("This hearing has no judge"); _logger.LogDebug("Attempting to update hearing {Hearing} to booking status {BookingStatus}", hearingId, updateBookingStatusRequest.Status); diff --git a/AdminWebsite/AdminWebsite/Controllers/JudiciaryAccountsController.cs b/AdminWebsite/AdminWebsite/Controllers/JudiciaryAccountsController.cs index 69dec7af2..a05806837 100644 --- a/AdminWebsite/AdminWebsite/Controllers/JudiciaryAccountsController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/JudiciaryAccountsController.cs @@ -11,8 +11,8 @@ using System.Text.Encodings.Web; using System.Threading.Tasks; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.Controllers { diff --git a/AdminWebsite/AdminWebsite/Controllers/JusticeUsersController.cs b/AdminWebsite/AdminWebsite/Controllers/JusticeUsersController.cs index 51ae76c13..919fbe7b3 100644 --- a/AdminWebsite/AdminWebsite/Controllers/JusticeUsersController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/JusticeUsersController.cs @@ -5,8 +5,8 @@ using AdminWebsite.Mappers; using AdminWebsite.Models; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; diff --git a/AdminWebsite/AdminWebsite/Controllers/PersonsController.cs b/AdminWebsite/AdminWebsite/Controllers/PersonsController.cs index 5c482fc0f..2a47b3462 100644 --- a/AdminWebsite/AdminWebsite/Controllers/PersonsController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/PersonsController.cs @@ -11,8 +11,8 @@ using AdminWebsite.Contracts.Requests; using AdminWebsite.Services; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using UserApi.Client; namespace AdminWebsite.Controllers diff --git a/AdminWebsite/AdminWebsite/Controllers/ReferenceDataController.cs b/AdminWebsite/AdminWebsite/Controllers/ReferenceDataController.cs index 510a32c11..e8dac2b16 100644 --- a/AdminWebsite/AdminWebsite/Controllers/ReferenceDataController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/ReferenceDataController.cs @@ -1,15 +1,16 @@ using AdminWebsite.Models; -using AdminWebsite.Security; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; +using AdminWebsite.Configuration; using AdminWebsite.Contracts.Responses; using AdminWebsite.Mappers; using AdminWebsite.Services; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; +using BookingsApi.Contract.Interfaces.Response; using HearingTypeResponse = AdminWebsite.Contracts.Responses.HearingTypeResponse; namespace AdminWebsite.Controllers @@ -24,14 +25,19 @@ public class ReferenceDataController : ControllerBase { private readonly IBookingsApiClient _bookingsApiClient; private readonly IPublicHolidayRetriever _publicHolidayRetriever; + private readonly IFeatureToggles _featureToggles; /// /// Instantiate the controller /// - public ReferenceDataController(IBookingsApiClient bookingsApiClient, IPublicHolidayRetriever publicHolidayRetriever) + public ReferenceDataController( + IBookingsApiClient bookingsApiClient, + IPublicHolidayRetriever publicHolidayRetriever, + IFeatureToggles featureToggles) { _bookingsApiClient = bookingsApiClient; _publicHolidayRetriever = publicHolidayRetriever; + _featureToggles = featureToggles; } /// @@ -41,14 +47,16 @@ public ReferenceDataController(IBookingsApiClient bookingsApiClient, IPublicHoli [HttpGet("types", Name = "GetHearingTypes")] [ProducesResponseType(typeof(IList), (int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task>> GetHearingTypes() + public async Task>> GetHearingTypes([FromQuery] bool includeDeleted = false) { - var caseTypes = await _bookingsApiClient.GetCaseTypesAsync(); + var caseTypes = await _bookingsApiClient.GetCaseTypesAsync(includeDeleted); var result = caseTypes.SelectMany(caseType => caseType.HearingTypes.Select(hearingType => new HearingTypeResponse { Group = caseType.Name, Id = hearingType.Id, - Name = hearingType.Name + Name = hearingType.Name, + ServiceId = caseType.ServiceId, + Code = hearingType.Code })).ToList(); return Ok(result); @@ -61,19 +69,39 @@ public async Task>> GetHearingTypes() [HttpGet("participantroles", Name = "GetParticipantRoles")] [ProducesResponseType(typeof(IList), (int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task>> GetParticipantRoles(string caseTypeName) + public async Task>> GetParticipantRoles(string caseTypeParameter) { var response = new List(); - - var caseRoles = await _bookingsApiClient.GetCaseRolesForCaseTypeAsync(caseTypeName); - if (caseRoles != null && caseRoles.Any()) + List iCaseRoles; + if (_featureToggles.ReferenceDataToggle()) + { + var caseRoles2 = await _bookingsApiClient.GetCaseRolesForCaseServiceAsync(caseTypeParameter); + iCaseRoles = caseRoles2?.Select(e => (ICaseRoleResponse)e).ToList(); + } + else + { + var caseRoles1 = await _bookingsApiClient.GetCaseRolesForCaseTypeAsync(caseTypeParameter); + iCaseRoles = caseRoles1?.Select(e => (ICaseRoleResponse)e).ToList(); + } + + if (iCaseRoles != null && iCaseRoles.Any()) { - foreach (var item in caseRoles) + foreach (var item in iCaseRoles) { var caseRole = new CaseAndHearingRolesResponse { Name = item.Name }; - var hearingRoles = await _bookingsApiClient.GetHearingRolesForCaseRoleAsync(caseTypeName, item.Name); + List iHearingRoles; + if (_featureToggles.ReferenceDataToggle()) + { + var hearingRoles1 = await _bookingsApiClient.GetHearingRolesForCaseRoleV2Async(caseTypeParameter, item.Name); + iHearingRoles = hearingRoles1.Select(e => (IHearingRoleResponse)e).ToList(); + } + else + { + var hearingRoles2 = await _bookingsApiClient.GetHearingRolesForCaseRoleAsync(caseTypeParameter, item.Name); + iHearingRoles = hearingRoles2.Select(e => (IHearingRoleResponse)e).ToList(); + } - caseRole.HearingRoles = hearingRoles.ToList().ConvertAll(x => new HearingRole(x.Name, x.UserRole)); + caseRole.HearingRoles = iHearingRoles.ConvertAll(x => new HearingRole(x.Name, x.UserRole)); response.Add(caseRole); } @@ -91,7 +119,7 @@ public async Task>> GetParticipa [ProducesResponseType((int)HttpStatusCode.NotFound)] public async Task>> GetCourts() { - var response = await _bookingsApiClient.GetHearingVenuesAsync(); + var response = await _bookingsApiClient.GetHearingVenuesAsync(true); return Ok(response); } diff --git a/AdminWebsite/AdminWebsite/Controllers/StaffMemberController.cs b/AdminWebsite/AdminWebsite/Controllers/StaffMemberController.cs index 53ddfa1dd..eb71e1423 100644 --- a/AdminWebsite/AdminWebsite/Controllers/StaffMemberController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/StaffMemberController.cs @@ -1,11 +1,11 @@ using BookingsApi.Client; -using BookingsApi.Contract.Responses; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.Controllers { diff --git a/AdminWebsite/AdminWebsite/Controllers/SuitabilityAnswersController.cs b/AdminWebsite/AdminWebsite/Controllers/SuitabilityAnswersController.cs index 74dcca244..47d85faf0 100644 --- a/AdminWebsite/AdminWebsite/Controllers/SuitabilityAnswersController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/SuitabilityAnswersController.cs @@ -5,7 +5,7 @@ using System.Text.Encodings.Web; using System.Threading.Tasks; using BookingsApi.Client; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.Controllers { diff --git a/AdminWebsite/AdminWebsite/Controllers/UserIdentityController.cs b/AdminWebsite/AdminWebsite/Controllers/UserIdentityController.cs index a0b4cbb6d..6409eaf67 100644 --- a/AdminWebsite/AdminWebsite/Controllers/UserIdentityController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/UserIdentityController.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using System; using System.Collections.Generic; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; using Microsoft.Extensions.Logging; namespace AdminWebsite.Controllers diff --git a/AdminWebsite/AdminWebsite/Controllers/WorkAllocationController.cs b/AdminWebsite/AdminWebsite/Controllers/WorkAllocationController.cs index acd65a18e..0eb2abcde 100644 --- a/AdminWebsite/AdminWebsite/Controllers/WorkAllocationController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/WorkAllocationController.cs @@ -7,11 +7,12 @@ using AdminWebsite.Mappers; using AdminWebsite.Models; using BookingsApi.Client; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; +using HearingDetailsResponse = BookingsApi.Contract.V1.Responses.HearingDetailsResponse; namespace AdminWebsite.Controllers { diff --git a/AdminWebsite/AdminWebsite/Controllers/WorkHoursController.cs b/AdminWebsite/AdminWebsite/Controllers/WorkHoursController.cs index 790dd5083..033686dc9 100644 --- a/AdminWebsite/AdminWebsite/Controllers/WorkHoursController.cs +++ b/AdminWebsite/AdminWebsite/Controllers/WorkHoursController.cs @@ -1,12 +1,12 @@ using AdminWebsite.Models; using BookingsApi.Client; -using BookingsApi.Contract.Requests; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests; +using BookingsApi.Contract.V1.Responses; using Microsoft.AspNetCore.Authorization; namespace AdminWebsite.Controllers @@ -133,26 +133,29 @@ public async Task UpdateNonAvailabilityWorkHours(string username, } } - [HttpDelete("NonAvailability")] + [HttpDelete("NonAvailability/{username}/{nonAvailabilityId}")] [SwaggerOperation(OperationId = "DeleteNonAvailabilityWorkHours")] [ProducesResponseType((int) HttpStatusCode.OK)] [ProducesResponseType((int) HttpStatusCode.BadRequest)] [ProducesResponseType((int) HttpStatusCode.NotFound)] - public async Task DeleteNonAvailabilityWorkHours(long id) + public async Task DeleteNonAvailabilityWorkHours([FromRoute] string username, [FromRoute] long nonAvailabilityId) { try { - await _bookingsApiClient.DeleteVhoNonAvailabilityHoursAsync(id); + await _bookingsApiClient.DeleteVhoNonAvailabilityHoursAsync(username, nonAvailabilityId); return Ok(); } catch (BookingsApiException ex) { switch (ex.StatusCode) { - case (int) HttpStatusCode.NotFound: + case (int)HttpStatusCode.BadRequest: + { + var typedException = ex as BookingsApiException; + return ValidationProblem(typedException!.Result); + } + case (int)HttpStatusCode.NotFound: return NotFound("Record could not be found. Please check the id and try again"); - case (int) HttpStatusCode.BadRequest: - return BadRequest(ex.Response); default: throw; } diff --git a/AdminWebsite/AdminWebsite/Extensions/HearingDetailsResponseExtensions.cs b/AdminWebsite/AdminWebsite/Extensions/HearingDetailsResponseExtensions.cs index 7c3493850..df257b908 100644 --- a/AdminWebsite/AdminWebsite/Extensions/HearingDetailsResponseExtensions.cs +++ b/AdminWebsite/AdminWebsite/Extensions/HearingDetailsResponseExtensions.cs @@ -1,8 +1,8 @@ using System; using System.Linq; using AdminWebsite.Contracts.Enums; +using AdminWebsite.Contracts.Responses; using AdminWebsite.Models; -using BookingsApi.Contract.Responses; using Newtonsoft.Json; namespace AdminWebsite.Extensions @@ -19,8 +19,7 @@ public static bool HasScheduleAmended(this HearingDetailsResponse hearing, Heari { return hearing.ScheduledDateTime.Ticks != anotherHearing.ScheduledDateTime.Ticks; } - public static bool JudgeHasNotChangedForGenericHearing(this HearingDetailsResponse newHearingJudge, - HearingDetailsResponse originalHearingJudge) + public static bool JudgeHasNotChangedForGenericHearing(this HearingDetailsResponse newHearingJudge, HearingDetailsResponse originalHearingJudge) { var judgeFromUpdatedHearing = newHearingJudge.GetJudgeById(); var judgeFromOriginalHearing = originalHearingJudge.GetJudgeById(); @@ -35,8 +34,7 @@ public static bool JudgeHasNotChangedForGenericHearing(this HearingDetailsRespon return judgeId; } - public static bool HasJudgeEmailChanged(this HearingDetailsResponse hearing, - HearingDetailsResponse originalHearing) + public static bool HasJudgeEmailChanged(this HearingDetailsResponse hearing, HearingDetailsResponse originalHearing) { var isNewJudgeEJud = IsJudgeEmailEJud(hearing); var isOriginalJudgeEJud = IsJudgeEmailEJud(originalHearing); @@ -151,6 +149,12 @@ public static HearingDetailsResponse Duplicate(this HearingDetailsResponse heari var json = JsonConvert.SerializeObject(hearingDetailsResponse); return JsonConvert.DeserializeObject(json); } + + public static BookingsApi.Contract.V1.Responses.HearingDetailsResponse Duplicate(this BookingsApi.Contract.V1.Responses.HearingDetailsResponse hearingDetailsResponse) + { + var json = JsonConvert.SerializeObject(hearingDetailsResponse); + return JsonConvert.DeserializeObject(json); + } public static string GetJudgeOtherInformationString(string otherInformation) { diff --git a/AdminWebsite/AdminWebsite/Mappers/AddJusticeUserRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/AddJusticeUserRequestMapper.cs index 1ab489bc6..52692ab53 100644 --- a/AdminWebsite/AdminWebsite/Mappers/AddJusticeUserRequestMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/AddJusticeUserRequestMapper.cs @@ -1,5 +1,5 @@ using AdminWebsite.Contracts.Requests; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.Mappers { diff --git a/AdminWebsite/AdminWebsite/Mappers/AllocationHearingsResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/AllocationHearingsResponseMapper.cs index a2d198c99..3dbbe244b 100644 --- a/AdminWebsite/AdminWebsite/Mappers/AllocationHearingsResponseMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/AllocationHearingsResponseMapper.cs @@ -1,5 +1,5 @@ using AdminWebsite.Contracts.Responses; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.Mappers; diff --git a/AdminWebsite/AdminWebsite/Mappers/BookingDetailsRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/BookingDetailsRequestMapper.cs new file mode 100644 index 000000000..15de4bdb6 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/BookingDetailsRequestMapper.cs @@ -0,0 +1,77 @@ +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using AdminWebsite.Contracts.Requests; +using V1 = BookingsApi.Contract.V1.Requests; +using V2 = BookingsApi.Contract.V2.Requests; + +namespace AdminWebsite.Mappers; + +public static class BookingDetailsRequestMapper +{ + public static V1.BookNewHearingRequest MapToV1(this BookingDetailsRequest bookingDetails) + { + return new V1.BookNewHearingRequest + { + ScheduledDateTime = bookingDetails.ScheduledDateTime, + ScheduledDuration = bookingDetails.ScheduledDuration, + HearingVenueName = bookingDetails.HearingVenueName, + CaseTypeName = bookingDetails.CaseTypeName, + HearingTypeName = bookingDetails.HearingTypeName, + Cases = bookingDetails.Cases? + .Select(cr => new V1.CaseRequest + { + Number = cr.Number, + Name = cr.Name, + IsLeadCase = cr.IsLeadCase + }).ToList(), + Participants = bookingDetails.Participants? + .Select(p => p.MapToV1()) + .ToList(), + HearingRoomName = bookingDetails.HearingRoomName, + OtherInformation = bookingDetails.OtherInformation, + CreatedBy = bookingDetails.CreatedBy, + QuestionnaireNotRequired = bookingDetails.QuestionnaireNotRequired, + AudioRecordingRequired = bookingDetails.AudioRecordingRequired, + IsMultiDayHearing = bookingDetails.IsMultiDayHearing, + Endpoints = bookingDetails.Endpoints? + .Select(e => new V1.EndpointRequest + { + DisplayName = e.DisplayName, + DefenceAdvocateContactEmail = e.DefenceAdvocateContactEmail, + }).ToList(), + LinkedParticipants = bookingDetails.LinkedParticipants? + .Select(lp => lp.MapToV1()).ToList() + }; + } + + [ExcludeFromCodeCoverage] //Remove once used + public static V2.BookNewHearingRequestV2 MapToV2(this BookingDetailsRequest bookingDetails) + { + return new V2.BookNewHearingRequestV2 + { + ScheduledDateTime = bookingDetails.ScheduledDateTime, + ScheduledDuration = bookingDetails.ScheduledDuration, + Cases = bookingDetails.Cases + .Select(cr => new V2.CaseRequestV2 + { + Number = cr.Number, + Name = cr.Name, + IsLeadCase = cr.IsLeadCase + }).ToList(), + Participants = bookingDetails.Participants + .Select(p => p.MapToV2()) + .ToList(), + HearingRoomName = bookingDetails.HearingRoomName, + OtherInformation = bookingDetails.OtherInformation, + CreatedBy = bookingDetails.CreatedBy, + AudioRecordingRequired = bookingDetails.AudioRecordingRequired, + IsMultiDayHearing = bookingDetails.IsMultiDayHearing, + Endpoints = bookingDetails.Endpoints.Select(e => new V2.EndpointRequestV2 + { + DisplayName = e.DisplayName, + DefenceAdvocateContactEmail = e.DefenceAdvocateContactEmail, + }).ToList(), + LinkedParticipants = bookingDetails.LinkedParticipants.Select(lp => lp.MapToV2()).ToList() + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/BookingsHearingResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/BookingsHearingResponseMapper.cs new file mode 100644 index 000000000..b71fae4d6 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/BookingsHearingResponseMapper.cs @@ -0,0 +1,39 @@ +using AdminWebsite.Contracts.Responses; +using BookingsApi.Contract.V1.Responses; +using BookingsHearingResponse = AdminWebsite.Contracts.Responses.BookingsHearingResponse; + +namespace AdminWebsite.Mappers; + +public static class BookingsHearingResponseMapper +{ + public static BookingsHearingResponse Map(this BookingsApi.Contract.V1.Responses.BookingsHearingResponse hearingResponse) + { + return new BookingsHearingResponse + { + HearingId = hearingResponse.HearingId, + HearingNumber = hearingResponse.HearingNumber, + HearingName = hearingResponse.HearingName, + ScheduledDateTime = hearingResponse.ScheduledDateTime, + ScheduledDuration = hearingResponse.ScheduledDuration, + CaseTypeName = hearingResponse.CaseTypeName, + HearingTypeName = hearingResponse.HearingTypeName, + CourtRoom = hearingResponse.CourtRoom, + CourtAddress = hearingResponse.CourtAddress, + JudgeName = hearingResponse.JudgeName, + CreatedBy = hearingResponse.CreatedBy, + CreatedDate = hearingResponse.CreatedDate, + LastEditBy = hearingResponse.LastEditBy, + LastEditDate = hearingResponse.LastEditDate, + ConfirmedBy = hearingResponse.ConfirmedBy, + ConfirmedDate = hearingResponse.ConfirmedDate, + HearingDate = hearingResponse.HearingDate, + Status = hearingResponse.Status, + QuestionnaireNotRequired = hearingResponse.QuestionnaireNotRequired, + AudioRecordingRequired = hearingResponse.AudioRecordingRequired, + CancelReason = hearingResponse.CancelReason, + GroupId = hearingResponse.GroupId, + CourtRoomAccount = hearingResponse.CourtRoomAccount, + AllocatedTo = hearingResponse.AllocatedTo + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/BookingsListMapper.cs b/AdminWebsite/AdminWebsite/Mappers/BookingsListMapper.cs new file mode 100644 index 000000000..4276ab7c3 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/BookingsListMapper.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; +using AdminWebsite.Contracts.Responses; +using BookingsApi.Contract.V1.Responses; +using BookingsByDateResponse = AdminWebsite.Contracts.Responses.BookingsByDateResponse; +using BookingsResponse = AdminWebsite.Contracts.Responses.BookingsResponse; + +namespace AdminWebsite.Mappers; + +public static class BookingsListMapper +{ + public static BookingsResponse Map(this BookingsApi.Contract.V1.Responses.BookingsResponse bookingsResponse) + { + return new BookingsResponse + { + NextCursor = bookingsResponse.NextCursor, + Limit = bookingsResponse.Limit, + PrevPageUrl = bookingsResponse.PrevPageUrl, + NextPageUrl = bookingsResponse.NextPageUrl, + Hearings = bookingsResponse.Hearings?.Select(e + => new BookingsByDateResponse + { + ScheduledDate = e.ScheduledDate, + Hearings = e.Hearings.Select(h => h.Map()).ToList() + }) + .ToList() + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/EditEndpointRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/EditEndpointRequestMapper.cs index dc84b0b95..b4d3d6cbc 100644 --- a/AdminWebsite/AdminWebsite/Mappers/EditEndpointRequestMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/EditEndpointRequestMapper.cs @@ -1,7 +1,6 @@ -using AdminWebsite.Contracts.Enums; -using AdminWebsite.Contracts.Responses; +using AdminWebsite.Contracts.Responses; using AdminWebsite.Models; -using BookingsApi.Contract.Responses; +using V1 = BookingsApi.Contract.V1.Responses; namespace AdminWebsite.Mappers { @@ -18,5 +17,17 @@ public static EditEndpointRequest MapFrom(EndpointResponse response) }; } + public static EditEndpointRequest MapFrom(V1.EndpointResponse response) + { + return new EditEndpointRequest + { + Id = response.Id, + DisplayName = response.DisplayName, + DefenceAdvocateContactEmail = + response.DefenceAdvocateId == null ? null : response.DefenceAdvocateId.ToString() + }; + + } + } } diff --git a/AdminWebsite/AdminWebsite/Mappers/EditParticipantRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/EditParticipantRequestMapper.cs index 31ff3679e..46efbcdef 100644 --- a/AdminWebsite/AdminWebsite/Mappers/EditParticipantRequestMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/EditParticipantRequestMapper.cs @@ -1,8 +1,7 @@ -using AdminWebsite.Contracts.Enums; -using AdminWebsite.Contracts.Responses; +using AdminWebsite.Contracts.Responses; using AdminWebsite.Models; -using BookingsApi.Contract.Responses; - +using V1 = BookingsApi.Contract.V1.Responses; +using V2 = BookingsApi.Contract.V2.Responses; namespace AdminWebsite.Mappers { public static class EditParticipantRequestMapper @@ -24,7 +23,25 @@ public static EditParticipantRequest MapFrom(ParticipantResponse response) Representee = response.Representee, OrganisationName = response.Organisation, }; - + } + + public static EditParticipantRequest MapFrom(V1.ParticipantResponse response) + { + return new EditParticipantRequest + { + Id = response.Id, + Title = response.Title, + FirstName = response.FirstName, + MiddleNames = response.MiddleNames, + LastName = response.LastName, + ContactEmail = response.ContactEmail, + TelephoneNumber = response.TelephoneNumber, + DisplayName = response.DisplayName, + CaseRoleName = response.CaseRoleName, + HearingRoleName = response.HearingRoleName, + Representee = response.Representee, + OrganisationName = response.Organisation, + }; } } } \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/EndpointResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/EndpointResponseMapper.cs new file mode 100644 index 000000000..f10376978 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/EndpointResponseMapper.cs @@ -0,0 +1,31 @@ +using AdminWebsite.Contracts.Responses; +using V1 = BookingsApi.Contract.V1.Responses; +using V2 = BookingsApi.Contract.V2.Responses; +namespace AdminWebsite.Mappers; + +public static class EndpointResponseMapper +{ + public static EndpointResponse Map(this V1.EndpointResponse endpointResponse) + { + return new EndpointResponse + { + Id = endpointResponse.Id, + DisplayName = endpointResponse.DisplayName, + Sip = endpointResponse.Sip, + Pin = endpointResponse.Pin, + DefenceAdvocateId = endpointResponse.DefenceAdvocateId + }; + } + + public static EndpointResponse Map(this V2.EndpointResponseV2 endpointResponse) + { + return new EndpointResponse + { + Id = endpointResponse.Id, + DisplayName = endpointResponse.DisplayName, + Sip = endpointResponse.Sip, + Pin = endpointResponse.Pin, + DefenceAdvocateId = endpointResponse.DefenceAdvocateId + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/HearingDetailsResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/HearingDetailsResponseMapper.cs new file mode 100644 index 000000000..71593685b --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/HearingDetailsResponseMapper.cs @@ -0,0 +1,78 @@ +using System.Linq; +using AdminWebsite.Contracts.Responses; +using V1 = BookingsApi.Contract.V1.Responses; +using V2 = BookingsApi.Contract.V2.Responses; +namespace AdminWebsite.Mappers; + +public static class HearingDetailsResponseMapper +{ + public static HearingDetailsResponse Map(this V1.HearingDetailsResponse hearingDetails) + { + return new HearingDetailsResponse + { + Id = hearingDetails.Id, + ScheduledDateTime = hearingDetails.ScheduledDateTime, + ScheduledDuration = hearingDetails.ScheduledDuration, + HearingVenueName = hearingDetails.HearingVenueName, + CaseTypeName = hearingDetails.CaseTypeName, + HearingTypeName = hearingDetails.HearingTypeName, + Cases = hearingDetails.Cases?.Select(e => new CaseResponse + { + IsLeadCase = e.IsLeadCase, + Name = e.Name, + Number = e.Number + }).ToList(), + Participants = hearingDetails.Participants?.Map(), + TelephoneParticipants = hearingDetails.TelephoneParticipants? + .Select(t => t.Map()) + .ToList(), + HearingRoomName = hearingDetails.HearingRoomName, + OtherInformation = hearingDetails.OtherInformation, + CreatedDate = hearingDetails.CreatedDate, + CreatedBy = hearingDetails.CreatedBy, + UpdatedBy = hearingDetails.UpdatedBy, + UpdatedDate = hearingDetails.UpdatedDate, + ConfirmedBy = hearingDetails.ConfirmedBy, + ConfirmedDate = hearingDetails.ConfirmedDate, + Status = (Contracts.Enums.BookingStatus)hearingDetails.Status, + QuestionnaireNotRequired = hearingDetails.QuestionnaireNotRequired, + AudioRecordingRequired = hearingDetails.AudioRecordingRequired, + CancelReason = hearingDetails.CancelReason, + Endpoints = hearingDetails.Endpoints?.Select(e => e.Map()).ToList(), + GroupId = hearingDetails.GroupId + }; + } + + public static HearingDetailsResponse Map(this V2.HearingDetailsResponseV2 hearingDetails) + { + return new HearingDetailsResponse + { + Id = hearingDetails.Id, + ScheduledDateTime = hearingDetails.ScheduledDateTime, + ScheduledDuration = hearingDetails.ScheduledDuration, + HearingVenueCode = hearingDetails.HearingVenueCode, + ServiceId = hearingDetails.ServiceId, + HearingTypeCode = hearingDetails.HearingTypeCode, + Cases = hearingDetails.Cases?.Select(e => new CaseResponse + { + IsLeadCase = e.IsLeadCase, + Name = e.Name, + Number = e.Number + }).ToList(), + Participants = hearingDetails.Participants?.Map(), + HearingRoomName = hearingDetails.HearingRoomName, + OtherInformation = hearingDetails.OtherInformation, + CreatedDate = hearingDetails.CreatedDate, + CreatedBy = hearingDetails.CreatedBy, + UpdatedBy = hearingDetails.UpdatedBy, + UpdatedDate = hearingDetails.UpdatedDate, + ConfirmedBy = hearingDetails.ConfirmedBy, + ConfirmedDate = hearingDetails.ConfirmedDate, + Status = (Contracts.Enums.BookingStatus)hearingDetails.Status, + AudioRecordingRequired = hearingDetails.AudioRecordingRequired, + CancelReason = hearingDetails.CancelReason, + Endpoints = hearingDetails.Endpoints.Select(e => e.Map()).ToList(), + GroupId = hearingDetails.GroupId + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/HearingUpdateRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/HearingUpdateRequestMapper.cs index 462ef9c9d..9ba46a84a 100644 --- a/AdminWebsite/AdminWebsite/Mappers/HearingUpdateRequestMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/HearingUpdateRequestMapper.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; using System.Linq; using AdminWebsite.Models; -using BookingsApi.Contract.Enums; -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; +using LinkedParticipantType = BookingsApi.Contract.V1.Enums.LinkedParticipantType; namespace AdminWebsite.Mappers { @@ -27,7 +27,7 @@ public static UpdateHearingRequest MapTo(EditHearingRequest editHearingRequest, } }, QuestionnaireNotRequired = false, - AudioRecordingRequired = editHearingRequest.Participants.Any(x=>x.LinkedParticipants.Any(s=>s.Type == LinkedParticipantType.Interpreter)) || editHearingRequest.AudioRecordingRequired, + AudioRecordingRequired = editHearingRequest.AudioRecordingRequired }; return updateHearingRequest; } diff --git a/AdminWebsite/AdminWebsite/Mappers/HearingsForAudioFileSearchMapper.cs b/AdminWebsite/AdminWebsite/Mappers/HearingsForAudioFileSearchMapper.cs index 593a208a4..45ae6cd5f 100644 --- a/AdminWebsite/AdminWebsite/Mappers/HearingsForAudioFileSearchMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/HearingsForAudioFileSearchMapper.cs @@ -1,5 +1,5 @@ using AdminWebsite.Models; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.Mappers { diff --git a/AdminWebsite/AdminWebsite/Mappers/JudgeResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/JudgeResponseMapper.cs index c1fb816c9..c8315c757 100644 --- a/AdminWebsite/AdminWebsite/Mappers/JudgeResponseMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/JudgeResponseMapper.cs @@ -1,6 +1,6 @@ using AdminWebsite.Contracts.Enums; using AdminWebsite.Contracts.Responses; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; namespace AdminWebsite.Mappers { diff --git a/AdminWebsite/AdminWebsite/Mappers/LinkedParticipantRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/LinkedParticipantRequestMapper.cs new file mode 100644 index 000000000..734e52c53 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/LinkedParticipantRequestMapper.cs @@ -0,0 +1,30 @@ +using System.Diagnostics.CodeAnalysis; +using AdminWebsite.Contracts.Requests; +using V1 = BookingsApi.Contract.V1; +using V2 = BookingsApi.Contract.V2; + +namespace AdminWebsite.Mappers; + +public static class LinkedParticipantRequestMapper +{ + public static V1.Requests.LinkedParticipantRequest MapToV1(this LinkedParticipantRequest linkedParticipant) + { + return new V1.Requests.LinkedParticipantRequest + { + LinkedParticipantContactEmail = linkedParticipant.LinkedParticipantContactEmail, + ParticipantContactEmail = linkedParticipant.ParticipantContactEmail, + Type = (V1.Enums.LinkedParticipantType)linkedParticipant.Type + }; + } + + [ExcludeFromCodeCoverage] //remove once used + public static V2.Requests.LinkedParticipantRequestV2 MapToV2(this LinkedParticipantRequest linkedParticipant) + { + return new V2.Requests.LinkedParticipantRequestV2 + { + LinkedParticipantContactEmail = linkedParticipant.LinkedParticipantContactEmail, + ParticipantContactEmail = linkedParticipant.ParticipantContactEmail, + TypeV2 = (V2.Enums.LinkedParticipantTypeV2)linkedParticipant.Type + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/LinkedParticipantResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/LinkedParticipantResponseMapper.cs new file mode 100644 index 000000000..654a49545 --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/LinkedParticipantResponseMapper.cs @@ -0,0 +1,26 @@ +using AdminWebsite.Contracts.Enums; +using AdminWebsite.Contracts.Responses; + +namespace AdminWebsite.Mappers; + +public static class LinkedParticipantResponseMapper +{ + public static LinkedParticipantResponse Map(this BookingsApi.Contract.V1.Responses.LinkedParticipantResponse linkedParticipant) + { + return new LinkedParticipantResponse + { + LinkedId = linkedParticipant.LinkedId, + Type = (LinkedParticipantType)linkedParticipant.Type + }; + } + + public static LinkedParticipantResponse Map(this BookingsApi.Contract.V2.Responses.LinkedParticipantResponseV2 linkedParticipant) + { + return new LinkedParticipantResponse + { + LinkedId = linkedParticipant.LinkedId, + Type = (LinkedParticipantType)linkedParticipant.TypeV2 + }; + } + +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/NewParticipantRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/NewParticipantRequestMapper.cs index c71bde3de..2be6b964b 100644 --- a/AdminWebsite/AdminWebsite/Mappers/NewParticipantRequestMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/NewParticipantRequestMapper.cs @@ -1,5 +1,5 @@ -using BookingsApi.Contract.Requests; -using AdminWebsite.Models; +using AdminWebsite.Models; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.Mappers { diff --git a/AdminWebsite/AdminWebsite/Mappers/ParticipantRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/ParticipantRequestMapper.cs new file mode 100644 index 000000000..72584131b --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/ParticipantRequestMapper.cs @@ -0,0 +1,47 @@ +using System.Diagnostics.CodeAnalysis; +using AdminWebsite.Contracts.Requests; +using V1 = BookingsApi.Contract.V1.Requests; +using V2 = BookingsApi.Contract.V2.Requests; +namespace AdminWebsite.Mappers; + +public static class ParticipantRequestMapper +{ + public static V1.ParticipantRequest MapToV1(this ParticipantRequest participantRequest) + { + return new V1.ParticipantRequest + { + CaseRoleName = participantRequest.CaseRoleName, + ContactEmail = participantRequest.ContactEmail, + DisplayName = participantRequest.DisplayName, + FirstName = participantRequest.FirstName, + HearingRoleName = participantRequest.HearingRoleName, + LastName = participantRequest.LastName, + MiddleNames = participantRequest.MiddleNames, + Representee = participantRequest.Representee, + TelephoneNumber = participantRequest.TelephoneNumber, + Title = participantRequest.Title, + Username = participantRequest.Username, + OrganisationName = participantRequest.OrganisationName, + }; + } + + [ExcludeFromCodeCoverage] //remove once used + public static V2.ParticipantRequestV2 MapToV2(this ParticipantRequest participantRequest) + { + return new V2.ParticipantRequestV2 + { + CaseRoleName = participantRequest.CaseRoleName, + ContactEmail = participantRequest.ContactEmail, + DisplayName = participantRequest.DisplayName, + FirstName = participantRequest.FirstName, + HearingRoleName = participantRequest.HearingRoleName, + LastName = participantRequest.LastName, + MiddleNames = participantRequest.MiddleNames, + Representee = participantRequest.Representee, + TelephoneNumber = participantRequest.TelephoneNumber, + Title = participantRequest.Title, + Username = participantRequest.Username, + OrganisationName = participantRequest.OrganisationName, + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/ParticipantResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/ParticipantResponseMapper.cs new file mode 100644 index 000000000..81217dc7f --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/ParticipantResponseMapper.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using System.Linq; +using AdminWebsite.Contracts.Responses; +using V1 = BookingsApi.Contract.V1.Responses; +using V2 = BookingsApi.Contract.V2.Responses; + +namespace AdminWebsite.Mappers; + +public static class ParticipantResponseMapper +{ + public static List Map(this List participants) + { + return participants.Select(p => + new ParticipantResponse + { + Id = p.Id, + DisplayName = p.DisplayName, + CaseRoleName = p.CaseRoleName, + HearingRoleName = p.HearingRoleName, + UserRoleName = p.UserRoleName, + Title = p.Title, + FirstName = p.FirstName, + MiddleNames = p.MiddleNames, + LastName = p.LastName, + ContactEmail = p.ContactEmail, + TelephoneNumber = p.TelephoneNumber, + Username = p.Username, + Organisation = p.Organisation, + Representee = p.Representee, + LinkedParticipants = p.LinkedParticipants?.Select(lp => lp.Map()).ToList() + }).ToList(); + } + + public static List Map(this List participants) + { + return participants.Select(p => + new ParticipantResponse + { + Id = p.Id, + DisplayName = p.DisplayName, + CaseRoleName = p.CaseRoleName, + HearingRoleName = p.HearingRoleName, + UserRoleName = p.UserRoleName, + Title = p.Title, + FirstName = p.FirstName, + MiddleNames = p.MiddleNames, + LastName = p.LastName, + ContactEmail = p.ContactEmail, + TelephoneNumber = p.TelephoneNumber, + Username = p.Username, + Organisation = p.Organisation, + Representee = p.Representee, + LinkedParticipants = p.LinkedParticipants?.Select(lp => lp.Map()).ToList() + }).ToList(); + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/TelephoneParticipantResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/TelephoneParticipantResponseMapper.cs new file mode 100644 index 000000000..e5484c96f --- /dev/null +++ b/AdminWebsite/AdminWebsite/Mappers/TelephoneParticipantResponseMapper.cs @@ -0,0 +1,25 @@ +using System.Linq; +using AdminWebsite.Contracts.Responses; +using V1 = BookingsApi.Contract.V1.Responses; + +namespace AdminWebsite.Mappers; + +public static class TelephoneParticipantResponseMapper +{ + public static TelephoneParticipantResponse Map(this V1.TelephoneParticipantResponse telephoneParticipant) + { + return new TelephoneParticipantResponse + { + Id = telephoneParticipant.Id, + CaseRoleName = telephoneParticipant.CaseRoleName, + HearingRoleName = telephoneParticipant.HearingRoleName, + FirstName = telephoneParticipant.FirstName, + LastName = telephoneParticipant.LastName, + ContactEmail = telephoneParticipant.ContactEmail, + TelephoneNumber = telephoneParticipant.TelephoneNumber, + MobileNumber = telephoneParticipant.MobileNumber, + Representee = telephoneParticipant.Representee, + LinkedParticipants = telephoneParticipant.LinkedParticipants?.Select(lp => lp.Map()).ToList() + }; + } +} \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Mappers/UnallocatedHearingsForVHOMapper.cs b/AdminWebsite/AdminWebsite/Mappers/UnallocatedHearingsForVHOMapper.cs index 81a9c1e47..455cde3c9 100644 --- a/AdminWebsite/AdminWebsite/Mappers/UnallocatedHearingsForVHOMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/UnallocatedHearingsForVHOMapper.cs @@ -2,8 +2,8 @@ using System.Collections.Generic; using System.Linq; using AdminWebsite.Contracts.Responses; -using AdminWebsite.Extensions; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Responses; +using HearingDetailsResponse = BookingsApi.Contract.V1.Responses.HearingDetailsResponse; namespace AdminWebsite.Mappers; diff --git a/AdminWebsite/AdminWebsite/Mappers/UpdateParticipantRequestMapper.cs b/AdminWebsite/AdminWebsite/Mappers/UpdateParticipantRequestMapper.cs index 6b0f5b277..d3af7a06e 100644 --- a/AdminWebsite/AdminWebsite/Mappers/UpdateParticipantRequestMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/UpdateParticipantRequestMapper.cs @@ -1,6 +1,6 @@ using AdminWebsite.Models; -using BookingsApi.Contract.Requests; using System; +using BookingsApi.Contract.V1.Requests; namespace AdminWebsite.Mappers { diff --git a/AdminWebsite/AdminWebsite/Mappers/UserResponseMapper.cs b/AdminWebsite/AdminWebsite/Mappers/UserResponseMapper.cs index 280732e74..a77f697a0 100644 --- a/AdminWebsite/AdminWebsite/Mappers/UserResponseMapper.cs +++ b/AdminWebsite/AdminWebsite/Mappers/UserResponseMapper.cs @@ -1,4 +1,5 @@ -using BookingsApi.Contract.Responses; + +using BookingsApi.Contract.V1.Responses; using UserApi.Contract.Responses; namespace AdminWebsite.Mappers diff --git a/AdminWebsite/AdminWebsite/Models/LinkedParticipant.cs b/AdminWebsite/AdminWebsite/Models/LinkedParticipant.cs index 0d94d9011..bc7759cca 100644 --- a/AdminWebsite/AdminWebsite/Models/LinkedParticipant.cs +++ b/AdminWebsite/AdminWebsite/Models/LinkedParticipant.cs @@ -1,5 +1,5 @@ using System; -using BookingsApi.Contract.Enums; +using AdminWebsite.Contracts.Enums; namespace AdminWebsite.Models { diff --git a/AdminWebsite/AdminWebsite/Services/AppRoleService.cs b/AdminWebsite/AdminWebsite/Services/AppRoleService.cs index f475501e1..4e68dc049 100644 --- a/AdminWebsite/AdminWebsite/Services/AppRoleService.cs +++ b/AdminWebsite/AdminWebsite/Services/AppRoleService.cs @@ -4,8 +4,8 @@ using System.Threading.Tasks; using AdminWebsite.Models; using BookingsApi.Client; -using BookingsApi.Contract.Requests.Enums; -using BookingsApi.Contract.Responses; +using BookingsApi.Contract.V1.Requests.Enums; +using BookingsApi.Contract.V1.Responses; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; diff --git a/AdminWebsite/AdminWebsite/Services/HearingsService.cs b/AdminWebsite/AdminWebsite/Services/HearingsService.cs index 76b4c60db..b6efccf5a 100644 --- a/AdminWebsite/AdminWebsite/Services/HearingsService.cs +++ b/AdminWebsite/AdminWebsite/Services/HearingsService.cs @@ -3,26 +3,22 @@ using AdminWebsite.Mappers; using AdminWebsite.Models; using BookingsApi.Client; -using BookingsApi.Contract.Configuration; -using BookingsApi.Contract.Requests; -using BookingsApi.Contract.Responses; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using AdminWebsite.Configuration; +using AdminWebsite.Contracts.Responses; +using BookingsApi.Contract.V1.Configuration; +using BookingsApi.Contract.V1.Requests; using VideoApi.Contract.Consts; -using AddEndpointRequest = BookingsApi.Contract.Requests.AddEndpointRequest; -using EndpointResponse = BookingsApi.Contract.Responses.EndpointResponse; -using ParticipantRequest = BookingsApi.Contract.Requests.ParticipantRequest; -using UpdateEndpointRequest = BookingsApi.Contract.Requests.UpdateEndpointRequest; -using UpdateParticipantRequest = BookingsApi.Contract.Requests.UpdateParticipantRequest; namespace AdminWebsite.Services { public interface IHearingsService { - void AssignEndpointDefenceAdvocates(List endpointsWithDa, IReadOnlyCollection participants); + void AssignEndpointDefenceAdvocates(List endpointsWithDa, IReadOnlyCollection participants); Task ProcessParticipants(Guid hearingId, List existingParticipants, List newParticipants, List removedParticipantIds, List linkedParticipants); Task ProcessNewParticipant(Guid hearingId, EditParticipantRequest participant, List removedParticipantIds, HearingDetailsResponse hearing); Task ProcessEndpoints(Guid hearingId, EditHearingRequest request, HearingDetailsResponse hearing, List newParticipantList); @@ -37,34 +33,32 @@ public class HearingsService : IHearingsService private readonly IBookingsApiClient _bookingsApiClient; private readonly ILogger _logger; #pragma warning disable S107 - public HearingsService(IBookingsApiClient bookingsApiClient, ILogger logger) + public HearingsService(IBookingsApiClient bookingsApiClient, ILogger logger, IFeatureToggles featureFlag) { _bookingsApiClient = bookingsApiClient; _logger = logger; } - public void AssignEndpointDefenceAdvocates(List endpointsWithDa, - IReadOnlyCollection participants) + public void AssignEndpointDefenceAdvocates(List endpointsWithDa, IReadOnlyCollection participants) { // update the username of defence advocate foreach (var endpoint in endpointsWithDa) { _logger.LogDebug("Attempting to find defence advocate {DefenceAdvocate} for endpoint {Endpoint}", endpoint.DefenceAdvocateContactEmail, endpoint.DisplayName); - var defenceAdvocate = participants.Single(x => - x.ContactEmail.Equals(endpoint.DefenceAdvocateContactEmail, - StringComparison.CurrentCultureIgnoreCase)); + var defenceAdvocate = participants.Single(x => + x.ContactEmail.Equals(endpoint.DefenceAdvocateContactEmail,StringComparison.CurrentCultureIgnoreCase)); endpoint.DefenceAdvocateContactEmail = defenceAdvocate.ContactEmail; } } - public bool IsAddingParticipantOnly(EditHearingRequest editHearingRequest, - HearingDetailsResponse hearingDetailsResponse) + public bool IsAddingParticipantOnly(EditHearingRequest editHearingRequest, HearingDetailsResponse hearingDetailsResponse) { var originalParticipants = hearingDetailsResponse.Participants.Where(x=>x.HearingRoleName != HearingRoleName.StaffMember) - .Select(EditParticipantRequestMapper.MapFrom).ToList(); + .Select(EditParticipantRequestMapper.MapFrom) + .ToList(); var requestParticipants = editHearingRequest.Participants.FindAll(x=>x.HearingRoleName != HearingRoleName.StaffMember); - var hearingCase = hearingDetailsResponse.Cases.First(); + var hearingCase = hearingDetailsResponse.Cases[0]; var addedParticipant = GetAddedParticipant(originalParticipants, requestParticipants); @@ -82,10 +76,10 @@ public bool IsUpdatingJudge(EditHearingRequest editHearingRequest, HearingDetailsResponse hearingDetailsResponse) { var existingJudge = - hearingDetailsResponse.Participants.FirstOrDefault( + hearingDetailsResponse.Participants.Find( x => x.HearingRoleName == HearingRoleName.Judge); var newJudge = - editHearingRequest.Participants.FirstOrDefault(x => x.HearingRoleName == HearingRoleName.Judge); + editHearingRequest.Participants.Find(x => x.HearingRoleName == HearingRoleName.Judge); var existingJudgeOtherInformation = HearingDetailsResponseExtensions.GetJudgeOtherInformationString(hearingDetailsResponse.OtherInformation); var newJudgeOtherInformation = HearingDetailsResponseExtensions.GetJudgeOtherInformationString(editHearingRequest.OtherInformation); @@ -93,13 +87,11 @@ public bool IsUpdatingJudge(EditHearingRequest editHearingRequest, newJudgeOtherInformation != existingJudgeOtherInformation; } - public bool HasEndpointsBeenChanged(EditHearingRequest editHearingRequest, - HearingDetailsResponse hearingDetailsResponse) + public bool HasEndpointsBeenChanged(EditHearingRequest editHearingRequest, HearingDetailsResponse hearingDetailsResponse) { var originalEndpoints = hearingDetailsResponse.Endpoints == null ? new List() - : hearingDetailsResponse.Endpoints - .Select(EditEndpointRequestMapper.MapFrom).ToList(); + : hearingDetailsResponse.Endpoints.Select(EditEndpointRequestMapper.MapFrom).ToList(); var requestEndpoints = editHearingRequest.Endpoints ?? new List(); var ogEndpoints = originalEndpoints.Except(requestEndpoints, EditEndpointRequest.EditEndpointRequestComparer).ToList(); @@ -120,9 +112,13 @@ public List GetAddedParticipant(List(); } - public async Task ProcessParticipants(Guid hearingId, List existingParticipants, List newParticipants, - List removedParticipantIds, List linkedParticipants) + public async Task ProcessParticipants(Guid hearingId, + List existingParticipants, + List newParticipants, + List removedParticipantIds, + List linkedParticipants) { + var updateHearingParticipantsRequest = new UpdateHearingParticipantsRequest { ExistingParticipants = existingParticipants, @@ -130,7 +126,6 @@ public async Task ProcessParticipants(Guid hearingId, List ProcessNewParticipant( || (!ejudFeatureFlag && participant.CaseRoleName == RoleNames.Judge)) { if (hearing.Participants != null && - hearing.Participants.Any(p => p.ContactEmail.Equals(participant.ContactEmail) && removedParticipantIds.All(removedParticipantId => removedParticipantId != p.Id))) + hearing.Participants.Exists(p => p.ContactEmail.Equals(participant.ContactEmail) && removedParticipantIds.TrueForAll(removedParticipantId => removedParticipantId != p.Id))) { //If the judge already exists in the database, there is no need to add again. return null; @@ -168,39 +163,37 @@ public async Task ProcessNewParticipant( public async Task ProcessEndpoints(Guid hearingId, EditHearingRequest request, HearingDetailsResponse hearing, List newParticipantList) { - if (hearing.Endpoints == null) - { - return; - } + if (hearing.Endpoints == null) return; - var listOfEndpointsToDelete = hearing.Endpoints.Where(e => request.Endpoints.All(re => re.Id != e.Id)); + var listOfEndpointsToDelete = hearing.Endpoints.Where(e => request.Endpoints.TrueForAll(re => re.Id != e.Id)); await RemoveEndpointsFromHearing(hearing, listOfEndpointsToDelete); + foreach (var endpoint in request.Endpoints) { - var epToUpdate = newParticipantList - .Find(p => p.ContactEmail.Equals(endpoint.DefenceAdvocateContactEmail, - StringComparison.CurrentCultureIgnoreCase)); - if (epToUpdate != null) - { - endpoint.DefenceAdvocateContactEmail = epToUpdate.ContactEmail; - } + UpdateEndpointWithNewlyAddedParticipant(newParticipantList, endpoint); if (endpoint.Id.HasValue) - { await UpdateEndpointInHearing(hearingId, hearing, endpoint); - } else - { await AddEndpointToHearing(hearingId, hearing, endpoint); - } } } + + private static void UpdateEndpointWithNewlyAddedParticipant(List newParticipantList, EditEndpointRequest endpoint) + { + var epToUpdate = newParticipantList + .Find(p => p.ContactEmail.Equals(endpoint.DefenceAdvocateContactEmail, + StringComparison.CurrentCultureIgnoreCase)); + if (epToUpdate != null) + endpoint.DefenceAdvocateContactEmail = epToUpdate.ContactEmail; + } + public async Task UpdateFailedBookingStatus(Guid hearingId) { await _bookingsApiClient.UpdateBookingStatusAsync(hearingId, new UpdateBookingStatusRequest { - Status = BookingsApi.Contract.Requests.Enums.UpdateBookingStatus.Failed, + Status = BookingsApi.Contract.V1.Requests.Enums.UpdateBookingStatus.Failed, UpdatedBy = "System", CancelReason = string.Empty }); @@ -230,13 +223,13 @@ private async Task AddEndpointToHearing(Guid hearingId, HearingDetailsResponse h await _bookingsApiClient.AddEndPointToHearingAsync(hearing.Id, addEndpointRequest); } - private async Task UpdateEndpointInHearing(Guid hearingId, HearingDetailsResponse hearing, - EditEndpointRequest endpoint) + private async Task UpdateEndpointInHearing(Guid hearingId, HearingDetailsResponse hearing, EditEndpointRequest endpoint) { - var existingEndpointToEdit = hearing.Endpoints.FirstOrDefault(e => e.Id.Equals(endpoint.Id)); + var existingEndpointToEdit = hearing.Endpoints.Find(e => e.Id.Equals(endpoint.Id)); + var endpointRequestDefenceAdvocate = hearing.Participants.Find(e => e.ContactEmail == endpoint.DefenceAdvocateContactEmail); if (existingEndpointToEdit == null || existingEndpointToEdit.DisplayName == endpoint.DisplayName && - existingEndpointToEdit.DefenceAdvocateId.ToString() == endpoint.DefenceAdvocateContactEmail) + existingEndpointToEdit.DefenceAdvocateId == endpointRequestDefenceAdvocate?.Id) return; _logger.LogDebug("Updating endpoint {Endpoint} - {EndpointDisplayName} in hearing {Hearing}", @@ -246,8 +239,7 @@ private async Task UpdateEndpointInHearing(Guid hearingId, HearingDetailsRespons DisplayName = endpoint.DisplayName, DefenceAdvocateContactEmail = endpoint.DefenceAdvocateContactEmail }; - await _bookingsApiClient.UpdateDisplayNameForEndpointAsync(hearing.Id, endpoint.Id.Value, - updateEndpointRequest); + await _bookingsApiClient.UpdateDisplayNameForEndpointAsync(hearing.Id, endpoint.Id.Value, updateEndpointRequest); } } } \ No newline at end of file diff --git a/AdminWebsite/AdminWebsite/Services/UserAccountService.cs b/AdminWebsite/AdminWebsite/Services/UserAccountService.cs index f0c1cb5f5..49bc9b96c 100644 --- a/AdminWebsite/AdminWebsite/Services/UserAccountService.cs +++ b/AdminWebsite/AdminWebsite/Services/UserAccountService.cs @@ -9,7 +9,6 @@ using AdminWebsite.Security; using AdminWebsite.Services.Models; using BookingsApi.Client; -using BookingsApi.Contract.Requests; using Microsoft.Extensions.Logging; using NotificationApi.Client; using UserApi.Client; @@ -114,25 +113,17 @@ public async Task GetAdUserIdForUsername(string username) { try { - _logger.LogDebug($"{nameof(GetAdUserIdForUsername)} - Attempting to get an AD user with username {username} found.", username); var user = await _userApiClient.GetUserByAdUserIdAsync(username); - _logger.LogDebug($"{nameof(GetAdUserIdForUsername)} - AD User with username {username} found.", username); - - if(user.HasValidUserRole()) - { - _logger.LogWarning($"{nameof(GetAdUserIdForUsername)} - AD user with username {username} does not have a user role."); - } - return user.UserId; } catch (UserApiException e) { if (e.StatusCode == (int) HttpStatusCode.NotFound) { - _logger.LogWarning($"{nameof(GetAdUserIdForUsername)} - AD User with username {username} not found.", username); + _logger.LogWarning($"{nameof(GetAdUserIdForUsername)} - AD User not found."); return null; } - _logger.LogError(e, $"{nameof(GetAdUserIdForUsername)} - Unhandled error getting an AD user with username {username}.", username); + _logger.LogError(e, $"{nameof(GetAdUserIdForUsername)} - Unhandled error getting an AD user"); throw; } } @@ -177,43 +168,27 @@ public async Task> SearchEjudiciaryJudgesByEmailUserRe public async Task ResetParticipantPassword(string userName) { - _logger.LogDebug("Attempting to reset AD user {Username}", userName); var userProfile = await _userApiClient.GetUserByAdUserNameAsync(userName); if (userProfile == null) - { - var e = new UserServiceException - { - Reason = "Unable to generate new password" - }; - _logger.LogError(e, "Unable to reset password for AD user {Username}", userName); - throw e; - } - - _logger.LogDebug("AD user {Username} found", userName); + throw new UserServiceException { Reason = "Unable to generate new password" }; + var passwordResetResponse = await _userApiClient.ResetUserPasswordAsync(userName); - _logger.LogDebug("AD user {Username} password has been reset", userName); - var passwordResetNotificationRequest = AddNotificationRequestMapper.MapToPasswordResetNotification( - $"{userProfile.FirstName} {userProfile.LastName}", passwordResetResponse.NewPassword, - userProfile.Email); + var passwordResetNotificationRequest = + AddNotificationRequestMapper.MapToPasswordResetNotification( + $"{userProfile.FirstName} {userProfile.LastName}", + passwordResetResponse.NewPassword, + userProfile.Email); await _notificationApiClient.CreateNewNotificationAsync(passwordResetNotificationRequest); } public async Task DeleteParticipantAccountAsync(string username) { if (await CheckUsernameExistsInAdAsync(username)) - { - _logger.LogDebug("Attempting to delete AD User {username}.", username); await _userApiClient.DeleteUserAsync(username); - _logger.LogDebug("Successfully deleted AD User {username}.", username); - } - + if (await CheckPersonExistsInBookingsAsync(username)) - { - _logger.LogDebug("Attempting to anonymise person in Bookings API {username}.", username); await _bookingsApiClient.AnonymisePersonWithUsernameAsync(username); - _logger.LogDebug("Successfully anonymised person in Bookings API {username}.", username); - } } public async Task AssignParticipantToGroup(string username, string userRole) @@ -266,12 +241,10 @@ private async Task AddGroup(string username, string groupName) GroupName = groupName }; await _userApiClient.AddUserToGroupAsync(addUserToGroupRequest); - _logger.LogDebug("{username} to group {group}.", username, addUserToGroupRequest.GroupName); } catch (UserApiException e) { - _logger.LogError(e, - $"Failed to add user {username} to {groupName} in User API. " + + _logger.LogError(e, $"Failed to add user to {groupName} in User API. " + $"Status Code {e.StatusCode} - Message {e.Message}"); throw; } @@ -281,7 +254,6 @@ private async Task CheckUsernameExistsInAdAsync(string username) { try { - _logger.LogDebug("Attempting to check if {username} exists in AD", username); var person = await _userApiClient.GetUserByAdUserNameAsync(username); Enum.TryParse(person.UserRole, out var userRoleResult); if (userRoleResult == UserRoleType.Judge || userRoleResult == UserRoleType.VhOfficer) @@ -290,24 +262,19 @@ private async Task CheckUsernameExistsInAdAsync(string username) { Reason = $"Unable to delete account with role {userRoleResult}" }; - _logger.LogError(e, "Not allowed to delete {username}", username); + _logger.LogError(e, "Not allowed to delete user"); throw e; } - - _logger.LogDebug("{username} exists in AD", username); return true; } catch (UserApiException e) { - _logger.LogError(e, "Failed to get user {username} in User API. Status Code {StatusCode} - Message {Message}", - username, e.StatusCode, e.Response); + _logger.LogError(e, "Failed to get user in User API. Status Code {StatusCode} - Message {Message}",e.StatusCode, e.Response); if (e.StatusCode == (int)HttpStatusCode.NotFound) { - _logger.LogWarning(e, "{username} not found. Status Code {StatusCode} - Message {Message}", - username, e.StatusCode, e.Response); + _logger.LogWarning(e, "User not found. Status Code {StatusCode} - Message {Message}",e.StatusCode, e.Response); return false; } - throw; } } @@ -316,22 +283,17 @@ private async Task CheckPersonExistsInBookingsAsync(string username) { try { - _logger.LogDebug("Attempting to check if {username} exists in Bookings API", username); await _bookingsApiClient.GetHearingsByUsernameForDeletionAsync(username); - _logger.LogDebug("{username} exists in Bookings API", username); return true; } catch (BookingsApiException e) { - _logger.LogError(e, "Failed to get person {username} in User API. Status Code {StatusCode} - Message {Message}", - username, e.StatusCode, e.Response); + _logger.LogError(e, "Failed to get person in User API. Status Code {StatusCode} - Message {Message}",e.StatusCode, e.Response); if (e.StatusCode == (int)HttpStatusCode.NotFound) { - _logger.LogWarning(e, "{username} not found. Status Code {StatusCode} - Message {Message}", - username, e.StatusCode, e.Response); + _logger.LogWarning(e, "User not found. Status Code {StatusCode} - Message {Message}", e.StatusCode, e.Response); return false; } - throw; } } diff --git a/AdminWebsite/AdminWebsite/Startup.cs b/AdminWebsite/AdminWebsite/Startup.cs index 7cfd2d2c6..160907299 100644 --- a/AdminWebsite/AdminWebsite/Startup.cs +++ b/AdminWebsite/AdminWebsite/Startup.cs @@ -29,8 +29,7 @@ public Startup(IConfiguration configuration) // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - services.AddApplicationInsightsTelemetry(options => - options.ConnectionString = Configuration["ApplicationInsights:InstrumentationKey"]); + services.AddApplicationInsightsTelemetry(); services.AddSingleton(new CloudRoleNameInitializer()); var envName = Configuration["AzureAd:RedirectUri"]; // resource ID is a GUID, services.AddSingleton(new FeatureToggles(Configuration["FeatureToggle:SdkKey"], envName)); diff --git a/AdminWebsite/AdminWebsite/Validators/CaseRequestValidation.cs b/AdminWebsite/AdminWebsite/Validators/CaseRequestValidation.cs index 689753647..c9d964388 100644 --- a/AdminWebsite/AdminWebsite/Validators/CaseRequestValidation.cs +++ b/AdminWebsite/AdminWebsite/Validators/CaseRequestValidation.cs @@ -1,4 +1,4 @@ -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; using FluentValidation; namespace AdminWebsite.Validators diff --git a/AdminWebsite/AdminWebsite/Validators/ParticipantRequestValidation.cs b/AdminWebsite/AdminWebsite/Validators/ParticipantRequestValidation.cs index d8fa2895c..26953b25f 100644 --- a/AdminWebsite/AdminWebsite/Validators/ParticipantRequestValidation.cs +++ b/AdminWebsite/AdminWebsite/Validators/ParticipantRequestValidation.cs @@ -1,4 +1,4 @@ -using BookingsApi.Contract.Requests; +using BookingsApi.Contract.V1.Requests; using FluentValidation; namespace AdminWebsite.Validators diff --git a/AdminWebsite/AdminWebsite/packages.lock.json b/AdminWebsite/AdminWebsite/packages.lock.json index 3fe07b4d2..41c628aa6 100644 --- a/AdminWebsite/AdminWebsite/packages.lock.json +++ b/AdminWebsite/AdminWebsite/packages.lock.json @@ -4,9 +4,9 @@ "net6.0": { "BookingsApi.Client": { "type": "Direct", - "requested": "[1.44.6, )", - "resolved": "1.44.6", - "contentHash": "pr59SEWnlnkGyZmilLh+6JiUEZqLXn6iic5NVTEjO22VFs3Qij0RfZ2q+fotW2rk/tVcs0P2WGITt9kulBm5SQ==", + "requested": "[1.46.9, )", + "resolved": "1.46.9", + "contentHash": "/WKAyKGdjSMt6I/1MnkH9+J8nqfmYqbRUtVSAOqvwjbYBpoZ1GZCqPMDoOcgDtNdGzQboo9wt2lQBa8snjhbpw==", "dependencies": { "Microsoft.AspNetCore.Mvc.Core": "2.2.5" } diff --git a/charts/vh-admin-web/Chart.yaml b/charts/vh-admin-web/Chart.yaml index be85189b3..00c065fee 100644 --- a/charts/vh-admin-web/Chart.yaml +++ b/charts/vh-admin-web/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: vh-admin-web home: https://github.com/hmcts/vh-admin-web -version: 0.0.20 +version: 0.0.21 description: Helm Chart for Admin Web maintainers: - name: VH Devops diff --git a/charts/vh-admin-web/values.yaml b/charts/vh-admin-web/values.yaml index 1120fccd8..a4896eff1 100644 --- a/charts/vh-admin-web/values.yaml +++ b/charts/vh-admin-web/values.yaml @@ -16,7 +16,8 @@ java: resourceGroup: vh-infra-core-{{ .Values.global.environment }} usePodIdentity: true secrets: - - applicationinsights--instrumentationkey + - name: connectionstrings--applicationinsights + alias: applicationinsights--connectionstring - azuread--tenantid - name: dom1--tenant--id alias: DOM1--TenantId