+
+
+
diff --git a/legacy/docs/intellij-run-config.png b/legacy/docs/intellij-run-config.png
new file mode 100644
index 0000000000..b9c70d20e3
Binary files /dev/null and b/legacy/docs/intellij-run-config.png differ
diff --git a/legacy/openshift.deploy.yml b/legacy/openshift.deploy.yml
index e42b69bdf7..1f8f0eecfa 100644
--- a/legacy/openshift.deploy.yml
+++ b/legacy/openshift.deploy.yml
@@ -24,9 +24,6 @@ parameters:
- name: PROMOTE
description: Image (namespace/name:tag) to promote/import
value: bcgov/nr-old-growth:prod-backend
- - name: FOREST_API_URL
- description: Forest Client service api url
- required: true
- name: ORACLEDB_KEYSTORE
description: Oracle database keystore file
- name: CPU_REQUEST
@@ -37,6 +34,9 @@ parameters:
value: 75Mi
- name: MEMORY_LIMIT
value: 75Mi
+ - name: BCREGISTRY_URI
+ description: Bc Registry API address
+ required: true
objects:
- apiVersion: v1
kind: ImageStream
@@ -85,6 +85,8 @@ objects:
volumes:
- name: certs
emptyDir: { }
+ - name: reports
+ emptyDir: { }
initContainers:
- name: ${NAME}-init
image: ${REGISTRY}/bcgov/${NAME}/common:${ZONE}
@@ -104,15 +106,11 @@ objects:
- image: ${NAME}-${ZONE}-${COMPONENT}:${IMAGE_TAG}
imagePullPolicy: Always
name: ${NAME}
- env:
- - name: FRONTEND_URL
- value: https://${NAME}-${ZONE}-frontend.${DOMAIN}
+ env:
- name: BACKEND_URL
value: https://${NAME}-${ZONE}-backend.${DOMAIN}
- - name: LEGACY_URL
- value: https://${NAME}-${ZONE}-legacy.${DOMAIN}
- name: FOREST_API_URL
- value: ${FOREST_API_URL}
+ value: https://${NAME}-${ZONE}-legacy.${DOMAIN}
- name: ORACLEDB_USER
valueFrom:
secretKeyRef:
@@ -147,6 +145,18 @@ objects:
key: oracle-secret
- name: ORACLEDB_KEYSTORE
value: /cert/jssecacerts
+ - 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: 9000
protocol: TCP
@@ -180,6 +190,8 @@ objects:
volumeMounts:
- mountPath: /cert
name: certs
+ - mountPath: /workspace/temp
+ name: reports
- apiVersion: v1
kind: Service
metadata:
diff --git a/legacy/pom.xml b/legacy/pom.xml
index 6f76a11d67..546cb1dfa4 100644
--- a/legacy/pom.xml
+++ b/legacy/pom.xml
@@ -67,6 +67,7 @@
2022.0.1${project.version}
+ 5.2.3
@@ -114,6 +115,12 @@
true
+
+ org.dhatim
+ fastexcel
+ 0.15.3
+
+
org.springframework.bootspring-boot-starter-test
@@ -211,7 +218,7 @@
gcr.io/paketo-buildpacks/image-labels
- 19.0.2
+ 17https://github.com/bcgov/nr-forest-client${project.version}${project.description}
@@ -272,7 +279,7 @@
org.jacocojacoco-maven-plugin
- 0.8.9
+ 0.8.8${jacoco.skip}
diff --git a/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java b/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java
index 31e73eeb28..f77b71ea21 100644
--- a/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java
+++ b/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java
@@ -3,8 +3,10 @@
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.servers.Server;
+import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@OpenAPIDefinition(info = @Info(
@@ -16,9 +18,12 @@
@Server(url = "/", description = "Default Server URL")
}
)
+@EnableScheduling
public class LegacyApplication {
public static void main(String[] args) {
+ SLF4JBridgeHandler.removeHandlersForRootLogger();
+ SLF4JBridgeHandler.install();
SpringApplication.run(LegacyApplication.class, args);
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java b/legacy/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java
index beab39167a..17ce1298b7 100644
--- a/legacy/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java
+++ b/legacy/src/main/java/ca/bc/gov/app/configuration/GlobalServiceConfiguration.java
@@ -1,15 +1,31 @@
package ca.bc.gov.app.configuration;
+import ca.bc.gov.app.dto.OrgBookTopicDto;
+import ca.bc.gov.app.dto.OrgBookTopicListResponse;
+import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
+@RegisterReflectionForBinding({OrgBookTopicDto.class, OrgBookTopicListResponse.class})
public class GlobalServiceConfiguration {
+ /**
+ * Creates and configures a WebClient instance for accessing OrgBook API based on the provided
+ * {@link LegacyConfiguration}.
+ *
+ * @param configuration The {@link LegacyConfiguration} containing the OrgBook API URI.
+ * @return A {@link WebClient} instance configured for accessing OrgBook API.
+ */
@Bean
- public WebClient forestClientApi(ForestConfiguration configuration) {
- return WebClient.builder().baseUrl(configuration.getUri()).build();
+ public WebClient orgBookApi(LegacyConfiguration configuration) {
+ return WebClient.builder().baseUrl(configuration.getOrgbook()).build();
+ }
+
+ @Bean
+ public WebClient forestClientApi(LegacyConfiguration configuration) {
+ return WebClient.builder().baseUrl(configuration.getForest().getUri()).build();
}
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/configuration/ForestConfiguration.java b/legacy/src/main/java/ca/bc/gov/app/configuration/LegacyConfiguration.java
similarity index 54%
rename from legacy/src/main/java/ca/bc/gov/app/configuration/ForestConfiguration.java
rename to legacy/src/main/java/ca/bc/gov/app/configuration/LegacyConfiguration.java
index c0f85ce886..49760e46bd 100644
--- a/legacy/src/main/java/ca/bc/gov/app/configuration/ForestConfiguration.java
+++ b/legacy/src/main/java/ca/bc/gov/app/configuration/LegacyConfiguration.java
@@ -12,7 +12,16 @@
@NoArgsConstructor
@AllArgsConstructor
@Component
-@ConfigurationProperties("ca.bc.gov.nrs.forest")
-public class ForestConfiguration {
- private String uri;
+@ConfigurationProperties("ca.bc.gov.nrs")
+public class LegacyConfiguration {
+ private ForestClientConfiguration forest;
+ private String orgbook;
+
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class ForestClientConfiguration {
+ private String uri;
+ }
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/controller/ClientSearchController.java b/legacy/src/main/java/ca/bc/gov/app/controller/ClientSearchController.java
index 36e91ed31d..a518a83f44 100644
--- a/legacy/src/main/java/ca/bc/gov/app/controller/ClientSearchController.java
+++ b/legacy/src/main/java/ca/bc/gov/app/controller/ClientSearchController.java
@@ -75,57 +75,5 @@ public Flux findByIncorporationOrName(
.findByIncorporationOrName(incorporationNumber, companyName);
}
- @GetMapping("/nameAndBirth")
- @Operation(
- summary = "List forest client entries by first name, last name and date of birth",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "Returns a client based on it's number",
- content = @Content(
- mediaType = MediaType.APPLICATION_JSON_VALUE,
- array = @ArraySchema(
- schema = @Schema(
- name = "ForestClient",
- implementation = ForestClientDto.class
- )
- )
- )
- )
- }
- )
- public Flux findByNameAndBirth(
- @Parameter(
- description = "First name to lookup. For companies, you can pass an empty value",
- example = "Jhon",
- required = false
- )
- @RequestParam(required = false,defaultValue = "") String firstName,
-
- @Parameter(
- description = "Last name to lookup. For companies, this will be the company name",
- example = "Doh",
- required = false
- )
- @RequestParam(required = false) String lastName,
-
- @Parameter(
- description = """
- Date of birth to lookup in an ISO Local Date format,
- such as YYYY-MM-dd.
- For companies, you can pass an empty value""",
- example = "1955-05-09",
- required = false
- )
- @RequestParam(required = false,defaultValue = "") String birthdate
- ) {
- return service
- .findByNameAndBirth(
- Optional.ofNullable(firstName),
- Optional.ofNullable(lastName),
- Optional.ofNullable(birthdate)
- );
- }
-
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/controller/ForestClientController.java b/legacy/src/main/java/ca/bc/gov/app/controller/ForestClientController.java
deleted file mode 100644
index 0547917c97..0000000000
--- a/legacy/src/main/java/ca/bc/gov/app/controller/ForestClientController.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package ca.bc.gov.app.controller;
-
-import ca.bc.gov.app.dto.ClientPublicViewDto;
-import ca.bc.gov.app.dto.FirstNationBandVidationDto;
-import ca.bc.gov.app.dto.ForestClientDto;
-import ca.bc.gov.app.service.ForestClientService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.ArraySchema;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.ExampleObject;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import reactor.core.publisher.Flux;
-
-@RestController
-@Slf4j
-@Tag(
- name = "Forest Client",
- description = "Aggregation and other reports for forest clients"
-)
-@RequestMapping(value = "/api/client", produces = MediaType.APPLICATION_JSON_VALUE)
-@RequiredArgsConstructor
-public class ForestClientController {
-
- private final ForestClientService service;
-
- @GetMapping("/bands")
- @Operation(
- summary = "List First nation band validation information",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "Returns a client based on it's number",
- content = @Content(
- mediaType = MediaType.APPLICATION_JSON_VALUE,
- array = @ArraySchema(
- schema = @Schema(
- name = "FirstNationBand",
- implementation = FirstNationBandVidationDto.class
- )
- )
- )
- )
- }
- )
- public Flux getFirstNationBandInfo() {
- return service.getFirstNationBandInfo();
- }
-
-
- @GetMapping("/business")
- @Operation(
- summary = "List all clients we are doing business with",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "Returns a client based on it's number",
- content = @Content(
- mediaType = MediaType.APPLICATION_JSON_VALUE,
- array = @ArraySchema(
- schema = @Schema(
- name = "ClientInformation",
- implementation = ClientPublicViewDto.class
- )
- )
- )
- )
- }
- )
- public Flux getClientDoingBusiness() {
- return service.getClientDoingBusiness();
- }
-
- @GetMapping("/unregistered")
- @Operation(
- summary = "List all clients that are unregistered",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "Returns a client based on it's number",
- content = @Content(
- mediaType = MediaType.APPLICATION_JSON_VALUE,
- array = @ArraySchema(
- schema = @Schema(
- name = "ClientInformation",
- implementation = ClientPublicViewDto.class
- )
- )
- )
- )
- }
- )
- public Flux getUnregisteredCompanies() {
- return service.getUnregisteredCompanies();
- }
-}
diff --git a/legacy/src/main/java/ca/bc/gov/app/controller/ReportingClientController.java b/legacy/src/main/java/ca/bc/gov/app/controller/ReportingClientController.java
new file mode 100644
index 0000000000..aeef408bf2
--- /dev/null
+++ b/legacy/src/main/java/ca/bc/gov/app/controller/ReportingClientController.java
@@ -0,0 +1,75 @@
+package ca.bc.gov.app.controller;
+
+import ca.bc.gov.app.service.ReportingClientService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.io.File;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ZeroCopyHttpOutputMessage;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+@RestController
+@Slf4j
+@Tag(
+ name = "Forest Client Reporting",
+ description = "Generate reports for the forest client"
+)
+@RequestMapping(value = "/api/reports", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+@RequiredArgsConstructor
+public class ReportingClientController {
+
+ private final ReportingClientService service;
+
+ @GetMapping("/all")
+ @Operation(summary = "Get an excel report file for all existing forest clients")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Excel file generated successfully"),
+ @ApiResponse(responseCode = "500", description = "Internal server error")
+ })
+ public Mono getAllClientsReport(ServerHttpResponse response) {
+ return
+ getReport(
+ service.generateAllClientsReport(),
+ response,
+ "All Clients"
+ );
+ }
+
+ @GetMapping("/businessAs")
+ @Operation(summary = "Get a business as excel report file")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Excel file generated successfully"),
+ @ApiResponse(responseCode = "500", description = "Internal server error")
+ })
+ public Mono getBusinessAsReport(ServerHttpResponse response) {
+ return
+ getReport(
+ service.generateDoingBusinessAsReport(),
+ response,
+ "Business As"
+ );
+ }
+
+ private Mono getReport(Mono request, ServerHttpResponse response, String fileName) {
+ ZeroCopyHttpOutputMessage zeroCopyResponse = (ZeroCopyHttpOutputMessage) response;
+ zeroCopyResponse.getHeaders()
+ .set(HttpHeaders.CONTENT_DISPOSITION,
+ "attachment; filename=FC Report " + fileName + ".xlsx");
+ zeroCopyResponse.getHeaders().setContentType(MediaType.APPLICATION_OCTET_STREAM);
+
+ return
+ request
+ .doOnNext(sheet -> zeroCopyResponse.getHeaders().setContentLength(sheet.length()))
+ .flatMap(sheet -> zeroCopyResponse.writeWith(sheet, 0, sheet.length()));
+ }
+
+}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/ClientNameCodeDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/ClientNameCodeDto.java
new file mode 100644
index 0000000000..2256d9a9c0
--- /dev/null
+++ b/legacy/src/main/java/ca/bc/gov/app/dto/ClientNameCodeDto.java
@@ -0,0 +1,4 @@
+package ca.bc.gov.app.dto;
+
+public record ClientNameCodeDto(String code, String name) {
+}
\ No newline at end of file
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicFilterObjectDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicFilterObjectDto.java
deleted file mode 100644
index b7ea13d2b0..0000000000
--- a/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicFilterObjectDto.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package ca.bc.gov.app.dto;
-
-public record ClientPublicFilterObjectDto(
- String clientName,
- String clientFirstName,
- String clientMiddleName,
- String clientTypeCodesAsCsv,
- int currentPage,
- int itemsPerPage
-) {
-}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicViewDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicViewDto.java
index b7a043416f..d0d4dfc9d0 100644
--- a/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicViewDto.java
+++ b/legacy/src/main/java/ca/bc/gov/app/dto/ClientPublicViewDto.java
@@ -1,22 +1,56 @@
package ca.bc.gov.app.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
public record ClientPublicViewDto(
String clientNumber,
- String incorporationNumber,
String clientName,
- String legalFirstName,
- String legalMiddleName,
- String clientStatusCode,
- String clientTypeCode,
- String clientNameInOrgBook
+ String incorporationNumber,
+
+ String orgBookNumber,
+
+ String orgBookName,
+ boolean status
) {
@JsonProperty
- public boolean sameName() {
- return StringUtils.equalsIgnoreCase(clientNameInOrgBook, clientName);
+ public String sameName() {
+ return
+ BooleanUtils.toStringYesNo(
+ StringUtils.equalsIgnoreCase(orgBookName, clientName)
+ );
+ }
+
+ @JsonProperty
+ public String sameNumber() {
+ return
+ BooleanUtils.toStringYesNo(
+ StringUtils.equalsIgnoreCase(orgBookNumber, incorporationNumber)
+ );
}
+
+ @JsonProperty
+ public String found() {
+ return
+ BooleanUtils.toString(
+ StringUtils.equalsIgnoreCase(orgBookName, clientName)
+ && StringUtils.equalsIgnoreCase(orgBookNumber, incorporationNumber),
+ "F",
+ BooleanUtils.toString(
+ StringUtils.equalsIgnoreCase(orgBookName, clientName)
+ || StringUtils.equalsIgnoreCase(orgBookNumber, incorporationNumber),
+ "PF",
+ "NF"
+ )
+ );
+ }
+
+ @JsonProperty
+ public String active() {
+ return BooleanUtils.toStringYesNo(status);
+ }
+
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/ClientTypeCodes.java b/legacy/src/main/java/ca/bc/gov/app/dto/ClientTypeCodes.java
deleted file mode 100644
index 06f96a9d46..0000000000
--- a/legacy/src/main/java/ca/bc/gov/app/dto/ClientTypeCodes.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package ca.bc.gov.app.dto;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-
-public enum ClientTypeCodes {
- INDIVIDUAL("I"),
- ASSOCIATION("A"),
- CORPORATION("C"),
- FIRST_NATION_BAND("B"),
- UNREGISTERED_COMPANY("U");
-
- private final String value;
-
- ClientTypeCodes(String value) {
- this.value = value;
- }
-
- @JsonValue
- public String value() {
- return this.value;
- }
-
- @JsonCreator
- public static ClientTypeCodes fromValue(String value) {
- for (ClientTypeCodes c : values()) {
- if (c.value().equalsIgnoreCase(value)) {
- return c;
- }
- }
- throw new IllegalArgumentException(value);
- }
-
-}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/FirstNationBandVidationDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/FirstNationBandVidationDto.java
deleted file mode 100644
index 9eccba35b5..0000000000
--- a/legacy/src/main/java/ca/bc/gov/app/dto/FirstNationBandVidationDto.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package ca.bc.gov.app.dto;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import org.apache.commons.lang3.StringUtils;
-
-public record FirstNationBandVidationDto(
- String clientNumber,
- String corpRegnNmbr,
- String clientName,
- String sourceClientName,
- String addressOne,
- String sourceAddressOne,
- String addressTwo,
- String sourceAddressTwo,
- String city,
- String sourceCity,
- String province,
- String sourceProvince,
- String postalCode,
- String sourcePostalCode
-) {
- @JsonProperty
- public boolean nameMatch() {
- return StringUtils.equalsIgnoreCase(clientName, sourceClientName);
- }
-
- @JsonProperty
- public boolean addressMatch() {
-
- return
- (
- (
- StringUtils.isNotBlank(addressOne)
- && StringUtils.isNotBlank(sourceAddressOne)
- && addressOne.equalsIgnoreCase(
- sourceAddressOne.replace(".", "")
- )
- )
- || (
- StringUtils.isNotBlank(addressTwo)
- && StringUtils.isNotBlank(sourceAddressTwo)
- && addressTwo.equalsIgnoreCase(
- sourceAddressTwo.replace(".", "")
- )
- )
- )
- && StringUtils.equalsIgnoreCase(city, sourceCity)
- && (
- StringUtils.isNotBlank(postalCode)
- && postalCode.equalsIgnoreCase(
- sourcePostalCode.replaceAll("\\s", "")
- )
- );
- }
-}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/ForestClientDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/ForestClientDto.java
index dcc0fef2e4..f6f5b03ab0 100644
--- a/legacy/src/main/java/ca/bc/gov/app/dto/ForestClientDto.java
+++ b/legacy/src/main/java/ca/bc/gov/app/dto/ForestClientDto.java
@@ -9,7 +9,6 @@ public record ForestClientDto(
String legalMiddleName,
String clientStatusCode,
String clientTypeCode,
- LocalDate birthdate,
String clientIdTypeCode,
String clientIdentification,
String registryCompanyTypeCode,
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookNameDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookNameDto.java
index 56524d21ab..4006abd951 100644
--- a/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookNameDto.java
+++ b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookNameDto.java
@@ -2,27 +2,17 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
+import java.util.List;
-@Schema(name = "NamedResult")
@JsonIgnoreProperties(ignoreUnknown = true)
public record OrgBookNameDto(
- @Schema(
- name = "value",
- title = "Name of the entity being searched",
- example = "U3 POWER CORP",
- requiredMode = Schema.RequiredMode.REQUIRED
- )
- String value,
- @Schema(
- name = "topic_source_id",
- title = "The incorporation ID",
- example = "BC0772006",
- requiredMode = Schema.RequiredMode.REQUIRED
- )
+ String value,
+ @JsonProperty("sub_type")
+ String subType,
@JsonProperty("topic_source_id")
- String topicSourceId
+ String topicSourceId,
+ List names
) {
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicDto.java
new file mode 100644
index 0000000000..eb2cc3736b
--- /dev/null
+++ b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicDto.java
@@ -0,0 +1,27 @@
+package ca.bc.gov.app.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record OrgBookTopicDto(
+ Integer id,
+ @JsonProperty("source_id") String sourceId,
+ List names,
+ Boolean inactive
+) {
+ public String name() {
+ if (CollectionUtils.isEmpty(names)) {
+ return StringUtils.EMPTY;
+ }
+ return names
+ .stream()
+ .filter(entry -> entry.topicNameType().equalsIgnoreCase("entity_name"))
+ .map(OrgBookTopicNameDto::text)
+ .findFirst()
+ .orElse(StringUtils.EMPTY);
+ }
+}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicListResponse.java b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicListResponse.java
new file mode 100644
index 0000000000..389ac3239b
--- /dev/null
+++ b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicListResponse.java
@@ -0,0 +1,15 @@
+package ca.bc.gov.app.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record OrgBookTopicListResponse(
+ int total,
+ Integer page,
+ @JsonProperty("page_size")
+ Integer pageSize,
+ List results
+) {
+}
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicNameDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicNameDto.java
new file mode 100644
index 0000000000..8eb060528a
--- /dev/null
+++ b/legacy/src/main/java/ca/bc/gov/app/dto/OrgBookTopicNameDto.java
@@ -0,0 +1,11 @@
+package ca.bc.gov.app.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record OrgBookTopicNameDto(
+ String text,
+ @JsonProperty("type") String topicNameType
+) {
+}
\ No newline at end of file
diff --git a/legacy/src/main/java/ca/bc/gov/app/dto/PropertyDto.java b/legacy/src/main/java/ca/bc/gov/app/dto/PropertyDto.java
deleted file mode 100644
index 17cd2ad96e..0000000000
--- a/legacy/src/main/java/ca/bc/gov/app/dto/PropertyDto.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package ca.bc.gov.app.dto;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public record PropertyDto(
- @JsonProperty("FIRST_NATION_FEDERAL_NAME") String firstNationFederalName,
- @JsonProperty("FIRST_NATION_FEDERAL_ID") Integer firstNationFederalId,
- @JsonProperty("ADDRESS_LINE1") String addressLine1,
- @JsonProperty("ADDRESS_LINE2") String addressLine2,
- @JsonProperty("OFFICE_CITY") String officeCity,
- @JsonProperty("OFFICE_PROVINCE") String officeProvince,
- @JsonProperty("OFFICE_POSTAL_CODE") String officePostalCode
-) {
-}
\ No newline at end of file
diff --git a/legacy/src/main/java/ca/bc/gov/app/entity/ClientLocationEntity.java b/legacy/src/main/java/ca/bc/gov/app/entity/ClientLocationEntity.java
index 62efbefc06..15b4dd24c2 100644
--- a/legacy/src/main/java/ca/bc/gov/app/entity/ClientLocationEntity.java
+++ b/legacy/src/main/java/ca/bc/gov/app/entity/ClientLocationEntity.java
@@ -82,24 +82,4 @@ public class ClientLocationEntity {
@Column("CLI_LOCN_COMMENT ")
private String cliLocnComment;
- @Column("UPDATE_TIMESTAMP")
- private LocalDate updateTimestamp;
-
- @Column("UPDATE_USERID")
- private String updateUserId;
-
- @Column("UPDATE_ORG_UNIT")
- private Long updateOrgUnit;
-
- @Column("ADD_TIMESTAMP")
- private LocalDate addTimestamp;
-
- @Column("ADD_USERID")
- private String addUserId;
-
- @Column("ADD_ORG_UNIT")
- private Long addOrgUnit;
-
- @Column("REVISION_COUNT")
- private Long revisionCount;
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/entity/ClientStatusCodeEntity.java b/legacy/src/main/java/ca/bc/gov/app/entity/ClientStatusCodeEntity.java
index b151561476..dd7676da34 100644
--- a/legacy/src/main/java/ca/bc/gov/app/entity/ClientStatusCodeEntity.java
+++ b/legacy/src/main/java/ca/bc/gov/app/entity/ClientStatusCodeEntity.java
@@ -20,8 +20,6 @@
@Table(name = "CLIENT_STATUS_CODE", schema = ORACLE_ATTRIBUTE_SCHEMA)
public class ClientStatusCodeEntity {
- public static final String ACTIVE = "ACT"; //TODO: move to enum
-
@Id
@Column("CLIENT_STATUS_CODE")
private String clientStatusCode;
@@ -35,16 +33,4 @@ public class ClientStatusCodeEntity {
@Column("EXPIRY_DATE")
private LocalDate expiryDate;
- @Column("CREATE_TIMESTAMP")
- private LocalDate createTimestamp;
-
- @Column("UPDATE_TIMESTAMP")
- private LocalDate updateTimestamp;
-
- @Column("CREATE_USER")
- private String createUser;
-
- @Column("UPDATE_USER")
- private String updateUser;
-
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/entity/ForestClientEntity.java b/legacy/src/main/java/ca/bc/gov/app/entity/ForestClientEntity.java
index 6246427754..2a10927378 100644
--- a/legacy/src/main/java/ca/bc/gov/app/entity/ForestClientEntity.java
+++ b/legacy/src/main/java/ca/bc/gov/app/entity/ForestClientEntity.java
@@ -41,9 +41,6 @@ public class ForestClientEntity {
@Column("CLIENT_TYPE_CODE")
private String clientTypeCode;
- @Column("BIRTHDATE")
- private LocalDate birthdate;
-
@Column("CLIENT_ID_TYPE_CODE")
private String clientIdTypeCode;
@@ -68,26 +65,4 @@ public class ForestClientEntity {
@Column("CLIENT_COMMENT")
private String clientComment;
- @Column("ADD_TIMESTAMP")
- private LocalDateTime addTimestamp;
-
- @Column("ADD_USERID")
- private String addUserId;
-
- @Column("ADD_ORG_UNIT")
- private Long addOrgUnit;
-
- @Column("UPDATE_TIMESTAMP")
- private LocalDateTime updateTimestamp;
-
- @Column("UPDATE_USERID")
- private String updateUserId;
-
- @Column("UPDATE_ORG_UNIT")
- private Long updateOrgUnit;
-
- @Column("REVISION_COUNT")
- private Long revisionCount;
-
-
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/exception/CannotWriteReportException.java b/legacy/src/main/java/ca/bc/gov/app/exception/CannotWriteReportException.java
new file mode 100644
index 0000000000..7debb59a3d
--- /dev/null
+++ b/legacy/src/main/java/ca/bc/gov/app/exception/CannotWriteReportException.java
@@ -0,0 +1,12 @@
+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.UNPROCESSABLE_ENTITY)
+public class CannotWriteReportException extends ResponseStatusException {
+ public CannotWriteReportException(String errorMessage) {
+ super(HttpStatus.UNPROCESSABLE_ENTITY,errorMessage);
+ }
+}
diff --git a/legacy/src/main/java/ca/bc/gov/app/repository/ClientDoingBusinessAsRepository.java b/legacy/src/main/java/ca/bc/gov/app/repository/ClientDoingBusinessAsRepository.java
index 80e633843a..54d41136fa 100644
--- a/legacy/src/main/java/ca/bc/gov/app/repository/ClientDoingBusinessAsRepository.java
+++ b/legacy/src/main/java/ca/bc/gov/app/repository/ClientDoingBusinessAsRepository.java
@@ -1,12 +1,16 @@
package ca.bc.gov.app.repository;
import ca.bc.gov.app.entity.ClientDoingBusinessAsEntity;
+import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.data.repository.reactive.ReactiveSortingRepository;
import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Flux;
@Repository
public interface ClientDoingBusinessAsRepository extends
ReactiveCrudRepository,
ReactiveSortingRepository {
+
+ Flux findBy(Pageable page);
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/repository/ForestClientRepository.java b/legacy/src/main/java/ca/bc/gov/app/repository/ForestClientRepository.java
index bc44f04fed..c524f8344d 100644
--- a/legacy/src/main/java/ca/bc/gov/app/repository/ForestClientRepository.java
+++ b/legacy/src/main/java/ca/bc/gov/app/repository/ForestClientRepository.java
@@ -1,6 +1,7 @@
package ca.bc.gov.app.repository;
import ca.bc.gov.app.entity.ForestClientEntity;
+import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
@@ -14,6 +15,8 @@ public interface ForestClientRepository extends ReactiveCrudRepository,
ReactiveSortingRepository {
+ Flux findBy(Pageable page);
+
@Query("""
select * from FOREST_CLIENT x
where x.CLIENT_TYPE_CODE = 'B'
diff --git a/legacy/src/main/java/ca/bc/gov/app/service/ClientSearchService.java b/legacy/src/main/java/ca/bc/gov/app/service/ClientSearchService.java
index e82ce3c5b6..b8ca141cfa 100644
--- a/legacy/src/main/java/ca/bc/gov/app/service/ClientSearchService.java
+++ b/legacy/src/main/java/ca/bc/gov/app/service/ClientSearchService.java
@@ -1,19 +1,12 @@
package ca.bc.gov.app.service;
-import ca.bc.gov.app.ApplicationConstants;
import ca.bc.gov.app.dto.ForestClientDto;
-import ca.bc.gov.app.entity.ForestClientEntity;
import ca.bc.gov.app.exception.MissingRequiredParameterException;
import ca.bc.gov.app.repository.ForestClientRepository;
import ca.bc.gov.app.util.MonoUtil;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
-import org.springframework.data.domain.Example;
-import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
@@ -45,7 +38,6 @@ public Flux findByIncorporationOrName(
entity.getLegalMiddleName(),
entity.getClientStatusCode(),
entity.getClientTypeCode(),
- entity.getBirthdate(),
entity.getClientIdTypeCode(),
entity.getClientIdentification(),
entity.getRegistryCompanyTypeCode(),
@@ -59,75 +51,4 @@ public Flux findByIncorporationOrName(
.doOnNext(MonoUtil.logContent(log));
}
- public Flux findByNameAndBirth(
- Optional firstName,
- Optional lastName,
- Optional birthDate
- ) {
-
- //First, we validate to see if it's empty or not, empty values cannot be passed on
- //For requests, when someone is consuming our endpoint and want to send an empty value
- //for example, when looking up for companies, not individuals, it has to provide the
- //query param without any value, such as firstName=&birthdate=&lastName=My Company
- if (lastName.isEmpty()) {
- throw new MissingRequiredParameterException(ApplicationConstants.CLIENT_SEARCH_LAST_NAME);
- }
-
- if (birthDate.isEmpty()) {
- throw new MissingRequiredParameterException(ApplicationConstants.CLIENT_SEARCH_BIRTHDATE);
- }
-
- if (firstName.isEmpty()) {
- throw new MissingRequiredParameterException(ApplicationConstants.CLIENT_SEARCH_FIRST_NAME);
- }
-
- //The search probe is just an example object with the fields populated with the values we
- //are looking for.
- ForestClientEntity searchProbe = new ForestClientEntity()
- .withBirthdate(
- birthDate
- .filter(StringUtils::isNotBlank)
- .map(date -> LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE))
- .orElse(null)
- )
- .withLegalFirstName(firstName.filter(StringUtils::isNotBlank).orElse(null))
- .withClientName(lastName.filter(StringUtils::isNotBlank).orElse(null));
-
- //The matcher defines how we will look up for the data provided
- ExampleMatcher searchMatcher = ExampleMatcher
- .matchingAll()
- .withMatcher(
- "clientName",
- ExampleMatcher.GenericPropertyMatcher::ignoreCase
- )
- .withMatcher(
- "legalFirstName",
- ExampleMatcher.GenericPropertyMatcher::ignoreCase
- )
- .withIncludeNullValues();
-
- return forestClientRepository
- //Then we look up for all that matches the example
- .findAll(Example.of(searchProbe, searchMatcher))
- .map(entity ->
- new ForestClientDto(
- entity.getClientNumber(),
- entity.getClientName(),
- entity.getLegalFirstName(),
- entity.getLegalMiddleName(),
- entity.getClientStatusCode(),
- entity.getClientTypeCode(),
- entity.getBirthdate(),
- entity.getClientIdTypeCode(),
- entity.getClientIdentification(),
- entity.getRegistryCompanyTypeCode(),
- entity.getCorpRegnNmbr(),
- entity.getClientAcronym(),
- entity.getWcbFirmNumber(),
- entity.getOcgSupplierNmbr(),
- entity.getClientComment()
- )
- );
- }
-
}
diff --git a/legacy/src/main/java/ca/bc/gov/app/service/ForestClientService.java b/legacy/src/main/java/ca/bc/gov/app/service/ForestClientService.java
deleted file mode 100644
index df5f8ad588..0000000000
--- a/legacy/src/main/java/ca/bc/gov/app/service/ForestClientService.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package ca.bc.gov.app.service;
-
-import static java.util.function.Predicate.not;
-
-import ca.bc.gov.app.dto.ClientPublicViewDto;
-import ca.bc.gov.app.dto.FirstNationBandVidationDto;
-import ca.bc.gov.app.dto.OrgBookResultListResponse;
-import ca.bc.gov.app.dto.PropertyDto;
-import ca.bc.gov.app.entity.ForestClientEntity;
-import ca.bc.gov.app.repository.ClientDoingBusinessAsRepository;
-import ca.bc.gov.app.repository.ClientLocationRepository;
-import ca.bc.gov.app.repository.ForestClientRepository;
-import java.util.List;
-import java.util.function.Function;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.data.domain.Sort;
-import org.springframework.http.MediaType;
-import org.springframework.stereotype.Service;
-import org.springframework.web.reactive.function.client.WebClient;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-@Service
-@Slf4j
-@RequiredArgsConstructor
-public class ForestClientService {
-
- private final ForestClientRepository forestClientRepository;
- private final ClientLocationRepository clientLocationRepository;
- private final ClientDoingBusinessAsRepository clientDoingBusinessAsRepository;
-
- private final WebClient forestClientApi;
-
- public Flux getFirstNationBandInfo() {
- return
- forestClientRepository
- .findAllFirstNationBandClients()
- .flatMap(entity ->
- Mono
- .just(entity)
- .doOnNext(
- current -> log.info("Checking data for {} CorpRegnNmbr {}",
- current.getClientName(),
- current.getCorpRegnNmbr())
- )
- .filter(current -> StringUtils.isNotBlank(current.getCorpRegnNmbr()))
- .flatMap(getBandInfoFromMap())
- .switchIfEmpty(getEmptyBandValidation(entity))
- );
- }
-
- public Flux getClientDoingBusiness() {
- return
- clientDoingBusinessAsRepository
- .findAll(Sort.by("doingBusinessAsName"))
- .flatMap(entity ->
- findByClientName(entity.getDoingBusinessAsName())
- .filter(not(OrgBookResultListResponse::empty))
- .map(orgBookResponse ->
- new ClientPublicViewDto(
- entity.getClientNumber(),
- null,
- entity.getDoingBusinessAsName(),
- null,
- null,
- null,
- null,
- orgBookResponse.results().get(0).value()
- )
- )
- .switchIfEmpty(
- Mono
- .just(
- new ClientPublicViewDto(
- entity.getClientNumber(),
- null,
- entity.getDoingBusinessAsName(),
- null,
- null,
- null,
- null,
- null
- )
- )
- )
- );
- }
-
- public Flux getUnregisteredCompanies() {
- return
- forestClientRepository
- .findAll(Sort.by("clientName"))
- .flatMap(entity ->
- findByClientName(entity.getClientName())
- .filter(not(OrgBookResultListResponse::empty))
- .map(orgBookResponse ->
- new ClientPublicViewDto(
- entity.getClientNumber(),
- StringUtils
- .equals(
- orgBookResponse.results().get(0).value(),
- entity.getClientName()
- ) ? orgBookResponse.results().get(0).topicSourceId() : null,
- entity.getClientName(),
- null,
- null,
- null,
- null,
- orgBookResponse.results().get(0).value()
- )
- )
- .switchIfEmpty(Mono.just(
- new ClientPublicViewDto(
- entity.getClientNumber(),
- null,
- entity.getClientName(),
- null,
- null,
- null,
- null,
- null
- )
- ))
- );
- }
-
- private Mono findByClientName(String clientName) {
- return
- forestClientApi
- .get()
- .uri("/api/orgbook/name/{name}", clientName)
- .exchangeToMono(response -> response.bodyToMono(OrgBookResultListResponse.class));
- }
-
- private static Mono getEmptyBandValidation(
- ForestClientEntity entity
- ) {
- return Mono.just(new FirstNationBandVidationDto(
- entity.getClientNumber(),
- entity.getCorpRegnNmbr(),
- entity.getClientName(),
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null
- )
- );
- }
-
- private Function> getBandInfoFromMap() {
- return currentEntity ->
- forestClientApi
- .get()
- .uri("/api/maps/firstNation/{id}", currentEntity.getCorpRegnNmbr())
- .accept(MediaType.APPLICATION_JSON)
- .exchangeToMono(response -> response.bodyToMono(PropertyDto.class))
- .doOnNext(response ->
- log.info(
- """
- Information about first nation band with id {} and client number {} found.
- Looking up for location details from band {}
- """,
- currentEntity.getCorpRegnNmbr(),
- currentEntity.getClientNumber(),
- response
- )
- )
- .flatMap(response ->
- clientLocationRepository
- .findAllById(List.of(currentEntity.getClientNumber()))
- .map(clientLocation ->
- new FirstNationBandVidationDto(
- currentEntity.getClientNumber(),
- currentEntity.getCorpRegnNmbr(),
- currentEntity.getClientName(),
- response.firstNationFederalName(),
- clientLocation.getAddressOne(),
- response.addressLine1(),
- clientLocation.getAddressTwo(),
- response.addressLine2(),
- clientLocation.getCity(),
- response.officeCity(),
- clientLocation.getProvince(),
- response.officeProvince(),
- clientLocation.getPostalCode(),
- response.officePostalCode()
- )
- )
- .filter(FirstNationBandVidationDto::nameMatch)
- .next()
- )
- .doOnNext(bandValidation -> log.info("Band validation completed for {} {}",bandValidation.clientNumber(),bandValidation.clientName()))
- .onErrorResume(t -> getEmptyBandValidation(currentEntity)
- );
- }
-
-}
diff --git a/legacy/src/main/java/ca/bc/gov/app/service/ReportingClientService.java b/legacy/src/main/java/ca/bc/gov/app/service/ReportingClientService.java
new file mode 100644
index 0000000000..a52f005801
--- /dev/null
+++ b/legacy/src/main/java/ca/bc/gov/app/service/ReportingClientService.java
@@ -0,0 +1,227 @@
+package ca.bc.gov.app.service;
+
+import ca.bc.gov.app.dto.ClientPublicViewDto;
+import ca.bc.gov.app.dto.OrgBookTopicDto;
+import ca.bc.gov.app.dto.OrgBookTopicListResponse;
+import ca.bc.gov.app.entity.ClientDoingBusinessAsEntity;
+import ca.bc.gov.app.entity.ForestClientEntity;
+import ca.bc.gov.app.repository.ClientDoingBusinessAsRepository;
+import ca.bc.gov.app.repository.ForestClientRepository;
+import ca.bc.gov.app.util.SheetWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Service
+@Slf4j
+public class ReportingClientService {
+
+ private final ForestClientRepository forestClientRepository;
+ private final ClientDoingBusinessAsRepository clientDoingBusinessAsRepository;
+ private final WebClient orgBookApi;
+
+ public ReportingClientService(ForestClientRepository forestClientRepository,
+ ClientDoingBusinessAsRepository clientDoingBusinessAsRepository,
+ @Qualifier("orgBookApi") WebClient orgBookApi) {
+ this.forestClientRepository = forestClientRepository;
+ this.clientDoingBusinessAsRepository = clientDoingBusinessAsRepository;
+ this.orgBookApi = orgBookApi;
+ }
+
+ public Mono generateDoingBusinessAsReport() {
+
+ return
+ generateReport(
+ clientDoingBusinessAsRepository
+ //As we are streaming through the data with Flux, we will not have the entire
+ //dataset in memory at any given time
+ .findAll()
+ //for each entry, we will grab the data from orgbook
+ .flatMap(this::mapToPublicView)
+ );
+ }
+
+ public Mono generateAllClientsReport() {
+ return
+ generateReport(
+ forestClientRepository
+ //As we are streaming through the data with Flux, we will not have the entire
+ //dataset in memory at any given time
+ .findAll()
+ //for each entry, we will grab the data from orgbook
+ .flatMap(this::mapToPublicView)
+ );
+ }
+
+ @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.MINUTES)
+ @SuppressWarnings({"java:S3864", "java:S4042"})
+ public void cleanOldReports() {
+
+ Path sheetFolder = Paths
+ .get("./temp/")
+ .normalize();
+
+ if (!sheetFolder.toFile().exists()) {
+ log.info(
+ "Temporary folder for reports {} does not exist, creating {}",
+ sheetFolder.toFile().getAbsolutePath(),
+ sheetFolder.toFile().mkdirs()
+ );
+ }
+
+ try (Stream paths = Files.list(sheetFolder)) {
+ paths
+ .peek(file -> log.info("Found report on folder with name {}", file.getFileName()))
+ .filter(file -> isFileOlderThan(file.toFile(), 5))
+ .forEach(path -> path.toFile().delete());
+ } catch (IOException exception) {
+ log.error("Error while cleaning temp folder", exception);
+ }
+
+
+ }
+
+ private boolean isFileOlderThan(File file, int minutesDiff) {
+ return
+ Duration
+ .between(
+ Instant.ofEpochMilli(file.lastModified()),
+ Instant.now()
+ )
+ .toMinutes() > minutesDiff;
+ }
+
+ private Mono generateReport(Flux values) {
+
+ File sheetFile = Paths
+ .get("./temp/", UUID.randomUUID().toString() + ".xlsx")
+ .normalize()
+ .toFile();
+
+ if (!sheetFile.getParentFile().exists()) {
+ log.info(
+ "Temporary folder for reports {} does not exist, creating {}",
+ sheetFile.getParentFile().getAbsolutePath(),
+ sheetFile.getParentFile().mkdirs()
+ );
+ }
+
+ SheetWriter writer = new SheetWriter(sheetFile);
+
+ log.debug("Generating sheet file {}", sheetFile);
+ return values
+ //Persist it into the spreadsheet for each entry
+ .doOnNext(writer::write)
+ //Once all is done move ahead to complete and close the file
+ .doOnComplete(writer::complete)
+ //return the file
+ .then(Mono.just(sheetFile));
+ }
+
+ private Mono mapToPublicView(ForestClientEntity entity) {
+ return loadValueFromOrgbook(
+ entity.getClientName(),
+ entity.getClientNumber(),
+ String.format("%s%s",
+ StringUtils.defaultString(entity.getRegistryCompanyTypeCode()),
+ StringUtils.defaultString(entity.getCorpRegnNmbr())
+ )
+ );
+ }
+
+ private Mono mapToPublicView(ClientDoingBusinessAsEntity entity) {
+ return loadValueFromOrgbook(
+ entity.getDoingBusinessAsName(),
+ entity.getClientNumber(),
+ StringUtils.EMPTY
+ );
+ }
+
+ private Mono loadValueFromOrgbook(
+ String clientName,
+ String clientNumber,
+ String incorporationNumber
+ ) {
+ return
+ findOnTopic(clientName)
+ .next()
+ //if we find data, we build the data with it
+ .map(orgBook ->
+ new ClientPublicViewDto(
+ clientNumber,
+ clientName,
+ incorporationNumber,
+ orgBook.sourceId(),
+ orgBook.name(),
+ !orgBook.inactive()
+ )
+ )
+ //if not, we use just the entity data
+ .switchIfEmpty(Mono.just(
+ new ClientPublicViewDto(
+ clientNumber,
+ clientName,
+ incorporationNumber,
+ null,
+ null,
+ false
+ )
+ )
+ );
+ }
+
+ private Flux findOnTopic(String value) {
+ return
+ orgBookApi
+ .get()
+ .uri(uriBuilder -> uriBuilder
+ .path("/v4/search/topic")
+ .queryParam("format", "json")
+ .queryParam("inactive", "any")
+ .queryParam("ordering", "-score")
+ .queryParam("q", encodeUri(value))
+ .build(Map.of())
+ )
+ .accept(MediaType.APPLICATION_JSON)
+ .exchangeToMono(
+ clientResponse -> clientResponse.bodyToMono(OrgBookTopicListResponse.class)
+ )
+ .filter(response -> !CollectionUtils.isEmpty(response.results()))
+ .flatMapIterable(OrgBookTopicListResponse::results)
+ .doOnNext(
+ content -> log.info("OrgBook Topic Lookup {} -> {}", value,
+ content)
+ );
+
+ }
+
+ private static String encodeUri(String clientName) {
+ try {
+ return URLEncoder.encode(clientName, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ return clientName;
+ }
+ }
+
+}
diff --git a/legacy/src/main/java/ca/bc/gov/app/util/MonoUtil.java b/legacy/src/main/java/ca/bc/gov/app/util/MonoUtil.java
index 7e5fc006ca..f89792d377 100644
--- a/legacy/src/main/java/ca/bc/gov/app/util/MonoUtil.java
+++ b/legacy/src/main/java/ca/bc/gov/app/util/MonoUtil.java
@@ -18,41 +18,4 @@ public static Consumer logContent(Logger log) {
return received -> log.info("{}", received);
}
- /**
- *
Log Content
- * Log the content of the future and add a log message as well.
- *
- * @param logMessage A string message to be logged
- * @param The type that will be passed through the future.
- * @return the same content of the future
- */
- public static Consumer logContent(Logger log, String logMessage) {
- return received -> log.info(String.format("%s {}", logMessage), received);
- }
-
- /**
- *
Log Content
- * Log the content of the future and add a log message as well.
- *
- * @param logMessage A string message to be logged
- * @param params the params array to be passed to SL4J
- * @param The type that will be passed through the future.
- * @return the same content of the future
- */
- public static Consumer logContent(Logger log, String logMessage, Object... params) {
- return received -> log.info(String.format("%s {}", logMessage), params, received);
- }
-
- /**
- *