diff --git a/.github/workflows/merge-main.yml b/.github/workflows/merge-main.yml index d46fb9f5df..5f14dccdf1 100644 --- a/.github/workflows/merge-main.yml +++ b/.github/workflows/merge-main.yml @@ -250,7 +250,7 @@ jobs: -p ZONE=${{ env.ZONE }} -p NAME=${{ github.event.repository.name }} -p PROMOTE=${{ github.repository }}/backend:${{ env.ZONE }} -p CHES_TOKEN_URL='https://test.loginproxy.gov.bc.ca/auth/realms/comsvcauth/protocol/openid-connect/token' - -p CHES_API_URL='https://ches-test.api.gov.bc.ca/api/v1' + -p CHES_API_URL='https://ches-test.api.gov.bc.ca/api/v1/email' -p BCREGISTRY_URI='https://bcregistry-prod.apigee.net' -p COGNITO_REGION=ca-central-1 -p COGNITO_COOKIE_DOMAIN=gov.bc.ca @@ -403,7 +403,7 @@ jobs: -p ZONE=${{ env.ZONE }} -p NAME=${{ github.event.repository.name }} -p PROMOTE=${{ github.repository }}/backend:${{ env.PREV }} -p CHES_TOKEN_URL='https://loginproxy.gov.bc.ca/auth/realms/comsvcauth/protocol/openid-connect/token' - -p CHES_API_URL='https://ches.api.gov.bc.ca/api/v1' + -p CHES_API_URL='https://ches.api.gov.bc.ca/api/v1/email' -p BCREGISTRY_URI='https://bcregistry-prod.apigee.net' -p COGNITO_REGION=ca-central-1 -p COGNITO_COOKIE_DOMAIN=gov.bc.ca diff --git a/backend/pom.xml b/backend/pom.xml index fbb6ac2b06..55dd6a322c 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -102,11 +102,6 @@ lombok true - - org.springdoc - springdoc-openapi-starter-webflux-ui - 2.2.0 - org.springframework.boot spring-boot-starter-test diff --git a/backend/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java b/backend/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java index adfe417f05..321ffdfd9d 100644 --- a/backend/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java +++ b/backend/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java @@ -36,6 +36,8 @@ public class ForestClientConfiguration { @NestedConfigurationProperty private CognitoConfiguration cognito; + private Duration submissionLimit; + /** * The Common hosted email service configuration. */ diff --git a/backend/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java b/backend/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java index 1efd2dbce9..d85a9820a2 100644 --- a/backend/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java +++ b/backend/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java @@ -132,8 +132,13 @@ public WebClient authApi(ForestClientConfiguration configuration) { return WebClient .builder() .baseUrl(configuration.getChes().getTokenUrl()) - .filter(ExchangeFilterFunctions.basicAuthentication(configuration.getChes().getClientId(), - configuration.getChes().getClientSecret())) + .filter( + ExchangeFilterFunctions + .basicAuthentication( + configuration.getChes().getClientId(), + configuration.getChes().getClientSecret() + ) + ) .build(); } @@ -183,23 +188,24 @@ public WebClient addressCompleteApi(ForestClientConfiguration configuration) { /** * Returns a configured instance of WebClient for accessing the Cognito API. + * * @param objectMapper the object mapper * @return A configured instance of WebClient for accessing the Cognito API. */ @Bean - public WebClient cognitoApi(ObjectMapper objectMapper) { - return WebClient - .builder() - .codecs(clientCodecConfigurer -> { - clientCodecConfigurer - .customCodecs() - .register(new AwsJsonMessageEncoder(objectMapper)); - clientCodecConfigurer - .customCodecs() - .register(new AwsJsonMessageDecoder(objectMapper)); - }) - .build(); - } + public WebClient cognitoApi(ObjectMapper objectMapper) { + return WebClient + .builder() + .codecs(clientCodecConfigurer -> { + clientCodecConfigurer + .customCodecs() + .register(new AwsJsonMessageEncoder(objectMapper)); + clientCodecConfigurer + .customCodecs() + .register(new AwsJsonMessageDecoder(objectMapper)); + }) + .build(); + } @Bean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { diff --git a/backend/src/main/java/ca/bc/gov/app/controller/ches/ChesController.java b/backend/src/main/java/ca/bc/gov/app/controller/ches/ChesController.java index 98e68bc304..bac6cf34ff 100644 --- a/backend/src/main/java/ca/bc/gov/app/controller/ches/ChesController.java +++ b/backend/src/main/java/ca/bc/gov/app/controller/ches/ChesController.java @@ -2,8 +2,8 @@ import ca.bc.gov.app.dto.client.EmailRequestDto; import ca.bc.gov.app.service.client.ClientService; -import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; @@ -14,20 +14,17 @@ import reactor.core.publisher.Mono; /** - * Controller for handling email sending via CHES (Common Hosted Email Service). - * This controller provides endpoints for sending emails using the CHES service. + * Controller for handling email sending via CHES (Common Hosted Email Service). This controller + * provides endpoints for sending emails using the CHES service. */ @RestController -@Tag( - name = "CHES", - description = "The CHES endpoint is responsible for handling the sending of emails" -) +@Slf4j @RequestMapping(value = "/api/ches", produces = MediaType.APPLICATION_JSON_VALUE) @RequiredArgsConstructor public class ChesController { - + private final ClientService clientService; - + /** * Endpoint for sending an email using CHES. * @@ -37,7 +34,8 @@ public class ChesController { @PostMapping("/email") @ResponseStatus(HttpStatus.ACCEPTED) public Mono sendEmail(@RequestBody EmailRequestDto emailRequestDto) { + log.info("Sending email using CHES {}", emailRequestDto); return clientService.sendEmail(emailRequestDto); } - + } diff --git a/backend/src/main/java/ca/bc/gov/app/controller/client/ClientAddressController.java b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientAddressController.java index 6805fdea6d..b495bd79a0 100644 --- a/backend/src/main/java/ca/bc/gov/app/controller/client/ClientAddressController.java +++ b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientAddressController.java @@ -3,13 +3,6 @@ import ca.bc.gov.app.dto.client.ClientAddressDto; import ca.bc.gov.app.dto.client.CodeNameDto; import ca.bc.gov.app.service.client.ClientAddressService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; @@ -23,10 +16,6 @@ @RestController @Slf4j -@Tag( - name = "FSA Clients", - description = "The FSA Client endpoint, responsible for handling client data" -) @RequestMapping(value = "/api/clients", produces = MediaType.APPLICATION_JSON_VALUE) @RequiredArgsConstructor public class ClientAddressController { @@ -34,38 +23,11 @@ public class ClientAddressController { private final ClientAddressService clientAddressService; @GetMapping("/addresses") - @Operation( - summary = "Autocomplete addresses", - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns a list of possible addresses", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - array = @ArraySchema( - schema = @Schema( - name = "NameCode", - implementation = CodeNameDto.class - ) - ) - ) - ) - } - ) public Flux findPossibleAddresses( - @Parameter(description = - "The name or ISO 2 or 3 character code for the country to search in, defaults to CA", - example = "UK") @RequestParam(value = "country", required = false, defaultValue = "CA") String country, - - @Parameter(description = - "The maximum number of autocomplete suggestions to return, defaults to 7", - example = "7") @RequestParam(value = "maxSuggestions", required = false, defaultValue = "7") Integer maxSuggestions, - - @Parameter(description = "The search term to find", example = "2701 ri") @RequestParam(value = "searchTerm", required = true) String searchTerm) { return clientAddressService @@ -73,31 +35,7 @@ public Flux findPossibleAddresses( } @GetMapping("/addresses/{addressId}") - @Operation( - summary = "Retrieve address", - responses = { - @ApiResponse( - responseCode = "200", - description = "Returns an addresses", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - array = @ArraySchema( - schema = @Schema( - name = "Address", - implementation = ClientAddressDto.class - ) - ) - ) - ) - } - ) public Mono getAddress( - @Parameter( - description = """ - The id of the address to retrieve the details for. - The id can be obtained through /api/client/addresses endpoint""", - example = "CA|CP|B|0000001" - ) @PathVariable String addressId) { return clientAddressService .getAddress(addressId); diff --git a/backend/src/main/java/ca/bc/gov/app/dto/bcregistry/ClientDetailsDto.java b/backend/src/main/java/ca/bc/gov/app/dto/bcregistry/ClientDetailsDto.java index d7e6e82cf1..16269a3cfd 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/bcregistry/ClientDetailsDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/bcregistry/ClientDetailsDto.java @@ -2,94 +2,20 @@ import ca.bc.gov.app.dto.client.ClientAddressDto; import ca.bc.gov.app.dto.client.ClientContactDto; -import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.With; /** * A data transfer object representing the details of a client. */ -@Schema( - example = """ - { - "name": "Acme Inc.", - "id": "AC0000000", - "goodStanding": true, - "addresses": [ - { - "streetAddress": "123 Main St", - "country": {"value": "CA", "text": "Canada"}, - "province": {"value": "ON", text": "Ontario"}, - "city": "Toronto", - "postalCode": "M5V1E3", - "locationName":"Billing Address", - "index": 0 - }, - { - "streetAddress": "456 Queen St", - "country": {"value": "CA", text": "Canada"}, - "province": {"value": "QC", text": "Quebec"}, - "city": "Montreal", - "postalCode": "H3B1A7", - "locationName":"Mailing address", - "index": 1, - }, - ], - "contacts":[{ - "type": "person", - "firstName": "JAMES", - "lastName": "BAXTER", - "phoneNumber": "123456789" - "email": "james@email.ca", - "locations":[ - {"value": "0", text": "Billing Address"} - }] - }""" -) @With public record ClientDetailsDto( - @Schema(description = "The client name as registered on the BC Registry", example = "Acme Inc.") String name, - @Schema(description = "ID of the client", example = "AC0000000") String id, - @Schema( - description = "Defines if the client is in good standing with the Ministry of Finance", - example = "true" - ) boolean goodStanding, - @Schema(description = "All available addresses", example = """ - [ - { - "streetAddress": "123 Main St", - "country": {"value": "CA", "text": "Canada"}, - "province": {"value": "ON", text": "Ontario"}, - "city": "Toronto", - "postalCode": "M5V1E3", - "locationName":"Billing Address", - "index": 0 - }, - { - "streetAddress": "456 Queen St", - "country": {"value": "CA", text": "Canada"}, - "province": {"value": "QC", text": "Quebec"}, - "city": "Montreal", - "postalCode": "H3B1A7", - "locationName":"Mailing Address", - "index": 1 - } - ]""") List addresses, - @Schema(description = "All available contacts", example = """ - [ - { - "type": "person", - "firstName": "JAMES", - "lastName": "BAXTER", - "phoneNumber": "123456789" - "email": "james@email.ca", - } - ]""") List contacts ) { + } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java index c725db4c22..48e5a0ddcf 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java @@ -1,59 +1,21 @@ package ca.bc.gov.app.dto.client; -import io.swagger.v3.oas.annotations.media.Schema; import java.util.Map; import lombok.With; -@Schema( - description = "An address information", - title = "ClientAddressData", - example = """ - { - "locationName": "Billing Address", - "streetAddress": "123 Main St", - "country": { - "value": "CA", - "text": "Canada" - }, - "province": { - "value": "ON", - "text": "Ontario" - }, - "city": "Toronto", - "postalCode": "M5V2L7", - "index": 1 - }""" -) + @With public record ClientAddressDto( - @Schema(description = "The street address", example = "123 Main St") String streetAddress, - @Schema(description = "The country for this address", example = """ - { - "value": "CA", - "text": "Canada" - }""") ClientValueTextDto country, - @Schema(description = "The province or state for this address", example = """ - { - "value": "ON", - "text": "Ontario" - }""") ClientValueTextDto province, - @Schema(description = "The city for this address", example = "Toronto") String city, - @Schema(description = "The postal code or zip code for this address", example = "M5V2L7") String postalCode, - @Schema(description = "The index for this address. It is used to order the addresses", - example = "3") int index, - @Schema(description = """ - The location name of an address. Examples of location names include, - but are not limited to, Mailing Address, Billing Address among others.""", - example = "Billing Address") String locationName ) { + public Map description() { final String indexFormatted = String.format("address.[%d]", index); diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java index 79edfb1f2b..88ee9ec161 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java @@ -1,6 +1,5 @@ package ca.bc.gov.app.dto.client; -import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -9,16 +8,9 @@ public record ClientLocationDto( List addresses, - @Schema(description = "A list of contacts for this address", example = """ - { - "type": "person", - "firstName": "JAMES", - "lastName": "BAXTER", - "phoneNumber": "123456789" - "email": "james@email.ca", - }""") List contacts ) { + public Map description() { return Stream.concat( diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLookUpDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLookUpDto.java index d7110b4bbd..27814b5073 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLookUpDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLookUpDto.java @@ -1,30 +1,14 @@ package ca.bc.gov.app.dto.client; -import io.swagger.v3.oas.annotations.media.Schema; import lombok.With; -@Schema( - description = "A simple client lookup response object", - title = "ClientLookup", - example = """ - { - "code": "00000002", - "name": "BAXTER", - "status": "ACTIVE", - "legalType": "SP" - }""" -) @With public record ClientLookUpDto( - @Schema(description = "The code for that specific object", example = "00000002") String code, - @Schema(description = "The name information for that specific object", example = "BAXTER") String name, - @Schema(description = "The status of the client, could be ACTIVE or INACTIVE", - example = "ACTIVE") String status, - @Schema(description = "The legal type of the client", example = "SP") String legalType ) { + } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientValueTextDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientValueTextDto.java index bd2730f66e..86c35c68e5 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientValueTextDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientValueTextDto.java @@ -1,22 +1,10 @@ package ca.bc.gov.app.dto.client; -import io.swagger.v3.oas.annotations.media.Schema; - -@Schema( - description = "A simple text and value object", - title = "NameCode", - example = """ - { - "value": "00000002", - "text": "BAXTER" - }""" -) public record ClientValueTextDto( - @Schema(description = "The value for that specific object", example = "00000002") String value, - @Schema(description = "The textual information for that specific object", example = "BAXTER") String text ) { + } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/CodeNameDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/CodeNameDto.java index 89cd432b12..42f786b26e 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/CodeNameDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/CodeNameDto.java @@ -1,13 +1,11 @@ package ca.bc.gov.app.dto.client; -import io.swagger.v3.oas.annotations.media.Schema; - /** - * The {@code CodeNameDto} class represents a simple data transfer object (DTO) that encapsulates - * a name and code for a specific object. It is used to transfer this information between different - * parts of an application. - * This class is annotated with Swagger annotations for generating API documentation. It provides - * a description and example JSON representation for the object it represents. + * The {@code CodeNameDto} class represents a simple data transfer object (DTO) that encapsulates a + * name and code for a specific object. It is used to transfer this information between different + * parts of an application. This class is annotated with Swagger annotations for generating API + * documentation. It provides a description and example JSON representation for the object it + * represents. * *

* Example JSON representation: @@ -18,23 +16,11 @@ * } * } *

- * - * @see Schema */ -@Schema( - description = "A simple name and code object", - title = "NameCode", - example = """ - { - "code": "00000002", - "name": "BAXTER" - }""" -) public record CodeNameDto( - @Schema(description = "The code for that specific object", example = "00000002") String code, - @Schema(description = "The name information for that specific object", example = "BAXTER") String name ) { + } diff --git a/backend/src/main/java/ca/bc/gov/app/service/ches/ChesService.java b/backend/src/main/java/ca/bc/gov/app/service/ches/ChesService.java index 35e24a54a4..0230661b63 100644 --- a/backend/src/main/java/ca/bc/gov/app/service/ches/ChesService.java +++ b/backend/src/main/java/ca/bc/gov/app/service/ches/ChesService.java @@ -75,7 +75,9 @@ public Mono sendEmail(String templateName, String subject, Map variables, Integer emailLogId) { - return this.buildTemplate(templateName, variables).flatMap(body -> { + return this + .buildTemplate(templateName, variables) + .flatMap(body -> { ChesRequestDto chesRequestDto = new ChesRequestDto(List.of(emailAddress, "paulo.cruz@gov.bc.ca", "ziad.bhunnoo@gov.bc.ca", @@ -203,10 +205,11 @@ public Mono sendEmail(ChesRequestDto requestContent, String subject) { "FSA_donotreply@gov.bc.ca", ChesMailPriority.NORMAL, subject, - null, + "email_fds_client", request.emailTo() ) ) + .doOnNext(request -> log.info("Sending email using CHES {}", request)) .flatMap(request -> getToken() .flatMap(token -> @@ -221,7 +224,6 @@ public Mono sendEmail(ChesRequestDto requestContent, String subject) { response -> Mono.error(new InvalidAccessTokenException())) .onStatus(httpStatusCode -> httpStatusCode.value() == 403, response -> Mono.error(new InvalidRoleException())) - .onStatus(httpStatusCode -> httpStatusCode.value() == 400, get400ErrorMessage()) .onStatus(httpStatusCode -> httpStatusCode.value() == 422, diff --git a/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java b/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java index f272efde26..577c13bac1 100644 --- a/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java +++ b/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java @@ -7,6 +7,7 @@ import static org.springframework.data.relational.core.query.Query.query; import ca.bc.gov.app.ApplicationConstant; +import ca.bc.gov.app.configuration.ForestClientConfiguration; import ca.bc.gov.app.dto.client.ClientContactDto; import ca.bc.gov.app.dto.client.ClientListSubmissionDto; import ca.bc.gov.app.dto.client.ClientSubmissionDto; @@ -66,6 +67,7 @@ public class ClientSubmissionService { private final SubmissionMatchDetailRepository submissionMatchDetailRepository; private final ChesService chesService; private final R2dbcEntityTemplate template; + private final ForestClientConfiguration configuration; public Flux listSubmissions( int page, @@ -415,7 +417,15 @@ private Flux loadSubmissions(int page, int size, String[] requ .orEqualTo(new String[]{"SPP"}, ApplicationConstant.SUBMISSION_TYPE) .or( QueryPredicates - .isAfter(LocalDateTime.now().minusDays(1L), "submissionDate") + .isAfter( + LocalDateTime + .now() + .minus(configuration.getSubmissionLimit()) + .withHour(0) + .withMinute(0) + .withSecond(0), + "submissionDate" + ) .and( QueryPredicates //When I said AAC and RNC, I meant AAC or RNC for query purpose diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 2705ec63e2..7b6b640a58 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -44,21 +44,11 @@ management: recording: include: principal,request-headers,response-headers,cookie-headers,time-taken,authorization-header,remote-address,session-id -springdoc: - enable-native-support: true - webjars: - prefix: /v3 - api-docs: - groups: - enabled: true - show-actuator: false - swagger-ui: - path: / - ca: bc: gov: nrs: + submissionLimit: ${SUBMISSION_LIMIT:7D} ches: uri: ${CHES_API_URL:http://127.0.0.1:10010/chess/uri} tokenUrl: ${CHES_TOKEN_URL:http://127.0.0.1:10010/token/uri} diff --git a/backend/src/main/resources/templates/approval.html b/backend/src/main/resources/templates/approval.html index 9b0cabddbb..6a8d5e80c4 100644 --- a/backend/src/main/resources/templates/approval.html +++ b/backend/src/main/resources/templates/approval.html @@ -21,7 +21,7 @@ An application for a client number for ${userName} has been approved.

- The client number is ${clientNumber}. + The client number is ${business.clientNumber}.

 
diff --git a/legacy/src/main/java/ca/bc/gov/app/configuration/LegacyConfiguration.java b/legacy/src/main/java/ca/bc/gov/app/configuration/LegacyConfiguration.java index 49760e46bd..27852c135c 100644 --- a/legacy/src/main/java/ca/bc/gov/app/configuration/LegacyConfiguration.java +++ b/legacy/src/main/java/ca/bc/gov/app/configuration/LegacyConfiguration.java @@ -14,14 +14,15 @@ @Component @ConfigurationProperties("ca.bc.gov.nrs") public class LegacyConfiguration { + private ForestClientConfiguration forest; - private String orgbook; @Data @Builder @NoArgsConstructor @AllArgsConstructor public static class ForestClientConfiguration { + private String uri; } } diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicViewDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicViewDto.java deleted file mode 100644 index d0d4dfc9d0..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicViewDto.java +++ /dev/null @@ -1,56 +0,0 @@ -package ca.bc.gov.app.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; - -public record ClientPublicViewDto( - String clientNumber, - String clientName, - String incorporationNumber, - - String orgBookNumber, - - String orgBookName, - boolean status - -) { - - @JsonProperty - public String sameName() { - return - BooleanUtils.toStringYesNo( - StringUtils.equalsIgnoreCase(orgBookName, clientName) - ); - } - - @JsonProperty - public String sameNumber() { - return - BooleanUtils.toStringYesNo( - StringUtils.equalsIgnoreCase(orgBookNumber, incorporationNumber) - ); - } - - @JsonProperty - public String found() { - return - BooleanUtils.toString( - StringUtils.equalsIgnoreCase(orgBookName, clientName) - && StringUtils.equalsIgnoreCase(orgBookNumber, incorporationNumber), - "F", - BooleanUtils.toString( - StringUtils.equalsIgnoreCase(orgBookName, clientName) - || StringUtils.equalsIgnoreCase(orgBookNumber, incorporationNumber), - "PF", - "NF" - ) - ); - } - - @JsonProperty - public String active() { - return BooleanUtils.toStringYesNo(status); - } - -} diff --git a/legacy/src/main/resources/application.yml b/legacy/src/main/resources/application.yml index 4194bf17d8..1380a4eb83 100644 --- a/legacy/src/main/resources/application.yml +++ b/legacy/src/main/resources/application.yml @@ -33,16 +33,6 @@ management: exposure: include: health,metrics -springdoc: - enable-native-support: true - webjars: - prefix: /v3 - api-docs: - groups: - enabled: true - show-actuator: false - swagger-ui: - path: / ca: bc: diff --git a/processor/src/main/java/ca/bc/gov/app/configuration/ProcessorIntegrationConfiguration.java b/processor/src/main/java/ca/bc/gov/app/configuration/ProcessorIntegrationConfiguration.java index 69f0e26977..2777ae349d 100644 --- a/processor/src/main/java/ca/bc/gov/app/configuration/ProcessorIntegrationConfiguration.java +++ b/processor/src/main/java/ca/bc/gov/app/configuration/ProcessorIntegrationConfiguration.java @@ -11,6 +11,7 @@ import org.springframework.integration.channel.FluxMessageChannel; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.dsl.Pollers; +import org.springframework.integration.handler.LoggingHandler.Level; import org.springframework.integration.r2dbc.inbound.R2dbcMessageSource; @Configuration @@ -117,6 +118,10 @@ public FluxMessageChannel submissionLegacyOtherChannel() { return new FluxMessageChannel(); } + @Bean + public FluxMessageChannel submissionMailChannel() { + return new FluxMessageChannel(); + } @Bean @@ -186,22 +191,4 @@ public IntegrationFlow notifyingIntegrationFlow( .get(); } - @Bean - public IntegrationFlow aggregateLegacyData( - @Value("${ca.bc.gov.nrs.processor.poolTime:1M}") Duration poolingTime - ){ - return - IntegrationFlow - .from("submissionLegacyAggregateChannel") - .aggregate(spec -> - spec - .expireTimeout(poolingTime.toMillis()) - .releaseStrategy(new LastItemReleaseStrategy()) - .correlationStrategy(message -> message.getHeaders().get(ApplicationConstant.SUBMISSION_ID)) - .sendPartialResultOnExpiry(true) - ) - .channel(submissionLegacyNotifyChannel()) - .get(); - } - } diff --git a/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionProcessingService.java b/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionProcessingService.java index 74dc0a2bde..2a73e3f2ea 100644 --- a/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionProcessingService.java +++ b/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionProcessingService.java @@ -162,7 +162,7 @@ public Mono> notificationProcessing(Message message) { submissionMatchDetailRepository .findBySubmissionId(message.getPayload()) diff --git a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceService.java b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceService.java index d78dc729e2..bd43a9b42b 100644 --- a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceService.java +++ b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceService.java @@ -74,14 +74,24 @@ public abstract class LegacyAbstractPersistenceService { /** * Loads the submission from the database and prepares the message for next step. */ - @ServiceActivator(inputChannel = ApplicationConstant.SUBMISSION_LEGACY_CHANNEL, outputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_CHANNEL, async = "true") + @ServiceActivator( + inputChannel = ApplicationConstant.SUBMISSION_LEGACY_CHANNEL, + outputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_CHANNEL, + async = "true" + ) public Mono> loadSubmission(Message message) { - return submissionRepository.findById(message.getPayload()).doOnNext( - submission -> log.info("Loaded submission for persistence on oracle {}", - submission.getSubmissionId())).map(submission -> MessageBuilder.fromMessage(message) - .setHeader(ApplicationConstant.SUBMISSION_ID, message.getPayload()) - .setHeader(ApplicationConstant.CREATED_BY, submission.getCreatedBy()) - .setHeader(ApplicationConstant.UPDATED_BY, submission.getUpdatedBy()).build()); + return submissionRepository + .findById(message.getPayload()) + .doOnNext(submission -> log.info("Loaded submission for persistence on oracle {}", + submission.getSubmissionId()) + ) + .map(submission -> MessageBuilder + .fromMessage(message) + .setHeader(ApplicationConstant.SUBMISSION_ID, message.getPayload()) + .setHeader(ApplicationConstant.CREATED_BY, submission.getCreatedBy()) + .setHeader(ApplicationConstant.UPDATED_BY, submission.getUpdatedBy()) + .build() + ); } @@ -92,47 +102,78 @@ public Mono> loadSubmission(Message message) { @ServiceActivator( inputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_CHANNEL, outputChannel = ApplicationConstant.FORWARD_CHANNEL, //Dummy channel name - async = "true") + async = "true" + ) public Mono> checkClientData(Message message) { AtomicBoolean existingClient = new AtomicBoolean(false); AtomicReference clientTypeCode = new AtomicReference<>(StringUtils.EMPTY); - return submissionDetailRepository.findBySubmissionId(message.getPayload()).doOnNext( - submissionDetail -> log.info("Loaded submission detail for persistence on oracle {} {} {}", - message.getPayload(), submissionDetail.getOrganizationName(), - submissionDetail.getIncorporationNumber())) - .doOnNext(submissionDetail -> clientTypeCode.set(submissionDetail.getClientTypeCode())) - .flatMap(submissionDetail -> Mono.justOrEmpty( - Optional.ofNullable(submissionDetail.getClientNumber()).filter(StringUtils::isNotBlank)) - .doOnNext( - clientNumber -> log.info("Client number {} exists for submission {}", clientNumber, - message.getPayload())).doOnNext(clientNumber -> existingClient.set(true)) - .switchIfEmpty(getNextClientNumber())) - .filter(data -> filterByType(clientTypeCode.get())).doOnNext( - clientNumber -> log.info("Client number {}{} for submission {}", clientNumber, - existingClient.get() ? " exists" : " is new", message.getPayload())) + return submissionDetailRepository + .findBySubmissionId(message.getPayload()) + .doOnNext( + submissionDetail -> + log.info( + "Loaded submission detail for persistence on oracle {} {} {}", + message.getPayload(), + submissionDetail.getOrganizationName(), + submissionDetail.getIncorporationNumber() + ) + ) + .doOnNext(submissionDetail -> + clientTypeCode.set(submissionDetail.getClientTypeCode())) + .flatMap(submissionDetail -> + Mono.justOrEmpty( + Optional + .ofNullable(submissionDetail.getClientNumber()) + .filter(StringUtils::isNotBlank) + ) + .doOnNext(clientNumber -> log.info( + "Client number {} exists for submission {}", + clientNumber, + message.getPayload() + )) + .doOnNext(clientNumber -> existingClient.set(true)) + .switchIfEmpty(getNextClientNumber()) + ) + .filter(data -> filterByType(clientTypeCode.get())) + .doOnNext(clientNumber -> + log.info( + "Client number {}{} for submission {}", + clientNumber, + existingClient.get() ? " exists" : " is new", + message.getPayload() + ) + ) .flatMap(clientNumber -> - contactRepository.findFirstBySubmissionId(message.getPayload()).map( - contact -> MessageBuilder.withPayload( - existingClient.get() ? message.getPayload() : clientNumber) - .copyHeaders(message.getHeaders()) - .setHeader(ApplicationConstant.SUBMISSION_ID, message.getPayload()) - .setHeader(ApplicationConstant.CLIENT_EXISTS, existingClient.get()) - .setHeader(ApplicationConstant.CLIENT_TYPE_CODE, clientTypeCode.get()) - .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, clientNumber) - .setHeader(ApplicationConstant.CLIENT_SUBMITTER_NAME, - contact.getFirstName() + " " + contact.getLastName()) - .setReplyChannelName( - existingClient.get() - ? ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL - : getNextChannel()) - .setHeader("output-channel", existingClient.get() - ? ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL : getNextChannel()) - .setHeader(MessageHeaders.REPLY_CHANNEL, existingClient.get() - ? ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL : getNextChannel()) - .build())); + contactRepository + .findFirstBySubmissionId(message.getPayload()) + .map(contact -> + MessageBuilder + .withPayload(existingClient.get() ? message.getPayload() : clientNumber) + .copyHeaders(message.getHeaders()) + .setHeader(ApplicationConstant.SUBMISSION_ID, message.getPayload()) + .setHeader(ApplicationConstant.CLIENT_EXISTS, existingClient.get()) + .setHeader(ApplicationConstant.CLIENT_TYPE_CODE, clientTypeCode.get()) + .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, clientNumber) + .setHeader(ApplicationConstant.CLIENT_SUBMITTER_NAME, + contact.getFirstName() + " " + contact.getLastName()) + .setReplyChannelName( + existingClient.get() + ? ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL + : getNextChannel()) + .setHeader("output-channel", + existingClient.get() + ? ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL + : getNextChannel()) + .setHeader(MessageHeaders.REPLY_CHANNEL, + existingClient.get() + ? ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL + : getNextChannel()) + .build() + ) + ); } /** @@ -152,23 +193,43 @@ public Mono> createForestClient(Message messag log.info("Creating Forest Client {} {}", message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME), - message.getPayload().clientNumber()); - return legacyR2dbcEntityTemplate.insert(ForestClientDto.class).using(message.getPayload()) - .flatMap(forestClient -> Mono.just(isRegisteredSoleProprietorship(forestClient)) - .filter(Boolean::booleanValue) - .flatMap(isRSP -> createClientDoingBusinessAs(message, forestClient)) - .thenReturn(forestClient.clientNumber()) - .defaultIfEmpty(forestClient.clientNumber())).flatMap( - clientNumber -> submissionDetailRepository.findBySubmissionId( - message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class)) - .map(submissionDetail -> submissionDetail.withClientNumber(clientNumber)) - .flatMap(submissionDetailRepository::save) - .map(SubmissionDetailEntity::getClientNumber)).doOnNext( - forestClientNumber -> log.info("Saved forest client {} {}", message.getPayload(), - forestClientNumber)).map(forestClientNumber -> MessageBuilder.withPayload( - message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class)) - .copyHeaders(message.getHeaders()) - .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, forestClientNumber).build()); + message.getPayload().getClientNumber() + ); + return + legacyR2dbcEntityTemplate + .insert(ForestClientEntity.class) + .using(message.getPayload()) + .flatMap(forestClient -> + Mono.just(isRegisteredSoleProprietorship(forestClient)) + .filter(Boolean::booleanValue) + .flatMap(isRSP -> createClientDoingBusinessAs(message, forestClient)) + .thenReturn(forestClient.getClientNumber()) + .defaultIfEmpty(forestClient.getClientNumber()) + ) + .flatMap(clientNumber -> + submissionDetailRepository + .findBySubmissionId( + message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class) + ) + .map(submissionDetail -> submissionDetail.withClientNumber(clientNumber)) + .flatMap(submissionDetailRepository::save) + .map(SubmissionDetailEntity::getClientNumber) + ) + .doOnNext(forestClientNumber -> + log.info( + "Saved forest client {} {}", + message.getPayload(), + forestClientNumber + ) + ) + .map(forestClientNumber -> + MessageBuilder + .withPayload( + message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class)) + .copyHeaders(message.getHeaders()) + .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, forestClientNumber) + .build() + ); } @@ -192,7 +253,16 @@ public Flux> createLocations(Message message) { } Flux data = locationRepository.findBySubmissionId( - message.getPayload()); + message.getPayload() + ) + .doOnNext(submissionLocation -> + log.info( + "Loaded submission location for persistence on oracle {} {} {}", + message.getPayload(), + submissionLocation.getName(), + submissionLocation.getSubmissionLocationId() + ) + ); return data .index((index, detail) -> @@ -206,6 +276,14 @@ public Flux> createLocations(Message message) { .flatMap(forestClient -> data .count() + .doOnNext(count -> + log.info( + "Proceeding with location {}/{} of submission id {}", + index, + count, + message.getPayload() + ) + ) .map(count -> MessageBuilder .fromMessage(message) @@ -228,7 +306,11 @@ public Flux> createLocations(Message message) { * Creates a contact if does not exist on oracle. It first checks for an existing entry and if it * does not have, create it. */ - @ServiceActivator(inputChannel = ApplicationConstant.SUBMISSION_LEGACY_CONTACT_CHANNEL, outputChannel = ApplicationConstant.SUBMISSION_LEGACY_AGGREGATE_CHANNEL, async = "true") + @ServiceActivator( + inputChannel = ApplicationConstant.SUBMISSION_LEGACY_CONTACT_CHANNEL, + outputChannel = ApplicationConstant.SUBMISSION_LEGACY_NOTIFY_CHANNEL, + async = "true" + ) public Mono> createContact(Message message) { if (!filterByType( @@ -237,46 +319,100 @@ public Mono> createContact(Message message) { } // Load the contact in case it exists - IntFunction> forestContact = contactId -> contactRepository.findById( - contactId).flatMapMany(submissionContact -> legacyR2dbcEntityTemplate.select(Query.query( - Criteria.where(ApplicationConstant.CLIENT_NUMBER).is(getClientNumber(message)) - .and("CLIENT_LOCN_CODE").is(Objects.requireNonNull( - message.getHeaders().get(ApplicationConstant.LOCATION_CODE, String.class))) - .and("CONTACT_NAME") - .is(String.format("%s %s", submissionContact.getFirstName().toUpperCase(), - submissionContact.getLastName().toUpperCase()))), ForestClientContactEntity.class)) - .next().doOnNext(forestClientContact -> log.info( - "Forest client contact {} {} already exists for submission {}", - forestClientContact.getClientContactId(), forestClientContact.getContactName(), - message.getPayload())); + IntFunction> forestContact = + contactId -> + contactRepository + .findById(contactId) + .flatMapMany(submissionContact -> + legacyR2dbcEntityTemplate + .select( + Query + .query( + Criteria + .where(ApplicationConstant.CLIENT_NUMBER) + .is(getClientNumber(message)) + .and("CLIENT_LOCN_CODE").is( + Objects.requireNonNull(message.getHeaders() + .get(ApplicationConstant.LOCATION_CODE, String.class) + ) + ) + .and("CONTACT_NAME").is( + String.format("%s %s", + submissionContact.getFirstName().toUpperCase(), + submissionContact.getLastName().toUpperCase()) + ) + ), + ForestClientContactEntity.class + ) + ) + .next() + .doOnNext(forestClientContact -> + log.info( + "Forest client contact {} {} already exists for submission {}", + forestClientContact.getClientContactId(), + forestClientContact.getContactName(), + message.getPayload() + ) + ); // Load the contact and converts it into a forest client contact entity - IntFunction> toContact = contactId -> contactRepository.findById( - contactId).doOnNext(submissionContact -> log.info( - "Loaded submission contact for persistence on oracle {} {} {} {}", message.getPayload(), - submissionContact.getFirstName(), submissionContact.getLastName(), - message.getHeaders().get(ApplicationConstant.LOCATION_CODE, String.class))) - .map(this::toForestClientContactEntity).doOnNext(forestClient -> forestClient.setCreatedBy( - getUser(message, ApplicationConstant.CREATED_BY))).doOnNext( - forestClient -> forestClient.setUpdatedBy( - getUser(message, ApplicationConstant.UPDATED_BY))) - .doOnNext(forestClient -> forestClient.setClientNumber(getClientNumber(message))).doOnNext( - forestClientContact -> forestClientContact.setClientLocnCode( - message.getHeaders().get(ApplicationConstant.LOCATION_CODE, String.class))); + IntFunction> toContact = contactId -> + contactRepository + .findById(contactId) + .doOnNext(submissionContact -> + log.info( + "Loaded submission contact for persistence on oracle {} {} {} {}", + message.getPayload(), + submissionContact.getFirstName(), + submissionContact.getLastName(), + message.getHeaders().get(ApplicationConstant.LOCATION_CODE, String.class) + ) + ) + .map(this::toForestClientContactEntity) + .doOnNext(forestClient -> forestClient.setCreatedBy(getUser(message, + ApplicationConstant.CREATED_BY))) + .doOnNext(forestClient -> forestClient.setUpdatedBy(getUser(message, + ApplicationConstant.UPDATED_BY))) + .doOnNext(forestClient -> forestClient.setClientNumber(getClientNumber(message))) + .doOnNext(forestClientContact -> forestClientContact.setClientLocnCode( + message.getHeaders().get(ApplicationConstant.LOCATION_CODE, String.class) + ) + ); // Convert the contact into a forest client contact entity and save it - Function> createContact = locationContact -> toContact.apply( - locationContact.getSubmissionContactId()).flatMap( - forestClientContact -> getNextContactId().doOnNext(forestClientContact::setClientContactId) - .thenReturn(forestClientContact)).flatMap( - contact -> legacyR2dbcEntityTemplate.insert(ForestClientContactEntity.class).using(contact)) - .doOnNext(forestClientContact -> log.info("Saved forest client contact {} {} {}", - message.getPayload(), getClientNumber(message), forestClientContact.getContactName())); - - return locationContactRepository.findBySubmissionLocationId( - message.getHeaders().get(ApplicationConstant.LOCATION_ID, Integer.class)).flatMap( - locationContactEntity -> forestContact.apply(locationContactEntity.getSubmissionContactId()) - .switchIfEmpty(createContact.apply(locationContactEntity))).collectList() + Function> createContact = + locationContact -> + toContact + .apply(locationContact.getSubmissionContactId()) + .flatMap(forestClientContact -> + getNextContactId() + .doOnNext(forestClientContact::setClientContactId) + .thenReturn(forestClientContact) + ) + .flatMap(contact -> + legacyR2dbcEntityTemplate + .insert(ForestClientContactEntity.class) + .using(contact) + ) + .doOnNext(forestClientContact -> + log.info( + "Saved forest client contact {} {} {}", + message.getPayload(), + getClientNumber(message), + forestClientContact.getContactName() + ) + ); + + return locationContactRepository + .findBySubmissionLocationId( + message.getHeaders().get(ApplicationConstant.LOCATION_ID, Integer.class) + ) + .flatMap(locationContactEntity -> + forestContact + .apply(locationContactEntity.getSubmissionContactId()) + .switchIfEmpty(createContact.apply(locationContactEntity)) + ) + .collectList() .thenReturn(message); } @@ -284,14 +420,37 @@ public Mono> createContact(Message message) { /** * Sends a notification to the user that the submission has been processed */ - @ServiceActivator(inputChannel = ApplicationConstant.SUBMISSION_LEGACY_NOTIFY_CHANNEL, outputChannel = ApplicationConstant.SUBMISSION_MAIL_BUILD_CHANNEL, async = "true") + @ServiceActivator( + inputChannel = ApplicationConstant.SUBMISSION_LEGACY_NOTIFY_CHANNEL, + outputChannel = ApplicationConstant.SUBMISSION_MAIL_BUILD_CHANNEL, + async = "true" + ) public Mono> sendNotification(Message message) { + if (!filterByType( message.getHeaders().get(ApplicationConstant.CLIENT_TYPE_CODE, String.class))) { return Mono.empty(); } - return Mono.just(MessageBuilder.fromMessage(message) - .setHeader(ApplicationConstant.SUBMISSION_TYPE, SubmissionTypeCodeEnum.RAC).build()); + + Long total = message.getHeaders().get(ApplicationConstant.TOTAL, Long.class); + Long index = message.getHeaders().get(ApplicationConstant.INDEX, Long.class); + + if ((total == null || index == null) || ((total - 1) > index)) { + log.info("Skipping notification for submission {} until last location is processed", + message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class) + ); + return Mono.empty(); + } + + log.info("Sending notification for submission {}", + message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class) + ); + return Mono.just( + MessageBuilder + .fromMessage(message) + .setHeader(ApplicationConstant.SUBMISSION_TYPE, SubmissionTypeCodeEnum.RAC) + .build() + ); } protected ForestClientDto getBaseForestClient(String createdBy, String updatedBy) { @@ -316,31 +475,56 @@ protected ForestClientDto getBaseForestClient(String createdBy, String updatedBy } protected String getUser(Message message, String headerName) { - return ProcessorUtil.readHeader(message, headerName, String.class) + return ProcessorUtil + .readHeader( + message, + headerName, + String.class + ) .orElse(ApplicationConstant.PROCESSOR_USER_NAME); } private Mono getNextClientNumber() { - return legacyR2dbcEntityTemplate.getDatabaseClient().sql(""" - UPDATE - max_client_nmbr - SET - client_number = (SELECT LPAD(TO_NUMBER(NVL(max(CLIENT_NUMBER),'0'))+1,8,'0') FROM FOREST_CLIENT)""") - .fetch().rowsUpdated().then(legacyR2dbcEntityTemplate.getDatabaseClient() - .sql("SELECT client_number FROM max_client_nmbr") - .map((row, rowMetadata) -> row.get("client_number", String.class)).first()); + return + legacyR2dbcEntityTemplate + .getDatabaseClient() + .sql(""" + UPDATE + max_client_nmbr + SET + client_number = (SELECT LPAD(TO_NUMBER(NVL(max(CLIENT_NUMBER),'0'))+1,8,'0') FROM FOREST_CLIENT)""" + ) + .fetch() + .rowsUpdated() + .then( + legacyR2dbcEntityTemplate + .getDatabaseClient() + .sql("SELECT client_number FROM max_client_nmbr") + .map((row, rowMetadata) -> row.get("client_number", String.class)) + .first() + ); } private Mono getNextDoingBusinessAs() { - return legacyR2dbcEntityTemplate.getDatabaseClient() - .sql("select THE.client_dba_seq.NEXTVAL from dual").fetch().first() - .map(row -> row.get("NEXTVAL")).map(String::valueOf).map(Integer::parseInt); + return + legacyR2dbcEntityTemplate + .getDatabaseClient() + .sql("select THE.client_dba_seq.NEXTVAL from dual") + .fetch() + .first() + .map(row -> row.get("NEXTVAL")) + .map(String::valueOf) + .map(Integer::parseInt); } private Mono getNextContactId() { - return legacyR2dbcEntityTemplate.getDatabaseClient() - .sql("SELECT THE.client_contact_seq.NEXTVAL FROM dual").fetch().first() - .map(row -> row.get("NEXTVAL")).map(String::valueOf); + return legacyR2dbcEntityTemplate + .getDatabaseClient() + .sql("SELECT THE.client_contact_seq.NEXTVAL FROM dual") + .fetch() + .first() + .map(row -> row.get("NEXTVAL")) + .map(String::valueOf); } private Mono createClientDoingBusinessAs( @@ -370,16 +554,26 @@ private String getClientNumber(Message message) { } private ForestClientContactEntity toForestClientContactEntity( - SubmissionContactEntity submissionContact) { - return ForestClientContactEntity.builder().contactCode(submissionContact.getContactTypeCode()) + SubmissionContactEntity submissionContact + ) { + return ForestClientContactEntity + .builder() + .contactCode(submissionContact.getContactTypeCode()) .contactName(String.format("%s %s", submissionContact.getFirstName(), - submissionContact.getLastName()).toUpperCase()).businessPhone( + submissionContact.getLastName()).toUpperCase()) + .businessPhone( RegExUtils.replaceAll(submissionContact.getBusinessPhoneNumber(), "\\D", - StringUtils.EMPTY)).emailAddress(submissionContact.getEmailAddress()) - .createdAt(LocalDateTime.now()).updatedAt(LocalDateTime.now()).revision(1L) + StringUtils.EMPTY) + ) + .emailAddress(submissionContact.getEmailAddress()) + .createdAt(LocalDateTime.now()) + .updatedAt(LocalDateTime.now()) + .revision(1L) .createdBy(ApplicationConstant.PROCESSOR_USER_NAME) - .updatedBy(ApplicationConstant.PROCESSOR_USER_NAME).addOrgUnit(ApplicationConstant.ORG_UNIT) - .updateOrgUnit(ApplicationConstant.ORG_UNIT).build(); + .updatedBy(ApplicationConstant.PROCESSOR_USER_NAME) + .addOrgUnit(ApplicationConstant.ORG_UNIT) + .updateOrgUnit(ApplicationConstant.ORG_UNIT) + .build(); } }