diff --git a/.github/workflows/merge-main.yml b/.github/workflows/merge-main.yml
index 4ecef383d8..4f80e9699b 100644
--- a/.github/workflows/merge-main.yml
+++ b/.github/workflows/merge-main.yml
@@ -297,6 +297,7 @@ jobs:
-p ZONE=${{ env.ZONE }} -p NAME=${{ github.event.repository.name }}
-p PROMOTE=${{ github.repository }}/processor:${{ env.ZONE }}
-p URL_ZONE=${{ env.ZONE }}
+ -p BCREGISTRY_URI='https://bcregistry-prod.apigee.net'
image-promotions:
name: Promote images to PROD
@@ -449,3 +450,4 @@ jobs:
-p ZONE=${{ env.ZONE }} -p NAME=${{ github.event.repository.name }}
-p PROMOTE=${{ github.repository }}/processor:${{ env.PREV }}
-p URL_ZONE=${{ env.ZONE }}
+ -p BCREGISTRY_URI='https://bcregistry-prod.apigee.net'
diff --git a/.github/workflows/pr-open.yml b/.github/workflows/pr-open.yml
index 00e91c29f4..c4bc0fd775 100644
--- a/.github/workflows/pr-open.yml
+++ b/.github/workflows/pr-open.yml
@@ -256,6 +256,7 @@ jobs:
-p ZONE=${{ github.event.number }} -p NAME=${{ github.event.repository.name }}
-p PROMOTE=${{ github.repository }}/processor:${{ github.event.number }}
-p URL_ZONE=$((${{ github.event.number }} % 50))
+ -p BCREGISTRY_URI='https://bcregistry-prod.apigee.net'
cypress-run:
name: "User flow test"
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index caea7e445b..fea9f860ae 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -20,7 +20,7 @@ concurrency:
jobs:
tests-java:
- name: Integrated Tests
+ name: Backend Tests
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
runs-on: ubuntu-22.04
steps:
@@ -70,7 +70,7 @@ jobs:
-Dsonar.projectKey=nr-forest-client_processor
-Dsonar.coverage.jacoco.xmlReportPaths=target/coverage-reports/merged-test-report/jacoco.xml
-Dsonar.java.checkstyle.reportPaths=target/checkstyle-result.xml
- -Dsonar.coverage.exclusions=**/configuration/**,**/dto/**,**/entity/**,**/repository/**,**/*$*Builder*,**/ProcessApplication***/ApplicationConstant*
+ -Dsonar.coverage.exclusions=**/configuration/**,**/dto/**,**/exception/**,**/entity/**,**/repository/**,**/*$*Builder*,**/ProcessApplication***/ApplicationConstant*
sonar_project_token: ${{ secrets.SONAR_TOKEN_PROCESSOR }}
- name: Archive CycloneDX
diff --git a/backend/pom.xml b/backend/pom.xml
index 523c33f6cc..7fed6d9c60 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -138,8 +138,8 @@
test
- com.github.tomakehurst
- wiremock-jre8-standalone
+ org.wiremock
+ wiremock-standalone
3.0.1
test
diff --git a/frontend/src/assets/styles/global.scss b/frontend/src/assets/styles/global.scss
index 908525dbc9..11d30f3322 100644
--- a/frontend/src/assets/styles/global.scss
+++ b/frontend/src/assets/styles/global.scss
@@ -43,6 +43,7 @@
--light-theme-miscellaneous-interactive: #0073e6;
--light-theme-background-background-selected: #93939533;
--light-theme-text-text-disabled: rgba(19, 19, 21, 0.25);
+ --light-theme-text-text-on-color: #FFFFFF;
//Buttons
--cds-button-disabled: #c6c6c8;
@@ -296,6 +297,7 @@ div#app {
align-items: center;
background: var(--light-theme-layer-layer-02, #fff);
flex-grow: 1;
+ margin-top: 3.5rem;
}
.full {
@@ -1005,6 +1007,15 @@ cds-header-global-action {
background: var(--light-theme-layer-layer-02, #FFF) !important;
}
+cds-header-menu-button::part(svg) {
+ width: 1rem;
+ height: 1rem;
+}
+
+cds-header-menu-button:not([active])::part(svg) {
+ fill: var(--light-theme-text-text-on-color, #FFF);
+}
+
cds-header-global-action svg {
fill: var(--dark-theme-focus-focus);
}
diff --git a/frontend/src/components/MainHeaderComponent.vue b/frontend/src/components/MainHeaderComponent.vue
index 5555dce6b4..d4c0ecf348 100644
--- a/frontend/src/components/MainHeaderComponent.vue
+++ b/frontend/src/components/MainHeaderComponent.vue
@@ -99,7 +99,9 @@ const onClickLogout = () => {
+ button-label-inactive="Open menu"
+ v-shadow="2"
+ >
diff --git a/legacy/pom.xml b/legacy/pom.xml
index 519d15438b..f5f55504e9 100644
--- a/legacy/pom.xml
+++ b/legacy/pom.xml
@@ -150,8 +150,8 @@
test
- com.github.tomakehurst
- wiremock-jre8-standalone
+ org.wiremock
+ wiremock-standalone
3.0.1
test
diff --git a/processor/openshift.deploy.yml b/processor/openshift.deploy.yml
index a90c9ba3c0..f3670728cb 100644
--- a/processor/openshift.deploy.yml
+++ b/processor/openshift.deploy.yml
@@ -40,6 +40,9 @@ parameters:
- name: URL_ZONE
description: Zone to use for URL
required: true
+ - name: BCREGISTRY_URI
+ description: Bc Registry API address
+ required: true
objects:
- apiVersion: v1
kind: ImageStream
@@ -195,6 +198,18 @@ objects:
value: 30S
- name: TZ
value: America/Vancouver
+ - name: BCREGISTRY_URI
+ value: ${BCREGISTRY_URI}
+ - name: BCREGISTRY_KEY
+ valueFrom:
+ secretKeyRef:
+ name: ${NAME}-${ZONE}
+ key: bcregistry-key
+ - name: BCREGISTRY_ACCOUNT
+ valueFrom:
+ secretKeyRef:
+ name: ${NAME}-${ZONE}
+ key: bcregistry-account
ports:
- containerPort: 3000
protocol: TCP
diff --git a/processor/pom.xml b/processor/pom.xml
index bf91d2c1da..0ff61af729 100644
--- a/processor/pom.xml
+++ b/processor/pom.xml
@@ -160,9 +160,10 @@
test
- com.github.tomakehurst
- wiremock-jre8-standalone
+ org.wiremock
+ wiremock-standalone
3.0.1
+ test
diff --git a/processor/src/main/java/ca/bc/gov/app/ApplicationConstant.java b/processor/src/main/java/ca/bc/gov/app/ApplicationConstant.java
index f5d30eb1c6..eb9a163154 100644
--- a/processor/src/main/java/ca/bc/gov/app/ApplicationConstant.java
+++ b/processor/src/main/java/ca/bc/gov/app/ApplicationConstant.java
@@ -1,5 +1,9 @@
package ca.bc.gov.app;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentAccessRequestDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentAccessTypeDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentRequestBodyDto;
+import java.util.List;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@@ -17,6 +21,7 @@ public final class ApplicationConstant {
public static final String REVIEW_CHANNEL = "reviewChannel";
public static final String SUBMISSION_MAIL_CHANNEL = "submissionMailChannel";
public static final String SUBMISSION_LEGACY_CLIENT_CHANNEL = "submissionLegacyClientChannel";
+ public static final String SUBMISSION_LEGACY_CLIENT_PERSIST_CHANNEL = "submissionLegacyClientPersistChannel";
public static final String SUBMISSION_LEGACY_LOCATION_CHANNEL = "submissionLegacyLocationChannel";
public static final String SUBMISSION_LEGACY_CONTACT_CHANNEL = "submissionLegacyContactChannel";
public static final String SUBMISSION_LEGACY_AGGREGATE_CHANNEL = "submissionLegacyAggregateChannel";
@@ -42,4 +47,20 @@ public final class ApplicationConstant {
public static final String LOCATION_CODE = "locationCode";
public static final String SUBMISSION_MAIL_BUILD_CHANNEL = "submissionMailBuildChannel";
public static final String CLIENT_NUMBER = "CLIENT_NUMBER";
+ public static final String CLIENT_TYPE_CODE = "CLIENT_TYPE_CODE";
+ public static final String SUBMISSION_LEGACY_INDIVIDUAL_CHANNEL = "submissionLegacyIndividualChannel";
+ public static final String SUBMISSION_LEGACY_USP_CHANNEL = "submissionLegacyUSPChannel";
+ public static final String SUBMISSION_LEGACY_RSP_CHANNEL = "submissionLegacyRSPChannel";
+ public static final String SUBMISSION_LEGACY_OTHER_CHANNEL = "submissionLegacyOtherChannel";
+ public static final String CLIENT_EXISTS = "client-exists";
+
+ public static final BcRegistryDocumentRequestBodyDto
+ BUSINESS_SUMMARY_FILING_HISTORY =
+ new BcRegistryDocumentRequestBodyDto(
+ new BcRegistryDocumentAccessRequestDto(
+ List.of(
+ new BcRegistryDocumentAccessTypeDto("BUSINESS_SUMMARY_FILING_HISTORY")
+ )
+ )
+ );
}
diff --git a/processor/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java b/processor/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java
index e9ce5068ba..130553a648 100644
--- a/processor/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java
+++ b/processor/src/main/java/ca/bc/gov/app/configuration/ForestClientConfiguration.java
@@ -27,6 +27,9 @@ public class ForestClientConfiguration {
@NestedConfigurationProperty
private BackendConfiguration backend;
+ @NestedConfigurationProperty
+ private BcRegistryConfiguration bcregistry;
+
@Data
@Builder
@NoArgsConstructor
@@ -43,4 +46,18 @@ public static class BackendConfiguration {
private String uri;
}
+ /**
+ * The BC Registry configuration.
+ */
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class BcRegistryConfiguration {
+
+ private String uri;
+ private String apiKey;
+ private String accountId;
+ }
+
}
diff --git a/processor/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java b/processor/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java
index c8d3bda245..471171bf6a 100644
--- a/processor/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java
+++ b/processor/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java
@@ -25,4 +25,20 @@ public WebClient forestClientApi(ForestClientConfiguration configuration) {
.build();
}
+ /**
+ * Returns a configured instance of WebClient for accessing the BC Registry API.
+ *
+ * @param configuration The configuration for the ForestClient.
+ * @return A configured instance of WebClient for accessing the BC Registry API.
+ */
+ @Bean
+ public WebClient bcRegistryApi(ForestClientConfiguration configuration) {
+ return WebClient
+ .builder()
+ .baseUrl(configuration.getBcregistry().getUri())
+ .defaultHeader("x-apikey", configuration.getBcregistry().getApiKey())
+ .defaultHeader("Account-Id", configuration.getBcregistry().getAccountId())
+ .build();
+ }
+
}
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 fcbe464450..69f0e26977 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
@@ -92,6 +92,32 @@ public FluxMessageChannel submissionLegacyNotifyChannel() {
return new FluxMessageChannel();
}
+ @Bean
+ public FluxMessageChannel submissionLegacyClientPersistChannel() {
+ return new FluxMessageChannel();
+ }
+
+ @Bean
+ public FluxMessageChannel submissionLegacyIndividualChannel() {
+ return new FluxMessageChannel();
+ }
+
+ @Bean
+ public FluxMessageChannel submissionLegacyUSPChannel() {
+ return new FluxMessageChannel();
+ }
+
+ @Bean
+ public FluxMessageChannel submissionLegacyRSPChannel() {
+ return new FluxMessageChannel();
+ }
+
+ @Bean
+ public FluxMessageChannel submissionLegacyOtherChannel() {
+ return new FluxMessageChannel();
+ }
+
+
@Bean
public R2dbcMessageSource submissionMessages(
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/SubmissionInformationDto.java b/processor/src/main/java/ca/bc/gov/app/dto/SubmissionInformationDto.java
index ed0f7faac8..8dbbdb7c85 100644
--- a/processor/src/main/java/ca/bc/gov/app/dto/SubmissionInformationDto.java
+++ b/processor/src/main/java/ca/bc/gov/app/dto/SubmissionInformationDto.java
@@ -1,11 +1,14 @@
package ca.bc.gov.app.dto;
+import java.time.LocalDate;
import lombok.With;
@With
public record SubmissionInformationDto(
- String legalName,
+ String corporationName,
+ LocalDate dateOfBirth,
String incorporationNumber,
- String goodStanding
+ String goodStanding,
+ String clientType
) {
}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentAccessRequestDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentAccessRequestDto.java
new file mode 100644
index 0000000000..6f553306dd
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentAccessRequestDto.java
@@ -0,0 +1,12 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.util.List;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryDocumentAccessRequestDto(
+ List documents
+) {
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentAccessTypeDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentAccessTypeDto.java
new file mode 100644
index 0000000000..5f03073856
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentAccessTypeDto.java
@@ -0,0 +1,13 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryDocumentAccessTypeDto(
+ @JsonProperty("type")
+ String documentType
+) {
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentDto.java
new file mode 100644
index 0000000000..3ac6d5f7cc
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentDto.java
@@ -0,0 +1,23 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.util.List;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryDocumentDto(
+ List parties
+) {
+
+ public BcRegistryPartyDto getProprietor() {
+ if (parties == null) {
+ return null;
+ }
+ return parties
+ .stream()
+ .filter(BcRegistryPartyDto::isProprietor)
+ .findFirst()
+ .orElse(null);
+ }
+}
\ No newline at end of file
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestBodyDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestBodyDto.java
new file mode 100644
index 0000000000..c4cbcaa44d
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestBodyDto.java
@@ -0,0 +1,11 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryDocumentRequestBodyDto(
+ BcRegistryDocumentAccessRequestDto documentAccessRequest
+) {
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestDocumentDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestDocumentDto.java
new file mode 100644
index 0000000000..cde4ef9e06
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestDocumentDto.java
@@ -0,0 +1,14 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryDocumentRequestDocumentDto(
+ String documentKey,
+ String documentType,
+ String fileName,
+ Long id
+) {
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestResponseDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestResponseDto.java
new file mode 100644
index 0000000000..ef00c42a5e
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryDocumentRequestResponseDto.java
@@ -0,0 +1,16 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.util.List;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryDocumentRequestResponseDto(
+ String businessIdentifier,
+ String businessName,
+ List documents,
+ String paymentStatus,
+ String status
+) {
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryExceptionMessageDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryExceptionMessageDto.java
new file mode 100644
index 0000000000..0126c1bcf2
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryExceptionMessageDto.java
@@ -0,0 +1,12 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryExceptionMessageDto(
+ String errorMessage,
+ String rootCause
+) {
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryOfficerDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryOfficerDto.java
new file mode 100644
index 0000000000..880c75b761
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryOfficerDto.java
@@ -0,0 +1,13 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryOfficerDto(
+ String email,
+ String firstName,
+ String lastName,
+ String middleInitial,
+ String partyType
+) {
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryPartyDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryPartyDto.java
new file mode 100644
index 0000000000..ee2ce9aa19
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryPartyDto.java
@@ -0,0 +1,24 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.util.List;
+import lombok.With;
+import org.apache.commons.lang3.StringUtils;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryPartyDto(
+ BcRegistryOfficerDto officer,
+ List roles
+) {
+
+ public boolean isProprietor() {
+ if (roles == null) {
+ return false;
+ }
+ return roles
+ .stream()
+ .filter(BcRegistryRoleDto::active)
+ .anyMatch(role -> StringUtils.equalsIgnoreCase(role.roleType(), "Proprietor"));
+ }
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryRoleDto.java b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryRoleDto.java
new file mode 100644
index 0000000000..debea97e3e
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/dto/bcregistry/BcRegistryRoleDto.java
@@ -0,0 +1,17 @@
+package ca.bc.gov.app.dto.bcregistry;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.time.LocalDate;
+import lombok.With;
+
+@With
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record BcRegistryRoleDto(
+ LocalDate appointmentDate,
+ LocalDate cessationDate,
+ String roleType
+) {
+ public boolean active() {
+ return cessationDate == null || LocalDate.now().isBefore(cessationDate);
+ }
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/entity/client/SubmissionDetailEntity.java b/processor/src/main/java/ca/bc/gov/app/entity/client/SubmissionDetailEntity.java
index 481981a2dd..1a9d54db4c 100644
--- a/processor/src/main/java/ca/bc/gov/app/entity/client/SubmissionDetailEntity.java
+++ b/processor/src/main/java/ca/bc/gov/app/entity/client/SubmissionDetailEntity.java
@@ -1,12 +1,14 @@
package ca.bc.gov.app.entity.client;
import ca.bc.gov.app.ApplicationConstant;
+import java.time.LocalDate;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.With;
import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.Transient;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@@ -42,4 +44,7 @@ public class SubmissionDetailEntity {
@Column("good_standing_ind")
private String goodStandingInd;
+
+ @Column("birthdate")
+ private LocalDate birthdate;
}
diff --git a/processor/src/main/java/ca/bc/gov/app/entity/legacy/ClientDoingBusinessAsEntity.java b/processor/src/main/java/ca/bc/gov/app/entity/legacy/ClientDoingBusinessAsEntity.java
new file mode 100644
index 0000000000..a93c71283e
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/entity/legacy/ClientDoingBusinessAsEntity.java
@@ -0,0 +1,46 @@
+package ca.bc.gov.app.entity.legacy;
+
+import java.time.LocalDateTime;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.With;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.relational.core.mapping.Column;
+import org.springframework.data.relational.core.mapping.Table;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+@Builder
+@With
+@Table(name = "CLIENT_DOING_BUSINESS_AS", schema = "THE")
+public class ClientDoingBusinessAsEntity {
+
+ @Id
+ @Column("CLIENT_DBA_ID")
+ private Integer id;
+
+ @Column("CLIENT_NUMBER")
+ private String clientNumber;
+
+ @Column("DOING_BUSINESS_AS_NAME")
+ private String doingBusinessAsName;
+
+ @Column("ADD_TIMESTAMP")
+ private LocalDateTime createdAt;
+ @Column("ADD_USERID")
+ private String createdBy;
+ @Column("UPDATE_TIMESTAMP")
+ private LocalDateTime updatedAt;
+ @Column("UPDATE_USERID")
+ private String updatedBy;
+ @Column("UPDATE_ORG_UNIT")
+ private Long updateOrgUnit;
+ @Column("ADD_ORG_UNIT")
+ private Long addOrgUnit;
+ @Column("REVISION_COUNT")
+ private Long revision;
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/exception/InvalidAccessTokenException.java b/processor/src/main/java/ca/bc/gov/app/exception/InvalidAccessTokenException.java
new file mode 100644
index 0000000000..7d1c09c0ea
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/exception/InvalidAccessTokenException.java
@@ -0,0 +1,14 @@
+package ca.bc.gov.app.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.server.ResponseStatusException;
+
+@ResponseStatus(HttpStatus.UNAUTHORIZED)
+public class InvalidAccessTokenException extends ResponseStatusException {
+
+ public InvalidAccessTokenException() {
+ super(HttpStatus.UNAUTHORIZED, "Provided access token is missing or invalid");
+ }
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/exception/NoClientDataFound.java b/processor/src/main/java/ca/bc/gov/app/exception/NoClientDataFound.java
new file mode 100644
index 0000000000..68b0312708
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/exception/NoClientDataFound.java
@@ -0,0 +1,15 @@
+package ca.bc.gov.app.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.server.ResponseStatusException;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class NoClientDataFound extends ResponseStatusException {
+
+ public NoClientDataFound(String clientNumber) {
+ super(HttpStatus.NOT_FOUND,
+ String.format("No data found for client number %s", clientNumber));
+ }
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/repository/legacy/ClientDoingBusinessAsRepository.java b/processor/src/main/java/ca/bc/gov/app/repository/legacy/ClientDoingBusinessAsRepository.java
new file mode 100644
index 0000000000..a88b803025
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/repository/legacy/ClientDoingBusinessAsRepository.java
@@ -0,0 +1,25 @@
+package ca.bc.gov.app.repository.legacy;
+
+import ca.bc.gov.app.entity.legacy.ClientDoingBusinessAsEntity;
+import org.springframework.data.r2dbc.repository.Query;
+import org.springframework.data.repository.reactive.ReactiveCrudRepository;
+import org.springframework.data.repository.reactive.ReactiveSortingRepository;
+import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Repository
+public interface ClientDoingBusinessAsRepository extends
+ ReactiveCrudRepository,
+ ReactiveSortingRepository {
+
+ Mono existsByClientNumber(String clientNumber);
+
+ @Query("""
+ SELECT *
+ FROM THE.CLIENT_DOING_BUSINESS_AS
+ WHERE
+ UTL_MATCH.JARO_WINKLER_SIMILARITY(UPPER(DOING_BUSINESS_AS_NAME),UPPER(:companyName)) >= 95
+ ORDER BY CLIENT_NUMBER""")
+ Flux matchBy(String companyName);
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/repository/legacy/ForestClientRepository.java b/processor/src/main/java/ca/bc/gov/app/repository/legacy/ForestClientRepository.java
index 98bb558ca3..a58b118b61 100644
--- a/processor/src/main/java/ca/bc/gov/app/repository/legacy/ForestClientRepository.java
+++ b/processor/src/main/java/ca/bc/gov/app/repository/legacy/ForestClientRepository.java
@@ -1,6 +1,7 @@
package ca.bc.gov.app.repository.legacy;
import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import java.time.LocalDateTime;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
@@ -31,4 +32,16 @@ public interface ForestClientRepository extends ReactiveCrudRepository findByIncorporationNumber(String incorporationNumber);
+ @Query("""
+ SELECT *
+ FROM THE.FOREST_CLIENT
+ WHERE
+ UPPER(LEGAL_FIRST_NAME) = UPPER(:firstName)
+ AND UPPER(CLIENT_NAME) = UPPER(:lastName)
+ AND BIRTHDATE = :dob
+ AND CLIENT_STATUS_CODE = 'ACT'
+ AND CLIENT_TYPE_CODE = 'I'
+ ORDER BY CLIENT_NUMBER""")
+ Flux findByIndividual(String firstName, String lastName, LocalDateTime dob);
+
}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/bcregistry/BcRegistryService.java b/processor/src/main/java/ca/bc/gov/app/service/bcregistry/BcRegistryService.java
new file mode 100644
index 0000000000..62f6a917b4
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/bcregistry/BcRegistryService.java
@@ -0,0 +1,113 @@
+package ca.bc.gov.app.service.bcregistry;
+
+import static ca.bc.gov.app.ApplicationConstant.BUSINESS_SUMMARY_FILING_HISTORY;
+
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentRequestDocumentDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentRequestResponseDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryExceptionMessageDto;
+import ca.bc.gov.app.exception.InvalidAccessTokenException;
+import ca.bc.gov.app.exception.NoClientDataFound;
+import java.util.Map;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.HttpStatusCode;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Slf4j
+@Service
+public class BcRegistryService {
+
+ private final WebClient bcRegistryApi;
+
+ public BcRegistryService(@Qualifier("bcRegistryApi") WebClient bcRegistryApi) {
+ this.bcRegistryApi = bcRegistryApi;
+ }
+
+ /**
+ * Sends a request to retrieve the document data for a given value using the BC Registry API. The
+ * method returns a Flux of {@link BcRegistryDocumentDto}, which represents the document data.
+ *
+ * @param value the value used to identify the document data
+ * @return a Flux of {@link BcRegistryDocumentDto} representing the requested document data
+ * @throws NoClientDataFound if the API responds with a 404 status code indicating that
+ * no data was found for the given value
+ * @throws InvalidAccessTokenException if the API responds with a 401 status code indicating that
+ * the access token used for the request is invalid
+ */
+ public Flux requestDocumentData(String value) {
+ log.info("Requesting document for {}", value);
+ return
+ bcRegistryApi
+ .post()
+ .uri("/registry-search/api/v1/businesses/{identifier}/documents/requests",
+ Map.of("identifier", value)
+ )
+ .accept(MediaType.APPLICATION_JSON)
+ .body(BodyInserters.fromValue(BUSINESS_SUMMARY_FILING_HISTORY))
+ .retrieve()
+ // handle different HTTP error codes
+ .onStatus(
+ statusCode -> statusCode.isSameCodeAs(HttpStatusCode.valueOf(404)),
+ exception -> Mono.error(new NoClientDataFound(value))
+ )
+ .onStatus(
+ statusCode -> statusCode.isSameCodeAs(HttpStatusCode.valueOf(401)),
+ exception -> Mono.error(new InvalidAccessTokenException())
+ )
+ .onStatus(
+ statusCode -> statusCode.isSameCodeAs(HttpStatusCode.valueOf(400)),
+ exception ->
+ exception
+ .bodyToMono(BcRegistryExceptionMessageDto.class)
+ .map(BcRegistryExceptionMessageDto::rootCause)
+ .doOnNext(
+ message -> log.error("Error while requesting data for {} -- {}", value,
+ message))
+ .map(message -> message.contains("not found"))
+ .filter(message -> message)
+ .switchIfEmpty(Mono.error(new InvalidAccessTokenException()))
+ .flatMap(message -> Mono.error(new NoClientDataFound(value)))
+
+ )
+ .bodyToMono(BcRegistryDocumentRequestResponseDto.class)
+ .flatMapIterable(BcRegistryDocumentRequestResponseDto::documents)
+ .map(BcRegistryDocumentRequestDocumentDto::documentKey)
+ .doOnNext(documentKey -> log.info("Loading document {} for identifier {}", documentKey,
+ value))
+ .flatMap(documentKey -> getDocumentData(value, documentKey));
+ }
+
+ private Mono getDocumentData(String identifier, String documentKey) {
+ return
+ bcRegistryApi
+ .get()
+ .uri("/registry-search/api/v1/businesses/{identifier}/documents/{documentKey}",
+ Map.of("identifier", identifier, "documentKey", documentKey)
+ )
+ .accept(MediaType.APPLICATION_JSON)
+ .retrieve()
+ // handle different HTTP error codes
+ .onStatus(
+ statusCode -> statusCode.isSameCodeAs(HttpStatusCode.valueOf(404)),
+ exception -> Mono.error(new NoClientDataFound(identifier))
+ )
+ .onStatus(
+ statusCode -> statusCode.isSameCodeAs(HttpStatusCode.valueOf(401)),
+ exception -> Mono.error(new InvalidAccessTokenException())
+ )
+ .onStatus(
+ statusCode -> statusCode.isSameCodeAs(HttpStatusCode.valueOf(400)),
+ exception -> Mono.error(new InvalidAccessTokenException())
+ )
+ .bodyToMono(BcRegistryDocumentDto.class)
+ .doOnNext(
+ document -> log.info("Document loaded for {} {} as {}", identifier, documentKey,
+ document));
+ }
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionAutoProcessingService.java b/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionAutoProcessingService.java
index d7f7e1fd82..e268fe8659 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionAutoProcessingService.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionAutoProcessingService.java
@@ -33,15 +33,15 @@ public class ClientSubmissionAutoProcessingService {
private final SubmissionRepository submissionRepository;
private final SubmissionMatchDetailRepository submissionMatchDetailRepository;
+ /**
+ * This method is responsible for marking the submission as approved
+ * and sending to the nexty step.
+ */
@ServiceActivator(
inputChannel = ApplicationConstant.AUTO_APPROVE_CHANNEL,
outputChannel = ApplicationConstant.SUBMISSION_POSTPROCESSOR_CHANNEL,
async = "true"
)
- /**
- * This method is responsible for marking the submission as approved
- * and sending to the nexty step.
- */
public Mono> approved(Message> message) {
int submissionId =
Objects.requireNonNull(
@@ -69,14 +69,14 @@ public Mono> approved(Message> message) {
}
+ /**
+ * This method is responsible for marking the submission as processed
+ */
@ServiceActivator(
inputChannel = ApplicationConstant.SUBMISSION_COMPLETION_CHANNEL,
outputChannel = ApplicationConstant.SUBMISSION_MAIL_CHANNEL,
async = "true"
)
- /**
- * This method is responsible for marking the submission as processed
- */
public Mono> completeProcessing(Message message) {
return
submissionMatchDetailRepository
@@ -88,14 +88,14 @@ public Mono> completeProcessing(Message> reviewed(Message> message) {
return
persistData(
diff --git a/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionLoadingService.java b/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionLoadingService.java
index a6c82ace80..9505bb9ebe 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionLoadingService.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionLoadingService.java
@@ -5,8 +5,8 @@
import ca.bc.gov.app.dto.SubmissionInformationDto;
import ca.bc.gov.app.repository.client.SubmissionContactRepository;
import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import java.time.LocalDate;
import java.util.Map;
-import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.integration.annotation.ServiceActivator;
@@ -15,25 +15,27 @@
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
-@Service
-@RequiredArgsConstructor
-@Slf4j
+
/**
* This class is responsible for loading the submission details and submission contact details
*/
+@Service
+@RequiredArgsConstructor
+@Slf4j
public class ClientSubmissionLoadingService {
private final SubmissionDetailRepository submissionDetailRepository;
private final SubmissionContactRepository contactRepository;
+
+ /**
+ * Load the submission details to be processed later on
+ */
@ServiceActivator(
inputChannel = ApplicationConstant.SUBMISSION_LIST_CHANNEL,
outputChannel = ApplicationConstant.MATCH_CHECKING_CHANNEL,
async = "true"
)
- /**
- * Load the submission details to be processed later on
- */
public Mono> loadSubmissionDetails(Integer submissionId) {
return
@@ -43,8 +45,10 @@ public Mono> loadSubmissionDetails(Integer sub
//Grab what we need for the match part
.map(details -> new SubmissionInformationDto(
details.getOrganizationName(),
+ details.getBirthdate(),
details.getIncorporationNumber(),
- details.getGoodStandingInd()
+ details.getGoodStandingInd(),
+ details.getClientTypeCode()
)
)
@@ -57,14 +61,15 @@ public Mono> loadSubmissionDetails(Integer sub
);
}
+
+ /**
+ * Build the email request dto to be sent to the email service
+ */
@ServiceActivator(
inputChannel = ApplicationConstant.SUBMISSION_MAIL_BUILD_CHANNEL,
outputChannel = ApplicationConstant.SUBMISSION_MAIL_CHANNEL,
async = "true"
)
- /**
- * Build the email request dto to be sent to the email service
- */
public Mono> sendNotification(Message message) {
return
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 8490bd858b..74dc0a2bde 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
@@ -31,16 +31,18 @@ public class ClientSubmissionProcessingService {
private final SubmissionMatchDetailRepository submissionMatchDetailRepository;
private final SubmissionContactRepository contactRepository;
+
+ /**
+ * This method will process the submission and send the notification to the user.
+ */
@ServiceActivator(
inputChannel = ApplicationConstant.SUBMISSION_POSTPROCESSOR_CHANNEL,
outputChannel = ApplicationConstant.NOTIFICATION_PROCESSING_CHANNEL,
async = "true"
)
- /**
- * This method will process the submission and send the notification to the user.
- */
public Mono> processSubmission(
- Message submissionMessage) {
+ Message submissionMessage
+ ) {
Integer submissionId = submissionMessage.getPayload();
return
@@ -73,15 +75,16 @@ public Mono> processSubmission(
);
}
+
+ /**
+ * This method will process the submission and send the notification to the user.
+ */
+ @SuppressWarnings("java:S1452")
@ServiceActivator(
inputChannel = ApplicationConstant.NOTIFICATION_PROCESSING_CHANNEL,
outputChannel = ApplicationConstant.FORWARD_CHANNEL,
async = "true"
)
- /**
- * This method will process the submission and send the notification to the user.
- */
- @SuppressWarnings("java:S1452")
public Mono> notificationProcessing(Message message) {
SubmissionStatusEnum status = ProcessorUtil.readHeader(message,
@@ -159,4 +162,13 @@ public Mono> notificationProcessing(Message message) {
+ submissionMatchDetailRepository
+ .findBySubmissionId(message.getPayload())
+ .map(match -> match.withProcessed(true))
+ .flatMap(submissionMatchDetailRepository::save)
+ .subscribe(match -> log.info("Updated match for submission {}", match.getSubmissionId()));
+ }
+
}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyPersistenceService.java b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceService.java
similarity index 64%
rename from processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyPersistenceService.java
rename to processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceService.java
index 3da13ea433..08b5cda4e9 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyPersistenceService.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceService.java
@@ -1,13 +1,14 @@
-
package ca.bc.gov.app.service.legacy;
+import static java.util.function.Predicate.not;
+
import ca.bc.gov.app.ApplicationConstant;
-import ca.bc.gov.app.dto.EmailRequestDto;
import ca.bc.gov.app.entity.client.SubmissionContactEntity;
import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
import ca.bc.gov.app.entity.client.SubmissionLocationContactEntity;
import ca.bc.gov.app.entity.client.SubmissionLocationEntity;
import ca.bc.gov.app.entity.client.SubmissionTypeCodeEnum;
+import ca.bc.gov.app.entity.legacy.ClientDoingBusinessAsEntity;
import ca.bc.gov.app.entity.legacy.ForestClientContactEntity;
import ca.bc.gov.app.entity.legacy.ForestClientEntity;
import ca.bc.gov.app.entity.legacy.ForestClientLocationEntity;
@@ -17,7 +18,7 @@
import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
import ca.bc.gov.app.repository.client.SubmissionRepository;
-import ca.bc.gov.app.repository.legacy.ForestClientContactRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
import ca.bc.gov.app.util.ProcessorUtil;
import jakarta.annotation.PostConstruct;
import java.time.LocalDateTime;
@@ -25,9 +26,12 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.IntFunction;
+import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RegExUtils;
@@ -35,38 +39,48 @@
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
-import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-@Service
-@Slf4j
-@RequiredArgsConstructor
/**
* This class is responsible for persisting the submission into the legacy database.
*/
-public class LegacyPersistenceService {
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public abstract class LegacyAbstractPersistenceService {
+ @Getter
private final SubmissionDetailRepository submissionDetailRepository;
private final SubmissionRepository submissionRepository;
private final SubmissionLocationRepository locationRepository;
+ @Getter
private final SubmissionContactRepository contactRepository;
private final SubmissionLocationContactRepository locationContactRepository;
private final R2dbcEntityOperations legacyR2dbcEntityTemplate;
private final CountryCodeRepository countryCodeRepository;
+ private final ClientDoingBusinessAsRepository doingBusinessAsRepository;
private final Map countryList = new HashMap<>();
- @PostConstruct
+
+ abstract Mono> generateForestClient(Message message);
+
+ abstract boolean filterByType(String clientTypeCode);
+
+ abstract String getNextChannel();
+
/**
* Loads the country list from the database.
*/
+ @PostConstruct
public void setUp() {
countryCodeRepository
.findAll()
@@ -80,15 +94,14 @@ public void setUp() {
.subscribe();
}
-
+ /**
+ * 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"
)
- /**
- * Loads the submission from the database and prepares the message for next step.
- */
public Mono> loadSubmission(Message message) {
return submissionRepository
.findById(message.getPayload())
@@ -105,18 +118,21 @@ public Mono> loadSubmission(Message message) {
}
+ /**
+ * Checks if the client number exists for that submission and prepares the message for next step.
+ * The next step will be identified and handled by individual channels
+ */
@ServiceActivator(
inputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_CHANNEL,
- outputChannel = ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL,
+ outputChannel = ApplicationConstant.FORWARD_CHANNEL, //Dummy channel name
async = "true"
)
- /**
- * Creates a client if does not exist on oracle and get back the client number.
- */
- public Mono> createForestClient(Message message) {
+ public Mono> checkClientData(Message message) {
+
+ AtomicBoolean existingClient = new AtomicBoolean(false);
+ AtomicReference clientTypeCode = new AtomicReference<>(StringUtils.EMPTY);
- // Load the details of the submission
- Mono submission = submissionDetailRepository
+ return submissionDetailRepository
.findBySubmissionId(message.getPayload())
.doOnNext(
submissionDetail ->
@@ -126,63 +142,91 @@ public Mono> createForestClient(Message message) {
submissionDetail.getOrganizationName(),
submissionDetail.getIncorporationNumber()
)
- );
-
- // Checks if the client number exists for that submission
- Mono clientExists = submission
- .flatMap(submissionDetail -> Mono.justOrEmpty(
- Optional.ofNullable(submissionDetail.getClientNumber())
- )
)
+ .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 {} exists for submission {}",
+ "Client number {}{} for submission {}",
clientNumber,
+ existingClient.get() ? " exists" : " is new",
message.getPayload()
)
+ )
+ .map(clientNumber ->
+ 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)
+ .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()
);
+ }
- // Convert the submission into a forest client entity
- Mono client = submission
- .map(this::toForestClientEntity)
- .doOnNext(forestClient -> forestClient.setCreatedBy(getUser(message,
- ApplicationConstant.CREATED_BY)))
- .doOnNext(forestClient -> forestClient.setUpdatedBy(getUser(message,
- ApplicationConstant.UPDATED_BY)));
+ /**
+ * Creates a client if does not exist on oracle and get back the client number.
+ */
+ @ServiceActivator(
+ inputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_PERSIST_CHANNEL,
+ outputChannel = ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL,
+ async = "true"
+ )
+ public Mono> createForestClient(Message message) {
- // Grabs the next forest client number for insertion
- Mono nextClientNumber = legacyR2dbcEntityTemplate
- .selectOne(
- Query
- .empty()
- .sort(Sort.by(Direction.DESC, ApplicationConstant.CLIENT_NUMBER))
- .limit(1),
- ForestClientEntity.class
- )
- .map(ForestClientEntity::getClientNumber)
- .map(lastForestClientNumber -> String.format("%08d",
- Integer.parseInt(lastForestClientNumber) + 1)
- );
+ if (!filterByType(
+ message.getHeaders().get(ApplicationConstant.CLIENT_TYPE_CODE, String.class))) {
+ return Mono.empty();
+ }
- // Saves the forest client entity and gets the client number and updates on the database
- Mono savedClient =
- nextClientNumber
- .flatMap(clientNumber ->
- client
- .doOnNext(forestClient -> forestClient.setClientNumber(clientNumber))
- .flatMap(forestClient ->
- legacyR2dbcEntityTemplate
- .insert(ForestClientEntity.class)
- .using(forestClient)
- )
+ log.info("Creating Forest Client {} {}",
+ message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME),
+ 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())
)
- .map(ForestClientEntity::getClientNumber)
.flatMap(clientNumber ->
submissionDetailRepository
- .findBySubmissionId(message.getPayload())
+ .findBySubmissionId(
+ message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class)
+ )
.map(submissionDetail -> submissionDetail.withClientNumber(clientNumber))
.flatMap(submissionDetailRepository::save)
- .map(submissionDetail -> clientNumber)
+ .map(SubmissionDetailEntity::getClientNumber)
)
.doOnNext(forestClientNumber ->
log.info(
@@ -190,39 +234,33 @@ public Mono> createForestClient(Message message) {
message.getPayload(),
forestClientNumber
)
- );
-
- return
- // If the clients number already exists, move on, else do the save
- clientExists
- .switchIfEmpty(savedClient)
- // Get the details and prepare the message for next step
- .flatMap(forestClientNumber ->
- submission
- .map(forestClientDetail ->
- MessageBuilder
- .fromMessage(message)
- .copyHeaders(message.getHeaders())
- .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, forestClientNumber)
- .setHeader(ApplicationConstant.FOREST_CLIENT_NAME,
- forestClientDetail.getOrganizationName())
- .setHeader(ApplicationConstant.INCORPORATION_NUMBER,
- forestClientDetail.getIncorporationNumber())
- .build()
- )
+ )
+ .map(forestClientNumber ->
+ MessageBuilder
+ .withPayload(
+ message.getHeaders().get(ApplicationConstant.SUBMISSION_ID, Integer.class))
+ .copyHeaders(message.getHeaders())
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, forestClientNumber)
+ .build()
);
}
+
+ /**
+ * Creates a location if does not exist on oracle.
+ */
@ServiceActivator(
inputChannel = ApplicationConstant.SUBMISSION_LEGACY_LOCATION_CHANNEL,
outputChannel = ApplicationConstant.SUBMISSION_LEGACY_CONTACT_CHANNEL,
async = "true"
)
- /**
- * Creates a location if does not exist on oracle.
- */
public Flux> createLocations(Message message) {
+ if (!filterByType(
+ message.getHeaders().get(ApplicationConstant.CLIENT_TYPE_CODE, String.class))) {
+ return Flux.empty();
+ }
+
Flux data = locationRepository.findBySubmissionId(
message.getPayload()
);
@@ -301,17 +339,22 @@ 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"
)
- /**
- * Creates a contact if does not exist on oracle.
- * It first checks for an existing entry and if it does not have, create it.
- */
public Mono> createContact(Message message) {
+ if (!filterByType(
+ message.getHeaders().get(ApplicationConstant.CLIENT_TYPE_CODE, String.class))) {
+ return Mono.empty();
+ }
+
// Load the contact in case it exists
IntFunction> forestContact =
contactId ->
@@ -323,7 +366,8 @@ public Mono> createContact(Message message) {
Query
.query(
Criteria
- .where(ApplicationConstant.CLIENT_NUMBER).is(getClientNumber(message))
+ .where(ApplicationConstant.CLIENT_NUMBER)
+ .is(getClientNumber(message))
.and("CLIENT_LOCN_CODE").is(
Objects.requireNonNull(message.getHeaders()
.get(ApplicationConstant.LOCATION_CODE, String.class)
@@ -347,7 +391,7 @@ public Mono> createContact(Message message) {
);
// Load the next contact id
- Mono nextContactId = legacyR2dbcEntityTemplate
+ IntFunction> nextContactId = increment -> legacyR2dbcEntityTemplate
.selectOne(
Query
.empty()
@@ -357,7 +401,7 @@ public Mono> createContact(Message message) {
)
.map(ForestClientContactEntity::getClientContactId)
.map(lastForestClientContactId -> String.valueOf(
- Integer.parseInt(lastForestClientContactId) + 1));
+ Integer.parseInt(lastForestClientContactId) + increment));
// Load the contact and converts it into a forest client contact entity
IntFunction> toContact = contactId ->
@@ -384,50 +428,63 @@ public Mono> createContact(Message message) {
);
// Convert the contact into a forest client contact entity and save it
- Function> createContact = locationContact ->
- toContact
- .apply(locationContact.getSubmissionContactId())
- .flatMap(forestClientContact ->
- nextContactId
- .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()
+ BiFunction> createContact =
+ (locationContact, increment) ->
+ toContact
+ .apply(locationContact.getSubmissionContactId())
+ .flatMap(forestClientContact ->
+ nextContactId
+ .apply(increment)
+ .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(locationContact ->
+ .index()
+ .flatMap(locationContactTuple ->
forestContact
- .apply(locationContact.getSubmissionContactId())
- .switchIfEmpty(createContact.apply(locationContact))
+ .apply(locationContactTuple.getT2().getSubmissionContactId())
+ .switchIfEmpty(
+ createContact
+ .apply(
+ locationContactTuple.getT2(),
+ locationContactTuple.getT1().intValue() + 1
+ )
+ )
)
.collectList()
.thenReturn(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"
)
- /**
- * Sends a notification to the user that the submission has been processed
- */
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)
@@ -436,27 +493,14 @@ public Mono> sendNotification(Message message) {
);
}
-
- private ForestClientEntity toForestClientEntity(
- SubmissionDetailEntity submissionDetail
+ protected ForestClientEntity getBaseForestClient(
+ String createdBy,
+ String updatedBy
) {
return ForestClientEntity
.builder()
.clientNumber("000")
- .legalFirstName(null)
- .legalMiddleName(null)
- .clientIdTypeCode(null)
- .clientIdentification(null)
- .clientAcronym(null)
- .wcbFirmNumber(null)
- .ocgSupplierNmbr(null)
- .clientComment(null)
.clientStatusCode("ACT")
- .clientName(submissionDetail.getOrganizationName().toUpperCase())
- .clientTypeCode(submissionDetail.getClientTypeCode())
- .registryCompanyTypeCode(
- ProcessorUtil.extractLetters(submissionDetail.getIncorporationNumber()))
- .corpRegnNmbr(ProcessorUtil.extractNumbers(submissionDetail.getIncorporationNumber()))
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.revision(1L)
@@ -464,9 +508,94 @@ private ForestClientEntity toForestClientEntity(
.updatedBy(ApplicationConstant.PROCESSOR_USER_NAME)
.addOrgUnit(ApplicationConstant.ORG_UNIT)
.updateOrgUnit(ApplicationConstant.ORG_UNIT)
+ .createdBy(createdBy)
+ .updatedBy(updatedBy)
.build();
}
+
+ protected String getUser(Message> message, String headerName) {
+ return ProcessorUtil
+ .readHeader(
+ message,
+ headerName,
+ String.class
+ )
+ .orElse(ApplicationConstant.PROCESSOR_USER_NAME);
+ }
+
+ private Mono getNextClientNumber() {
+ return legacyR2dbcEntityTemplate
+ .selectOne(
+ Query
+ .empty()
+ .sort(Sort.by(Direction.DESC, ApplicationConstant.CLIENT_NUMBER))
+ .limit(1),
+ ForestClientEntity.class
+ )
+ .map(ForestClientEntity::getClientNumber)
+ .map(lastForestClientNumber -> String.format("%08d",
+ Integer.parseInt(lastForestClientNumber) + 1)
+ );
+ }
+
+ private Mono getNextDoingBusinessAs() {
+ return legacyR2dbcEntityTemplate
+ .selectOne(
+ Query
+ .empty()
+ .sort(Sort.by(Direction.DESC, "CLIENT_DBA_ID"))
+ .limit(1),
+ ClientDoingBusinessAsEntity.class
+ )
+ .map(ClientDoingBusinessAsEntity::getId)
+ .map(lastId -> lastId + 1);
+ }
+
+ private Mono createClientDoingBusinessAs(
+ Message message, ForestClientEntity forestClient) {
+ return doingBusinessAsRepository
+ .existsByClientNumber(forestClient.getClientNumber())
+ .filter(not(Boolean::booleanValue))
+ .flatMap(doesNotExist -> getNextDoingBusinessAs())
+ .map(nextId ->
+ ClientDoingBusinessAsEntity
+ .builder()
+ .id(nextId)
+ .clientNumber(forestClient.getClientNumber())
+ .doingBusinessAsName(message
+ .getHeaders()
+ .get(ApplicationConstant.FOREST_CLIENT_NAME,
+ String.class)
+ )
+ .revision(1L)
+ .createdBy(ApplicationConstant.PROCESSOR_USER_NAME)
+ .createdAt(LocalDateTime.now())
+ .updatedBy(ApplicationConstant.PROCESSOR_USER_NAME)
+ .updatedAt(LocalDateTime.now())
+ .addOrgUnit(ApplicationConstant.ORG_UNIT)
+ .updateOrgUnit(ApplicationConstant.ORG_UNIT)
+ .build()
+ )
+ .flatMap(doingBusinessAs ->
+ legacyR2dbcEntityTemplate
+ .insert(ClientDoingBusinessAsEntity.class)
+ .using(doingBusinessAs)
+ );
+ }
+
+ private boolean isRegisteredSoleProprietorship(ForestClientEntity forestClient) {
+ return forestClient
+ .getClientTypeCode()
+ .equalsIgnoreCase("I")
+ &&
+ StringUtils.equalsIgnoreCase(
+ forestClient
+ .getClientIdTypeCode(),
+ "OTHR"
+ );
+ }
+
private Mono toForestClientLocationEntity(
long index,
SubmissionLocationEntity submissionLocation
@@ -506,6 +635,16 @@ private Mono toForestClientLocationEntity(
);
}
+ private String getClientNumber(Message> message) {
+ return ProcessorUtil
+ .readHeader(
+ message,
+ ApplicationConstant.FOREST_CLIENT_NUMBER,
+ String.class
+ )
+ .orElse(StringUtils.EMPTY);
+ }
+
private ForestClientContactEntity toForestClientContactEntity(
SubmissionContactEntity submissionContact
) {
@@ -514,8 +653,10 @@ private ForestClientContactEntity toForestClientContactEntity(
.contactCode(submissionContact.getContactTypeCode())
.contactName(String.format("%s %s", submissionContact.getFirstName(),
submissionContact.getLastName()).toUpperCase())
- .businessPhone(RegExUtils.replaceAll(submissionContact.getBusinessPhoneNumber(), "\\D",
- StringUtils.EMPTY))
+ .businessPhone(
+ RegExUtils.replaceAll(submissionContact.getBusinessPhoneNumber(), "\\D",
+ StringUtils.EMPTY)
+ )
.emailAddress(submissionContact.getEmailAddress())
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
@@ -527,26 +668,4 @@ private ForestClientContactEntity toForestClientContactEntity(
.build();
}
- private String getUser(Message> message, String headerName) {
- return ProcessorUtil
- .readHeader(
- message,
- headerName,
- String.class
- )
- .orElse(ApplicationConstant.PROCESSOR_USER_NAME);
- }
-
- private String getClientNumber(Message> message) {
- return ProcessorUtil
- .readHeader(
- message,
- ApplicationConstant.FOREST_CLIENT_NUMBER,
- String.class
- )
- .orElse(StringUtils.EMPTY);
- }
-
}
-
-
diff --git a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyClientPersistenceService.java b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyClientPersistenceService.java
new file mode 100644
index 0000000000..52fc087e57
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyClientPersistenceService.java
@@ -0,0 +1,122 @@
+
+package ca.bc.gov.app.service.legacy;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import ca.bc.gov.app.util.ProcessorUtil;
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.messaging.Message;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+
+/**
+ * This class is responsible for persisting the submission into the legacy database.
+ */
+@Service
+@Slf4j
+public class LegacyClientPersistenceService extends LegacyAbstractPersistenceService {
+
+ public LegacyClientPersistenceService(
+ SubmissionDetailRepository submissionDetailRepository,
+ SubmissionRepository submissionRepository,
+ SubmissionLocationRepository locationRepository,
+ SubmissionContactRepository contactRepository,
+ SubmissionLocationContactRepository locationContactRepository,
+ R2dbcEntityOperations legacyR2dbcEntityTemplate,
+ CountryCodeRepository countryCodeRepository,
+ ClientDoingBusinessAsRepository doingBusinessAsRepository
+ ) {
+ super(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository
+ );
+ }
+
+ /**
+ * This method is responsible for filtering the submission based on the type.
+ *
+ * @param clientTypeCode - the client type code.
+ * @return - true if the type is not RSP, USP or I, otherwise false.
+ */
+ @Override
+ boolean filterByType(String clientTypeCode) {
+ return !List.of("RSP", "USP", "I").contains(clientTypeCode);
+ }
+
+ @Override
+ String getNextChannel() {
+ return ApplicationConstant.SUBMISSION_LEGACY_OTHER_CHANNEL;
+ }
+
+ @ServiceActivator(
+ inputChannel = ApplicationConstant.SUBMISSION_LEGACY_OTHER_CHANNEL,
+ outputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_PERSIST_CHANNEL,
+ async = "true"
+ )
+ @Override
+ public Mono> generateForestClient(Message message) {
+ return
+ getSubmissionDetailRepository()
+ .findBySubmissionId(
+ message
+ .getHeaders()
+ .get(ApplicationConstant.SUBMISSION_ID, Integer.class)
+ )
+ .map(submissionDetail ->
+ getBaseForestClient(
+ getUser(message, ApplicationConstant.CREATED_BY),
+ getUser(message, ApplicationConstant.UPDATED_BY)
+ )
+ .withClientComment(
+ "Client details acquired from BC Registry " +
+ submissionDetail.getIncorporationNumber()
+ )
+ .withClientName(submissionDetail.getOrganizationName().toUpperCase())
+ .withClientTypeCode(submissionDetail.getClientTypeCode())
+ .withRegistryCompanyTypeCode(
+ ProcessorUtil.extractLetters(submissionDetail.getIncorporationNumber())
+ )
+ .withCorpRegnNmbr(
+ ProcessorUtil.extractNumbers(submissionDetail.getIncorporationNumber())
+ )
+ .withClientNumber(message.getHeaders()
+ .get(ApplicationConstant.FOREST_CLIENT_NUMBER, String.class))
+ )
+ .map(forestClient ->
+ MessageBuilder
+ .withPayload(forestClient)
+ .copyHeaders(message.getHeaders())
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NAME,
+ forestClient.getClientName()
+ )
+ .setHeader(ApplicationConstant.INCORPORATION_NUMBER,
+ String.join(StringUtils.EMPTY,
+ forestClient.getRegistryCompanyTypeCode(),
+ forestClient.getCorpRegnNmbr()
+ )
+ )
+ .build()
+ );
+
+ }
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyIndividualPersistenceService.java b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyIndividualPersistenceService.java
new file mode 100644
index 0000000000..77e51f9560
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyIndividualPersistenceService.java
@@ -0,0 +1,115 @@
+
+package ca.bc.gov.app.service.legacy;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import ca.bc.gov.app.util.ProcessorUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.messaging.Message;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+
+/**
+ * This class is responsible for persisting the submission of individuals into the legacy database.
+ */
+@Service
+@Slf4j
+public class LegacyIndividualPersistenceService extends LegacyAbstractPersistenceService {
+
+ public LegacyIndividualPersistenceService(
+ SubmissionDetailRepository submissionDetailRepository,
+ SubmissionRepository submissionRepository,
+ SubmissionLocationRepository locationRepository,
+ SubmissionContactRepository contactRepository,
+ SubmissionLocationContactRepository locationContactRepository,
+ R2dbcEntityOperations legacyR2dbcEntityTemplate,
+ CountryCodeRepository countryCodeRepository,
+ ClientDoingBusinessAsRepository doingBusinessAsRepository
+ ) {
+ super(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository
+ );
+ }
+
+ /**
+ * This method is responsible for filtering the submission based on the type.
+ * @param clientTypeCode - the client type code.
+ * @return - true if the type is I, otherwise false.
+ */
+ @Override
+ boolean filterByType(String clientTypeCode) {
+ return StringUtils.equalsIgnoreCase(clientTypeCode,"I");
+ }
+
+ @Override
+ String getNextChannel() {
+ return ApplicationConstant.SUBMISSION_LEGACY_INDIVIDUAL_CHANNEL;
+ }
+
+ /**
+ * Generate the individual to be persisted into forest client database.
+ */
+ @ServiceActivator(
+ inputChannel = ApplicationConstant.SUBMISSION_LEGACY_INDIVIDUAL_CHANNEL,
+ outputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_PERSIST_CHANNEL,
+ async = "true"
+ )
+ @Override
+ public Mono> generateForestClient(Message message) {
+ return
+ getSubmissionDetailRepository()
+ .findBySubmissionId(
+ message
+ .getHeaders()
+ .get(ApplicationConstant.SUBMISSION_ID, Integer.class)
+ )
+ .map(detailEntity ->
+ getBaseForestClient(
+ getUser(message, ApplicationConstant.CREATED_BY),
+ getUser(message, ApplicationConstant.UPDATED_BY)
+ )
+ .withLegalFirstName(ProcessorUtil.splitName(detailEntity.getOrganizationName())[1].toUpperCase())
+ .withClientName(ProcessorUtil.splitName(detailEntity.getOrganizationName())[0].toUpperCase())
+ .withClientComment("Individual with data acquired from BC Services Card")
+ .withClientTypeCode("I")
+ .withClientNumber(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER, String.class))
+ )
+ .map(forestClient ->
+ MessageBuilder
+ .withPayload(forestClient)
+ .copyHeaders(message.getHeaders())
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NAME,
+ String.join(" ",
+ forestClient.getLegalFirstName(),
+ forestClient.getClientName()
+ )
+ )
+ .setHeader(ApplicationConstant.INCORPORATION_NUMBER,
+ "not applicable")
+ .build()
+ );
+ }
+
+
+}
+
+
diff --git a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyLoadingService.java b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyLoadingService.java
index 940fd53410..3271d46a75 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyLoadingService.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyLoadingService.java
@@ -56,6 +56,7 @@ public Mono>> matchCheck(
public Mono> validateSubmission(SubmissionInformationDto message) {
return Flux
.fromIterable(matchers)
+ .filter(matcher -> matcher.enabled(message))
.doOnNext(matcher -> log.info("Running {}", matcher.name()))
//If matcher returns empty, all good, if not, it is a problem
.flatMap(matcher -> matcher.matches(message))
diff --git a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyRegisteredSPPersistenceService.java b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyRegisteredSPPersistenceService.java
new file mode 100644
index 0000000000..213ffda263
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyRegisteredSPPersistenceService.java
@@ -0,0 +1,184 @@
+
+package ca.bc.gov.app.service.legacy;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryPartyDto;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import ca.bc.gov.app.service.bcregistry.BcRegistryService;
+import ca.bc.gov.app.util.ProcessorUtil;
+import java.util.Optional;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.messaging.Message;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+import reactor.util.function.Tuple2;
+
+
+/**
+ * This class is responsible for persisting the submission of registered sole proprietorship into
+ * the legacy database.
+ */
+@Service
+@Slf4j
+public class LegacyRegisteredSPPersistenceService extends LegacyAbstractPersistenceService {
+
+ private final BcRegistryService bcRegistryService;
+
+ public LegacyRegisteredSPPersistenceService(
+ SubmissionDetailRepository submissionDetailRepository,
+ SubmissionRepository submissionRepository,
+ SubmissionLocationRepository locationRepository,
+ SubmissionContactRepository contactRepository,
+ SubmissionLocationContactRepository locationContactRepository,
+ R2dbcEntityOperations legacyR2dbcEntityTemplate,
+ CountryCodeRepository countryCodeRepository,
+ ClientDoingBusinessAsRepository doingBusinessAsRepository,
+ BcRegistryService bcRegistryService
+ ) {
+ super(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository
+ );
+ this.bcRegistryService = bcRegistryService;
+ }
+
+ /**
+ * This method is responsible for filtering the submission based on the type.
+ *
+ * @param clientTypeCode - the client type code.
+ * @return - true if the type is RSP, otherwise false.
+ */
+ @Override
+ boolean filterByType(String clientTypeCode) {
+ return StringUtils.equalsIgnoreCase(clientTypeCode, "RSP");
+ }
+
+ @Override
+ String getNextChannel() {
+ return ApplicationConstant.SUBMISSION_LEGACY_RSP_CHANNEL;
+ }
+
+ @ServiceActivator(
+ inputChannel = ApplicationConstant.SUBMISSION_LEGACY_RSP_CHANNEL,
+ outputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_PERSIST_CHANNEL,
+ async = "true"
+ )
+ @Override
+ public Mono> generateForestClient(Message message) {
+
+ return
+ getSubmissionDetailRepository()
+ .findBySubmissionId(
+ message
+ .getHeaders()
+ .get(ApplicationConstant.SUBMISSION_ID, Integer.class)
+ )
+ .map(submissionDetail ->
+ getBaseForestClient(
+ getUser(message, ApplicationConstant.CREATED_BY),
+ getUser(message, ApplicationConstant.UPDATED_BY)
+ )
+ .withClientIdentification(submissionDetail.getIncorporationNumber())
+ .withClientComment(
+ String.join(" ",
+ "Sole proprietorship registered on BC Registry with number",
+ submissionDetail.getIncorporationNumber(),
+ "and company name",
+ submissionDetail.getOrganizationName().toUpperCase()
+ )
+ )
+ .withRegistryCompanyTypeCode(ProcessorUtil.extractLetters(
+ submissionDetail.getIncorporationNumber()))
+ .withCorpRegnNmbr(ProcessorUtil.extractNumbers(
+ submissionDetail.getIncorporationNumber()))
+ )
+ //Load the details to set the remaining fields
+ .flatMap(forestClient ->
+ bcRegistryService
+ .requestDocumentData(forestClient.getClientIdentification())
+ // Should only be one
+ .next()
+ // Get the proprietor or empty if none
+ .flatMap(document ->
+ Mono.justOrEmpty(
+ Optional.ofNullable(
+ document.getProprietor()
+ )
+ )
+ )
+ .map(BcRegistryPartyDto::officer)
+ .map(contact ->
+ new String[]{
+ contact.firstName().toUpperCase(),
+ contact.lastName().toUpperCase()
+ })
+ .switchIfEmpty(
+ //In case of negative results from BC Registry (rare)
+ // load from contacts as a fallback
+ getContactRepository()
+ //Get all contacts for the submission
+ .findBySubmissionId(
+ message
+ .getHeaders()
+ .get(ApplicationConstant.SUBMISSION_ID, Integer.class)
+ )
+ //Handle as a flux with the index
+ .index()
+ //Only deal with the first 2
+ .filter(index -> index.getT1() < 2)
+ .map(Tuple2::getT2)
+ .map(contact -> new String[]{
+ contact.getFirstName().toUpperCase(),
+ contact.getLastName().toUpperCase()
+ })
+ //Grab the last, as it should cover the case of the second being removed
+ .last()
+ )
+ .map(contact ->
+ forestClient
+ .withLegalFirstName(contact[0])
+ .withClientName(contact[1])
+ .withClientTypeCode("I")
+ .withClientIdTypeCode("OTHR")
+ .withClientNumber(message.getHeaders()
+ .get(ApplicationConstant.FOREST_CLIENT_NUMBER, String.class))
+ )
+ )
+ .map(forestClient ->
+ MessageBuilder
+ .withPayload(forestClient)
+ .copyHeaders(message.getHeaders())
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NAME,
+ forestClient
+ .getClientComment()
+ .split("and company name ")[1]
+ )
+ .setHeader(ApplicationConstant.INCORPORATION_NUMBER,
+ String.join(StringUtils.EMPTY,
+ forestClient.getRegistryCompanyTypeCode(),
+ forestClient.getCorpRegnNmbr()
+ )
+ )
+ .build()
+ );
+
+ }
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyUnregisteredSPPersistenceService.java b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyUnregisteredSPPersistenceService.java
new file mode 100644
index 0000000000..a4d24d4714
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/legacy/LegacyUnregisteredSPPersistenceService.java
@@ -0,0 +1,129 @@
+
+package ca.bc.gov.app.service.legacy;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import ca.bc.gov.app.util.ProcessorUtil;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.messaging.Message;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+
+/**
+ * This class is responsible for persisting the submission of unregistered sole proprietorship
+ * into the legacy database.
+ */
+@Service
+@Slf4j
+public class LegacyUnregisteredSPPersistenceService extends LegacyAbstractPersistenceService {
+
+ public LegacyUnregisteredSPPersistenceService(
+ SubmissionDetailRepository submissionDetailRepository,
+ SubmissionRepository submissionRepository,
+ SubmissionLocationRepository locationRepository,
+ SubmissionContactRepository contactRepository,
+ SubmissionLocationContactRepository locationContactRepository,
+ R2dbcEntityOperations legacyR2dbcEntityTemplate,
+ CountryCodeRepository countryCodeRepository,
+ ClientDoingBusinessAsRepository doingBusinessAsRepository
+ ) {
+ super(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository
+ );
+ }
+
+ /**
+ * This method is responsible for filtering the submission based on the type.
+ * @param clientTypeCode - the client type code.
+ * @return - true if the type is USP, otherwise false.
+ */
+ @Override
+ boolean filterByType(String clientTypeCode) {
+ return StringUtils.equalsIgnoreCase(clientTypeCode,"USP");
+ }
+
+ @Override
+ String getNextChannel() {
+ return ApplicationConstant.SUBMISSION_LEGACY_USP_CHANNEL;
+ }
+
+ /**
+ * This method is responsible for generating the forest client for unregistered sole proprietorship.
+ * @param message - the message containing the submission id.
+ * @return - the forest client.
+ */
+ @ServiceActivator(
+ inputChannel = ApplicationConstant.SUBMISSION_LEGACY_USP_CHANNEL,
+ outputChannel = ApplicationConstant.SUBMISSION_LEGACY_CLIENT_PERSIST_CHANNEL,
+ async = "true"
+ )
+ @Override
+ public Mono> generateForestClient(Message message) {
+ return
+ getSubmissionDetailRepository()
+ .findBySubmissionId(
+ message
+ .getHeaders()
+ .get(ApplicationConstant.SUBMISSION_ID, Integer.class)
+ )
+ .map(detail ->
+ getBaseForestClient(
+ getUser(message, ApplicationConstant.CREATED_BY),
+ getUser(message, ApplicationConstant.UPDATED_BY)
+ )
+ .withLegalFirstName(ProcessorUtil.splitName(detail.getOrganizationName())[1].toUpperCase())
+ .withClientName(ProcessorUtil.splitName(detail.getOrganizationName())[0].toUpperCase())
+ .withLegalMiddleName(ProcessorUtil.splitName(detail.getOrganizationName())[2].toUpperCase())
+ .withClientComment(
+ "Sole proprietorship with data acquired from BC Business eID")
+ .withClientTypeCode("I")
+ .withClientNumber(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER, String.class))
+ )
+ .doOnNext(forestClient ->
+ log.info("generated forest client for USP {} {}",
+ forestClient.getClientNumber(),
+ message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER, String.class)
+ )
+ )
+ .map(forestClient ->
+ MessageBuilder
+ .withPayload(forestClient)
+ .copyHeaders(message.getHeaders())
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NAME,
+ Stream.of(
+ forestClient.getLegalFirstName(),
+ forestClient.getLegalMiddleName(),
+ forestClient.getClientName()
+ )
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.joining(" "))
+ )
+ .setHeader(ApplicationConstant.INCORPORATION_NUMBER,
+ "not applicable")
+ .build()
+ );
+ }
+
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/processor/DoingBusinessAsProcessorMatcher.java b/processor/src/main/java/ca/bc/gov/app/service/processor/DoingBusinessAsProcessorMatcher.java
new file mode 100644
index 0000000000..2cf6c66c0c
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/processor/DoingBusinessAsProcessorMatcher.java
@@ -0,0 +1,57 @@
+package ca.bc.gov.app.service.processor;
+
+import static java.util.function.Predicate.not;
+
+import ca.bc.gov.app.dto.MatcherResult;
+import ca.bc.gov.app.dto.SubmissionInformationDto;
+import ca.bc.gov.app.entity.legacy.ClientDoingBusinessAsEntity;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class DoingBusinessAsProcessorMatcher implements ProcessorMatcher {
+
+ private final ClientDoingBusinessAsRepository doingBusinessAsRepository;
+
+ @Override
+ public boolean enabled(SubmissionInformationDto submission) {
+ return "RSP".equalsIgnoreCase(submission.clientType());
+ }
+
+ @Override
+ public String name() {
+ return "Doing Business As Fuzzy Matcher";
+ }
+
+ @Override
+ public Mono matches(SubmissionInformationDto submission) {
+
+ log.info("{} :: Validating {}", name(), submission.corporationName());
+
+ return
+ matchBy(submission.corporationName())
+ .map(ClientDoingBusinessAsEntity::getClientNumber)
+ .collectList()
+ .filter(not(List::isEmpty))
+ .map(values ->
+ new MatcherResult("corporationName", String.join(",", values))
+ );
+ }
+
+ private Flux matchBy(String companyName) {
+ return
+ doingBusinessAsRepository
+ .matchBy(companyName)
+ .doOnNext(entity -> log.info("Found a match {}", entity));
+
+ }
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcher.java b/processor/src/main/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcher.java
index 4c4d644915..815e0d1e2c 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcher.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcher.java
@@ -10,6 +10,12 @@
@Component
@Slf4j
public class GoodStandingProcessorMatcher implements ProcessorMatcher {
+
+ @Override
+ public boolean enabled(SubmissionInformationDto submission) {
+ return true;
+ }
+
@Override
public String name() {
return "Good Standing Matcher";
diff --git a/processor/src/main/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcher.java b/processor/src/main/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcher.java
index 72810bee1a..d9a7c9f5c6 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcher.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcher.java
@@ -9,6 +9,7 @@
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@@ -18,6 +19,11 @@
public class IncorporationNumberProcessorMatcher implements ProcessorMatcher {
private final ForestClientRepository forestClientRepository;
+ @Override
+ public boolean enabled(SubmissionInformationDto submission) {
+ return StringUtils.isNotBlank(submission.incorporationNumber());
+ }
+
@Override
public String name() {
return "Incorporation Number Matcher";
diff --git a/processor/src/main/java/ca/bc/gov/app/service/processor/IndividualProcessorMatcher.java b/processor/src/main/java/ca/bc/gov/app/service/processor/IndividualProcessorMatcher.java
new file mode 100644
index 0000000000..fabb1c11e4
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/processor/IndividualProcessorMatcher.java
@@ -0,0 +1,53 @@
+package ca.bc.gov.app.service.processor;
+
+import static java.util.function.Predicate.not;
+
+import ca.bc.gov.app.dto.MatcherResult;
+import ca.bc.gov.app.dto.SubmissionInformationDto;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.legacy.ForestClientRepository;
+import ca.bc.gov.app.util.ProcessorUtil;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class IndividualProcessorMatcher implements ProcessorMatcher {
+
+ private final ForestClientRepository forestClientRepository;
+
+ @Override
+ public boolean enabled(SubmissionInformationDto submission) {
+ return "I".equalsIgnoreCase(submission.clientType());
+ }
+
+ @Override
+ public String name() {
+ return "Individual Matcher";
+ }
+
+ @Override
+ public Mono matches(SubmissionInformationDto submission) {
+
+ log.info("{} :: Validating {}", name(), submission.corporationName());
+
+ return
+ forestClientRepository
+ .findByIndividual(
+ ProcessorUtil.splitName(submission.corporationName())[1],
+ ProcessorUtil.splitName(submission.corporationName())[0],
+ submission.dateOfBirth()!= null ? submission.dateOfBirth().atStartOfDay() : null
+ )
+ .map(ForestClientEntity::getClientNumber)
+ .collectList()
+ .filter(not(List::isEmpty))
+ .map(values ->
+ new MatcherResult("corporationName", String.join(",", values))
+ );
+ }
+
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcher.java b/processor/src/main/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcher.java
index aa6882ef21..871d75b55d 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcher.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcher.java
@@ -20,23 +20,28 @@ public class LegalNameProcessorMatcher implements ProcessorMatcher {
private final ForestClientRepository forestClientRepository;
+ @Override
+ public boolean enabled(SubmissionInformationDto submission) {
+ return List.of("I", "USP", "RSP").contains(submission.clientType());
+ }
+
@Override
public String name() {
- return "Legal Name Matcher";
+ return "Legal Name Fuzzy Matcher";
}
@Override
public Mono matches(SubmissionInformationDto submission) {
- log.info("{} :: Validating {}",name(),submission.legalName());
+ log.info("{} :: Validating {}", name(), submission.corporationName());
return
- matchBy(submission.legalName())
+ matchBy(submission.corporationName())
.map(ForestClientEntity::getClientNumber)
.collectList()
.filter(not(List::isEmpty))
.map(values ->
- new MatcherResult("legalName", String.join(",", values))
+ new MatcherResult("corporationName", String.join(",", values))
);
}
diff --git a/processor/src/main/java/ca/bc/gov/app/service/processor/ProcessorMatcher.java b/processor/src/main/java/ca/bc/gov/app/service/processor/ProcessorMatcher.java
index 9988605caa..1c892dcc63 100644
--- a/processor/src/main/java/ca/bc/gov/app/service/processor/ProcessorMatcher.java
+++ b/processor/src/main/java/ca/bc/gov/app/service/processor/ProcessorMatcher.java
@@ -6,6 +6,7 @@
public interface ProcessorMatcher {
+ boolean enabled(SubmissionInformationDto submission);
String name();
Mono matches(SubmissionInformationDto submission);
diff --git a/processor/src/main/java/ca/bc/gov/app/service/processor/SoleProprietorProcessorMatcher.java b/processor/src/main/java/ca/bc/gov/app/service/processor/SoleProprietorProcessorMatcher.java
new file mode 100644
index 0000000000..2aa05d4d8c
--- /dev/null
+++ b/processor/src/main/java/ca/bc/gov/app/service/processor/SoleProprietorProcessorMatcher.java
@@ -0,0 +1,53 @@
+package ca.bc.gov.app.service.processor;
+
+import static java.util.function.Predicate.not;
+
+import ca.bc.gov.app.dto.MatcherResult;
+import ca.bc.gov.app.dto.SubmissionInformationDto;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.legacy.ForestClientRepository;
+import ca.bc.gov.app.util.ProcessorUtil;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class SoleProprietorProcessorMatcher implements ProcessorMatcher {
+
+ private final ForestClientRepository forestClientRepository;
+
+ @Override
+ public boolean enabled(SubmissionInformationDto submission) {
+ return List.of("USP", "RSP").contains(submission.clientType());
+ }
+
+ @Override
+ public String name() {
+ return "Sole Proprietor Matcher";
+ }
+
+ @Override
+ public Mono matches(SubmissionInformationDto submission) {
+
+ log.info("{} :: Validating {}", name(), submission.corporationName());
+
+ return
+ forestClientRepository
+ .findByIndividual(
+ ProcessorUtil.splitName(submission.corporationName())[1],
+ ProcessorUtil.splitName(submission.corporationName())[0],
+ submission.dateOfBirth()!= null ? submission.dateOfBirth().atStartOfDay() : null
+ )
+ .doOnNext(entity -> log.info("Found a match {}", entity))
+ .map(ForestClientEntity::getClientNumber)
+ .collectList()
+ .filter(not(List::isEmpty))
+ .map(values ->
+ new MatcherResult("corporationName", String.join(",", values))
+ );
+ }
+}
diff --git a/processor/src/main/java/ca/bc/gov/app/util/ProcessorUtil.java b/processor/src/main/java/ca/bc/gov/app/util/ProcessorUtil.java
index bc30c14f32..a212a2da3e 100644
--- a/processor/src/main/java/ca/bc/gov/app/util/ProcessorUtil.java
+++ b/processor/src/main/java/ca/bc/gov/app/util/ProcessorUtil.java
@@ -30,6 +30,46 @@ public static String extractNumbers(String input) {
return getStringFromPattern(input, pattern);
}
+ public static String[] splitName(String input) {
+ //If is null or empty return empty array
+ if (StringUtils.isBlank(input)) {
+ return new String[]{StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY};
+ }
+
+ //If contains comma, split by comma and join back together with space, else just use the input
+ String cleanedInput = input.contains(",") ?
+ String.join(" ",
+ input
+ //Remove the commas
+ .replace(",", StringUtils.EMPTY)
+ //Remove the first word
+ .replace(input.split(",")[0], StringUtils.EMPTY),
+ //Add the first word to the end
+ input.split(",")[0].trim()
+ ).trim() :
+ input;
+
+ //Split by space
+ String[] words = cleanedInput.replace(",", StringUtils.EMPTY).split("\\s+");
+
+ //Keeping the OG switch statement as native has some issues with new switch
+ switch (words.length) {
+ case 1:
+ //Return the word for first 2 elements and empty string for the last
+ return new String[]{words[0].trim(), words[0].trim(), StringUtils.EMPTY};
+ case 2:
+ //Return the second word for first, first word for second and empty string for the last
+ return new String[]{words[1].trim(), words[0].trim(), StringUtils.EMPTY};
+ default:
+ //Return the last word for first, first word for second and the rest for the last
+ return new String[]{
+ words[words.length - 1].trim(),
+ words[0].trim(),
+ StringUtils.join(words, ' ', 1, words.length - 1).trim()
+ };
+ }
+ }
+
private static String getStringFromPattern(String input, Pattern pattern) {
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
diff --git a/processor/src/main/resources/application.yml b/processor/src/main/resources/application.yml
index f0c2d9107f..d414535509 100644
--- a/processor/src/main/resources/application.yml
+++ b/processor/src/main/resources/application.yml
@@ -56,3 +56,7 @@ ca:
username: ${POSTGRESQL_USER:user}
password: ${POSTGRESQL_PASSWORD:passwd}
url: r2dbc:postgresql://${ca.bc.gov.nrs.postgres.host}/${ca.bc.gov.nrs.postgres.database}
+ bcregistry:
+ uri: ${BCREGISTRY_URI:https://bcregistry-sandbox.apigee.net}
+ apiKey: ${BCREGISTRY_KEY:123456}
+ accountId: ${BCREGISTRY_ACCOUNT:123456}
diff --git a/processor/src/test/java/ca/bc/gov/app/TestConstants.java b/processor/src/test/java/ca/bc/gov/app/TestConstants.java
index 497f55c2e5..910b9d8957 100644
--- a/processor/src/test/java/ca/bc/gov/app/TestConstants.java
+++ b/processor/src/test/java/ca/bc/gov/app/TestConstants.java
@@ -2,8 +2,15 @@
import ca.bc.gov.app.dto.EmailRequestDto;
import ca.bc.gov.app.dto.SubmissionInformationDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryOfficerDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryPartyDto;
+import ca.bc.gov.app.dto.bcregistry.BcRegistryRoleDto;
import ca.bc.gov.app.entity.client.SubmissionContactEntity;
import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import java.time.LocalDate;
+import java.util.List;
import java.util.Map;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@@ -18,12 +25,12 @@ public class TestConstants {
.incorporationNumber("00000000")
.organizationName("TEST")
.businessTypeCode("T")
- .clientTypeCode("T")
+ .clientTypeCode("C")
.goodStandingInd("Y")
.build();
public static final SubmissionInformationDto SUBMISSION_INFORMATION =
- new SubmissionInformationDto("TEST", "00000000", "Y");
+ new SubmissionInformationDto("TEST", null, "00000000", "Y", "C");
public static final EmailRequestDto EMAIL_REQUEST = new EmailRequestDto(
"ABC1234",
@@ -43,23 +50,23 @@ public class TestConstants {
);
public static final String EMAIL_REQUEST_JSON = """
- {
- "incorporation": "ABC1234",
- "name": "Test Corp",
- "userId": "testuserid",
- "userName": "Test User",
- "email": "testuser@mail.tst",
- "templateName": "test",
- "subject": "Processor Tests",
- "variables": {
- "name": "Test User",
- "business": {
- "name": "Test Corp",
- "identifier": "ABC1234"
- }
+ {
+ "incorporation": "ABC1234",
+ "name": "Test Corp",
+ "userId": "testuserid",
+ "userName": "Test User",
+ "email": "testuser@mail.tst",
+ "templateName": "test",
+ "subject": "Processor Tests",
+ "variables": {
+ "name": "Test User",
+ "business": {
+ "name": "Test Corp",
+ "identifier": "ABC1234"
}
}
- """;
+ }
+ """;
public static final SubmissionContactEntity SUBMISSION_CONTACT = SubmissionContactEntity
.builder()
@@ -82,6 +89,72 @@ public class TestConstants {
"clientNumber", "00001000"
)
)
+ );
+ public static final BcRegistryDocumentDto BCREG_DOC_DATA =
+ new BcRegistryDocumentDto(
+ List.of(
+ new BcRegistryPartyDto(
+ new BcRegistryOfficerDto(
+ "baxterj@baxter.com",
+ "James",
+ "Baxter",
+ "W",
+ "Director"
+ ),
+ List.of(
+ new BcRegistryRoleDto(
+ LocalDate.of(2005, 7, 27),
+ null,
+ "Proprietor"
+ )
+ )
+ )
+ )
);
+ public static final String BCREG_DOC_REQ_RES = """
+ {
+ "businessIdentifier": "AA0000001",
+ "documents": [
+ {
+ "documentKey": "aa0a00a0a",
+ "documentType": "BUSINESS_SUMMARY_FILING_HISTORY",
+ "id": 18315
+ }
+ ]
+ }""";
+
+ public static final String BCREG__RES1 = """
+ {
+ "parties": [
+ {
+ "officer": {
+ "email": "",
+ "firstName": "JAMES",
+ "lastName": "BAXTER",
+ "middleInitial": "G.",
+ "partyType": "person"
+ },
+ "roles": [
+ {
+ "appointmentDate": "1992-09-11",
+ "cessationDate": null,
+ "roleType": "Proprietor"
+ }
+ ]
+ }
+ ]
+ }""";
+
+ public static final String BCREG_RES2 = """
+ {
+ "errorMessage": "API backend third party service error.",
+ "rootCause": "message:ResourceErrorCodes.NOT_FOUND_ERR: no Document found for 7QbI0M6uBxx. "
+ }""";
+
+ public static final ForestClientEntity CLIENT_ENTITY = ForestClientEntity.builder()
+ .clientNumber("00001000")
+ .clientTypeCode("C")
+ .build();
+
}
diff --git a/processor/src/test/java/ca/bc/gov/app/extensions/WiremockLogNotifier.java b/processor/src/test/java/ca/bc/gov/app/extensions/WiremockLogNotifier.java
new file mode 100644
index 0000000000..26e916b271
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/extensions/WiremockLogNotifier.java
@@ -0,0 +1,23 @@
+package ca.bc.gov.app.extensions;
+
+import com.github.tomakehurst.wiremock.common.Notifier;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class WiremockLogNotifier implements Notifier {
+
+ @Override
+ public void info(String message) {
+ log.info(message);
+ }
+
+ @Override
+ public void error(String message) {
+ log.error(message);
+ }
+
+ @Override
+ public void error(String message, Throwable t) {
+ log.error(message, t);
+ }
+}
diff --git a/processor/src/test/java/ca/bc/gov/app/service/bcregistry/BcRegistryServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/bcregistry/BcRegistryServiceTest.java
new file mode 100644
index 0000000000..64e1696b74
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/bcregistry/BcRegistryServiceTest.java
@@ -0,0 +1,114 @@
+package ca.bc.gov.app.service.bcregistry;
+
+import static ca.bc.gov.app.TestConstants.BCREG_DOC_REQ_RES;
+import static ca.bc.gov.app.TestConstants.BCREG_RES2;
+import static ca.bc.gov.app.TestConstants.BCREG__RES1;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.status;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import ca.bc.gov.app.dto.bcregistry.BcRegistryDocumentDto;
+import ca.bc.gov.app.extensions.WiremockLogNotifier;
+import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.springframework.http.MediaType;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | BC Registry Service")
+class BcRegistryServiceTest {
+
+ @RegisterExtension
+ static WireMockExtension bcRegistryStub = WireMockExtension
+ .newInstance()
+ .options(
+ wireMockConfig()
+ .port(10040)
+ .notifier(new WiremockLogNotifier())
+ .asynchronousResponseEnabled(true)
+ .stubRequestLoggingDisabled(false)
+ )
+ .configureStaticDsl(true)
+ .build();
+
+ private final BcRegistryService service = new BcRegistryService(
+ WebClient
+ .builder()
+ .baseUrl("http://localhost:10040")
+ .build()
+ );
+
+ @ParameterizedTest
+ @MethodSource("documentData")
+ @DisplayName("should read document data")
+ void shouldReadDocumentData(
+ String clientNumber,
+ int requestStatus,
+ String requestBody,
+ int detailsStatus,
+ String detailsBody
+ ) {
+
+ bcRegistryStub
+ .stubFor(post(urlPathEqualTo(
+ "/registry-search/api/v1/businesses/" + clientNumber + "/documents/requests"))
+ .willReturn(
+ status(requestStatus)
+ .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
+ .withBody(requestBody)
+ )
+ );
+
+ bcRegistryStub
+ .stubFor(get(urlPathEqualTo(
+ "/registry-search/api/v1/businesses/" + clientNumber + "/documents/aa0a00a0a"
+ )
+ )
+ .willReturn(
+ status(detailsStatus)
+ .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
+ .withBody(detailsBody)
+ )
+ );
+
+ StepVerifier.FirstStep test =
+ service
+ .requestDocumentData(clientNumber)
+ .as(StepVerifier::create);
+
+ if (detailsStatus == 200 && requestStatus == 200) {
+ test
+ .assertNext(document -> assertTrue(document.getProprietor().isProprietor()))
+ .verifyComplete();
+ }else{
+ test
+ .expectError()
+ .verify();
+ }
+
+
+ }
+
+ private static Stream documentData() {
+ return Stream.of(
+ Arguments.of("CP0000001",200,BCREG_DOC_REQ_RES, 200, BCREG__RES1),
+ Arguments.of("CP0000002",200,BCREG_DOC_REQ_RES, 404, BCREG_RES2),
+
+ Arguments.of("CP0000002",404,BCREG_RES2, 404, BCREG_RES2),
+ Arguments.of("CP0000002",401,BCREG_RES2, 404, BCREG_RES2),
+ Arguments.of("CP0000002",400,BCREG_RES2, 404, BCREG_RES2),
+
+ Arguments.of("CP0000002",200,BCREG_DOC_REQ_RES, 401, BCREG_RES2),
+ Arguments.of("CP0000002",200,BCREG_DOC_REQ_RES, 400, BCREG_RES2)
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/client/ClientSubmissionMailServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/client/ClientSubmissionMailServiceTest.java
index 42ccdad4b4..ca7b9a2da7 100644
--- a/processor/src/test/java/ca/bc/gov/app/service/client/ClientSubmissionMailServiceTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/service/client/ClientSubmissionMailServiceTest.java
@@ -9,7 +9,9 @@
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.awaitility.Awaitility.await;
+import ca.bc.gov.app.ApplicationConstant;
import ca.bc.gov.app.TestConstants;
+import ca.bc.gov.app.entity.client.SubmissionTypeCodeEnum;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import java.time.Duration;
import org.junit.jupiter.api.BeforeAll;
@@ -63,4 +65,29 @@ void shouldSendEmail() {
});
}
+ @Test
+ @DisplayName("preview email on review")
+ void shouldPreventReviewMails() {
+ service.sendMail(
+ MessageBuilder
+ .withPayload(TestConstants.EMAIL_REQUEST)
+ .setHeader(ApplicationConstant.SUBMISSION_TYPE, SubmissionTypeCodeEnum.RNC)
+ .build()
+ );
+
+ await()
+ .alias("Email sent")
+ .atMost(Duration.ofSeconds(2))
+ .untilAsserted(() -> {
+ wireMockExtension
+ .verify(
+ 0,
+ postRequestedFor(urlEqualTo("/ches/email"))
+ .withHeader("Content-Type", containing(MediaType.APPLICATION_JSON_VALUE))
+ .withRequestBody(equalToJson(TestConstants.EMAIL_REQUEST_JSON)
+ )
+ );
+ });
+ }
+
}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/client/ClientSubmissionProcessingServiceIntegrationTest.java b/processor/src/test/java/ca/bc/gov/app/service/client/ClientSubmissionProcessingServiceIntegrationTest.java
new file mode 100644
index 0000000000..af819d3be2
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/client/ClientSubmissionProcessingServiceIntegrationTest.java
@@ -0,0 +1,233 @@
+package ca.bc.gov.app.service.client;
+
+import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.dto.EmailRequestDto;
+import ca.bc.gov.app.entity.client.SubmissionContactEntity;
+import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
+import ca.bc.gov.app.entity.client.SubmissionEntity;
+import ca.bc.gov.app.entity.client.SubmissionMatchDetailEntity;
+import ca.bc.gov.app.entity.client.SubmissionStatusEnum;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionMatchDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import java.time.Duration;
+import java.util.Map;
+import java.util.stream.Stream;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.messaging.Message;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Client Service")
+class ClientSubmissionProcessingServiceIntegrationTest {
+
+ private final SubmissionDetailRepository submissionDetailRepository = mock(
+ SubmissionDetailRepository.class);
+ private final SubmissionRepository submissionRepository = mock(SubmissionRepository.class);
+ private final SubmissionMatchDetailRepository submissionMatchDetailRepository = mock(
+ SubmissionMatchDetailRepository.class);
+ private final SubmissionContactRepository contactRepository = mock(
+ SubmissionContactRepository.class);
+ private final ClientSubmissionProcessingService service = new ClientSubmissionProcessingService(
+ submissionDetailRepository,
+ submissionRepository,
+ submissionMatchDetailRepository,
+ contactRepository
+ );
+
+ @ParameterizedTest
+ @MethodSource("submissionLoads")
+ @DisplayName("submission loads")
+ void shouldLoadSubmission(
+ Mono submission,
+ Mono submissionDetail,
+ Mono submissionMatchDetail,
+ Message expected
+ ) {
+
+ when(submissionDetailRepository.findBySubmissionId(1)).thenReturn(submissionDetail);
+ when(submissionRepository.findById(1)).thenReturn(submission);
+ when(submissionMatchDetailRepository.findBySubmissionId(1)).thenReturn(submissionMatchDetail);
+
+ StepVerifier.FirstStep> test =
+ service
+ .processSubmission(
+ MessageBuilder
+ .withPayload(1)
+ .build()
+ )
+ .as(StepVerifier::create);
+
+ if (expected != null) {
+ test.assertNext(message -> {
+ assertEquals(expected.getPayload(), message.getPayload());
+ assertEquals(
+ expected.getHeaders().get(ApplicationConstant.SUBMISSION_ID),
+ message.getHeaders().get(ApplicationConstant.SUBMISSION_ID)
+ );
+ assertEquals(
+ expected.getHeaders().get(ApplicationConstant.SUBMISSION_STATUS),
+ message.getHeaders().get(ApplicationConstant.SUBMISSION_STATUS)
+ );
+ assertEquals(
+ expected.getHeaders().get(ApplicationConstant.SUBMISSION_CLIENTID),
+ message.getHeaders().get(ApplicationConstant.SUBMISSION_CLIENTID)
+ );
+ assertEquals(
+ expected.getHeaders().get(ApplicationConstant.SUBMISSION_NAME),
+ message.getHeaders().get(ApplicationConstant.SUBMISSION_NAME)
+ );
+ })
+ .verifyComplete();
+ } else {
+ test.verifyComplete();
+ }
+
+
+ }
+
+ @ParameterizedTest
+ @MethodSource("notification")
+ @DisplayName("notification is sent")
+ void shouldNotify(
+ SubmissionStatusEnum statusEnum,
+ Mono contact,
+ Mono detail,
+ Mono match,
+ Object response
+ ) {
+
+ when(contactRepository.findFirstBySubmissionId(1)).thenReturn(contact);
+ when(submissionDetailRepository.findBySubmissionId(1)).thenReturn(detail);
+ when(submissionMatchDetailRepository.findBySubmissionId(1)).thenReturn(match);
+
+ service
+ .notificationProcessing(
+ MessageBuilder
+ .withPayload(SubmissionMatchDetailEntity.builder().build())
+ .setHeader(ApplicationConstant.SUBMISSION_STATUS, statusEnum)
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 1)
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message ->
+ assertEquals(response, message.getPayload())
+ )
+ .verifyComplete();
+ }
+
+ @Test
+ @DisplayName("update match")
+ void shouldUpdateMatch() {
+ when(submissionMatchDetailRepository.findBySubmissionId(1))
+ .thenReturn(Mono.just(SubmissionMatchDetailEntity.builder().build()));
+ service
+ .updateMatch(MessageBuilder.withPayload(1).build());
+
+ await()
+ .alias("Submission matches")
+ .atMost(Duration.ofSeconds(5))
+ .untilAsserted(() -> {
+ verify(submissionMatchDetailRepository, atLeastOnce())
+ .save(any(SubmissionMatchDetailEntity.class));
+ verify(submissionMatchDetailRepository, atLeastOnce())
+ .findBySubmissionId(eq(1));
+ }
+ );
+ }
+
+ private static Stream submissionLoads() {
+ return
+ Stream.of(
+ Arguments.of(
+ Mono.empty(),
+ Mono.empty(),
+ Mono.empty(),
+ null
+ ),
+ Arguments.of(
+ Mono.just(
+ SubmissionEntity.builder().submissionStatus(SubmissionStatusEnum.N).build()),
+ Mono.just(SubmissionDetailEntity.builder().organizationName("TEST").build()),
+ Mono.empty(),
+ MessageBuilder
+ .withPayload(SubmissionMatchDetailEntity.builder().build())
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 1)
+ .setHeader(ApplicationConstant.SUBMISSION_STATUS, SubmissionStatusEnum.N)
+ .setHeader(ApplicationConstant.SUBMISSION_CLIENTID, StringUtils.EMPTY)
+ .setHeader(ApplicationConstant.SUBMISSION_NAME, "TEST")
+ .build()
+
+ ),
+ Arguments.of(
+ Mono.just(
+ SubmissionEntity.builder().submissionStatus(SubmissionStatusEnum.N).build()),
+ Mono.just(SubmissionDetailEntity.builder().organizationName("TEST").build()),
+ Mono.just(SubmissionMatchDetailEntity.builder().build()),
+ MessageBuilder
+ .withPayload(SubmissionMatchDetailEntity.builder().build())
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 1)
+ .setHeader(ApplicationConstant.SUBMISSION_STATUS, SubmissionStatusEnum.N)
+ .setHeader(ApplicationConstant.SUBMISSION_CLIENTID, StringUtils.EMPTY)
+ .setHeader(ApplicationConstant.SUBMISSION_NAME, "TEST")
+ .build()
+
+ )
+ );
+ }
+
+ private static Stream notification() {
+ return
+ Stream
+ .of(
+ Arguments.of(
+ SubmissionStatusEnum.A,
+ Mono.empty(),
+ Mono.empty(),
+ Mono.empty(),
+ 1
+ ),
+ Arguments.of(
+ SubmissionStatusEnum.R,
+ Mono.just(SubmissionContactEntity.builder().userId("uid1").firstName("Test")
+ .emailAddress("Mail")
+ .build()),
+ Mono.just(SubmissionDetailEntity.builder().organizationName("TEST")
+ .incorporationNumber("XX012345").build()),
+ Mono.just(
+ SubmissionMatchDetailEntity.builder().matchingMessage("Test").build()),
+ new EmailRequestDto(
+ "XX012345",
+ "TEST",
+ "uid1",
+ "Test",
+ "Mail",
+ "rejection",
+ "Failure",
+ Map.of(
+ "userName", "Test",
+ "name", "TEST",
+ "reason", "Test"
+ )
+ )
+ )
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyPersistenceServiceIntegrationTest.java b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceServiceIntegrationTest.java
similarity index 91%
rename from processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyPersistenceServiceIntegrationTest.java
rename to processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceServiceIntegrationTest.java
index 343bc3628f..92ddb9cf56 100644
--- a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyPersistenceServiceIntegrationTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceServiceIntegrationTest.java
@@ -12,10 +12,10 @@
import reactor.test.StepVerifier;
@DisplayName("Integration Test | Legacy Persistence Service")
-class LegacyPersistenceServiceIntegrationTest extends AbstractTestContainer {
+class LegacyAbstractPersistenceServiceIntegrationTest extends AbstractTestContainer {
@Autowired
- private LegacyPersistenceService service;
+ private LegacyClientPersistenceService service;
@Test
@DisplayName("load submission with id 2")
diff --git a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyPersistenceServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceServiceTest.java
similarity index 77%
rename from processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyPersistenceServiceTest.java
rename to processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceServiceTest.java
index 2eb44272dc..1212ff208d 100644
--- a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyPersistenceServiceTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyAbstractPersistenceServiceTest.java
@@ -8,11 +8,13 @@
import static org.mockito.Mockito.when;
import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.TestConstants;
import ca.bc.gov.app.entity.client.CountryCodeEntity;
import ca.bc.gov.app.entity.client.SubmissionContactEntity;
import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
import ca.bc.gov.app.entity.client.SubmissionLocationContactEntity;
import ca.bc.gov.app.entity.client.SubmissionLocationEntity;
+import ca.bc.gov.app.entity.legacy.ClientDoingBusinessAsEntity;
import ca.bc.gov.app.entity.legacy.ForestClientContactEntity;
import ca.bc.gov.app.entity.legacy.ForestClientEntity;
import ca.bc.gov.app.entity.legacy.ForestClientLocationEntity;
@@ -22,10 +24,15 @@
import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
import ca.bc.gov.app.repository.client.SubmissionRepository;
-import ca.bc.gov.app.repository.legacy.ForestClientRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import java.util.stream.Stream;
+import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.r2dbc.core.ReactiveInsertOperation.ReactiveInsert;
import org.springframework.integration.support.MessageBuilder;
@@ -34,31 +41,31 @@
import reactor.test.StepVerifier;
@DisplayName("Unit Test | Legacy Persistence Service")
-class LegacyPersistenceServiceTest {
+class LegacyAbstractPersistenceServiceTest {
private final SubmissionDetailRepository submissionDetailRepository = mock(
SubmissionDetailRepository.class);
private final SubmissionRepository submissionRepository = mock(SubmissionRepository.class);
private final SubmissionLocationRepository locationRepository = mock(
SubmissionLocationRepository.class);
- private final ForestClientRepository forestClientRepository = mock(ForestClientRepository.class);
-
private final SubmissionContactRepository contactRepository = mock(
SubmissionContactRepository.class);
private final SubmissionLocationContactRepository locationContactRepository = mock(
SubmissionLocationContactRepository.class);
private final R2dbcEntityTemplate legacyR2dbcEntityTemplate = mock(R2dbcEntityTemplate.class);
-
private final CountryCodeRepository countryCodeRepository = mock(CountryCodeRepository.class);
+ private final ClientDoingBusinessAsRepository doingBusinessAsRepository = mock(
+ ClientDoingBusinessAsRepository.class);
- private final LegacyPersistenceService service = new LegacyPersistenceService(
+ private final LegacyClientPersistenceService service = new LegacyClientPersistenceService(
submissionDetailRepository,
submissionRepository,
locationRepository,
contactRepository,
locationContactRepository,
legacyR2dbcEntityTemplate,
- countryCodeRepository
+ countryCodeRepository,
+ doingBusinessAsRepository
);
@BeforeEach
@@ -67,93 +74,6 @@ void beforeEach() {
.thenReturn(Flux.just(new CountryCodeEntity("CA", "Canada")));
}
- @Test
- @DisplayName("create forest client")
- void shouldCreateForestClient() {
- ReactiveInsert reactiveInsert = mock(ReactiveInsert.class);
-
- SubmissionDetailEntity entity = SubmissionDetailEntity.builder()
- .submissionId(2)
- .submissionDetailId(2)
- .organizationName("STAR DOT STAR VENTURES")
- .incorporationNumber("FM0159297")
- .businessTypeCode("R")
- .clientTypeCode("P")
- .goodStandingInd("Y")
- .build();
-
- when(submissionDetailRepository.findBySubmissionId(eq(2)))
- .thenReturn(Mono.just(entity));
- when(forestClientRepository.save(any(ForestClientEntity.class)))
- .thenReturn(Mono.just(ForestClientEntity.builder()
- .clientNumber("00000000")
- .build()
- )
- );
- when(submissionDetailRepository.save(any(SubmissionDetailEntity.class)))
- .thenReturn(Mono.just(entity));
- when(legacyR2dbcEntityTemplate.selectOne(any(), any()))
- .thenReturn(Mono.just(ForestClientEntity.builder()
- .clientNumber("00000000")
- .build()
- )
- );
- when(legacyR2dbcEntityTemplate.insert(eq(ForestClientEntity.class)))
- .thenReturn(reactiveInsert);
- when(reactiveInsert.using(any()))
- .thenReturn(Mono.just(ForestClientEntity.builder()
- .clientNumber("00000000")
- .build()
- )
- );
-
- service
- .createForestClient(
- MessageBuilder
- .withPayload(2)
- .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
- .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
- .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
- .build()
- )
- .as(StepVerifier::create)
- .assertNext(message -> {
- assertThat(message)
- .isNotNull()
- .hasFieldOrPropertyWithValue("payload", 2);
-
- assertThat(message.getHeaders().get(ApplicationConstant.SUBMISSION_ID))
- .isNotNull()
- .isInstanceOf(Integer.class)
- .isEqualTo(2);
-
- assertThat(message.getHeaders().get(ApplicationConstant.CREATED_BY))
- .isNotNull()
- .isInstanceOf(String.class);
-
- assertThat(message.getHeaders().get(ApplicationConstant.UPDATED_BY))
- .isNotNull()
- .isInstanceOf(String.class);
-
- assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME))
- .isNotNull()
- .isInstanceOf(String.class)
- .isEqualTo("STAR DOT STAR VENTURES");
-
- assertThat(message.getHeaders().get(ApplicationConstant.INCORPORATION_NUMBER))
- .isNotNull()
- .isInstanceOf(String.class)
- .isEqualTo("FM0159297");
-
- assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
- .isNotNull()
- .isInstanceOf(String.class)
- .isEqualTo("00000000");
-
- })
- .verifyComplete();
- }
-
@Test
@DisplayName("create locations")
void shouldCreateLocations() {
@@ -195,6 +115,7 @@ void shouldCreateLocations() {
.setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000000")
.setHeader(ApplicationConstant.FOREST_CLIENT_NAME, "STAR DOT STAR VENTURES")
.setHeader(ApplicationConstant.INCORPORATION_NUMBER, "FM0159297")
+ .setHeader(ApplicationConstant.CLIENT_TYPE_CODE, "C")
.build()
)
.as(StepVerifier::create)
@@ -304,6 +225,7 @@ void shouldCreateContacts() {
.setHeader(ApplicationConstant.LOCATION_ID, 1)
.setHeader(ApplicationConstant.TOTAL, 1L)
.setHeader(ApplicationConstant.INDEX, 0L)
+ .setHeader(ApplicationConstant.CLIENT_TYPE_CODE, "C")
.build()
)
.as(StepVerifier::create)
@@ -382,6 +304,7 @@ void shouldSendEmail() {
.setHeader(ApplicationConstant.LOCATION_ID, 1)
.setHeader(ApplicationConstant.TOTAL, 1L)
.setHeader(ApplicationConstant.INDEX, 0L)
+ .setHeader(ApplicationConstant.CLIENT_TYPE_CODE, "C")
.build()
)
.as(StepVerifier::create)
@@ -394,4 +317,145 @@ void shouldSendEmail() {
.verifyComplete();
}
-}
\ No newline at end of file
+ @ParameterizedTest
+ @MethodSource("clientData")
+ @DisplayName("check client data")
+ void shouldCheckClientData(
+ String clientTypeCode,
+ String clientNumber) {
+
+ when(submissionDetailRepository.findBySubmissionId(any()))
+ .thenReturn(Mono.just(
+ SubmissionDetailEntity
+ .builder()
+ .submissionId(2)
+ .incorporationNumber("XX0000000")
+ .organizationName("Sample test")
+ .clientTypeCode(clientTypeCode)
+ .clientNumber(clientNumber)
+ .build()
+ )
+ );
+
+ when(legacyR2dbcEntityTemplate.selectOne(any(), any()))
+ .thenReturn(
+ Mono.just(ForestClientEntity.builder().clientNumber("00000000").build()));
+
+ service
+ .checkClientData(
+ MessageBuilder
+ .withPayload(2)
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ assertThat(message)
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("payload",
+ StringUtils.isNotBlank(clientNumber) ? 2 : "00000001");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.SUBMISSION_ID))
+ .as("submission id")
+ .isNotNull()
+ .isInstanceOf(Integer.class)
+ .isEqualTo(2);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CREATED_BY))
+ .as("created by")
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.UPDATED_BY))
+ .as("updated by")
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .as("forest client number")
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo(StringUtils.defaultString(clientNumber, "00000001"));
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CLIENT_TYPE_CODE))
+ .as("client type code")
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo(clientTypeCode);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CLIENT_EXISTS))
+ .as("client exists")
+ .isNotNull()
+ .isInstanceOf(Boolean.class)
+ .isEqualTo(StringUtils.isNotBlank(clientNumber));
+ })
+ .verifyComplete();
+ }
+
+
+ @Test
+ @DisplayName("create client that is not individual")
+ void shouldCreateClient() {
+
+ ReactiveInsert reactiveInsert = mock(ReactiveInsert.class);
+
+ SubmissionDetailEntity detailEntity = SubmissionDetailEntity
+ .builder()
+ .submissionId(2)
+ .incorporationNumber("XX0000000")
+ .organizationName("Sample test")
+ .clientTypeCode("C")
+ .clientNumber("00000000")
+ .build();
+
+ when(submissionDetailRepository.findBySubmissionId(any()))
+ .thenReturn(Mono.just(detailEntity));
+ when(submissionDetailRepository.save(any()))
+ .thenReturn(Mono.just(detailEntity));
+ when(legacyR2dbcEntityTemplate.insert(eq(ForestClientEntity.class)))
+ .thenReturn(reactiveInsert);
+ when(reactiveInsert.using(any()))
+ .thenReturn(Mono.just(TestConstants.CLIENT_ENTITY));
+ when(legacyR2dbcEntityTemplate.selectOne(any(), any()))
+ .thenReturn(Mono.empty());
+
+ service
+ .createForestClient(
+ MessageBuilder
+ .withPayload(TestConstants.CLIENT_ENTITY)
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.CLIENT_TYPE_CODE, "C")
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000000")
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NAME, "CHAMPAGNE SUPERNOVA")
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ assertThat(message)
+ .as("message")
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("payload",2);
+
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .as("forest client number")
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("00000000");
+ })
+ .verifyComplete();
+
+ }
+
+ private static Stream clientData() {
+ return Stream.of(
+ Arguments.of("C", "00000000"),
+ Arguments.of("C", null)
+ );
+ }
+
+}
diff --git a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyClientPersistenceServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyClientPersistenceServiceTest.java
new file mode 100644
index 0000000000..d5b76d2c0b
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyClientPersistenceServiceTest.java
@@ -0,0 +1,157 @@
+package ca.bc.gov.app.service.legacy;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.r2dbc.core.ReactiveInsertOperation.ReactiveInsert;
+import org.springframework.integration.support.MessageBuilder;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Legacy Client Persistence Service")
+class LegacyClientPersistenceServiceTest {
+
+ private final SubmissionDetailRepository submissionDetailRepository = mock(
+ SubmissionDetailRepository.class);
+ private final SubmissionRepository submissionRepository = mock(SubmissionRepository.class);
+ private final SubmissionLocationRepository locationRepository = mock(
+ SubmissionLocationRepository.class);
+ private final SubmissionContactRepository contactRepository = mock(
+ SubmissionContactRepository.class);
+ private final SubmissionLocationContactRepository locationContactRepository = mock(
+ SubmissionLocationContactRepository.class);
+ private final R2dbcEntityTemplate legacyR2dbcEntityTemplate = mock(R2dbcEntityTemplate.class);
+ private final CountryCodeRepository countryCodeRepository = mock(CountryCodeRepository.class);
+ private final ClientDoingBusinessAsRepository doingBusinessAsRepository = mock(
+ ClientDoingBusinessAsRepository.class);
+
+ private final LegacyClientPersistenceService service = new LegacyClientPersistenceService(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository
+ );
+
+ @ParameterizedTest(name = "type: {0} expected: {1}")
+ @MethodSource("byType")
+ @DisplayName("filter by type")
+ void shouldFilterByType(String type, boolean expected){
+ assertEquals(expected, service.filterByType(type));
+ }
+
+ @Test
+ @DisplayName("get next channel")
+ void shouldGetNextChannel(){
+ assertEquals(ApplicationConstant.SUBMISSION_LEGACY_OTHER_CHANNEL, service.getNextChannel());
+ }
+
+
+ @Test
+ @DisplayName("create forest client")
+ void shouldCreateForestClient() {
+ ReactiveInsert reactiveInsert = mock(ReactiveInsert.class);
+
+ SubmissionDetailEntity entity = SubmissionDetailEntity.builder()
+ .submissionId(2)
+ .submissionDetailId(2)
+ .organizationName("STAR DOT STAR VENTURES")
+ .incorporationNumber("FM0159297")
+ .businessTypeCode("R")
+ .clientTypeCode("C")
+ .goodStandingInd("Y")
+ .build();
+
+ when(submissionDetailRepository.findBySubmissionId(eq(2)))
+ .thenReturn(Mono.just(entity));
+
+ service
+ .generateForestClient(
+ MessageBuilder
+ .withPayload("00000001")
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000001")
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ assertThat(message)
+ .isNotNull()
+ .hasFieldOrProperty("payload");
+
+ assertThat(message.getPayload())
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("clientName", "STAR DOT STAR VENTURES")
+ .hasFieldOrPropertyWithValue("clientTypeCode", "C")
+ .hasFieldOrPropertyWithValue("registryCompanyTypeCode", "FM")
+ .hasFieldOrPropertyWithValue("corpRegnNmbr", "0159297")
+ .hasFieldOrPropertyWithValue("clientNumber", "00000001")
+ .hasFieldOrPropertyWithValue("clientComment", "Client details acquired from BC Registry FM0159297");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.SUBMISSION_ID))
+ .isNotNull()
+ .isInstanceOf(Integer.class)
+ .isEqualTo(2);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CREATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.UPDATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("STAR DOT STAR VENTURES");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.INCORPORATION_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("FM0159297");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("00000001");
+
+ })
+ .verifyComplete();
+ }
+
+ private static Stream byType(){
+ return Stream.of(
+ Arguments.of("I", false),
+ Arguments.of("C", true),
+ Arguments.of("USP", false),
+ Arguments.of("RSP", false)
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyIndividualPersistenceServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyIndividualPersistenceServiceTest.java
new file mode 100644
index 0000000000..8138d43d25
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyIndividualPersistenceServiceTest.java
@@ -0,0 +1,157 @@
+package ca.bc.gov.app.service.legacy;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.r2dbc.core.ReactiveInsertOperation.ReactiveInsert;
+import org.springframework.integration.support.MessageBuilder;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Legacy Individual Persistence Service")
+class LegacyIndividualPersistenceServiceTest {
+
+
+ private final SubmissionDetailRepository submissionDetailRepository = mock(
+ SubmissionDetailRepository.class);
+ private final SubmissionRepository submissionRepository = mock(SubmissionRepository.class);
+ private final SubmissionLocationRepository locationRepository = mock(
+ SubmissionLocationRepository.class);
+ private final SubmissionContactRepository contactRepository = mock(
+ SubmissionContactRepository.class);
+ private final SubmissionLocationContactRepository locationContactRepository = mock(
+ SubmissionLocationContactRepository.class);
+ private final R2dbcEntityTemplate legacyR2dbcEntityTemplate = mock(R2dbcEntityTemplate.class);
+ private final CountryCodeRepository countryCodeRepository = mock(CountryCodeRepository.class);
+ private final ClientDoingBusinessAsRepository doingBusinessAsRepository = mock(
+ ClientDoingBusinessAsRepository.class);
+
+ private final LegacyIndividualPersistenceService service = new LegacyIndividualPersistenceService(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository
+ );
+
+ @ParameterizedTest(name = "type: {0} expected: {1}")
+ @MethodSource("byType")
+ @DisplayName("filter by type")
+ void shouldFilterByType(String type, boolean expected){
+ assertEquals(expected, service.filterByType(type));
+ }
+
+
+ @Test
+ @DisplayName("get next channel")
+ void shouldGetNextChannel(){
+ assertEquals(ApplicationConstant.SUBMISSION_LEGACY_INDIVIDUAL_CHANNEL, service.getNextChannel());
+ }
+
+
+ @Test
+ @DisplayName("create forest client")
+ void shouldCreateForestClient() {
+ ReactiveInsert reactiveInsert = mock(ReactiveInsert.class);
+
+ SubmissionDetailEntity entity = SubmissionDetailEntity.builder()
+ .submissionId(2)
+ .submissionDetailId(2)
+ .organizationName("James Baxter")
+ .businessTypeCode("U")
+ .clientTypeCode("I")
+ .goodStandingInd("Y")
+ .build();
+
+ when(submissionDetailRepository.findBySubmissionId(eq(2)))
+ .thenReturn(Mono.just(entity));
+
+ service
+ .generateForestClient(
+ MessageBuilder
+ .withPayload("00000001")
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000001")
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ assertThat(message)
+ .isNotNull()
+ .hasFieldOrProperty("payload");
+
+ assertThat(message.getPayload())
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("clientName", "BAXTER")
+ .hasFieldOrPropertyWithValue("legalFirstName", "JAMES")
+ .hasFieldOrPropertyWithValue("clientComment", "Individual with data acquired from BC Services Card")
+ .hasFieldOrPropertyWithValue("clientTypeCode", "I")
+ .hasFieldOrPropertyWithValue("clientNumber", "00000001");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.SUBMISSION_ID))
+ .isNotNull()
+ .isInstanceOf(Integer.class)
+ .isEqualTo(2);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CREATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.UPDATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("JAMES BAXTER");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.INCORPORATION_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("not applicable");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("00000001");
+
+ })
+ .verifyComplete();
+ }
+
+ private static Stream byType(){
+ return Stream.of(
+ Arguments.of("I", true),
+ Arguments.of("C", false),
+ Arguments.of("USP", false),
+ Arguments.of("RSP", false)
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyLoadingServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyLoadingServiceTest.java
index 5af37cf399..196ae90fbe 100644
--- a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyLoadingServiceTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyLoadingServiceTest.java
@@ -86,6 +86,11 @@ private static Stream matchCheck() {
private static class TestProcessorMatcher implements ProcessorMatcher{
+ @Override
+ public boolean enabled(SubmissionInformationDto submission) {
+ return true;
+ }
+
@Override
public String name() {
return "Test matcher";
diff --git a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyRegisteredSPPersistenceServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyRegisteredSPPersistenceServiceTest.java
new file mode 100644
index 0000000000..942cc28aed
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyRegisteredSPPersistenceServiceTest.java
@@ -0,0 +1,349 @@
+package ca.bc.gov.app.service.legacy;
+
+import static ca.bc.gov.app.TestConstants.SUBMISSION_CONTACT;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.status;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.TestConstants;
+import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
+import ca.bc.gov.app.entity.legacy.ClientDoingBusinessAsEntity;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.entity.legacy.ForestClientLocationEntity;
+import ca.bc.gov.app.extensions.WiremockLogNotifier;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import ca.bc.gov.app.service.bcregistry.BcRegistryService;
+import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
+import java.util.stream.Stream;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.r2dbc.core.ReactiveInsertOperation.ReactiveInsert;
+import org.springframework.http.MediaType;
+import org.springframework.integration.support.MessageBuilder;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Legacy Registered Sole Proprietor Persistence Service")
+class LegacyRegisteredSPPersistenceServiceTest {
+
+ private final SubmissionDetailRepository submissionDetailRepository = mock(
+ SubmissionDetailRepository.class);
+ private final SubmissionRepository submissionRepository = mock(SubmissionRepository.class);
+ private final SubmissionLocationRepository locationRepository = mock(
+ SubmissionLocationRepository.class);
+ private final SubmissionContactRepository contactRepository = mock(
+ SubmissionContactRepository.class);
+ private final SubmissionLocationContactRepository locationContactRepository = mock(
+ SubmissionLocationContactRepository.class);
+ private final R2dbcEntityTemplate legacyR2dbcEntityTemplate = mock(R2dbcEntityTemplate.class);
+ private final CountryCodeRepository countryCodeRepository = mock(CountryCodeRepository.class);
+ private final ClientDoingBusinessAsRepository doingBusinessAsRepository = mock(
+ ClientDoingBusinessAsRepository.class);
+ private final BcRegistryService bcRegistryService = mock(BcRegistryService.class);
+
+ private final LegacyRegisteredSPPersistenceService service = new LegacyRegisteredSPPersistenceService(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository,
+ bcRegistryService
+ );
+
+ @ParameterizedTest(name = "type: {0} expected: {1}")
+ @MethodSource("byType")
+ @DisplayName("filter by type")
+ void shouldFilterByType(String type, boolean expected){
+ assertEquals(expected, service.filterByType(type));
+ }
+
+ @Test
+ @DisplayName("get next channel")
+ void shouldGetNextChannel(){
+ assertEquals(ApplicationConstant.SUBMISSION_LEGACY_RSP_CHANNEL, service.getNextChannel());
+ }
+
+ @Test
+ @DisplayName("create forest client")
+ void shouldCreateForestClient() {
+
+ SubmissionDetailEntity entity = SubmissionDetailEntity.builder()
+ .submissionId(2)
+ .submissionDetailId(2)
+ .organizationName("Baxter Corp")
+ .incorporationNumber("FM00184546")
+ .businessTypeCode("R")
+ .clientTypeCode("RSP")
+ .goodStandingInd("Y")
+ .build();
+
+ when(bcRegistryService.requestDocumentData(any(String.class)))
+ .thenReturn(Flux.just(TestConstants.BCREG_DOC_DATA));
+
+ when(submissionDetailRepository.findBySubmissionId(any()))
+ .thenReturn(Mono.just(entity));
+
+ when(contactRepository.findBySubmissionId(any()))
+ .thenReturn(Flux.empty());
+
+ service
+ .generateForestClient(
+ MessageBuilder
+ .withPayload("00000001")
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000001")
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ assertThat(message)
+ .isNotNull()
+ .hasFieldOrProperty("payload");
+
+ assertThat(message.getPayload())
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("clientName", "BAXTER")
+ .hasFieldOrPropertyWithValue("legalFirstName", "JAMES")
+ .hasFieldOrPropertyWithValue("clientIdTypeCode", "OTHR")
+ .hasFieldOrPropertyWithValue("clientIdentification", "FM00184546")
+ .hasFieldOrPropertyWithValue("registryCompanyTypeCode", "FM")
+ .hasFieldOrPropertyWithValue("corpRegnNmbr", "00184546")
+ .hasFieldOrPropertyWithValue("clientComment",
+ String.join(" ",
+ "Sole proprietorship registered on BC Registry with number",
+ "FM00184546",
+ "and company name",
+ "BAXTER CORP"
+ )
+ )
+ .hasFieldOrPropertyWithValue("clientTypeCode", "I")
+ .hasFieldOrPropertyWithValue("clientNumber", "00000001");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.SUBMISSION_ID))
+ .isNotNull()
+ .isInstanceOf(Integer.class)
+ .isEqualTo(2);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CREATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.UPDATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("BAXTER CORP");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.INCORPORATION_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("FM00184546");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("00000001");
+
+ })
+ .verifyComplete();
+ }
+
+ @Test
+ @DisplayName("create forest client")
+ void shouldCreateForestClientWhenNoBcRegData() {
+
+ SubmissionDetailEntity entity = SubmissionDetailEntity.builder()
+ .submissionId(2)
+ .submissionDetailId(2)
+ .organizationName("Baxter Corp")
+ .incorporationNumber("FM00184546")
+ .businessTypeCode("R")
+ .clientTypeCode("RSP")
+ .goodStandingInd("Y")
+ .build();
+
+ when(bcRegistryService.requestDocumentData(any(String.class)))
+ .thenReturn(Flux.empty());
+
+ when(submissionDetailRepository.findBySubmissionId(any()))
+ .thenReturn(Mono.just(entity));
+
+ when(contactRepository.findBySubmissionId(any()))
+ .thenReturn(Flux.just(SUBMISSION_CONTACT.withLastName("BAXTER")));
+
+ service
+ .generateForestClient(
+ MessageBuilder
+ .withPayload("00000001")
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000001")
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ assertThat(message)
+ .isNotNull()
+ .hasFieldOrProperty("payload");
+
+ assertThat(message.getPayload())
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("clientName", "BAXTER")
+ .hasFieldOrPropertyWithValue("legalFirstName", "JAMES")
+ .hasFieldOrPropertyWithValue("clientIdTypeCode", "OTHR")
+ .hasFieldOrPropertyWithValue("clientIdentification", "FM00184546")
+ .hasFieldOrPropertyWithValue("registryCompanyTypeCode", "FM")
+ .hasFieldOrPropertyWithValue("corpRegnNmbr", "00184546")
+ .hasFieldOrPropertyWithValue("clientComment",
+ String.join(" ",
+ "Sole proprietorship registered on BC Registry with number",
+ "FM00184546",
+ "and company name",
+ "BAXTER CORP"
+ )
+ )
+ .hasFieldOrPropertyWithValue("clientTypeCode", "I")
+ .hasFieldOrPropertyWithValue("clientNumber", "00000001");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.SUBMISSION_ID))
+ .isNotNull()
+ .isInstanceOf(Integer.class)
+ .isEqualTo(2);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CREATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.UPDATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("BAXTER CORP");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.INCORPORATION_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("FM00184546");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("00000001");
+
+ })
+ .verifyComplete();
+ }
+
+ @Test
+ @DisplayName("create client with doing business")
+ void shouldCreateClient() {
+ ReactiveInsert doingBusinessInsert = mock(ReactiveInsert.class);
+ ReactiveInsert clientInsert = mock(ReactiveInsert.class);
+
+ SubmissionDetailEntity detailEntity = SubmissionDetailEntity
+ .builder()
+ .submissionId(2)
+ .incorporationNumber("XX0000000")
+ .organizationName("Sample test")
+ .clientTypeCode("RSP")
+ .clientNumber("00000000")
+ .build();
+
+ when(submissionDetailRepository.findBySubmissionId(any()))
+ .thenReturn(Mono.just(detailEntity));
+ when(submissionDetailRepository.save(any()))
+ .thenReturn(Mono.just(detailEntity));
+ when(doingBusinessAsRepository.existsByClientNumber(any()))
+ .thenReturn(Mono.just(false));
+ when(legacyR2dbcEntityTemplate.selectOne(any(),any()))
+ .thenReturn(Mono.just(ClientDoingBusinessAsEntity.builder().id(1).build()));
+ when(legacyR2dbcEntityTemplate.insert(ForestClientEntity.class))
+ .thenReturn(clientInsert);
+ when(legacyR2dbcEntityTemplate.insert(ClientDoingBusinessAsEntity.class))
+ .thenReturn(doingBusinessInsert);
+ when(doingBusinessInsert.using(any()))
+ .thenReturn(Mono.just(ClientDoingBusinessAsEntity.builder().clientNumber("00000000")
+ .build()
+ )
+ );
+ when(clientInsert.using(any())).thenReturn(Mono.just(TestConstants.CLIENT_ENTITY));
+
+ service
+ .createForestClient(
+ MessageBuilder
+ .withPayload(
+ TestConstants
+ .CLIENT_ENTITY
+ .withClientTypeCode("I")
+ .withClientIdTypeCode("OTHR")
+ )
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.CLIENT_TYPE_CODE, "RSP")
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000000")
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NAME, "CHAMPAGNE SUPERNOVA")
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ Assertions.assertThat(message)
+ .as("message")
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("payload",2);
+
+
+ Assertions.assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .as("forest client number")
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("00000000");
+ })
+ .verifyComplete();
+
+ }
+
+ private static Stream byType(){
+ return Stream.of(
+ Arguments.of("I", false),
+ Arguments.of("C", false),
+ Arguments.of("USP", false),
+ Arguments.of("RSP", true)
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyUnregisteredSPPersistenceServiceTest.java b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyUnregisteredSPPersistenceServiceTest.java
new file mode 100644
index 0000000000..9cc137b830
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/legacy/LegacyUnregisteredSPPersistenceServiceTest.java
@@ -0,0 +1,156 @@
+package ca.bc.gov.app.service.legacy;
+
+import static ca.bc.gov.app.TestConstants.SUBMISSION_CONTACT;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.ApplicationConstant;
+import ca.bc.gov.app.entity.client.SubmissionDetailEntity;
+import ca.bc.gov.app.repository.client.CountryCodeRepository;
+import ca.bc.gov.app.repository.client.SubmissionContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionDetailRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationContactRepository;
+import ca.bc.gov.app.repository.client.SubmissionLocationRepository;
+import ca.bc.gov.app.repository.client.SubmissionRepository;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import java.util.stream.Stream;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.integration.support.MessageBuilder;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Legacy Unregistered Sole Proprietor Persistence Service")
+class LegacyUnregisteredSPPersistenceServiceTest {
+
+
+ private final SubmissionDetailRepository submissionDetailRepository = mock(
+ SubmissionDetailRepository.class);
+ private final SubmissionRepository submissionRepository = mock(SubmissionRepository.class);
+ private final SubmissionLocationRepository locationRepository = mock(
+ SubmissionLocationRepository.class);
+ private final SubmissionContactRepository contactRepository = mock(
+ SubmissionContactRepository.class);
+ private final SubmissionLocationContactRepository locationContactRepository = mock(
+ SubmissionLocationContactRepository.class);
+ private final R2dbcEntityTemplate legacyR2dbcEntityTemplate = mock(R2dbcEntityTemplate.class);
+ private final CountryCodeRepository countryCodeRepository = mock(CountryCodeRepository.class);
+ private final ClientDoingBusinessAsRepository doingBusinessAsRepository = mock(
+ ClientDoingBusinessAsRepository.class);
+
+ private final LegacyUnregisteredSPPersistenceService service = new LegacyUnregisteredSPPersistenceService(
+ submissionDetailRepository,
+ submissionRepository,
+ locationRepository,
+ contactRepository,
+ locationContactRepository,
+ legacyR2dbcEntityTemplate,
+ countryCodeRepository,
+ doingBusinessAsRepository
+ );
+
+ @ParameterizedTest(name = "type: {0} expected: {1}")
+ @MethodSource("byType")
+ @DisplayName("filter by type")
+ void shouldFilterByType(String type, boolean expected){
+ assertEquals(expected, service.filterByType(type));
+ }
+
+ @Test
+ @DisplayName("get next channel")
+ void shouldGetNextChannel(){
+ assertEquals(ApplicationConstant.SUBMISSION_LEGACY_USP_CHANNEL, service.getNextChannel());
+ }
+
+ @Test
+ @DisplayName("create forest client")
+ void shouldCreateForestClient() {
+
+ SubmissionDetailEntity entity = SubmissionDetailEntity.builder()
+ .submissionId(2)
+ .submissionDetailId(2)
+ .organizationName("Baxter, James")
+ .businessTypeCode("U")
+ .clientTypeCode("USP")
+ .goodStandingInd("Y")
+ .build();
+
+ when(submissionDetailRepository.findBySubmissionId(eq(2)))
+ .thenReturn(Mono.just(entity));
+
+ service
+ .generateForestClient(
+ MessageBuilder
+ .withPayload("00000001")
+ .setHeader(ApplicationConstant.SUBMISSION_ID, 2)
+ .setHeader(ApplicationConstant.FOREST_CLIENT_NUMBER, "00000001")
+ .setHeader(ApplicationConstant.CREATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .setHeader(ApplicationConstant.UPDATED_BY, ApplicationConstant.PROCESSOR_USER_NAME)
+ .build()
+ )
+ .as(StepVerifier::create)
+ .assertNext(message -> {
+ assertThat(message)
+ .isNotNull()
+ .hasFieldOrProperty("payload");
+
+ assertThat(message.getPayload())
+ .isNotNull()
+ .hasFieldOrPropertyWithValue("clientName", "BAXTER")
+ .hasFieldOrPropertyWithValue("legalFirstName", "JAMES")
+ .hasFieldOrPropertyWithValue("legalMiddleName", StringUtils.EMPTY)
+ .hasFieldOrPropertyWithValue("clientComment","Sole proprietorship with data acquired from BC Business eID")
+ .hasFieldOrPropertyWithValue("clientTypeCode", "I")
+ .hasFieldOrPropertyWithValue("clientNumber", "00000001");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.SUBMISSION_ID))
+ .isNotNull()
+ .isInstanceOf(Integer.class)
+ .isEqualTo(2);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.CREATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.UPDATED_BY))
+ .isNotNull()
+ .isInstanceOf(String.class);
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NAME))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("JAMES BAXTER");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.INCORPORATION_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("not applicable");
+
+ assertThat(message.getHeaders().get(ApplicationConstant.FOREST_CLIENT_NUMBER))
+ .isNotNull()
+ .isInstanceOf(String.class)
+ .isEqualTo("00000001");
+
+ })
+ .verifyComplete();
+ }
+
+ private static Stream byType(){
+ return Stream.of(
+ Arguments.of("I", false),
+ Arguments.of("C", false),
+ Arguments.of("USP", true),
+ Arguments.of("RSP", false)
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/processor/DoingBusinessAsProcessorMatcherTest.java b/processor/src/test/java/ca/bc/gov/app/service/processor/DoingBusinessAsProcessorMatcherTest.java
new file mode 100644
index 0000000000..0024623834
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/processor/DoingBusinessAsProcessorMatcherTest.java
@@ -0,0 +1,88 @@
+package ca.bc.gov.app.service.processor;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.dto.MatcherResult;
+import ca.bc.gov.app.dto.SubmissionInformationDto;
+import ca.bc.gov.app.entity.legacy.ClientDoingBusinessAsEntity;
+import ca.bc.gov.app.repository.legacy.ClientDoingBusinessAsRepository;
+import java.time.LocalDate;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import reactor.core.publisher.Flux;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Doing Business As Matcher")
+class DoingBusinessAsProcessorMatcherTest {
+
+ private final ClientDoingBusinessAsRepository repository = mock(
+ ClientDoingBusinessAsRepository.class);
+ ProcessorMatcher matcher = new DoingBusinessAsProcessorMatcher(repository);
+
+ @Test
+ @DisplayName("Name matching")
+ void shouldMatchName() {
+ assertEquals("Doing Business As Fuzzy Matcher", matcher.name());
+ }
+
+ @ParameterizedTest
+ @MethodSource("legalName")
+ @DisplayName("Match or not")
+ void shouldMatchOrNot(
+ SubmissionInformationDto dto,
+ boolean success,
+ MatcherResult result,
+ Flux mockData
+ ) {
+
+ when(repository.matchBy(dto.corporationName()))
+ .thenReturn(mockData);
+
+ StepVerifier.FirstStep verifier =
+ matcher
+ .matches(dto)
+ .as(StepVerifier::create);
+
+ if (success) {
+ verifier.verifyComplete();
+ } else {
+ verifier
+ .expectNext(result)
+ .verifyComplete();
+ }
+ }
+
+ private static Stream legalName() {
+ return
+ Stream.of(
+ Arguments.of(
+ new SubmissionInformationDto("James", LocalDate.of(1970, 3, 4), "FM001122334", "Y",
+ "RSP"),
+ true,
+ null,
+ Flux.empty()
+ ),
+ Arguments.of(
+ new SubmissionInformationDto("Marco Polo Navigation Inc", LocalDate.of(1970, 3, 4),
+ "FM001122334", "Y", "RSP"),
+ false,
+ new MatcherResult("corporationName", String.join(",", "00000000")),
+ Flux.just(new ClientDoingBusinessAsEntity().withClientNumber("00000000"))
+ ),
+ Arguments.of(
+ new SubmissionInformationDto("Lucca", null, null, null, "RSP"),
+ false,
+ new MatcherResult("corporationName", String.join(",", "00000000", "00000001")),
+ Flux.just(new ClientDoingBusinessAsEntity().withClientNumber("00000000"),
+ new ClientDoingBusinessAsEntity().withClientNumber("00000001"))
+ )
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcherTest.java b/processor/src/test/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcherTest.java
index 07ba9e09ef..d921072eb5 100644
--- a/processor/src/test/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcherTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/service/processor/GoodStandingProcessorMatcherTest.java
@@ -1,6 +1,7 @@
package ca.bc.gov.app.service.processor;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import ca.bc.gov.app.dto.MatcherResult;
import ca.bc.gov.app.dto.SubmissionInformationDto;
@@ -24,6 +25,17 @@ void shouldMatchName() {
assertEquals("Good Standing Matcher", matcher.name());
}
+ @ParameterizedTest
+ @MethodSource("goodStanding")
+ @DisplayName("Is enabled?")
+ void shouldBeEnableForAll(
+ SubmissionInformationDto dto,
+ boolean success,
+ MatcherResult result
+ ) {
+ assertTrue(matcher.enabled(dto));
+ }
+
@ParameterizedTest
@MethodSource("goodStanding")
@DisplayName("Match or not")
@@ -51,22 +63,22 @@ private static Stream goodStanding() {
return
Stream.of(
Arguments.of(
- new SubmissionInformationDto(null, null, StringUtils.EMPTY),
+ new SubmissionInformationDto(null, null,null, StringUtils.EMPTY,null),
false,
new MatcherResult("goodStanding", "Value not found")
),
Arguments.of(
- new SubmissionInformationDto(null, null, null),
+ new SubmissionInformationDto(null, null,null, null,null),
false,
new MatcherResult("goodStanding", "Value not found")
),
Arguments.of(
- new SubmissionInformationDto(null, null, "N"),
+ new SubmissionInformationDto(null, null,null, "N",null),
false,
new MatcherResult("goodStanding", "Client not in good standing")
),
Arguments.of(
- new SubmissionInformationDto(null, null, "Y"),
+ new SubmissionInformationDto(null, null,null, "Y",null),
true,
null
)
diff --git a/processor/src/test/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcherTest.java b/processor/src/test/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcherTest.java
index 8243705604..3d8de2ba1a 100644
--- a/processor/src/test/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcherTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/service/processor/IncorporationNumberProcessorMatcherTest.java
@@ -30,6 +30,18 @@ void shouldMatchName() {
assertEquals("Incorporation Number Matcher", matcher.name());
}
+ @ParameterizedTest
+ @MethodSource("incorporation")
+ @DisplayName("Match or not")
+ void shouldBeEnabled(
+ SubmissionInformationDto dto,
+ boolean success,
+ MatcherResult result,
+ Flux mockData
+ ) {
+ assertTrue(matcher.enabled(dto));
+ }
+
@ParameterizedTest
@MethodSource("incorporation")
@DisplayName("Match or not")
@@ -61,13 +73,13 @@ private static Stream incorporation() {
return
Stream.of(
Arguments.of(
- new SubmissionInformationDto(null, "00000007", null),
+ new SubmissionInformationDto(null,null, "00000007", null,"C"),
true,
null,
Flux.empty()
),
Arguments.of(
- new SubmissionInformationDto(null, "00000006", null),
+ new SubmissionInformationDto(null,null, "00000006", null,"C"),
false,
new MatcherResult("incorporationNumber", "00000006"),
Flux.just(new ForestClientEntity().withClientNumber("00000006"))
diff --git a/processor/src/test/java/ca/bc/gov/app/service/processor/IndividualProcessorMatcherTest.java b/processor/src/test/java/ca/bc/gov/app/service/processor/IndividualProcessorMatcherTest.java
new file mode 100644
index 0000000000..f6d38000f4
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/processor/IndividualProcessorMatcherTest.java
@@ -0,0 +1,89 @@
+package ca.bc.gov.app.service.processor;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.dto.MatcherResult;
+import ca.bc.gov.app.dto.SubmissionInformationDto;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.legacy.ForestClientRepository;
+import java.time.LocalDate;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import reactor.core.publisher.Flux;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Individual Matcher")
+class IndividualProcessorMatcherTest {
+
+
+ private final ForestClientRepository repository = mock(ForestClientRepository.class);
+ private final ProcessorMatcher matcher = new IndividualProcessorMatcher(repository);
+
+
+ @Test
+ @DisplayName("Name matching")
+ void shouldMatchName() {
+ assertEquals("Individual Matcher", matcher.name());
+ }
+
+ @ParameterizedTest
+ @MethodSource("legalName")
+ @DisplayName("Match or not")
+ void shouldMatchOrNot(
+ SubmissionInformationDto dto,
+ boolean success,
+ MatcherResult result,
+ Flux mockData
+ ) {
+
+ when(repository.findByIndividual(anyString(),anyString(),any()))
+ .thenReturn(mockData);
+
+ StepVerifier.FirstStep verifier =
+ matcher
+ .matches(dto)
+ .as(StepVerifier::create);
+
+ if (success) {
+ verifier.verifyComplete();
+ } else {
+ verifier
+ .expectNext(result)
+ .verifyComplete();
+ }
+ }
+
+ private static Stream legalName() {
+ return
+ Stream.of(
+ Arguments.of(
+ new SubmissionInformationDto("James Frank", LocalDate.of(1985,10,4), null, "Y", "I"),
+ true,
+ null,
+ Flux.empty()
+ ),
+ Arguments.of(
+ new SubmissionInformationDto("Marco Polo", LocalDate.of(1977,3,22), null, "Y", "I"),
+ false,
+ new MatcherResult("corporationName", String.join(",", "00000000")),
+ Flux.just(new ForestClientEntity().withClientNumber("00000000"))
+ ),
+ Arguments.of(
+ new SubmissionInformationDto("Lucca DeBiaggio", LocalDate.of(1951,12,25), null, "Y", "I"),
+ false,
+ new MatcherResult("corporationName", String.join(",", "00000000", "00000001")),
+ Flux.just(new ForestClientEntity().withClientNumber("00000000"),
+ new ForestClientEntity().withClientNumber("00000001"))
+ )
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcherTest.java b/processor/src/test/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcherTest.java
index a5fad5e087..e09985bfe2 100644
--- a/processor/src/test/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcherTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/service/processor/LegalNameProcessorMatcherTest.java
@@ -9,6 +9,7 @@
import ca.bc.gov.app.dto.SubmissionInformationDto;
import ca.bc.gov.app.entity.legacy.ForestClientEntity;
import ca.bc.gov.app.repository.legacy.ForestClientRepository;
+import java.time.LocalDate;
import java.util.stream.Stream;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -27,7 +28,7 @@ class LegalNameProcessorMatcherTest {
@Test
@DisplayName("Name matching")
void shouldMatchName() {
- assertEquals("Legal Name Matcher", matcher.name());
+ assertEquals("Legal Name Fuzzy Matcher", matcher.name());
}
@ParameterizedTest
@@ -40,7 +41,7 @@ void shouldMatchOrNot(
Flux mockData
) {
- when(repository.matchBy(dto.legalName()))
+ when(repository.matchBy(dto.corporationName()))
.thenReturn(mockData);
StepVerifier.FirstStep verifier =
@@ -61,21 +62,21 @@ private static Stream legalName() {
return
Stream.of(
Arguments.of(
- new SubmissionInformationDto("James", null, null),
+ new SubmissionInformationDto("James", null,null, null,"C"),
true,
null,
Flux.empty()
),
Arguments.of(
- new SubmissionInformationDto("Marco", null, null),
+ new SubmissionInformationDto("Marco", null, null, null,"C"),
false,
- new MatcherResult("legalName", String.join(",", "00000000")),
+ new MatcherResult("corporationName", String.join(",", "00000000")),
Flux.just(new ForestClientEntity().withClientNumber("00000000"))
),
Arguments.of(
- new SubmissionInformationDto("Lucca", null, null),
+ new SubmissionInformationDto("Lucca", null, null, null,"C"),
false,
- new MatcherResult("legalName", String.join(",", "00000000", "00000001")),
+ new MatcherResult("corporationName", String.join(",", "00000000", "00000001")),
Flux.just(new ForestClientEntity().withClientNumber("00000000"),
new ForestClientEntity().withClientNumber("00000001"))
)
diff --git a/processor/src/test/java/ca/bc/gov/app/service/processor/SoleProprietorProcessorMatcherTest.java b/processor/src/test/java/ca/bc/gov/app/service/processor/SoleProprietorProcessorMatcherTest.java
new file mode 100644
index 0000000000..3aed05a741
--- /dev/null
+++ b/processor/src/test/java/ca/bc/gov/app/service/processor/SoleProprietorProcessorMatcherTest.java
@@ -0,0 +1,91 @@
+package ca.bc.gov.app.service.processor;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.app.dto.MatcherResult;
+import ca.bc.gov.app.dto.SubmissionInformationDto;
+import ca.bc.gov.app.entity.legacy.ForestClientEntity;
+import ca.bc.gov.app.repository.legacy.ForestClientRepository;
+import java.time.LocalDate;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import reactor.core.publisher.Flux;
+import reactor.test.StepVerifier;
+
+@DisplayName("Unit Test | Sole Proprietor Matcher")
+class SoleProprietorProcessorMatcherTest {
+
+ private final ForestClientRepository repository = mock(ForestClientRepository.class);
+ private final ProcessorMatcher matcher = new SoleProprietorProcessorMatcher(repository);
+
+
+ @Test
+ @DisplayName("Name matching")
+ void shouldMatchName() {
+ assertEquals("Sole Proprietor Matcher", matcher.name());
+ }
+
+ @ParameterizedTest
+ @MethodSource("legalName")
+ @DisplayName("Match or not")
+ void shouldMatchOrNot(
+ SubmissionInformationDto dto,
+ boolean success,
+ MatcherResult result,
+ Flux mockData
+ ) {
+
+ when(repository.findByIndividual(anyString(), anyString(), any()))
+ .thenReturn(mockData);
+
+ StepVerifier.FirstStep verifier =
+ matcher
+ .matches(dto)
+ .as(StepVerifier::create);
+
+ if (success) {
+ verifier.verifyComplete();
+ } else {
+ verifier
+ .expectNext(result)
+ .verifyComplete();
+ }
+ }
+
+ private static Stream legalName() {
+ return
+ Stream.of(
+ Arguments.of(
+ new SubmissionInformationDto("James Frank", LocalDate.of(2023, 4, 5), null, null,
+ "USP"),
+ true,
+ null,
+ Flux.empty()
+ ),
+ Arguments.of(
+ new SubmissionInformationDto("Marco Polo", LocalDate.of(2023, 9, 12), null, null,
+ "RSP"),
+ false,
+ new MatcherResult("corporationName", String.join(",", "00000000")),
+ Flux.just(new ForestClientEntity().withClientNumber("00000000"))
+ ),
+ Arguments.of(
+ new SubmissionInformationDto("Lucca DeBiaggio", LocalDate.of(2023, 10, 11), null,
+ null, "USP"),
+ false,
+ new MatcherResult("corporationName", String.join(",", "00000000", "00000001")),
+ Flux.just(new ForestClientEntity().withClientNumber("00000000"),
+ new ForestClientEntity().withClientNumber("00000001"))
+ )
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/processor/src/test/java/ca/bc/gov/app/util/ProcessorUtilTest.java b/processor/src/test/java/ca/bc/gov/app/util/ProcessorUtilTest.java
index e360f8e18c..c93b9f777d 100644
--- a/processor/src/test/java/ca/bc/gov/app/util/ProcessorUtilTest.java
+++ b/processor/src/test/java/ca/bc/gov/app/util/ProcessorUtilTest.java
@@ -43,6 +43,12 @@ void shouldExtractNumbers(String input, String expectedLetters, String expectedN
Assertions.assertEquals(expectedNumbers, ProcessorUtil.extractNumbers(input));
}
+ @ParameterizedTest(name = "should split name {0} and get {1}")
+ @MethodSource("splitName")
+ @DisplayName("should split name")
+ void shouldSplitName(String input, String[] expected) {
+ Assertions.assertArrayEquals(expected, ProcessorUtil.splitName(input));
+ }
private static Stream readHeader() {
return Stream.of(
@@ -61,5 +67,40 @@ private static Stream extract() {
);
}
+ private static Stream splitName() {
+ return
+ Stream.of(
+ Arguments.of(
+ "John Doe",
+ new String[]{"Doe", "John", ""}
+ ),
+ Arguments.of(
+ "Doe, John",
+ new String[]{"Doe", "John", ""}
+ ),
+ Arguments.of(
+ "John Doe Smith",
+ new String[]{"Smith", "John", "Doe"}
+ ),
+ Arguments.of(
+ "Doe, John Smith",
+ new String[]{"Doe", "John", "Smith"}
+ ),
+ Arguments.of(
+ "John Doe Smith Jones",
+ new String[]{"Jones", "John", "Doe Smith"}
+ ),
+ Arguments.of("Jhon", new String[]{"Jhon", "Jhon", ""}),
+ Arguments.of(StringUtils.EMPTY,
+ new String[]{StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY}
+ ),
+ Arguments.of(null,
+ new String[]{StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY}
+ ),
+ Arguments.of(" ",
+ new String[]{StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY}
+ )
+ );
+ }
}
\ No newline at end of file
diff --git a/processor/src/test/resources/application-default.yml b/processor/src/test/resources/application-default.yml
index db7953d9c7..b3b7a4db5c 100644
--- a/processor/src/test/resources/application-default.yml
+++ b/processor/src/test/resources/application-default.yml
@@ -14,6 +14,15 @@ spring:
url: jdbc:oracle:thin:@${ca.bc.gov.nrs.oracle.host}:${ca.bc.gov.nrs.oracle.port}/${ca.bc.gov.nrs.oracle.service}
+ca:
+ bc:
+ gov:
+ nrs:
+ bcregistry:
+ uri: 'http://127.0.0.1:10040'
+ apiKey: abc1234
+ accountId: 'account 0000'
+
logging:
level:
org:
diff --git a/processor/src/test/resources/init_pg.sql b/processor/src/test/resources/init_pg.sql
index 6e1bb2be65..e2aec3d751 100644
--- a/processor/src/test/resources/init_pg.sql
+++ b/processor/src/test/resources/init_pg.sql
@@ -32,7 +32,7 @@ drop sequence if exists nrfc.submission_submitter_seq;
create schema if not exists nrfc;
create table if not exists nrfc.client_type_code (
- client_type_code varchar(1) not null,
+ client_type_code varchar(5) not null,
description varchar(100) not null,
effective_date date not null,
expiry_date date default to_date('99991231','YYYYMMDD') not null,
@@ -54,7 +54,7 @@ comment on column nrfc.client_type_code.create_user is 'The user or proxy accoun
comment on column nrfc.client_type_code.update_user is 'The user or proxy account that created or last updated the record.';
create table if not exists nrfc.submission_status_code (
- submission_status_code varchar(5) not null,
+ submission_status_code varchar(5) not null,
description varchar(100) not null,
effective_date date not null,
expiry_date date default to_date('99991231','YYYYMMDD') not null,
@@ -192,13 +192,13 @@ comment on column nrfc.business_type_code.create_user is 'The user or proxy acco
comment on column nrfc.business_type_code.update_user is 'The user or proxy account that created or last updated the record.';
create table if not exists nrfc.submission(
- submission_id integer not null,
- submission_status_code varchar(5) null,
- submission_type_code varchar(5) null,
+ submission_id integer not null,
+ submission_status_code varchar(5) null,
+ submission_type_code varchar(5) null,
submission_date timestamp null,
update_timestamp timestamp default current_timestamp,
create_user varchar(60) not null,
- update_user varchar(60) null,
+ update_user varchar(60) null,
constraint submission_pk primary key (submission_id),
constraint submission_submission_status_code_fk foreign key (submission_status_code) references nrfc.submission_status_code(submission_status_code),
constraint submission_submission_type_code_fk foreign key (submission_type_code) references nrfc.submission_type_code(submission_type_code)
@@ -220,8 +220,9 @@ create table if not exists nrfc.submission_detail (
business_type_code varchar(1) not null,
incorporation_number varchar(50) null,
organization_name varchar(100) null,
- client_type_code varchar(1) not null,
+ client_type_code varchar(5) not null,
good_standing_ind varchar(1) null,
+ birthdate date null,
constraint submission_detail_id_pk primary key (submission_detail_id),
constraint submission_id_fk foreign key (submission_id) references nrfc.submission(submission_id),
constraint submission_detail_business_type_code_fk foreign key (business_type_code) references nrfc.business_type_code(business_type_code),
@@ -236,6 +237,7 @@ comment on column nrfc.submission_detail.incorporation_number is 'A number provi
comment on column nrfc.submission_detail.organization_name is 'The name of the client.';
comment on column nrfc.submission_detail.client_type_code is 'A code representing the type of a client.';
comment on column nrfc.submission_detail.good_standing_ind is 'An indicator that determines whether a client is in good standing with respect to their financial obligations.';
+comment on column nrfc.submission_detail.birthdate is 'The date that the BC Services Card logged in person was born.';
create table if not exists nrfc.submission_matching_detail (
submission_matching_detail_id integer not null,
@@ -368,6 +370,8 @@ insert into nrfc.client_type_code (client_type_code, description, effective_date
insert into nrfc.client_type_code (client_type_code, description, effective_date, create_user) values ('S', 'Society', current_timestamp, 'mariamar') on conflict (client_type_code) do nothing;
insert into nrfc.client_type_code (client_type_code, description, effective_date, create_user) values ('T', 'First Nation Tribal Council', current_timestamp, 'mariamar') on conflict (client_type_code) do nothing;
insert into nrfc.client_type_code (client_type_code, description, effective_date, create_user) values ('U', 'Unregistered Company', current_timestamp, 'mariamar') on conflict (client_type_code) do nothing;
+insert into nrfc.client_type_code (client_type_code, description, effective_date, create_user) values ('USP', 'Unregistered sole proprietorship', current_timestamp, 'mariamar') on conflict (client_type_code) do nothing;
+insert into nrfc.client_type_code (client_type_code, description, effective_date, create_user) values ('RSP', 'Registered sole proprietorship', current_timestamp, 'mariamar') on conflict (client_type_code) do nothing;
insert into nrfc.contact_type_code (contact_type_code, description, effective_date, create_user) values ('AP', 'Accounts Payable', current_timestamp, 'mariamar') on conflict (contact_type_code) do nothing;
insert into nrfc.contact_type_code (contact_type_code, description, effective_date, create_user) values ('AR', 'Accounts Receivable', current_timestamp, 'mariamar') on conflict (contact_type_code) do nothing;