From 8ce1a3b66aa062898a1616df681c3978a2d48f7f Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Wed, 15 Jan 2025 17:14:50 -0800 Subject: [PATCH 1/8] WFPREV-259 Update projects and projectFiscals endpoints for new db changes --- postman/Prevention.postman_collection.json | 26 +---- .../nrs/wfprev/common/enums/CodeTables.java | 1 + .../wfprev/controllers/CodesController.java | 3 + .../wfprev/controllers/ProjectController.java | 47 ++++---- .../ObjectiveTypeCodeResourceAssembler.java | 4 +- .../ProjectFiscalResourceAssembler.java | 16 +-- ...rojectPlanStatusCodeResourceAssembler.java | 71 ++++++++++++ .../assemblers/ProjectResourceAssembler.java | 12 +-- .../wfprev/data/entities/ProjectEntity.java | 8 +- .../data/entities/ProjectFiscalEntity.java | 10 +- .../entities/ProjectPlanStatusCodeEntity.java | 71 ++++++++++++ .../data/models/ProjectFiscalModel.java | 4 +- .../nrs/wfprev/data/models/ProjectModel.java | 4 +- .../models/ProjectPlanStatusCodeModel.java | 33 ++++++ .../ObjectiveTypeCodeRepository.java | 1 - .../ProjectPlanStatusCodeRepository.java | 10 ++ .../gov/nrs/wfprev/services/CodesService.java | 41 ++++--- .../gov/nrs/wfprev/ProjectControllerTest.java | 100 ++++++++++------- ...bjectiveTypeCodeResourceAssemblerTest.java | 14 +-- ...ctPlanStatusCodeResourceAssemblerTest.java | 101 +++++++++++++++++ .../nrs/wfprev/services/CodesServiceTest.java | 102 +++++++++++++++++- .../services/ProjectFiscalServiceTest.java | 24 ++--- 22 files changed, 534 insertions(+), 169 deletions(-) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssembler.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectPlanStatusCodeEntity.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectPlanStatusCodeModel.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectPlanStatusCodeRepository.java create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssemblerTest.java diff --git a/postman/Prevention.postman_collection.json b/postman/Prevention.postman_collection.json index 0f7049a87..e63371ab3 100644 --- a/postman/Prevention.postman_collection.json +++ b/postman/Prevention.postman_collection.json @@ -137,7 +137,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"WEST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Sample Forest Management Project\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalFundingRequestAmount\": 100000.00,\n \"totalAllocatedAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001\n,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", + "raw": "{\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"WEST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Sample Forest Management Project\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 100000.00,\n \"totalForecastAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001\n,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", "options": { "raw": { "language": "json" @@ -209,7 +209,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"TACT_PLAN\",\n \"fiscalYear\": 2023,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"PLANNED\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"totalCostEstimateAmount\": 2000.00,\n \"fiscalFundingRequestAmount\": 1500.00,\n \"fiscalAllocatedAmount\": 1200.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false\n}", + "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"TACT_PLAN\",\n \"fiscalYear\": 2023,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"DRAFT\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"totalCostEstimateAmount\": 2000.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false\n}", "options": { "raw": { "language": "json" @@ -271,7 +271,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectPlanFiscalGuid\": \"{{projectPlanFiscalGuid}}\",\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"RX_DEV\",\n \"fiscalYear\": 2024,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"PLANNED\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"totalCostEstimateAmount\": 2000.00,\n \"fiscalFundingRequestAmount\": 1500.00,\n \"fiscalAllocatedAmount\": 1200.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false\n}", + "raw": "{\n \"projectPlanFiscalGuid\": \"{{projectPlanFiscalGuid}}\",\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"RX_DEV\",\n \"fiscalYear\": 2024,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"PROPOSED\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"totalCostEstimateAmount\": 2000.00,\n \"fiscalForecastAmount\": 300.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false\n}", "options": { "raw": { "language": "json" @@ -417,7 +417,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"COAST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Test 3\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalFundingRequestAmount\": 100000.00,\n \"totalAllocatedAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001\n,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", + "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"COAST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Test 3\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 100000.00,\n \"totalForecastAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001\n,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", "options": { "raw": { "language": "json" @@ -703,15 +703,6 @@ "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\n \"projectPlanFiscalGuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"projectGuid\": \"123e4567-e89b-12d3-a456-426614174001\",\n \"activityCategoryCode\": \"Tactical Planning\",\n \"fiscalYear\": 2024,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"APPROVED\",\n \"projectFiscalName\": \"Forest Restoration\",\n \"projectFiscalDescription\": \"Restoration project for forest lands\",\n \"estimatedClwrrAllocAmount\": 50000.00,\n \"totalCostEstimateAmount\": 120000.00,\n \"fiscalFundingRequestAmount\": 70000.00,\n \"fiscalAllocatedAmount\": 65000.00,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"isApprovedInd\": true,\n \"isDelayedInd\": false,\n \"submissionTimestamp\": \"2025-01-01T00:00:00Z\",\n \"approverName\": \"John Doe\",\n \"approverUserGuid\": \"abcd1234-5678-9101-1121-314151617181\",\n \"approverUserUserid\": \"jdoe\",\n \"approvedTimestamp\": \"2025-01-01T10:00:00Z\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { "raw": "{{LOCAL_API_URL}}/codes/forestRegionCodes", "host": [ @@ -763,15 +754,6 @@ "type": "text" } ], - "body": { - "mode": "raw", - "raw": "{\n \"projectPlanFiscalGuid\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"projectGuid\": \"123e4567-e89b-12d3-a456-426614174001\",\n \"activityCategoryCode\": \"Tactical Planning\",\n \"fiscalYear\": 2024,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"APPROVED\",\n \"projectFiscalName\": \"Forest Restoration\",\n \"projectFiscalDescription\": \"Restoration project for forest lands\",\n \"estimatedClwrrAllocAmount\": 50000.00,\n \"totalCostEstimateAmount\": 120000.00,\n \"fiscalFundingRequestAmount\": 70000.00,\n \"fiscalAllocatedAmount\": 65000.00,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"isApprovedInd\": true,\n \"isDelayedInd\": false,\n \"submissionTimestamp\": \"2025-01-01T00:00:00Z\",\n \"approverName\": \"John Doe\",\n \"approverUserGuid\": \"abcd1234-5678-9101-1121-314151617181\",\n \"approverUserUserid\": \"jdoe\",\n \"approvedTimestamp\": \"2025-01-01T10:00:00Z\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { "raw": "{{LOCAL_API_URL}}/codes/bcParksRegionCodes", "host": [ diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java index 28b2fed44..40efac389 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java @@ -11,4 +11,5 @@ private CodeTables() {} public static final String BC_PARKS_REGION_CODE = "bcParksRegionCodes"; public static final String BC_PARKS_SECTION_CODE = "bcParksSectionCodes"; public static final String OBJECTIVE_TYPE_CODE = "objectiveTypeCodes"; + public static final String PROJECT_PLAN_STATUS_CODE = "projectPlanStatusCodes"; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java index e94ec6e14..f1091772d 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java @@ -57,6 +57,8 @@ public ResponseEntity> getCodes(@PathVariable("codeTable") St case CodeTables.BC_PARKS_REGION_CODE -> result = codesService.getAllBCParksRegionCodes(); case CodeTables.BC_PARKS_SECTION_CODE -> result = codesService.getAllBCParksSectionCodes(); case CodeTables.OBJECTIVE_TYPE_CODE -> result = codesService.getAllObjectiveTypeCodes(); + case CodeTables.PROJECT_PLAN_STATUS_CODE -> result = codesService.getAllProjectPlanStatusCodes(); + default -> { log.error("Invalid code table: {}", codeTable); return internalServerError(); @@ -131,6 +133,7 @@ private CommonModel fetchCodeById(String codeTable, String id) throws Service case CodeTables.BC_PARKS_REGION_CODE -> codesService.getBCParksRegionCodeById(Integer.parseInt(id)); case CodeTables.BC_PARKS_SECTION_CODE -> codesService.getBCParksSectionCodeById(Integer.parseInt(id)); case CodeTables.OBJECTIVE_TYPE_CODE -> codesService.getObjectiveTypeCodeById(id); + case CodeTables.PROJECT_PLAN_STATUS_CODE -> codesService.getProjectPlanStatusCodeById(id); default -> null; }; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java index fed473213..77c276359 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java @@ -17,6 +17,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import jakarta.persistence.EntityNotFoundException; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.hateoas.CollectionModel; @@ -159,30 +160,32 @@ public ResponseEntity updateProject(@RequestBody ProjectModel reso } @DeleteMapping("/{id}") - @Operation(summary = "Delete Project Resource", - description = "Delete Project Resource", - security = @SecurityRequirement(name = "Webade-OAUTH2", - scopes = { "WFPREV" }), - extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) - @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProjectModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) - @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER) - @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) - public ResponseEntity deleteProject(@PathVariable("id") String id) { - log.debug(" >> deleteProject"); - ResponseEntity response; + @Operation(summary = "Delete a Project Resource", + description = "Delete a specific Project Resource by its ID", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = {"WFPREV"})) + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "No Content"), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), + @ApiResponse(responseCode = "404", description = "Not Found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) + }) + public ResponseEntity deleteProject(@PathVariable("id") String id) { + log.debug(" >> deleteProject with id: {}", id); try { - ProjectModel resource = projectService.deleteProject(id); - response = resource == null ? notFound(): ok(resource); - } catch(ServiceException e) { - // most responses here will actually be Bad Requests, not Internal Server Errors - // This would be an ideal place to expand the "Catch" and return sensible - // HTTP status codes - response = internalServerError(); - log.error(" ### Error while updating Project", e); + projectService.deleteProject(id); + log.debug(" << deleteProjectFiscal success"); + return ResponseEntity.noContent().build(); + } catch (EntityNotFoundException e) { + log.warn(" ### Project not found with id: {}", id, e); + return ResponseEntity.notFound().build(); + } catch (IllegalArgumentException e) { + log.warn(" ### Invalid ID provided: {}", id, e); + return ResponseEntity.badRequest().build(); + } catch (Exception e) { + log.error(" ### Error while deleting Project ith id: {}", id, e); + return internalServerError(); } - - log.debug(" << deleteProject"); - return response; } } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssembler.java index 7a40bfff8..8c0dff6ff 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssembler.java @@ -42,7 +42,7 @@ public ObjectiveTypeCodeModel toModel(ObjectiveTypeCodeEntity entity) { resource.add(linkTo( methodOn(CodesController.class) - .getCodeById(CodeTables.GENERAL_SCOPE_CODE, entity.getObjectiveTypeCode())) + .getCodeById(CodeTables.OBJECTIVE_TYPE_CODE, entity.getObjectiveTypeCode())) .withSelfRel()); resource.setObjectiveTypeCode(entity.getObjectiveTypeCode()); @@ -64,7 +64,7 @@ public CollectionModel toCollectionModel(Iterable resources = super.toCollectionModel(entities); - resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.GENERAL_SCOPE_CODE)).withSelfRel()); + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.OBJECTIVE_TYPE_CODE)).withSelfRel()); return resources; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectFiscalResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectFiscalResourceAssembler.java index d33588be8..e19ed44ce 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectFiscalResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectFiscalResourceAssembler.java @@ -50,9 +50,7 @@ public ProjectFiscalModel toModel(final ProjectFiscalEntity entity) { model.setEstimatedClwrrAllocAmount(entity.getEstimatedClwrrAllocAmount()); model.setTotalCostEstimateAmount(entity.getTotalCostEstimateAmount()); model.setCfsProjectCode(entity.getCfsProjectCode()); - model.setFiscalFundingRequestAmount(entity.getFiscalFundingRequestAmount()); - model.setFiscalFundingAllocRationale(entity.getFiscalFundingAllocRationale()); - model.setFiscalAllocatedAmount(entity.getFiscalAllocatedAmount()); + model.setFiscalForecastAmount(entity.getFiscalForecastAmount()); model.setFiscalAncillaryFundAmount(entity.getFiscalAncillaryFundAmount()); model.setFiscalPlannedProjectSizeHa(entity.getFiscalPlannedProjectSizeHa()); model.setFiscalPlannedCostPerHaAmt(entity.getFiscalPlannedCostPerHaAmt()); @@ -128,9 +126,7 @@ public ProjectFiscalEntity toEntity(ProjectFiscalModel model, ProjectEntity proj entity.setEstimatedClwrrAllocAmount(model.getEstimatedClwrrAllocAmount()); entity.setTotalCostEstimateAmount(model.getTotalCostEstimateAmount()); entity.setCfsProjectCode(model.getCfsProjectCode()); - entity.setFiscalFundingRequestAmount(model.getFiscalFundingRequestAmount()); - entity.setFiscalFundingAllocRationale(model.getFiscalFundingAllocRationale()); - entity.setFiscalAllocatedAmount(model.getFiscalAllocatedAmount()); + entity.setFiscalForecastAmount(model.getFiscalForecastAmount()); entity.setFiscalAncillaryFundAmount(model.getFiscalAncillaryFundAmount()); entity.setFiscalPlannedProjectSizeHa(model.getFiscalPlannedProjectSizeHa()); entity.setFiscalPlannedCostPerHaAmt(model.getFiscalPlannedCostPerHaAmt()); @@ -202,12 +198,8 @@ public ProjectFiscalEntity updateEntity(ProjectFiscalModel projectFiscalModel, P nonNullOrDefault(projectFiscalModel.getTotalCostEstimateAmount(), existingEntity.getTotalCostEstimateAmount())); existingEntity.setCfsProjectCode( nonNullOrDefault(projectFiscalModel.getCfsProjectCode(), existingEntity.getCfsProjectCode())); - existingEntity.setFiscalFundingRequestAmount( - nonNullOrDefault(projectFiscalModel.getFiscalFundingRequestAmount(), existingEntity.getFiscalFundingRequestAmount())); - existingEntity.setFiscalFundingAllocRationale( - nonNullOrDefault(projectFiscalModel.getFiscalFundingAllocRationale(), existingEntity.getFiscalFundingAllocRationale())); - existingEntity.setFiscalAllocatedAmount( - nonNullOrDefault(projectFiscalModel.getFiscalAllocatedAmount(), existingEntity.getFiscalAllocatedAmount())); + existingEntity.setFiscalForecastAmount( + nonNullOrDefault(projectFiscalModel.getFiscalForecastAmount(), existingEntity.getFiscalForecastAmount())); existingEntity.setFiscalAncillaryFundAmount( nonNullOrDefault(projectFiscalModel.getFiscalAncillaryFundAmount(), existingEntity.getFiscalAncillaryFundAmount())); existingEntity.setFiscalPlannedProjectSizeHa( diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssembler.java new file mode 100644 index 000000000..f52571766 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssembler.java @@ -0,0 +1,71 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; +import ca.bc.gov.nrs.wfprev.controllers.CodesController; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectPlanStatusCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProjectPlanStatusCodeModel; + +@Component +public class ProjectPlanStatusCodeResourceAssembler extends RepresentationModelAssemblerSupport { + + public ProjectPlanStatusCodeResourceAssembler() { + super(CodesController.class, ProjectPlanStatusCodeModel.class); + } + + public ProjectPlanStatusCodeEntity toEntity(ProjectPlanStatusCodeModel resource) { + ProjectPlanStatusCodeEntity entity = new ProjectPlanStatusCodeEntity(); + + entity.setProjectPlanStatusCode(resource.getProjectPlanStatusCode()); + entity.setDescription(resource.getDescription()); + entity.setDisplayOrder(resource.getDisplayOrder()); + entity.setEffectiveDate(resource.getEffectiveDate()); + entity.setExpiryDate(resource.getExpiryDate()); + entity.setRevisionCount(resource.getRevisionCount()); + entity.setCreateUser(resource.getCreateUser()); + entity.setCreateDate(resource.getCreateDate()); + entity.setUpdateUser(resource.getUpdateUser()); + entity.setUpdateDate(resource.getUpdateDate()); + + return entity; + } + + @Override + public ProjectPlanStatusCodeModel toModel(ProjectPlanStatusCodeEntity entity) { + ProjectPlanStatusCodeModel resource = instantiateModel(entity); + + resource.add(linkTo( + methodOn(CodesController.class) + .getCodeById(CodeTables.PROJECT_PLAN_STATUS_CODE, entity.getProjectPlanStatusCode())) + .withSelfRel()); + + resource.setProjectPlanStatusCode(entity.getProjectPlanStatusCode()); + resource.setDescription(entity.getDescription()); + resource.setDisplayOrder(entity.getDisplayOrder()); + resource.setEffectiveDate(entity.getEffectiveDate()); + resource.setExpiryDate(entity.getExpiryDate()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setCreateUser(entity.getCreateUser()); + resource.setCreateDate(entity.getCreateDate()); + resource.setUpdateUser(entity.getUpdateUser()); + resource.setUpdateDate(entity.getUpdateDate()); + + return resource; + } + + @Override + public CollectionModel toCollectionModel(Iterable entities) + { + CollectionModel resources = super.toCollectionModel(entities); + + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.PROJECT_PLAN_STATUS_CODE)).withSelfRel()); + + return resources; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java index 0d1c9487a..84f78cc99 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java @@ -58,8 +58,8 @@ public ProjectEntity toEntity(ProjectModel resource) { entity.setProjectLeadEmailAddress(resource.getProjectLeadEmailAddress()); entity.setProjectDescription(resource.getProjectDescription()); entity.setClosestCommunityName(resource.getClosestCommunityName()); - entity.setTotalFundingRequestAmount(resource.getTotalFundingRequestAmount()); - entity.setTotalAllocatedAmount(resource.getTotalAllocatedAmount()); + entity.setTotalEstimatedCostAmount(resource.getTotalEstimatedCostAmount()); + entity.setTotalForecastAmount(resource.getTotalForecastAmount()); entity.setTotalPlannedProjectSizeHa(resource.getTotalPlannedProjectSizeHa()); entity.setTotalPlannedCostPerHectare(resource.getTotalPlannedCostPerHectare()); entity.setTotalActualAmount(resource.getTotalActualAmount()); @@ -111,8 +111,8 @@ public ProjectModel toModel(ProjectEntity entity) { resource.setProjectLeadEmailAddress(entity.getProjectLeadEmailAddress()); resource.setProjectDescription(entity.getProjectDescription()); resource.setClosestCommunityName(entity.getClosestCommunityName()); - resource.setTotalFundingRequestAmount(entity.getTotalFundingRequestAmount()); - resource.setTotalAllocatedAmount(entity.getTotalAllocatedAmount()); + resource.setTotalEstimatedCostAmount(entity.getTotalEstimatedCostAmount()); + resource.setTotalForecastAmount(entity.getTotalForecastAmount()); resource.setTotalPlannedProjectSizeHa(entity.getTotalPlannedProjectSizeHa()); resource.setTotalPlannedCostPerHectare(entity.getTotalPlannedCostPerHectare()); resource.setTotalActualAmount(entity.getTotalActualAmount()); @@ -182,8 +182,8 @@ public ProjectEntity updateEntity(ProjectModel model, ProjectEntity existingEnti entity.setTotalActualProjectSizeHa(nonNullOrDefault(model.getTotalActualProjectSizeHa(), existingEntity.getTotalActualProjectSizeHa())); entity.setTotalActualCostPerHectareAmount(nonNullOrDefault(model.getTotalActualCostPerHectareAmount(), existingEntity.getTotalActualCostPerHectareAmount())); entity.setTotalActualAmount(nonNullOrDefault(model.getTotalActualAmount(), existingEntity.getTotalActualAmount())); - entity.setTotalAllocatedAmount(nonNullOrDefault(model.getTotalAllocatedAmount(), existingEntity.getTotalAllocatedAmount())); - entity.setTotalFundingRequestAmount(nonNullOrDefault(model.getTotalFundingRequestAmount(), existingEntity.getTotalFundingRequestAmount())); + entity.setTotalEstimatedCostAmount(nonNullOrDefault(model.getTotalEstimatedCostAmount(), existingEntity.getTotalForecastAmount())); + entity.setTotalForecastAmount(nonNullOrDefault(model.getTotalForecastAmount(), existingEntity.getTotalForecastAmount())); entity.setTotalPlannedCostPerHectare(nonNullOrDefault(model.getTotalPlannedCostPerHectare(), existingEntity.getTotalPlannedCostPerHectare())); entity.setTotalPlannedProjectSizeHa(nonNullOrDefault(model.getTotalPlannedProjectSizeHa(), existingEntity.getTotalPlannedProjectSizeHa())); entity.setIsMultiFiscalYearProj(nonNullOrDefault(model.getIsMultiFiscalYearProj(), existingEntity.getIsMultiFiscalYearProj())); diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java index 6da341052..157fb0177 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java @@ -103,11 +103,11 @@ public class ProjectEntity implements Serializable { @Column(name = "closest_community_name", length = 250) private String closestCommunityName; - @Column(name = "total_funding_request_amount", precision = 15, scale = 2) - private BigDecimal totalFundingRequestAmount; + @Column(name = "total_estimated_cost_amount", precision = 15, scale = 2) + private BigDecimal totalEstimatedCostAmount; - @Column(name = "total_allocated_amount", precision = 15, scale = 2) - private BigDecimal totalAllocatedAmount; + @Column(name = "total_forecast_amount", precision = 15, scale = 2) + private BigDecimal totalForecastAmount; @Column(name = "total_planned_project_size_ha", columnDefinition = "Decimal(15, 4) default '0'") private BigDecimal totalPlannedProjectSizeHa; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectFiscalEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectFiscalEntity.java index c9e494d12..6de26a7c4 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectFiscalEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectFiscalEntity.java @@ -80,14 +80,8 @@ public class ProjectFiscalEntity implements Serializable { @Column(name = "cfs_project_code", length = 25) private String cfsProjectCode; - @Column(name = "fiscal_funding_request_amount", precision = 15, scale = 2) - private BigDecimal fiscalFundingRequestAmount; - - @Column(name = "fiscal_funding_alloc_rationale", length = 4000) - private String fiscalFundingAllocRationale; - - @Column(name = "fiscal_allocated_amount", precision = 15, scale = 2) - private BigDecimal fiscalAllocatedAmount; + @Column(name = "fiscal_forecast_amount", precision = 15, scale = 2) + private BigDecimal fiscalForecastAmount; @Column(name = "fiscal_ancillary_fund_amount", precision = 15, scale = 2) private BigDecimal fiscalAncillaryFundAmount; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectPlanStatusCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectPlanStatusCodeEntity.java new file mode 100644 index 000000000..d94b753d6 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectPlanStatusCodeEntity.java @@ -0,0 +1,71 @@ +package ca.bc.gov.nrs.wfprev.data.entities; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.*; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; + +import java.io.Serializable; +import java.util.Date; + +@Entity +@Table(name = "project_plan_status_code") +@JsonIgnoreProperties(ignoreUnknown = false) +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectPlanStatusCodeEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "project_plan_status_code") + @NotNull + private String projectPlanStatusCode; + + @NotNull + @Column(name = "description", length = 200) + private String description; + + @Column(name = "display_order", length = 3) + private Integer displayOrder; + + @NotNull + @Column(name = "effective_date") + private Date effectiveDate; + + @NotNull + @Column(name = "expiry_date") + private Date expiryDate; + + @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") + @NotNull + @Version + private Integer revisionCount; + + @CreatedBy + @NotNull + @Column(name="create_user", length = 64) + private String createUser; + + @CreatedDate + @NotNull + @Column(name="create_date") + private Date createDate; + + @LastModifiedBy + @NotNull + @Column(name="update_user", length = 64) + private String updateUser; + + @LastModifiedDate + @NotNull + @Column(name="update_date") + private Date updateDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectFiscalModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectFiscalModel.java index 82782daca..205283e69 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectFiscalModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectFiscalModel.java @@ -39,9 +39,7 @@ public class ProjectFiscalModel extends CommonModel { private BigDecimal estimatedClwrrAllocAmount; private BigDecimal totalCostEstimateAmount; private String cfsProjectCode; - private BigDecimal fiscalFundingRequestAmount; - private String fiscalFundingAllocRationale; - private BigDecimal fiscalAllocatedAmount; + private BigDecimal fiscalForecastAmount; private BigDecimal fiscalAncillaryFundAmount; private BigDecimal fiscalPlannedProjectSizeHa; private BigDecimal fiscalPlannedCostPerHaAmt; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java index 294b02d65..c5f2d0942 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java @@ -43,8 +43,8 @@ public class ProjectModel extends CommonModel { private String projectLeadEmailAddress; private String projectDescription; private String closestCommunityName; - private BigDecimal totalFundingRequestAmount; - private BigDecimal totalAllocatedAmount; + private BigDecimal totalEstimatedCostAmount; + private BigDecimal totalForecastAmount; private BigDecimal totalPlannedProjectSizeHa; private BigDecimal totalPlannedCostPerHectare; private BigDecimal totalActualAmount; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectPlanStatusCodeModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectPlanStatusCodeModel.java new file mode 100644 index 000000000..cdb48be59 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectPlanStatusCodeModel.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.wfprev.data.models; + +import java.util.Date; + +import org.springframework.hateoas.server.core.Relation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonRootName; + +import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + + +@Data +@EqualsAndHashCode(callSuper = false) +@JsonRootName(value = "objectiveTypeCode") +@Relation(collectionRelation = "objectiveTypeCode") +@JsonInclude(Include.NON_NULL) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectPlanStatusCodeModel extends CommonModel { + private String projectPlanStatusCode; + private String description; + private Integer displayOrder; + private Date effectiveDate; + private Date expiryDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ObjectiveTypeCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ObjectiveTypeCodeRepository.java index f570152cb..797b6c536 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ObjectiveTypeCodeRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ObjectiveTypeCodeRepository.java @@ -3,7 +3,6 @@ import ca.bc.gov.nrs.wfprev.data.entities.ObjectiveTypeCodeEntity; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; -import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; @RepositoryRestResource(exported = false) public interface ObjectiveTypeCodeRepository extends CommonRepository { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectPlanStatusCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectPlanStatusCodeRepository.java new file mode 100644 index 000000000..73d678449 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectPlanStatusCodeRepository.java @@ -0,0 +1,10 @@ +package ca.bc.gov.nrs.wfprev.data.repositories; + +import ca.bc.gov.nrs.wfprev.data.entities.ProjectPlanStatusCodeEntity; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; + +@RepositoryRestResource(exported = false) +public interface ProjectPlanStatusCodeRepository extends CommonRepository { + +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java index 0f30561d4..065252721 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java @@ -3,22 +3,8 @@ import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.services.CommonService; import ca.bc.gov.nrs.wfprev.data.assemblers.*; -import ca.bc.gov.nrs.wfprev.data.entities.BCParksOrgUnitEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ForestOrgUnitCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProgramAreaEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ObjectiveTypeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.models.BCParksRegionCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.BCParksSectionCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ForestDistrictUnitCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ForestRegionUnitCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ProgramAreaModel; -import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ObjectiveTypeCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.*; +import ca.bc.gov.nrs.wfprev.data.models.*; import ca.bc.gov.nrs.wfprev.data.repositories.*; import lombok.extern.slf4j.Slf4j; import org.springframework.hateoas.CollectionModel; @@ -48,6 +34,8 @@ public class CodesService implements CommonService { private final BCParksOrgUnitCodeRepository bcParksOrgUnitCodeRepository; private final ObjectiveTypeCodeResourceAssembler objectiveTypeCodeResourceAssembler; private final ObjectiveTypeCodeRepository objectiveTypeCodeRepository; + private final ProjectPlanStatusCodeResourceAssembler projectPlanStatusCodeResourceAssembler; + private final ProjectPlanStatusCodeRepository projectPlanStatusCodeRepository; public CodesService(ForestAreaCodeRepository forestAreaCodeRepository, ForestAreaCodeResourceAssembler forestAreaCodeResourceAssembler, @@ -55,7 +43,7 @@ public CodesService(ForestAreaCodeRepository forestAreaCodeRepository, ForestAre ProjectTypeCodeRepository projectTypeCodeRepository, ProjectTypeCodeResourceAssembler projectTypeCodeResourceAssembler, ProgramAreaRepository programAreaRepository, ProgramAreaResourceAssembler programAreaResourceAssembler, ForestOrgUnitCodeRepository forestRegionCodeRepository, ForestRegionUnitCodeResourceAssembler forestRegionCodeResourceAssembler, ForestDistrictUnitCodeResourceAssembler forestDistrictUnitCodeResourceAssembler, BCParksOrgUnitCodeRepository bcParksOrgUnitCodeRepository, BCParksRegionCodeResourceAssembler bcParksRegionCodeResourceAssembler, BCParksSectionCodeResourceAssembler bcParksSectionCodeResourceAssembler, - ObjectiveTypeCodeResourceAssembler objectiveTypeCodeResourceAssembler, ObjectiveTypeCodeRepository objectiveTypeCodeRepository) { + ObjectiveTypeCodeResourceAssembler objectiveTypeCodeResourceAssembler, ObjectiveTypeCodeRepository objectiveTypeCodeRepository, ProjectPlanStatusCodeResourceAssembler projectPlanStatusCodeResourceAssembler, ProjectPlanStatusCodeRepository projectPlanStatusCodeRepository) { this.forestAreaCodeRepository = forestAreaCodeRepository; this.forestAreaCodeResourceAssembler = forestAreaCodeResourceAssembler; this.generalScopeCodeRepository = generalScopeCodeRepository; @@ -72,6 +60,8 @@ public CodesService(ForestAreaCodeRepository forestAreaCodeRepository, ForestAre this.bcParksSectionCodeResourceAssembler = bcParksSectionCodeResourceAssembler; this.objectiveTypeCodeResourceAssembler = objectiveTypeCodeResourceAssembler; this.objectiveTypeCodeRepository = objectiveTypeCodeRepository; + this.projectPlanStatusCodeResourceAssembler = projectPlanStatusCodeResourceAssembler; + this.projectPlanStatusCodeRepository = projectPlanStatusCodeRepository; } /** @@ -238,4 +228,21 @@ public ObjectiveTypeCodeModel getObjectiveTypeCodeById(String id) throws Service throw new ServiceException(e.getLocalizedMessage(), e); } } + + public CollectionModel getAllProjectPlanStatusCodes() throws ServiceException { + try { + List entities = projectPlanStatusCodeRepository.findAll(); + return projectPlanStatusCodeResourceAssembler.toCollectionModel(entities); + } catch (Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + public ProjectPlanStatusCodeModel getProjectPlanStatusCodeById(String id) throws ServiceException { + try { + return projectPlanStatusCodeRepository.findById(id).map(projectPlanStatusCodeResourceAssembler::toModel).orElse(null); + } catch (Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } } diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java index 06e326bc3..9fa81ed78 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java @@ -7,6 +7,7 @@ import ca.bc.gov.nrs.wfprev.services.ProjectService; import com.nimbusds.jose.shaded.gson.Gson; import com.nimbusds.jose.shaded.gson.GsonBuilder; +import jakarta.persistence.EntityNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -17,6 +18,7 @@ import org.springframework.data.domain.AuditorAware; import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; import org.springframework.hateoas.CollectionModel; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; @@ -303,57 +305,73 @@ void testUpdateProject_BadRequest() throws Exception { @Test @WithMockUser - void testDeleteProject() throws Exception { - // Given - String projectGuid = UUID.randomUUID().toString(); - ProjectModel project = new ProjectModel(); - project.setProjectGuid(projectGuid); - - when(projectService.deleteProject(projectGuid)).thenReturn(project); - - // When - mockMvc.perform(delete("/projects/{id}", projectGuid) - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer admin-token")) - .andExpect(status().isOk()); - - // Then - verify(projectService, times(1)).deleteProject(projectGuid); + void testDeleteAProject_Success() throws Exception { + // GIVEN a valid project ID + String projectId = "456e7890-e89b-12d3-a456-426614174001"; + + // WHEN the delete endpoint is called + mockMvc.perform(delete("/projects/{id}", projectId) + .header(HttpHeaders.AUTHORIZATION, "Bearer test-token") + .accept(MediaType.APPLICATION_JSON)) + // THEN the response status should be 204 No Content + .andExpect(status().isNoContent()); + + // THEN the service's delete method should be called once with the correct ID + verify(projectService).deleteProject(projectId); } @Test @WithMockUser - void testDeleteProject_Exception() throws Exception { - // Given - String projectGuid = UUID.randomUUID().toString(); - when(projectService.deleteProject(projectGuid)).thenThrow(new ServiceException("Error deleting project")); - - // When - ResultActions result = mockMvc.perform(delete("/projects/{id}", projectGuid) - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer admin-token")) - .andExpect(status().is5xxServerError()); + void testDeleteAProject_NotFound() throws Exception { + // GIVEN a project ID that does not exist + String projectId = "456e7890-e89b-12d3-a456-426614174001"; + doThrow(new EntityNotFoundException("Not found")).when(projectService).deleteProject(projectId); + + // WHEN the delete endpoint is called + mockMvc.perform(delete("/projects/{id}", projectId) + .header(HttpHeaders.AUTHORIZATION, "Bearer test-token") + .accept(MediaType.APPLICATION_JSON)) + // THEN the response status should be 404 Not Found + .andExpect(status().isNotFound()); - // Then - verify(projectService, times(1)).deleteProject(projectGuid); - assertEquals(500, result.andReturn().getResponse().getStatus()); + // THEN the service's delete method should be called once with the correct ID + verify(projectService).deleteProject(projectId); } @Test @WithMockUser - void testDeleteProject_notFound() throws Exception { - // Given - String projectGuid = UUID.randomUUID().toString(); - when(projectService.deleteProject(projectGuid)).thenReturn(null); - // When - ResultActions result = mockMvc.perform(delete("/projects/{id}", projectGuid) - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer admin-token")) - .andExpect(status().is4xxClientError()); + void testDeleteAProject_InvalidId() throws Exception { + // GIVEN an invalid project ID + String invalidId = "invalid-uuid"; + doThrow(new IllegalArgumentException("Invalid UUID")).when(projectService).deleteProject(invalidId); + + // WHEN the delete endpoint is called + mockMvc.perform(delete("/projects/{id}", invalidId) + .header(HttpHeaders.AUTHORIZATION, "Bearer test-token") + .accept(MediaType.APPLICATION_JSON)) + // THEN the response status should be 400 Bad Request + .andExpect(status().isBadRequest()); + + // THEN the service's delete method should be called once with the invalid ID + verify(projectService).deleteProject(invalidId); + } - // Then - verify(projectService, times(1)).deleteProject(projectGuid); - assertEquals(404, result.andReturn().getResponse().getStatus()); + @Test + @WithMockUser + void testDeleteAProject_InternalServerError() throws Exception { + // GIVEN a valid project ID but an unexpected error occurs + String projectId = "456e7890-e89b-12d3-a456-426614174001"; + doThrow(new RuntimeException("Unexpected error")).when(projectService).deleteProject(projectId); + + // WHEN the delete endpoint is called + mockMvc.perform(delete("/projects/{id}", projectId) + .header(HttpHeaders.AUTHORIZATION, "Bearer test-token") + .accept(MediaType.APPLICATION_JSON)) + // THEN the response status should be 500 Internal Server Error + .andExpect(status().isInternalServerError()); + + // THEN the service's delete method should be called once with the correct ID + verify(projectService).deleteProject(projectId); } @Test diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssemblerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssemblerTest.java index 5b47a0d9b..bbd193559 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssemblerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ObjectiveTypeCodeResourceAssemblerTest.java @@ -1,23 +1,17 @@ package ca.bc.gov.nrs.wfprev.data.assemblers; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; - +import ca.bc.gov.nrs.wfprev.data.entities.ObjectiveTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.ObjectiveTypeCodeModel; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.hateoas.CollectionModel; -import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; -import ca.bc.gov.nrs.wfprev.controllers.CodesController; -import ca.bc.gov.nrs.wfprev.data.entities.ObjectiveTypeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.models.ObjectiveTypeCodeModel; - -import java.time.LocalDateTime; import java.util.Arrays; import java.util.Date; import java.util.List; +import static org.junit.jupiter.api.Assertions.*; + class ObjectiveTypeCodeResourceAssemblerTest { private ObjectiveTypeCodeResourceAssembler assembler; diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssemblerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssemblerTest.java new file mode 100644 index 000000000..cfb35cb8e --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectPlanStatusCodeResourceAssemblerTest.java @@ -0,0 +1,101 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; + +import ca.bc.gov.nrs.wfprev.data.entities.ProjectPlanStatusCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProjectPlanStatusCodeModel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.hateoas.CollectionModel; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ProjectPlanStatusCodeResourceAssemblerTest { + private ProjectPlanStatusCodeResourceAssembler assembler; + + @BeforeEach + void setUp() { + assembler = new ProjectPlanStatusCodeResourceAssembler(); + } + + @Test + void testToModel_Success() { + // Arrange + ProjectPlanStatusCodeEntity entity = createTestEntity(); + + // Act + ProjectPlanStatusCodeModel model = assembler.toModel(entity); + + // Assert + assertNotNull(model); + assertEquals(entity.getProjectPlanStatusCode(), model.getProjectPlanStatusCode()); + assertEquals(entity.getDescription(), model.getDescription()); + assertNotNull(model.getLinks()); + assertTrue(model.getLinks().hasLink("self")); + } + + @Test + void testToEntity_Success() { + // Arrange + ProjectPlanStatusCodeModel model = createTestModel(); + + // Act + ProjectPlanStatusCodeEntity entity = assembler.toEntity(model); + + // Assert + assertNotNull(entity); + assertEquals(model.getProjectPlanStatusCode(), entity.getProjectPlanStatusCode()); + assertEquals(model.getDescription(), entity.getDescription()); + } + + @Test + void testToCollectionModel_Success() { + // Arrange + ProjectPlanStatusCodeEntity entity1 = createTestEntity(); + ProjectPlanStatusCodeEntity entity2 = createTestEntity(); + entity2.setProjectPlanStatusCode("Code2"); + List entities = Arrays.asList(entity1, entity2); + + // Act + CollectionModel collectionModel = assembler.toCollectionModel(entities); + + // Assert + assertNotNull(collectionModel); + assertEquals(2, collectionModel.getContent().size()); + assertNotNull(collectionModel.getLinks()); + assertTrue(collectionModel.getLinks().hasLink("self")); + } + + private ProjectPlanStatusCodeEntity createTestEntity() { + ProjectPlanStatusCodeEntity entity = new ProjectPlanStatusCodeEntity(); + entity.setProjectPlanStatusCode("Code1"); + entity.setDescription("Test Description"); + entity.setDisplayOrder(1); + entity.setEffectiveDate(new Date()); + entity.setExpiryDate(new Date()); + entity.setRevisionCount(1); + entity.setCreateUser("TestUser"); + entity.setCreateDate(new Date()); + entity.setUpdateUser("Updater"); + entity.setUpdateDate(new Date()); + return entity; + } + + private ProjectPlanStatusCodeModel createTestModel() { + ProjectPlanStatusCodeModel model = new ProjectPlanStatusCodeModel(); + model.setProjectPlanStatusCode("Code1"); + model.setDescription("Test Description"); + model.setDisplayOrder(1); + model.setEffectiveDate(new Date()); + model.setExpiryDate(new Date()); + model.setRevisionCount(1); + model.setCreateUser("TestUser"); + model.setCreateDate(new Date()); + model.setUpdateUser("Updater"); + model.setUpdateDate(new Date()); + return model; + } +} diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/CodesServiceTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/CodesServiceTest.java index 97dc12023..ddd59bdc9 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/CodesServiceTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/CodesServiceTest.java @@ -27,6 +27,7 @@ class CodesServiceTest { private ProjectTypeCodeRepository projectTypeCodeRepository; private ProjectTypeCodeResourceAssembler projectTypeCodeResourceAssembler; private ObjectiveTypeCodeRepository objectiveTypeCodeRepository; + private ProjectPlanStatusCodeRepository projectPlanStatusCodeRepository; private ProgramAreaRepository programAreaRepository; private ProgramAreaResourceAssembler programAreaResourceAssembler; @@ -37,6 +38,7 @@ class CodesServiceTest { private BCParksRegionCodeResourceAssembler bcParksRegionCodeResourceAssembler; private BCParksSectionCodeResourceAssembler bcParksSectionCodeResourceAssembler; private ObjectiveTypeCodeResourceAssembler objectiveTypeCodeResourceAssembler; + private ProjectPlanStatusCodeResourceAssembler projectPlanStatusCodeResourceAssembler; @BeforeEach void setup() { @@ -56,12 +58,14 @@ void setup() { bcParksSectionCodeResourceAssembler = mock(BCParksSectionCodeResourceAssembler.class); objectiveTypeCodeResourceAssembler = mock(ObjectiveTypeCodeResourceAssembler.class); objectiveTypeCodeRepository = mock(ObjectiveTypeCodeRepository.class); + projectPlanStatusCodeResourceAssembler = mock(ProjectPlanStatusCodeResourceAssembler.class); + projectPlanStatusCodeRepository = mock(ProjectPlanStatusCodeRepository.class); codesService = new CodesService(forestAreaCodeRepository, forestAreaCodeResourceAssembler, generalScopeCodeRepository, generalScopeCodeResourceAssembler, projectTypeCodeRepository, projectTypeCodeResourceAssembler, programAreaRepository, programAreaResourceAssembler, forestOrgUnitCodeRepository, forestRegionUnitCodeResourceAssembler, forestDistrictUnitCodeResourceAssembler, bcParksOrgUnitCodeRepository, bcParksRegionCodeResourceAssembler, - bcParksSectionCodeResourceAssembler, objectiveTypeCodeResourceAssembler, objectiveTypeCodeRepository); + bcParksSectionCodeResourceAssembler, objectiveTypeCodeResourceAssembler, objectiveTypeCodeRepository, projectPlanStatusCodeResourceAssembler, projectPlanStatusCodeRepository); } @Test @@ -827,4 +831,100 @@ void testGetAllObjectiveTypeCodes_Exception() { assertEquals("Error fetching objective type codes", exception.getMessage()); } + @Test + void testGetAllProjectPlanStatusCodes_Success() throws ServiceException { + // Arrange + List entities = new ArrayList<>(); + entities.add(new ProjectPlanStatusCodeEntity()); + entities.add(new ProjectPlanStatusCodeEntity()); + + when(projectPlanStatusCodeRepository.findAll()).thenReturn(entities); + when(projectPlanStatusCodeResourceAssembler.toCollectionModel(entities)) + .thenReturn(CollectionModel.of(new ArrayList<>())); + + // Act + CollectionModel result = codesService.getAllProjectPlanStatusCodes(); + + // Assert + assertNotNull(result); + } + + @Test + void testGetProjectPlanStatusCodeById_Success() throws ServiceException { + // Arrange + String exampleId = UUID.randomUUID().toString(); + ProjectPlanStatusCodeEntity entity = new ProjectPlanStatusCodeEntity(); + when(projectPlanStatusCodeRepository.findById(exampleId)) + .thenReturn(Optional.of(entity)); + when(projectPlanStatusCodeResourceAssembler.toModel(entity)) + .thenReturn(new ProjectPlanStatusCodeModel()); + + // Act + ProjectPlanStatusCodeModel result = codesService.getProjectPlanStatusCodeById(exampleId); + + // Assert + assertNotNull(result); + } + + @Test + void testGetProjectPlanStatusCodeById_NotFound() throws ServiceException { + // Arrange + String nonExistentId = UUID.randomUUID().toString(); + when(projectPlanStatusCodeRepository.findById(nonExistentId)) + .thenReturn(Optional.empty()); + + // Act + ProjectPlanStatusCodeModel result = codesService.getProjectPlanStatusCodeById(nonExistentId); + + // Assert + assertNull(result); + } + + + @Test + void testProjectPlanStatusCodeById_Exception() { + // Arrange + String exampleId = UUID.randomUUID().toString(); + when(projectPlanStatusCodeRepository.findById(exampleId)) + .thenThrow(new RuntimeException("Error fetching project plan status code")); + + // Act & Assert + ServiceException exception = assertThrows( + ServiceException.class, + () -> codesService.getProjectPlanStatusCodeById(exampleId) + ); + assertTrue(exception.getMessage().contains("Error fetching project plan status code")); + } + + @Test + void getAllProjectPlanStatusCodes_Success() throws ServiceException { + // Arrange + List entities = new ArrayList<>(); + entities.add(new ProjectPlanStatusCodeEntity()); + entities.add(new ProjectPlanStatusCodeEntity()); + + when(projectPlanStatusCodeRepository.findAll()).thenReturn(entities); + when(projectPlanStatusCodeResourceAssembler.toCollectionModel(entities)) + .thenReturn(CollectionModel.of(new ArrayList<>())); + + // Act + CollectionModel result = codesService.getAllProjectPlanStatusCodes(); + + // Assert + assertNotNull(result); + } + + @Test + void testGetAllProjectPlanStatusCodes_Exception() { + // Arrange + when(projectPlanStatusCodeRepository.findAll()).thenThrow(new RuntimeException("Error fetching project plan status codes")); + + // Act & Assert + ServiceException exception = assertThrows( + ServiceException.class, + () -> codesService.getAllProjectPlanStatusCodes() + ); + assertEquals("Error fetching project plan status codes", exception.getMessage()); + } + } \ No newline at end of file diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectFiscalServiceTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectFiscalServiceTest.java index d24e80cff..2e5ae95c6 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectFiscalServiceTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectFiscalServiceTest.java @@ -73,9 +73,7 @@ void testGetAllProjectFiscals_NotEmpty() { projectFiscalModel1.setEstimatedClwrrAllocAmount(BigDecimal.valueOf(10000)); projectFiscalModel1.setTotalCostEstimateAmount(BigDecimal.valueOf(50000)); projectFiscalModel1.setCfsProjectCode("CFS-123"); - projectFiscalModel1.setFiscalFundingRequestAmount(BigDecimal.valueOf(20000)); - projectFiscalModel1.setFiscalFundingAllocRationale("Rationale for funding allocation 1"); - projectFiscalModel1.setFiscalAllocatedAmount(BigDecimal.valueOf(15000)); + projectFiscalModel1.setFiscalForecastAmount(BigDecimal.valueOf(15000)); projectFiscalModel1.setFiscalAncillaryFundAmount(BigDecimal.valueOf(5000)); projectFiscalModel1.setFiscalPlannedProjectSizeHa(BigDecimal.valueOf(50)); projectFiscalModel1.setFiscalPlannedCostPerHaAmt(BigDecimal.valueOf(300)); @@ -126,9 +124,7 @@ void testGetAllProjectFiscals_NotEmpty() { projectFiscalModel2.setEstimatedClwrrAllocAmount(BigDecimal.valueOf(20000)); projectFiscalModel2.setTotalCostEstimateAmount(BigDecimal.valueOf(60000)); projectFiscalModel2.setCfsProjectCode("CFS-456"); - projectFiscalModel2.setFiscalFundingRequestAmount(BigDecimal.valueOf(30000)); - projectFiscalModel2.setFiscalFundingAllocRationale("Rationale for funding allocation 2"); - projectFiscalModel2.setFiscalAllocatedAmount(BigDecimal.valueOf(25000)); + projectFiscalModel2.setFiscalForecastAmount(BigDecimal.valueOf(25000)); projectFiscalModel2.setFiscalAncillaryFundAmount(BigDecimal.valueOf(7000)); projectFiscalModel2.setFiscalPlannedProjectSizeHa(BigDecimal.valueOf(70)); projectFiscalModel2.setFiscalPlannedCostPerHaAmt(BigDecimal.valueOf(400)); @@ -273,9 +269,7 @@ void testUpdateProjectFiscal_Success() { projectFiscalModel.setEstimatedClwrrAllocAmount(BigDecimal.valueOf(10000)); projectFiscalModel.setTotalCostEstimateAmount(BigDecimal.valueOf(50000)); projectFiscalModel.setCfsProjectCode("CFS-123"); - projectFiscalModel.setFiscalFundingRequestAmount(BigDecimal.valueOf(20000)); - projectFiscalModel.setFiscalFundingAllocRationale("Rationale for funding allocation 1"); - projectFiscalModel.setFiscalAllocatedAmount(BigDecimal.valueOf(15000)); + projectFiscalModel.setFiscalForecastAmount(BigDecimal.valueOf(20000)); projectFiscalModel.setFiscalAncillaryFundAmount(BigDecimal.valueOf(5000)); projectFiscalModel.setFiscalPlannedProjectSizeHa(BigDecimal.valueOf(50)); projectFiscalModel.setFiscalPlannedCostPerHaAmt(BigDecimal.valueOf(300)); @@ -354,9 +348,7 @@ void testUpdateProjectFiscal_NotFoundOnGet() { projectFiscalModel.setEstimatedClwrrAllocAmount(BigDecimal.valueOf(10000)); projectFiscalModel.setTotalCostEstimateAmount(BigDecimal.valueOf(50000)); projectFiscalModel.setCfsProjectCode("CFS-123"); - projectFiscalModel.setFiscalFundingRequestAmount(BigDecimal.valueOf(20000)); - projectFiscalModel.setFiscalFundingAllocRationale("Rationale for funding allocation 1"); - projectFiscalModel.setFiscalAllocatedAmount(BigDecimal.valueOf(15000)); + projectFiscalModel.setFiscalActualAmount(BigDecimal.valueOf(15000)); projectFiscalModel.setFiscalAncillaryFundAmount(BigDecimal.valueOf(5000)); projectFiscalModel.setFiscalPlannedProjectSizeHa(BigDecimal.valueOf(50)); projectFiscalModel.setFiscalPlannedCostPerHaAmt(BigDecimal.valueOf(300)); @@ -402,9 +394,7 @@ void testUpdateProjectFiscal_NotFoundOnSave() { projectFiscalModel.setEstimatedClwrrAllocAmount(BigDecimal.valueOf(10000)); projectFiscalModel.setTotalCostEstimateAmount(BigDecimal.valueOf(50000)); projectFiscalModel.setCfsProjectCode("CFS-123"); - projectFiscalModel.setFiscalFundingRequestAmount(BigDecimal.valueOf(20000)); - projectFiscalModel.setFiscalFundingAllocRationale("Rationale for funding allocation 1"); - projectFiscalModel.setFiscalAllocatedAmount(BigDecimal.valueOf(15000)); + projectFiscalModel.setFiscalForecastAmount(BigDecimal.valueOf(20000)); projectFiscalModel.setFiscalAncillaryFundAmount(BigDecimal.valueOf(5000)); projectFiscalModel.setFiscalPlannedProjectSizeHa(BigDecimal.valueOf(50)); projectFiscalModel.setFiscalPlannedCostPerHaAmt(BigDecimal.valueOf(300)); @@ -461,9 +451,7 @@ void testUpdateProjectFiscal_DataIntegrityViolationException() { projectFiscalModel.setEstimatedClwrrAllocAmount(BigDecimal.valueOf(10000)); projectFiscalModel.setTotalCostEstimateAmount(BigDecimal.valueOf(50000)); projectFiscalModel.setCfsProjectCode("CFS-123"); - projectFiscalModel.setFiscalFundingRequestAmount(BigDecimal.valueOf(20000)); - projectFiscalModel.setFiscalFundingAllocRationale("Rationale for funding allocation 1"); - projectFiscalModel.setFiscalAllocatedAmount(BigDecimal.valueOf(15000)); + projectFiscalModel.setFiscalForecastAmount(BigDecimal.valueOf(20000)); projectFiscalModel.setFiscalAncillaryFundAmount(BigDecimal.valueOf(5000)); projectFiscalModel.setFiscalPlannedProjectSizeHa(BigDecimal.valueOf(50)); projectFiscalModel.setFiscalPlannedCostPerHaAmt(BigDecimal.valueOf(300)); From 7e0a3bfe3ffdac17654c51ac95f1a91640f0e6a8 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Wed, 15 Jan 2025 17:26:39 -0800 Subject: [PATCH 2/8] Update Postman collection --- postman/Prevention.postman_collection.json | 52 +++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/postman/Prevention.postman_collection.json b/postman/Prevention.postman_collection.json index e63371ab3..e5d858e75 100644 --- a/postman/Prevention.postman_collection.json +++ b/postman/Prevention.postman_collection.json @@ -815,6 +815,54 @@ }, "response": [] }, + { + "name": "GET Project Plan Status Codes", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function() {", + " pm.response.to.have.status(200);", + "})" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{accessToken}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{LOCAL_API_URL}}/codes/projectPlanStatusCodes", + "host": [ + "{{LOCAL_API_URL}}" + ], + "path": [ + "codes", + "projectPlanStatusCodes" + ] + } + }, + "response": [] + }, { "name": "Get ProjectFiscal", "event": [ @@ -953,8 +1001,8 @@ "listen": "test", "script": { "exec": [ - "pm.test(\"Status code is 200\", function() {", - " pm.response.to.have.status(200);", + "pm.test(\"Status code is 204\", function() {", + " pm.response.to.have.status(204);", "})" ], "type": "text/javascript", From 8fa73a5b7fa26a27c2b2b59e655fed21719c2bb1 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Wed, 15 Jan 2025 17:44:52 -0800 Subject: [PATCH 3/8] Update logging --- .../ca/bc/gov/nrs/wfprev/controllers/ProjectController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java index 77c276359..81aa6c770 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java @@ -175,13 +175,12 @@ public ResponseEntity deleteProject(@PathVariable("id") String id) { try { projectService.deleteProject(id); - log.debug(" << deleteProjectFiscal success"); + log.debug(" << deleteProject success"); return ResponseEntity.noContent().build(); } catch (EntityNotFoundException e) { log.warn(" ### Project not found with id: {}", id, e); return ResponseEntity.notFound().build(); } catch (IllegalArgumentException e) { - log.warn(" ### Invalid ID provided: {}", id, e); return ResponseEntity.badRequest().build(); } catch (Exception e) { log.error(" ### Error while deleting Project ith id: {}", id, e); From 4b282200cb3c7cef2070d814b023c41a3cb25893 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Thu, 16 Jan 2025 13:56:23 -0800 Subject: [PATCH 4/8] Fix Postman tests --- postman/Prevention.postman_collection.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/postman/Prevention.postman_collection.json b/postman/Prevention.postman_collection.json index e5d858e75..338b0f963 100644 --- a/postman/Prevention.postman_collection.json +++ b/postman/Prevention.postman_collection.json @@ -137,7 +137,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"WEST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Sample Forest Management Project\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 100000.00,\n \"totalForecastAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001\n,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", + "raw": "{\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"WEST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Sample Forest Management Project\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 100000.00,\n \"totalForecastAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", "options": { "raw": { "language": "json" @@ -209,7 +209,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"TACT_PLAN\",\n \"fiscalYear\": 2023,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"DRAFT\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"totalCostEstimateAmount\": 2000.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false\n}", + "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"TACT_PLAN\",\n \"fiscalYear\": 2023,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"DRAFT\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false,\n \"fiscalForecastAmount\": 1800.00}", "options": { "raw": { "language": "json" @@ -271,7 +271,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectPlanFiscalGuid\": \"{{projectPlanFiscalGuid}}\",\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"RX_DEV\",\n \"fiscalYear\": 2024,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"PROPOSED\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"totalCostEstimateAmount\": 2000.00,\n \"fiscalForecastAmount\": 300.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false\n}", + "raw": "{\n \"projectPlanFiscalGuid\": \"{{projectPlanFiscalGuid}}\",\n \"projectGuid\": \"{{projectGuid}}\",\n \"activityCategoryCode\": \"RX_DEV\",\n \"fiscalYear\": 2024,\n \"projectPlanStatusCode\": \"ACTIVE\",\n \"planFiscalStatusCode\": \"PROPOSED\",\n \"projectFiscalName\": \"Fiscal Project 1\",\n \"projectFiscalDescription\": \"This is a test project fiscal description.\",\n \"businessAreaComment\": \"Test comment\",\n \"estimatedClwrrAllocAmount\": 1000.00,\n \"fiscalForecastAmount\": 300.00,\n \"fiscalAncillaryFundAmount\": 300.00,\n \"fiscalPlannedProjectSizeHa\": 10.5,\n \"fiscalPlannedCostPerHaAmt\": 500.00,\n \"fiscalReportedSpendAmount\": 0.00,\n \"fiscalActualAmount\": 0.00,\n \"fiscalCompletedSizeHa\": 0.0,\n \"fiscalActualCostPerHaAmt\": 0.0,\n \"firstNationsDelivPartInd\": true,\n \"firstNationsEngagementInd\": false,\n \"firstNationsPartner\": \"Test Partner\",\n \"resultsNumber\": \"RN123456\",\n \"resultsOpeningId\": \"RO12345\",\n \"resultsContactEmail\": \"contact@example.com\",\n \"submittedByName\": \"Test User\",\n \"submittedByUserGuid\": \"123e4567-e89\",\n \"submittedByUserUserid\": \"testuser\",\n \"submissionTimestamp\": \"2024-01-01T12:00:00Z\",\n \"isApprovedInd\": true,\n \"isDelayedInd\": false\n}", "options": { "raw": { "language": "json" @@ -387,7 +387,7 @@ "response": [] }, { - "name": "Update Project Copy", + "name": "Update Project", "event": [ { "listen": "test", @@ -417,7 +417,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"COAST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Test 3\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 100000.00,\n \"totalForecastAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001\n,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", + "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"COAST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Test 3\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 177000.00,\n \"totalForecastAmount\": 125000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", "options": { "raw": { "language": "json" From 56f8e80ae42e44419c640bee84d09b476623b252 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Thu, 16 Jan 2025 18:35:46 -0800 Subject: [PATCH 5/8] WFPREV-259 Change project entity to use ObjectiveTypeCodeModel for JPA --- .github/workflows/build-full-environment.yml | 1 + .github/workflows/terragrunt-deploy.yml | 3 + postman/Prevention.postman_collection.json | 4 +- .../assemblers/ProjectResourceAssembler.java | 58 +++++++++++++------ .../wfprev/data/entities/ProjectEntity.java | 15 +++-- .../nrs/wfprev/data/models/ProjectModel.java | 7 ++- .../nrs/wfprev/services/ProjectService.java | 34 +++++++---- .../ProjectResourceAssemblerTest.java | 54 ++++++++++------- 8 files changed, 116 insertions(+), 60 deletions(-) diff --git a/.github/workflows/build-full-environment.yml b/.github/workflows/build-full-environment.yml index 8950b1e39..4a76bb17b 100644 --- a/.github/workflows/build-full-environment.yml +++ b/.github/workflows/build-full-environment.yml @@ -46,6 +46,7 @@ jobs: with: DEFAULT_APPLICATION_ENVIRONMENT: dev IMAGE_TAG: latest + RUN_LIQUIBASE: true secrets: inherit wfprev-ui: diff --git a/.github/workflows/terragrunt-deploy.yml b/.github/workflows/terragrunt-deploy.yml index 1203d7a63..552e83cf8 100644 --- a/.github/workflows/terragrunt-deploy.yml +++ b/.github/workflows/terragrunt-deploy.yml @@ -13,6 +13,9 @@ on: IMAGE_TAG: required: true type: string + RUN_LIQUIBASE: + required: true + type: string workflow_dispatch: inputs: DEFAULT_APPLICATION_ENVIRONMENT: diff --git a/postman/Prevention.postman_collection.json b/postman/Prevention.postman_collection.json index 338b0f963..6e7d4e2d7 100644 --- a/postman/Prevention.postman_collection.json +++ b/postman/Prevention.postman_collection.json @@ -137,7 +137,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"WEST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Sample Forest Management Project\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 100000.00,\n \"totalForecastAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", + "raw": "{\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"WEST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Sample Forest Management Project\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 100000.00,\n \"totalForecastAmount\": 95000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001,\n \"primaryObjectiveTypeCode\": {\n \"objectiveTypeCode\": \"CRIT_INFRA\"\n },\n \"secondaryObjectiveTypeCode\": {\n \"objectiveTypeCode\": \"WRR\"\n },\n \"tertiaryObjectiveTypeCode\": {\n \"objectiveTypeCode\": \"ECO_REST\"\n } \n}", "options": { "raw": { "language": "json" @@ -417,7 +417,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"COAST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Test 3\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 177000.00,\n \"totalForecastAmount\": 125000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001,\n \"primaryObjectiveTypeCode\": \"WRR\",\n \"secondaryObjectiveTypeCode\": \"CRIT_INFRA\",\n \"tertiaryObjectiveTypeCode\": \"ECO_REST\"}", + "raw": "{\n \"projectGuid\": \"{{projectGuid}}\",\n \"projectTypeCode\": {\n \"projectTypeCode\": \"FUEL_MGMT\"\n },\n \"siteUnitName\": \"Vancouver Forest Unit\",\n \"forestAreaCode\": {\n \"forestAreaCode\": \"COAST\"\n },\n \"generalScopeCode\": {\n \"generalScopeCode\": \"SL_ACT\"\n },\n \"project_status_code\": \"ACTIVE\",\n \"programAreaGuid\": \"27602cd9-4b6e-9be0-e063-690a0a0afb50\",\n \"projectName\": \"Test 3\",\n \"projectLead\": \"Jane Smith\",\n \"projectLeadEmailAddress\": \"jane.smith@example.com\",\n \"projectDescription\": \"This is a comprehensive forest management project focusing on sustainable practices\",\n \"closestCommunityName\": \"Vancouver\",\n \"totalEstimatedCostAmount\": 177000.00,\n \"totalForecastAmount\": 125000.00,\n \"totalPlannedProjectSizeHa\": 500.00,\n \"totalPlannedCostPerHectare\": 200.00,\n \"totalActualAmount\": 0.00,\n \"isMultiFiscalYearProj\": false,\n \"forestRegionOrgUnitId\": 1001,\n \"forestDistrictOrgUnitId\": 2001,\n \"fireCentreOrgUnitId\": 3001,\n \"bcParksRegionOrgUnitId\": 4001,\n \"bcParksSectionOrgUnitId\": 5001,\n \"primaryObjectiveTypeCode\": {\n \"objectiveTypeCode\": \"RECONCIL\"\n },\n \"secondaryObjectiveTypeCode\": {\n \"objectiveTypeCode\": \"HAZ_ABATE\"\n },\n \"tertiaryObjectiveTypeCode\": {\n \"objectiveTypeCode\": \"FOR_HEALTH\"\n } \n}", "options": { "raw": { "language": "json" diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java index 84f78cc99..87e82fd05 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java @@ -1,14 +1,8 @@ package ca.bc.gov.nrs.wfprev.data.assemblers; import ca.bc.gov.nrs.wfprev.controllers.ProjectController; -import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; -import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.*; +import ca.bc.gov.nrs.wfprev.data.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; @@ -48,6 +42,15 @@ public ProjectEntity toEntity(ProjectModel resource) { if (resource.getProgramAreaGuid() != null) { entity.setProgramAreaGuid(UUID.fromString(resource.getProgramAreaGuid())); } + if (resource.getPrimaryObjectiveTypeCode() != null) { + entity.setPrimaryObjectiveTypeCode(toObjectiveTypeCodeEntity(resource.getPrimaryObjectiveTypeCode())); + } + if (resource.getSecondaryObjectiveTypeCode() != null) { + entity.setSecondaryObjectiveTypeCode(toObjectiveTypeCodeEntity(resource.getSecondaryObjectiveTypeCode())); + } + if (resource.getTertiaryObjectiveTypeCode() != null) { + entity.setTertiaryObjectiveTypeCode(toObjectiveTypeCodeEntity(resource.getTertiaryObjectiveTypeCode())); + } entity.setForestRegionOrgUnitId(resource.getForestRegionOrgUnitId()); entity.setForestDistrictOrgUnitId(resource.getForestDistrictOrgUnitId()); entity.setFireCentreOrgUnitId(resource.getFireCentreOrgUnitId()); @@ -74,9 +77,6 @@ public ProjectEntity toEntity(ProjectModel resource) { entity.setCreateDate(resource.getCreateDate()); entity.setUpdateUser(resource.getUpdateUser()); entity.setUpdateDate(resource.getUpdateDate()); - entity.setPrimaryObjectiveTypeCode(resource.getPrimaryObjectiveTypeCode()); - entity.setSecondaryObjectiveTypeCode(resource.getSecondaryObjectiveTypeCode()); - entity.setTertiaryObjectiveTypeCode(resource.getTertiaryObjectiveTypeCode()); return entity; } @@ -100,6 +100,15 @@ public ProjectModel toModel(ProjectEntity entity) { if (entity.getGeneralScopeCode() != null) { resource.setGeneralScopeCode(toGeneralScopeCodeModel(entity.getGeneralScopeCode())); } + if (entity.getPrimaryObjectiveTypeCode() != null) { + resource.setPrimaryObjectiveTypeCode(toObjectiveTypeCodeModel(entity.getPrimaryObjectiveTypeCode())); + } + if (entity.getSecondaryObjectiveTypeCode() != null) { + resource.setSecondaryObjectiveTypeCode(toObjectiveTypeCodeModel(entity.getSecondaryObjectiveTypeCode())); + } + if (entity.getTertiaryObjectiveTypeCode() != null) { + resource.setTertiaryObjectiveTypeCode(toObjectiveTypeCodeModel(entity.getTertiaryObjectiveTypeCode())); + } resource.setProgramAreaGuid(entity.getProgramAreaGuid().toString()); resource.setForestRegionOrgUnitId(entity.getForestRegionOrgUnitId()); resource.setForestDistrictOrgUnitId(entity.getForestDistrictOrgUnitId()); @@ -127,9 +136,6 @@ public ProjectModel toModel(ProjectEntity entity) { resource.setCreateDate(entity.getCreateDate()); resource.setUpdateUser(entity.getUpdateUser()); resource.setUpdateDate(entity.getUpdateDate()); - resource.setPrimaryObjectiveTypeCode(entity.getPrimaryObjectiveTypeCode()); - resource.setSecondaryObjectiveTypeCode(entity.getSecondaryObjectiveTypeCode()); - resource.setTertiaryObjectiveTypeCode(entity.getTertiaryObjectiveTypeCode()); return resource; } @@ -172,6 +178,21 @@ private GeneralScopeCodeEntity toGeneralScopeCodeEntity(GeneralScopeCodeModel co return ra.toEntity(code); } + private ProjectStatusCodeEntity toProjectStatusCodeEntity(ProjectStatusCodeModel code) { + ProjectStatusCodeResourceAssembler ra = new ProjectStatusCodeResourceAssembler(); + return ra.toEntity(code); + } + + private ObjectiveTypeCodeModel toObjectiveTypeCodeModel(ObjectiveTypeCodeEntity code) { + ObjectiveTypeCodeResourceAssembler ra = new ObjectiveTypeCodeResourceAssembler(); + return ra.toModel(code); + } + + private ObjectiveTypeCodeEntity toObjectiveTypeCodeEntity (ObjectiveTypeCodeModel code) { + ObjectiveTypeCodeResourceAssembler ra = new ObjectiveTypeCodeResourceAssembler(); + return ra.toEntity(code); + } + public ProjectEntity updateEntity(ProjectModel model, ProjectEntity existingEntity) { log.debug(">> updateEntity"); System.out.println("In updateEntity"); @@ -191,7 +212,7 @@ public ProjectEntity updateEntity(ProjectModel model, ProjectEntity existingEnti entity.setLongitude(nonNullOrDefault(model.getLongitude(), existingEntity.getLongitude())); entity.setForestAreaCode(nonNullOrDefault(toForestAreaCodeEntity(model.getForestAreaCode()), existingEntity.getForestAreaCode())); entity.setRevisionCount(nonNullOrDefault(model.getRevisionCount(), existingEntity.getRevisionCount())); - entity.setProjectStatusCode(existingEntity.getProjectStatusCode()); + entity.setProjectStatusCode(nonNullOrDefault(toProjectStatusCodeEntity(model.getProjectStatusCode()), existingEntity.getProjectStatusCode())); entity.setSiteUnitName(nonNullOrDefault(model.getSiteUnitName(), existingEntity.getSiteUnitName())); entity.setProgramAreaGuid( nonNullOrDefault( @@ -212,9 +233,12 @@ public ProjectEntity updateEntity(ProjectModel model, ProjectEntity existingEnti entity.setCreateDate(existingEntity.getCreateDate()); entity.setUpdateUser(existingEntity.getUpdateUser()); entity.setUpdateDate(existingEntity.getUpdateDate()); - entity.setProjectTypeCode(existingEntity.getProjectTypeCode()); - entity.setGeneralScopeCode(existingEntity.getGeneralScopeCode()); + entity.setProjectTypeCode(nonNullOrDefault(toProjectTypeCodeEntity(model.getProjectTypeCode()), existingEntity.getProjectTypeCode())); + entity.setGeneralScopeCode(nonNullOrDefault(toGeneralScopeCodeEntity(model.getGeneralScopeCode()), existingEntity.getGeneralScopeCode())); entity.setProjectNumber(existingEntity.getProjectNumber()); + entity.setPrimaryObjectiveTypeCode(nonNullOrDefault(toObjectiveTypeCodeEntity(model.getPrimaryObjectiveTypeCode()), existingEntity.getPrimaryObjectiveTypeCode())); + entity.setSecondaryObjectiveTypeCode(nonNullOrDefault(toObjectiveTypeCodeEntity(model.getSecondaryObjectiveTypeCode()), existingEntity.getSecondaryObjectiveTypeCode())); + entity.setTertiaryObjectiveTypeCode(nonNullOrDefault(toObjectiveTypeCodeEntity(model.getTertiaryObjectiveTypeCode()), existingEntity.getTertiaryObjectiveTypeCode())); log.error("Updated entity: " + entity); return entity; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java index 157fb0177..6158cde76 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java @@ -170,12 +170,15 @@ public class ProjectEntity implements Serializable { @Column(name = "update_date") private Date updateDate; - @Column(name = "primary_objective_type_code") - private String primaryObjectiveTypeCode; + @ManyToOne(fetch = FetchType.EAGER, optional = true) + @JoinColumn(name = "primary_objective_type_code") + private ObjectiveTypeCodeEntity primaryObjectiveTypeCode; - @Column(name = "secondary_objective_type_code") - private String secondaryObjectiveTypeCode; + @ManyToOne(fetch = FetchType.EAGER, optional = true) + @JoinColumn(name = "secondary_objective_type_code") + private ObjectiveTypeCodeEntity secondaryObjectiveTypeCode; - @Column(name = "tertiary_objective_type_code") - private String tertiaryObjectiveTypeCode; + @ManyToOne(fetch = FetchType.EAGER, optional = true) + @JoinColumn(name = "tertiary_objective_type_code") + private ObjectiveTypeCodeEntity tertiaryObjectiveTypeCode; } \ No newline at end of file diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java index c5f2d0942..69edbf50f 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java @@ -3,6 +3,7 @@ import java.math.BigDecimal; import java.util.Date; +import ca.bc.gov.nrs.wfprev.data.entities.ObjectiveTypeCodeEntity; import org.springframework.hateoas.server.core.Relation; import com.fasterxml.jackson.annotation.JsonInclude; @@ -54,8 +55,8 @@ public class ProjectModel extends CommonModel { private BigDecimal latitude; private BigDecimal longitude; private Date lastProgressUpdateTimestamp; - private String primaryObjectiveTypeCode; - private String secondaryObjectiveTypeCode; - private String tertiaryObjectiveTypeCode; + private ObjectiveTypeCodeModel primaryObjectiveTypeCode; + private ObjectiveTypeCodeModel secondaryObjectiveTypeCode; + private ObjectiveTypeCodeModel tertiaryObjectiveTypeCode; } \ No newline at end of file diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java index 905e7933f..7895d2a51 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java @@ -4,17 +4,9 @@ import ca.bc.gov.nrs.wfprev.SpringSecurityAuditorAware; import ca.bc.gov.nrs.wfprev.common.services.CommonService; import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectStatusCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.*; import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; -import ca.bc.gov.nrs.wfprev.data.repositories.ForestAreaCodeRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.GeneralScopeCodeRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.ProjectRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.ProjectStatusCodeRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.ProjectTypeCodeRepository; +import ca.bc.gov.nrs.wfprev.data.repositories.*; import jakarta.persistence.EntityNotFoundException; import jakarta.transaction.Transactional; import jakarta.validation.ConstraintViolationException; @@ -36,6 +28,7 @@ public class ProjectService implements CommonService { private final ProjectTypeCodeRepository projectTypeCodeRepository; private final GeneralScopeCodeRepository generalScopeCodeRepository; private final ProjectStatusCodeRepository projectStatusCodeRepository; + private final ObjectiveTypeCodeRepository objectiveTypeCodeRepository; public ProjectService( @@ -44,13 +37,15 @@ public ProjectService( ForestAreaCodeRepository forestAreaCodeRepository, ProjectTypeCodeRepository projectTypeCodeRepository, GeneralScopeCodeRepository generalScopeCodeRepository, - ProjectStatusCodeRepository projectStatusCodeRepository) { + ProjectStatusCodeRepository projectStatusCodeRepository, + ObjectiveTypeCodeRepository objectiveTypeCodeRepository) { this.projectRepository = projectRepository; this.projectResourceAssembler = projectResourceAssembler; this.forestAreaCodeRepository = forestAreaCodeRepository; this.projectTypeCodeRepository = projectTypeCodeRepository; this.generalScopeCodeRepository = generalScopeCodeRepository; this.projectStatusCodeRepository = projectStatusCodeRepository; + this.objectiveTypeCodeRepository = objectiveTypeCodeRepository; } public CollectionModel getAllProjects() throws ServiceException { @@ -125,6 +120,17 @@ private void assignAssociatedEntities(ProjectModel resource, ProjectEntity entit entity.setGeneralScopeCode(loadGeneralScopeCode(resource.getGeneralScopeCode().getGeneralScopeCode())); } + if (resource.getPrimaryObjectiveTypeCode() != null && resource.getPrimaryObjectiveTypeCode().getObjectiveTypeCode() != null) { + entity.setPrimaryObjectiveTypeCode(loadObjectiveTypeCode(resource.getPrimaryObjectiveTypeCode().getObjectiveTypeCode())); + } + + if (resource.getSecondaryObjectiveTypeCode() != null && resource.getSecondaryObjectiveTypeCode().getObjectiveTypeCode() != null) { + entity.setSecondaryObjectiveTypeCode(loadObjectiveTypeCode(resource.getSecondaryObjectiveTypeCode().getObjectiveTypeCode())); + } + if (resource.getTertiaryObjectiveTypeCode() != null && resource.getTertiaryObjectiveTypeCode().getObjectiveTypeCode() != null) { + entity.setTertiaryObjectiveTypeCode(loadObjectiveTypeCode(resource.getTertiaryObjectiveTypeCode().getObjectiveTypeCode())); + } + String projectStatusCode1 = resource.getProjectStatusCode() != null ? resource.getProjectStatusCode().getProjectStatusCode() : null; @@ -152,6 +158,12 @@ private GeneralScopeCodeEntity loadGeneralScopeCode(String generalScopeCode) { .orElseThrow(() -> new EntityNotFoundException("General Scope Code not found: " + generalScopeCode)); } + private ObjectiveTypeCodeEntity loadObjectiveTypeCode(String objectiveTypeCode) { + return objectiveTypeCodeRepository + .findById(objectiveTypeCode) + .orElseThrow(() -> new EntityNotFoundException("Objective Type Code not found: " + objectiveTypeCode)); + } + private ProjectStatusCodeEntity loadOrSetDefaultProjectStatusCode(String projectStatusCode) { if (projectStatusCode == null) { return projectStatusCodeRepository diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssemblerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssemblerTest.java index 16b651a5a..1a64be20b 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssemblerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssemblerTest.java @@ -1,17 +1,10 @@ package ca.bc.gov.nrs.wfprev.data.assemblers; -import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.*; +import ca.bc.gov.nrs.wfprev.data.models.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; - import java.math.BigDecimal; import java.util.UUID; @@ -30,12 +23,13 @@ void setUp() { void testToEntity_Success() { // given there is a project model ProjectModel projectModel = new ProjectModel(); + ObjectiveTypeCodeModel objectiveTypeCodeModel = new ObjectiveTypeCodeModel(); String projectGuid = UUID.randomUUID().toString(); String programAreaGuid = UUID.randomUUID().toString(); projectModel.setProjectGuid(projectGuid); - projectModel.setPrimaryObjectiveTypeCode("random_test_string_1"); - projectModel.setSecondaryObjectiveTypeCode("random_test_string_2"); - projectModel.setTertiaryObjectiveTypeCode("random_test_string_3"); + projectModel.setPrimaryObjectiveTypeCode(objectiveTypeCodeModel); + projectModel.setSecondaryObjectiveTypeCode(objectiveTypeCodeModel); + projectModel.setTertiaryObjectiveTypeCode(objectiveTypeCodeModel); projectModel.setIsMultiFiscalYearProj(false); projectModel.setProjectNumber(1000); projectModel.setProgramAreaGuid(programAreaGuid); @@ -47,14 +41,15 @@ void testToEntity_Success() { ProjectEntity projectEntity = assembler.toEntity(projectModel); // then it should have all the same values in the entity object + ObjectiveTypeCodeEntity objectiveTypeCodeEntity = new ObjectiveTypeCodeEntity(); GeneralScopeCodeEntity generalScopeCodeEntity = new GeneralScopeCodeEntity(); // Mock or create an instance ForestAreaCodeEntity forestAreaCodeEntity = new ForestAreaCodeEntity(); ProjectTypeCodeEntity projectTypeCodeEntity = new ProjectTypeCodeEntity(); ProjectEntity expectedProjectEntity = ProjectEntity.builder().projectGuid(UUID.fromString(projectGuid)) - .primaryObjectiveTypeCode("random_test_string_1") - .secondaryObjectiveTypeCode("random_test_string_2") - .tertiaryObjectiveTypeCode("random_test_string_3").projectNumber(1000).programAreaGuid(UUID.fromString(programAreaGuid)) + .primaryObjectiveTypeCode(objectiveTypeCodeEntity) + .secondaryObjectiveTypeCode(objectiveTypeCodeEntity) + .tertiaryObjectiveTypeCode(objectiveTypeCodeEntity).projectNumber(1000).programAreaGuid(UUID.fromString(programAreaGuid)) .forestAreaCode(forestAreaCodeEntity) .generalScopeCode(generalScopeCodeEntity) .projectTypeCode(projectTypeCodeEntity).build(); @@ -68,6 +63,18 @@ void testToModel_Success() { projectTypeCodeEntity.setProjectTypeCode("FUEL_MGMT"); projectTypeCodeEntity.setDescription("Fuel Management"); + ObjectiveTypeCodeEntity primaryObjectiveTypeCodeEntity = new ObjectiveTypeCodeEntity(); + primaryObjectiveTypeCodeEntity.setObjectiveTypeCode("WRR"); + primaryObjectiveTypeCodeEntity.setDescription("Wildfire Risk Reduction"); + + ObjectiveTypeCodeEntity secondaryObjectiveTypeCodeEntity = new ObjectiveTypeCodeEntity(); + secondaryObjectiveTypeCodeEntity.setObjectiveTypeCode("CRIT_INFRA"); + secondaryObjectiveTypeCodeEntity.setDescription("Critical Infrastructure"); + + ObjectiveTypeCodeEntity tertiaryObjectiveTypeCodeEntity = new ObjectiveTypeCodeEntity(); + tertiaryObjectiveTypeCodeEntity.setObjectiveTypeCode("ECO_REST"); + tertiaryObjectiveTypeCodeEntity.setDescription("Ecosystem Restoration"); + // Create and populate the ProjectEntity ProjectEntity projectEntity = new ProjectEntity(); String projectGuid = UUID.randomUUID().toString(); @@ -75,9 +82,9 @@ void testToModel_Success() { projectEntity.setProjectGuid(UUID.fromString(projectGuid)); projectEntity.setProgramAreaGuid(UUID.fromString(programAreaGuid)); projectEntity.setProjectTypeCode(projectTypeCodeEntity); - projectEntity.setPrimaryObjectiveTypeCode("random_test_string_1"); - projectEntity.setSecondaryObjectiveTypeCode("random_test_string_2"); - projectEntity.setTertiaryObjectiveTypeCode("random_test_string_3"); + projectEntity.setPrimaryObjectiveTypeCode(primaryObjectiveTypeCodeEntity); + projectEntity.setSecondaryObjectiveTypeCode(secondaryObjectiveTypeCodeEntity); + projectEntity.setTertiaryObjectiveTypeCode(tertiaryObjectiveTypeCodeEntity); projectEntity.setIsMultiFiscalYearProj(false); projectEntity.setForestAreaCode(new ForestAreaCodeEntity()); projectEntity.setGeneralScopeCode(new GeneralScopeCodeEntity()); @@ -93,9 +100,9 @@ void testToModel_Success() { .projectTypeCode("FUEL_MGMT") .description("Fuel Management") .build()) - .primaryObjectiveTypeCode("random_test_string_1") - .secondaryObjectiveTypeCode("random_test_string_2") - .tertiaryObjectiveTypeCode("random_test_string_3") + .primaryObjectiveTypeCode(ObjectiveTypeCodeModel.builder().objectiveTypeCode("WRR").description("Wildfire Risk Reduction").build()) + .secondaryObjectiveTypeCode(ObjectiveTypeCodeModel.builder().objectiveTypeCode("CRIT_INFRA").description("Critical Infrastructure").build()) + .tertiaryObjectiveTypeCode(ObjectiveTypeCodeModel.builder().objectiveTypeCode("ECO_REST").description("Ecosystem Restoration").build()) .isMultiFiscalYearProj(false) .forestAreaCode(new ForestAreaCodeModel()) .generalScopeCode(new GeneralScopeCodeModel()) @@ -108,9 +115,14 @@ void testToModel_Success() { @Test void testUpdateEntity_Success() { ProjectModel model = new ProjectModel(); + ObjectiveTypeCodeModel objectiveTypeCodeModel = new ObjectiveTypeCodeModel(); model.setProjectName("Updated Project"); model.setLatitude(BigDecimal.valueOf(50.123)); model.setForestAreaCode(new ForestAreaCodeModel()); + model.setGeneralScopeCode(new GeneralScopeCodeModel()); + model.setPrimaryObjectiveTypeCode(objectiveTypeCodeModel); + model.setSecondaryObjectiveTypeCode(objectiveTypeCodeModel); + model.setTertiaryObjectiveTypeCode(objectiveTypeCodeModel); ProjectEntity existingEntity = new ProjectEntity(); existingEntity.setProjectGuid(UUID.randomUUID()); From b2cc98cf8500b469d61e109b5be9087f1a98791c Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Thu, 16 Jan 2025 18:47:49 -0800 Subject: [PATCH 6/8] Update ProjectServiceTest --- .../gov/nrs/wfprev/services/ProjectServiceTest.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java index 09e64dd36..586866ad4 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java @@ -13,11 +13,7 @@ import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; import ca.bc.gov.nrs.wfprev.data.models.ProjectStatusCodeModel; import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; -import ca.bc.gov.nrs.wfprev.data.repositories.ForestAreaCodeRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.GeneralScopeCodeRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.ProjectRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.ProjectStatusCodeRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.ProjectTypeCodeRepository; +import ca.bc.gov.nrs.wfprev.data.repositories.*; import jakarta.persistence.EntityNotFoundException; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; @@ -50,6 +46,7 @@ class ProjectServiceTest { private ProjectTypeCodeRepository projectTypeCodeRepository; private GeneralScopeCodeRepository generalScopeCodeRepository; private ProjectStatusCodeRepository projectStatusCodeRepository; + private ObjectiveTypeCodeRepository objectiveTypeCodeRepository; private SpringSecurityAuditorAware springSecurityAuditorAware; @BeforeEach @@ -61,14 +58,15 @@ void setup() { generalScopeCodeRepository = mock(GeneralScopeCodeRepository.class); projectStatusCodeRepository = mock(ProjectStatusCodeRepository.class); springSecurityAuditorAware = mock(SpringSecurityAuditorAware.class); - + objectiveTypeCodeRepository = mock(ObjectiveTypeCodeRepository.class); projectService = new ProjectService(projectRepository, projectResourceAssembler, forestAreaCodeRepository, - projectTypeCodeRepository, generalScopeCodeRepository, projectStatusCodeRepository); + projectTypeCodeRepository, generalScopeCodeRepository, projectStatusCodeRepository, objectiveTypeCodeRepository); setField(projectService, "forestAreaCodeRepository", forestAreaCodeRepository); setField(projectService, "projectTypeCodeRepository", projectTypeCodeRepository); setField(projectService, "generalScopeCodeRepository", generalScopeCodeRepository); setField(projectService, "projectStatusCodeRepository", projectStatusCodeRepository); + setField(projectService, "objectiveTypeCodeRepository", objectiveTypeCodeRepository); } @Test From 2ba7dea2c088f7b43397d1d38b47dd323456018b Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Thu, 16 Jan 2025 19:11:58 -0800 Subject: [PATCH 7/8] Increase test coverage --- .../wfprev/services/ProjectServiceTest.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java index 586866ad4..98b74031f 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/services/ProjectServiceTest.java @@ -3,16 +3,8 @@ import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.SpringSecurityAuditorAware; import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectStatusCodeEntity; -import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; -import ca.bc.gov.nrs.wfprev.data.models.ProjectStatusCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.*; +import ca.bc.gov.nrs.wfprev.data.models.*; import ca.bc.gov.nrs.wfprev.data.repositories.*; import jakarta.persistence.EntityNotFoundException; import jakarta.validation.ConstraintViolation; @@ -351,7 +343,10 @@ void test_create_project_with_null_reference_codes() throws ServiceException { .projectName("Test Project") .forestAreaCode(null) // null ForestAreaCode .projectTypeCode(null) // null ProjectTypeCode - .generalScopeCode(null) // null GeneralScopeCode + .generalScopeCode(null) // null GeneralScopeCode + .primaryObjectiveTypeCode(null) + .secondaryObjectiveTypeCode(null) + .tertiaryObjectiveTypeCode(null) .build(); ProjectEntity savedEntity = new ProjectEntity(); @@ -373,6 +368,7 @@ void test_create_project_with_null_reference_codes() throws ServiceException { verify(forestAreaCodeRepository, never()).findById(any()); verify(projectTypeCodeRepository, never()).findById(any()); verify(generalScopeCodeRepository, never()).findById(any()); + verify(objectiveTypeCodeRepository, never()).findById(any()); assertNotNull(result); } @@ -382,21 +378,33 @@ void test_create_project_with_valid_reference_codes() throws ServiceException { String forestAreaCode = "FAC1"; String projectTypeCode = "PTC1"; String generalScopeCode = "GSC1"; + String primaryObjectiveTypeCode = "PTC1"; + String secondaryObjectiveTypeCode = "PTC2"; + String tertiaryObjectiveTypeCode = "PTC3"; ProjectModel inputModel = ProjectModel.builder() .projectName("Test Project") .forestAreaCode(ForestAreaCodeModel.builder().forestAreaCode(forestAreaCode).build()) .projectTypeCode(ProjectTypeCodeModel.builder().projectTypeCode(projectTypeCode).build()) .generalScopeCode(GeneralScopeCodeModel.builder().generalScopeCode(generalScopeCode).build()) + .primaryObjectiveTypeCode(ObjectiveTypeCodeModel.builder().objectiveTypeCode(primaryObjectiveTypeCode).build()) + .secondaryObjectiveTypeCode(ObjectiveTypeCodeModel.builder().objectiveTypeCode(secondaryObjectiveTypeCode).build()) + .tertiaryObjectiveTypeCode(ObjectiveTypeCodeModel.builder().objectiveTypeCode(tertiaryObjectiveTypeCode).build()) .build(); ForestAreaCodeEntity forestAreaEntity = ForestAreaCodeEntity.builder().forestAreaCode(forestAreaCode).build(); ProjectTypeCodeEntity projectTypeEntity = ProjectTypeCodeEntity.builder().projectTypeCode(projectTypeCode).build(); GeneralScopeCodeEntity generalScopeEntity = GeneralScopeCodeEntity.builder().generalScopeCode(generalScopeCode).build(); + ObjectiveTypeCodeEntity primaryObjectiveTypeCodeEntity = ObjectiveTypeCodeEntity.builder().objectiveTypeCode(primaryObjectiveTypeCode).build(); + ObjectiveTypeCodeEntity secondaryObjectiveTypeCodeEntity = ObjectiveTypeCodeEntity.builder().objectiveTypeCode(secondaryObjectiveTypeCode).build(); + ObjectiveTypeCodeEntity tertiaryObjectiveTypeCodeEntity = ObjectiveTypeCodeEntity.builder().objectiveTypeCode(tertiaryObjectiveTypeCode).build(); when(forestAreaCodeRepository.findById(forestAreaCode)).thenReturn(Optional.of(forestAreaEntity)); when(projectTypeCodeRepository.findById(projectTypeCode)).thenReturn(Optional.of(projectTypeEntity)); when(generalScopeCodeRepository.findById(generalScopeCode)).thenReturn(Optional.of(generalScopeEntity)); + when(objectiveTypeCodeRepository.findById(primaryObjectiveTypeCode)).thenReturn(Optional.of(primaryObjectiveTypeCodeEntity)); + when(objectiveTypeCodeRepository.findById(secondaryObjectiveTypeCode)).thenReturn(Optional.of(secondaryObjectiveTypeCodeEntity)); + when(objectiveTypeCodeRepository.findById(tertiaryObjectiveTypeCode)).thenReturn(Optional.of(tertiaryObjectiveTypeCodeEntity)); ProjectEntity savedEntity = new ProjectEntity(); when(projectResourceAssembler.toEntity(any())).thenReturn(savedEntity); @@ -418,6 +426,9 @@ void test_create_project_with_valid_reference_codes() throws ServiceException { verify(forestAreaCodeRepository).findById(forestAreaCode); verify(projectTypeCodeRepository).findById(projectTypeCode); verify(generalScopeCodeRepository).findById(generalScopeCode); + verify(objectiveTypeCodeRepository).findById(primaryObjectiveTypeCode); + verify(objectiveTypeCodeRepository).findById(secondaryObjectiveTypeCode); + verify(objectiveTypeCodeRepository).findById(tertiaryObjectiveTypeCode); assertNotNull(result); } From f2210dc70b3b1c3ff25a31fc9d4ec1ea8ae3d726 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Fri, 17 Jan 2025 09:36:26 -0800 Subject: [PATCH 8/8] Add ObjectiveTypeCode to GraalVM refelction/serialization config --- .../resources/native-image/reflection-config.json | 15 +++++++++++++++ .../native-image/serialization-config.json | 4 +++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/server/wfprev-api/src/main/resources/native-image/reflection-config.json b/server/wfprev-api/src/main/resources/native-image/reflection-config.json index cfbb32175..1e100b62a 100644 --- a/server/wfprev-api/src/main/resources/native-image/reflection-config.json +++ b/server/wfprev-api/src/main/resources/native-image/reflection-config.json @@ -851,5 +851,20 @@ "allDeclaredConstructors": true, "allDeclaredMethods": true, "allDeclaredFields": true + }, + { + "name": "ca.bc.gov.nrs.wfprev.data.entities.ObjectiveTypeCodeEntity", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true + }, + { + "name": "ca.bc.gov.nrs.wfprev.data.models.ObjectiveTypeCodeModel", + "allDeclaredConstructors": true, + "allDeclaredMethods": true, + "allDeclaredFields": true } ] \ No newline at end of file diff --git a/server/wfprev-api/src/main/resources/native-image/serialization-config.json b/server/wfprev-api/src/main/resources/native-image/serialization-config.json index 2624a24d7..d905e6df6 100644 --- a/server/wfprev-api/src/main/resources/native-image/serialization-config.json +++ b/server/wfprev-api/src/main/resources/native-image/serialization-config.json @@ -7,6 +7,8 @@ { "name": "ca.bc.gov.nrs.wfprev.data.models.ProjectBoundaryModel" }, { "name": "ca.bc.gov.nrs.wfprev.data.models.ProjectModel" }, { "name": "ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel" }, + { "name": "ca.bc.gov.nrs.wfprev.data.models.ObjectiveTypeCodeModel" }, + { "name": "ca.bc.gov.nrs.wfprev.data.models.ProjectFiscalModel"}, { "name": "ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity" }, { "name": "ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity" }, @@ -14,7 +16,7 @@ { "name": "ca.bc.gov.nrs.wfprev.data.entities.ProjectBoundaryEntity" }, { "name": "ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity" }, { "name": "ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity" }, - { "name": "ca.bc.gov.nrs.wfprev.data.models.ProjectFiscalModel"}, + { "name": "ca.bc.gov.nrs.wfprev.data.entities.ObjectiveTypeCodeEntity" }, { "name": "org.springframework.hateoas.RepresentationModel"}, { "name": "org.springframework.hateoas.Link"}, { "name": "org.springframework.hateoas.Links"},