feat: add command handlers, permissions, and API resources for surveys and loan COB catch-up
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s
This commit is contained in:
+32
@@ -4809,4 +4809,36 @@ public class CommandWrapperBuilder {
|
|||||||
this.href = "/loans/" + loanId + "/originators/" + originatorId;
|
this.href = "/loans/" + loanId + "/originators/" + originatorId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder createSurvey() {
|
||||||
|
this.actionName = "CREATE";
|
||||||
|
this.entityName = "SURVEY";
|
||||||
|
this.entityId = null;
|
||||||
|
this.href = "/surveys";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder updateSurvey(final Long surveyId) {
|
||||||
|
this.actionName = "UPDATE";
|
||||||
|
this.entityName = "SURVEY";
|
||||||
|
this.entityId = surveyId;
|
||||||
|
this.href = "/surveys/" + surveyId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder activateSurvey(final Long surveyId) {
|
||||||
|
this.actionName = "ACTIVATE";
|
||||||
|
this.entityName = "SURVEY";
|
||||||
|
this.entityId = surveyId;
|
||||||
|
this.href = "/surveys/" + surveyId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder deactivateSurvey(final Long surveyId) {
|
||||||
|
this.actionName = "DEACTIVATE";
|
||||||
|
this.entityName = "SURVEY";
|
||||||
|
this.entityId = surveyId;
|
||||||
|
this.href = "/surveys/" + surveyId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -35,6 +35,7 @@ import org.apache.fineract.cob.data.OldestCOBProcessedLoanDTO;
|
|||||||
import org.apache.fineract.cob.service.LoanCOBCatchUpService;
|
import org.apache.fineract.cob.service.LoanCOBCatchUpService;
|
||||||
import org.apache.fineract.infrastructure.core.exception.JobIsNotFoundOrNotEnabledException;
|
import org.apache.fineract.infrastructure.core.exception.JobIsNotFoundOrNotEnabledException;
|
||||||
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Path("/v1/loans")
|
@Path("/v1/loans")
|
||||||
@@ -44,6 +45,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class LoanCOBCatchUpApiResource {
|
public class LoanCOBCatchUpApiResource {
|
||||||
|
|
||||||
private final Optional<LoanCOBCatchUpService> loanCOBCatchUpServiceOp;
|
private final Optional<LoanCOBCatchUpService> loanCOBCatchUpServiceOp;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("oldest-cob-closed")
|
@Path("oldest-cob-closed")
|
||||||
@@ -64,6 +66,7 @@ public class LoanCOBCatchUpApiResource {
|
|||||||
@ApiResponse(responseCode = "202", description = "Catch Up has been started")
|
@ApiResponse(responseCode = "202", description = "Catch Up has been started")
|
||||||
@ApiResponse(responseCode = "400", description = "Catch Up is already running")
|
@ApiResponse(responseCode = "400", description = "Catch Up is already running")
|
||||||
public Response executeLoanCOBCatchUp() {
|
public Response executeLoanCOBCatchUp() {
|
||||||
|
this.context.authenticatedUser().validateHasPermissionTo("EXECUTE_LOANCOBCATCHUP");
|
||||||
return loanCOBCatchUpServiceOp.map(loanCOBCatchUpService -> {
|
return loanCOBCatchUpServiceOp.map(loanCOBCatchUpService -> {
|
||||||
if (loanCOBCatchUpService.isCatchUpRunning().isCatchUpRunning()) {
|
if (loanCOBCatchUpService.isCatchUpRunning().isCatchUpRunning()) {
|
||||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.spm.api;
|
package org.apache.fineract.spm.api;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
||||||
@@ -37,10 +36,14 @@ import jakarta.ws.rs.Produces;
|
|||||||
import jakarta.ws.rs.QueryParam;
|
import jakarta.ws.rs.QueryParam;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
|
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||||
|
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.spm.data.SurveyData;
|
import org.apache.fineract.spm.data.SurveyData;
|
||||||
import org.apache.fineract.spm.domain.Survey;
|
import org.apache.fineract.spm.domain.Survey;
|
||||||
@@ -57,6 +60,8 @@ public class SpmApiResource {
|
|||||||
|
|
||||||
private final PlatformSecurityContext securityContext;
|
private final PlatformSecurityContext securityContext;
|
||||||
private final SpmService spmService;
|
private final SpmService spmService;
|
||||||
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
|
private final DefaultToApiJsonSerializer<CommandProcessingResult> toApiJsonSerializer;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@@ -103,12 +108,10 @@ public class SpmApiResource {
|
|||||||
@Operation(summary = "Create a Survey", description = "Adds a new survey to collect client related data.\n" + "\n"
|
@Operation(summary = "Create a Survey", description = "Adds a new survey to collect client related data.\n" + "\n"
|
||||||
+ "Mandatory Fields\n" + "\n" + "countryCode, key, name, questions, responses, sequenceNo, text, description")
|
+ "Mandatory Fields\n" + "\n" + "countryCode, key, name, questions, responses, sequenceNo, text, description")
|
||||||
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
|
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
|
||||||
public String createSurvey(@Parameter(description = "Create survey") final SurveyData surveyData) {
|
public String createSurvey(@Parameter(description = "Create survey") final String apiRequestBodyAsJson) {
|
||||||
this.securityContext.authenticatedUser();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().createSurvey().withJson(apiRequestBodyAsJson).build();
|
||||||
final Survey survey = SurveyMapper.map(surveyData, new Survey());
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
this.spmService.createSurvey(survey);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
return getResponse(survey.getId());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@@ -116,12 +119,10 @@ public class SpmApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Transactional
|
@Transactional
|
||||||
public String editSurvey(@PathParam("id") final Long id, final SurveyData surveyData) {
|
public String editSurvey(@PathParam("id") final Long id, final String apiRequestBodyAsJson) {
|
||||||
this.securityContext.authenticatedUser();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSurvey(id).withJson(apiRequestBodyAsJson).build();
|
||||||
final Survey surveyToUpdate = this.spmService.findById(id);
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
final Survey survey = SurveyMapper.map(surveyData, surveyToUpdate);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
this.spmService.updateSurvey(survey);
|
|
||||||
return getResponse(survey.getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -131,22 +132,17 @@ public class SpmApiResource {
|
|||||||
@Transactional
|
@Transactional
|
||||||
@Operation(summary = "Deactivate Survey", description = "")
|
@Operation(summary = "Deactivate Survey", description = "")
|
||||||
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
|
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
|
||||||
public void activateOrDeactivateSurvey(@PathParam("id") final Long id, @QueryParam("command") final String command) {
|
public String activateOrDeactivateSurvey(@PathParam("id") final Long id, @QueryParam("command") final String command) {
|
||||||
this.securityContext.authenticatedUser();
|
final CommandWrapperBuilder builder = new CommandWrapperBuilder();
|
||||||
|
final CommandWrapper commandRequest;
|
||||||
if (command != null && command.equalsIgnoreCase("activate")) {
|
if (command != null && command.equalsIgnoreCase("activate")) {
|
||||||
this.spmService.activateSurvey(id);
|
commandRequest = builder.activateSurvey(id).build();
|
||||||
} else if (command != null && command.equalsIgnoreCase("deactivate")) {
|
} else if (command != null && command.equalsIgnoreCase("deactivate")) {
|
||||||
this.spmService.deactivateSurvey(id);
|
commandRequest = builder.deactivateSurvey(id).build();
|
||||||
} else {
|
} else {
|
||||||
throw new UnrecognizedQueryParamException("command", command);
|
throw new UnrecognizedQueryParamException("command", command);
|
||||||
}
|
}
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
}
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
|
|
||||||
private String getResponse(Long id) {
|
|
||||||
Gson gson = new Gson();
|
|
||||||
HashMap<String, Object> response = new HashMap<>();
|
|
||||||
response.put("resourceId", id);
|
|
||||||
return gson.toJson(response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.spm.handler;
|
||||||
|
|
||||||
|
import org.apache.fineract.commands.annotation.CommandType;
|
||||||
|
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
|
import org.apache.fineract.spm.service.SpmService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@CommandType(entity = "SURVEY", action = "ACTIVATE")
|
||||||
|
public class ActivateSurveyCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final SpmService spmService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ActivateSurveyCommandHandler(final SpmService spmService) {
|
||||||
|
this.spmService = spmService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
this.spmService.activateSurvey(command.entityId());
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withCommandId(command.commandId()) //
|
||||||
|
.withEntityId(command.entityId()) //
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.spm.handler;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import org.apache.fineract.commands.annotation.CommandType;
|
||||||
|
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
|
import org.apache.fineract.spm.data.SurveyData;
|
||||||
|
import org.apache.fineract.spm.domain.Survey;
|
||||||
|
import org.apache.fineract.spm.service.SpmService;
|
||||||
|
import org.apache.fineract.spm.util.SurveyMapper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@CommandType(entity = "SURVEY", action = "CREATE")
|
||||||
|
public class CreateSurveyCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final SpmService spmService;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CreateSurveyCommandHandler(final SpmService spmService, final ObjectMapper objectMapper) {
|
||||||
|
this.spmService = spmService;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
final SurveyData surveyData = readSurveyData(command);
|
||||||
|
final Survey survey = SurveyMapper.map(surveyData, new Survey());
|
||||||
|
this.spmService.createSurvey(survey);
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withCommandId(command.commandId()) //
|
||||||
|
.withEntityId(survey.getId()) //
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SurveyData readSurveyData(final JsonCommand command) {
|
||||||
|
try {
|
||||||
|
return this.objectMapper.readValue(command.json(), SurveyData.class);
|
||||||
|
} catch (final JsonProcessingException e) {
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.survey.invalid.json", "Invalid survey payload: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.spm.handler;
|
||||||
|
|
||||||
|
import org.apache.fineract.commands.annotation.CommandType;
|
||||||
|
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
|
import org.apache.fineract.spm.service.SpmService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@CommandType(entity = "SURVEY", action = "DEACTIVATE")
|
||||||
|
public class DeactivateSurveyCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final SpmService spmService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public DeactivateSurveyCommandHandler(final SpmService spmService) {
|
||||||
|
this.spmService = spmService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
this.spmService.deactivateSurvey(command.entityId());
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withCommandId(command.commandId()) //
|
||||||
|
.withEntityId(command.entityId()) //
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.spm.handler;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import org.apache.fineract.commands.annotation.CommandType;
|
||||||
|
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
|
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
|
import org.apache.fineract.spm.data.SurveyData;
|
||||||
|
import org.apache.fineract.spm.domain.Survey;
|
||||||
|
import org.apache.fineract.spm.service.SpmService;
|
||||||
|
import org.apache.fineract.spm.util.SurveyMapper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@CommandType(entity = "SURVEY", action = "UPDATE")
|
||||||
|
public class UpdateSurveyCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final SpmService spmService;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UpdateSurveyCommandHandler(final SpmService spmService, final ObjectMapper objectMapper) {
|
||||||
|
this.spmService = spmService;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
final SurveyData surveyData = readSurveyData(command);
|
||||||
|
final Survey surveyToUpdate = this.spmService.findById(command.entityId());
|
||||||
|
final Survey survey = SurveyMapper.map(surveyData, surveyToUpdate);
|
||||||
|
this.spmService.updateSurvey(survey);
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withCommandId(command.commandId()) //
|
||||||
|
.withEntityId(survey.getId()) //
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SurveyData readSurveyData(final JsonCommand command) {
|
||||||
|
try {
|
||||||
|
return this.objectMapper.readValue(command.json(), SurveyData.class);
|
||||||
|
} catch (final JsonProcessingException e) {
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.survey.invalid.json", "Invalid survey payload: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
-1
@@ -114,17 +114,33 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
|
|||||||
+ "'SUBMITEDIT_CURRENTACCOUNT','APPROVEEDIT_CURRENTACCOUNT','REJECTEDIT_CURRENTACCOUNT',"
|
+ "'SUBMITEDIT_CURRENTACCOUNT','APPROVEEDIT_CURRENTACCOUNT','REJECTEDIT_CURRENTACCOUNT',"
|
||||||
+ "'SUBMITEDIT_CLIENT','APPROVEEDIT_CLIENT','REJECTEDIT_CLIENT'";
|
+ "'SUBMITEDIT_CLIENT','APPROVEEDIT_CLIENT','REJECTEDIT_CLIENT'";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unlike DEAD_MAKER_CHECKER_CODES above, these codes ARE read by the live maker-checker pipeline
|
||||||
|
* (CommandSourceService.isMakerCheckerEnabledForTask()) - they are excluded from this screen for a
|
||||||
|
* different reason: UPDATE_PERMISSION governs this very "Configure Maker Checker Tasks" screen
|
||||||
|
* (toggling which tasks require maker-checker), and UPDATE_CONFIGURATION governs the global
|
||||||
|
* maker-checker on/off switch and other System -> Configurations settings. If either were flipped
|
||||||
|
* to can_maker_checker=true and the approving checker.user lacked CHECKER_SUPER_USER, an admin
|
||||||
|
* could lock themselves out of ever approving further changes to maker-checker configuration
|
||||||
|
* itself, with no ordinary way to reverse it. Excluding them here only hides them from this
|
||||||
|
* screen; it does not touch their can_maker_checker value or their normal enforcement.
|
||||||
|
*/
|
||||||
|
private static final String SELF_REFERENTIAL_MAKER_CHECKER_CODES = "'UPDATE_PERMISSION','UPDATE_CONFIGURATION'";
|
||||||
|
|
||||||
public String makerCheckerablePermissionSchema() {
|
public String makerCheckerablePermissionSchema() {
|
||||||
/*
|
/*
|
||||||
* get all 'Maker-Checkerable' permissions - Maintenance permissions (i.e. exclude the 'special' grouping,
|
* get all 'Maker-Checkerable' permissions - Maintenance permissions (i.e. exclude the 'special' grouping,
|
||||||
* the READ permissions and the CHECKER permissions), and exclude permission codes whose approval
|
* the READ permissions and the CHECKER permissions), and exclude permission codes whose approval
|
||||||
* workflow does not actually read can_maker_checker (see DEAD_MAKER_CHECKER_CODES above).
|
* workflow does not actually read can_maker_checker (see DEAD_MAKER_CHECKER_CODES above), as well as
|
||||||
|
* codes that control maker-checker configuration itself (see SELF_REFERENTIAL_MAKER_CHECKER_CODES
|
||||||
|
* above) to avoid a self-lockout.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, p.can_maker_checker as selected"
|
return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, p.can_maker_checker as selected"
|
||||||
+ " from m_permission p " + " where " + sqlGenerator.escape("grouping")
|
+ " from m_permission p " + " where " + sqlGenerator.escape("grouping")
|
||||||
+ " != 'special' and code not like 'READ_%' and code not like '%\\_CHECKER'"
|
+ " != 'special' and code not like 'READ_%' and code not like '%\\_CHECKER'"
|
||||||
+ " and code not in (" + DEAD_MAKER_CHECKER_CODES + ")"
|
+ " and code not in (" + DEAD_MAKER_CHECKER_CODES + ")"
|
||||||
|
+ " and code not in (" + SELF_REFERENTIAL_MAKER_CHECKER_CODES + ")"
|
||||||
+ " order by p.grouping, coalesce(entity_name, ''), p.code";
|
+ " order by p.grouping, coalesce(entity_name, ''), p.code";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,4 +149,7 @@
|
|||||||
dev-latest's highest, 0582) to avoid ambiguity; content/semantics unchanged, only the file
|
dev-latest's highest, 0582) to avoid ambiguity; content/semantics unchanged, only the file
|
||||||
name and this changeset's id were updated to match. -->
|
name and this changeset's id were updated to match. -->
|
||||||
<include file="parts/0583_add_loan_originator_checker_permissions.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0583_add_loan_originator_checker_permissions.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0584_add_manage_survey_permissions.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0585_add_loan_cob_catchup_permission.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0586_add_system_module_checker_permissions.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
|
||||||
|
<!-- The Manage Surveys screen (SPM scorecards, spm.api.SpmApiResource) previously performed
|
||||||
|
create/update/activate/deactivate directly against SpmService with only a login check -
|
||||||
|
no permission check at any layer. These 4 write operations have now been wired into the
|
||||||
|
standard command pipeline (CommandWrapperBuilder.createSurvey/updateSurvey/activateSurvey/
|
||||||
|
deactivateSurvey -> CreateSurveyCommandHandler/UpdateSurveyCommandHandler/
|
||||||
|
ActivateSurveyCommandHandler/DeactivateSurveyCommandHandler, entity "SURVEY"), which requires
|
||||||
|
these permission rows to exist so PortfolioCommandSourceWritePlatformServiceImpl.logCommandSource()
|
||||||
|
can authorize the caller. Seeded with can_maker_checker=false: no prior maker-checker behaviour
|
||||||
|
existed for this screen, and enabling maker-checker is a business decision left for later. -->
|
||||||
|
<changeSet id="0584_add_manage_survey_permissions" author="cbs-anshul">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'CREATE_SURVEY'</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="configuration"/>
|
||||||
|
<column name="code" value="CREATE_SURVEY"/>
|
||||||
|
<column name="entity_name" value="SURVEY"/>
|
||||||
|
<column name="action_name" value="CREATE"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="configuration"/>
|
||||||
|
<column name="code" value="UPDATE_SURVEY"/>
|
||||||
|
<column name="entity_name" value="SURVEY"/>
|
||||||
|
<column name="action_name" value="UPDATE"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="configuration"/>
|
||||||
|
<column name="code" value="ACTIVATE_SURVEY"/>
|
||||||
|
<column name="entity_name" value="SURVEY"/>
|
||||||
|
<column name="action_name" value="ACTIVATE"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="configuration"/>
|
||||||
|
<column name="code" value="DEACTIVATE_SURVEY"/>
|
||||||
|
<column name="entity_name" value="SURVEY"/>
|
||||||
|
<column name="action_name" value="DEACTIVATE"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<!-- No role previously held any permission for this screen (it had no permission check at all),
|
||||||
|
so there are no "roles that already hold the base permission" to copy from. Following the
|
||||||
|
0511_institution_and_branch_profile.xml convention for a brand-new permission model: grant to
|
||||||
|
Super user plus any manager-named role. -->
|
||||||
|
<changeSet id="0584_grant_manage_survey_permissions" author="cbs-anshul">
|
||||||
|
<sql>
|
||||||
|
INSERT INTO m_role_permission (role_id, permission_id)
|
||||||
|
SELECT r.id, p.id
|
||||||
|
FROM m_role r
|
||||||
|
JOIN m_permission p ON p.code IN ('CREATE_SURVEY', 'UPDATE_SURVEY', 'ACTIVATE_SURVEY', 'DEACTIVATE_SURVEY')
|
||||||
|
WHERE (LOWER(r.name) LIKE '%manager%' OR LOWER(r.name) = 'super user')
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM m_role_permission rp2
|
||||||
|
WHERE rp2.role_id = r.id AND rp2.permission_id = p.id
|
||||||
|
)
|
||||||
|
</sql>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
|
||||||
|
<!-- LoanCOBCatchUpApiResource.executeLoanCOBCatchUp() (POST /v1/loans/catch-up) previously had no
|
||||||
|
permission check at all. A validateHasPermissionTo("EXECUTE_LOANCOBCATCHUP") check was added
|
||||||
|
directly (not full CommandWrapper/maker-checker wiring, since this is a job-execution trigger,
|
||||||
|
not a CRUD operation on a persisted entity - matching the existing EXECUTE_INLINE_JOB precedent),
|
||||||
|
which requires this permission row to exist. can_maker_checker=false: this closes the
|
||||||
|
authorization gap only, it does not introduce maker-checker for job execution. -->
|
||||||
|
<changeSet id="0585_add_loan_cob_catchup_permission" author="cbs-anshul">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'EXECUTE_LOANCOBCATCHUP'</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="organisation"/>
|
||||||
|
<column name="code" value="EXECUTE_LOANCOBCATCHUP"/>
|
||||||
|
<column name="entity_name" value="LOANCOBCATCHUP"/>
|
||||||
|
<column name="action_name" value="EXECUTE"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<!-- No role previously held any permission for this endpoint (it had no permission check at all),
|
||||||
|
so there are no "roles that already hold the base permission" to copy from. Following the
|
||||||
|
0511_institution_and_branch_profile.xml convention for a brand-new permission model: grant to
|
||||||
|
Super user plus any manager-named role. -->
|
||||||
|
<changeSet id="0585_grant_loan_cob_catchup_permission" author="cbs-anshul">
|
||||||
|
<sql>
|
||||||
|
INSERT INTO m_role_permission (role_id, permission_id)
|
||||||
|
SELECT r.id, p.id
|
||||||
|
FROM m_role r
|
||||||
|
JOIN m_permission p ON p.code = 'EXECUTE_LOANCOBCATCHUP'
|
||||||
|
WHERE (LOWER(r.name) LIKE '%manager%' OR LOWER(r.name) = 'super user')
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM m_role_permission rp2
|
||||||
|
WHERE rp2.role_id = r.id AND rp2.permission_id = p.id
|
||||||
|
)
|
||||||
|
</sql>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
|
||||||
|
<!-- The Admin -> System maker-checker audit found 8 base permissions whose "_CHECKER" counterpart
|
||||||
|
row was never seeded (AppUser.validateHasCheckerPermissionTo() computes
|
||||||
|
checkerPermissionName = code.toUpperCase() + "_CHECKER" and requires the approver to hold
|
||||||
|
either CHECKER_SUPER_USER or that exact permission code - see the identical issue already
|
||||||
|
fixed for LOAN_ORIGINATOR in 0583_add_loan_originator_checker_permissions.xml). Without these
|
||||||
|
rows, no ordinary role can ever be granted checker rights for these operations, and
|
||||||
|
UPDATE_BATCH_BUSINESS_STEP (Manage Jobs - COB Workflow Step Reorder) is the one permission in
|
||||||
|
all of Admin -> System that already has can_maker_checker=true today, making its missing
|
||||||
|
checker row a live gap, not merely a structural one. All 8 rows are seeded with
|
||||||
|
can_maker_checker=false: this changeset only makes the approval path structurally ready, it
|
||||||
|
does not itself enable maker-checker on any base permission.
|
||||||
|
|
||||||
|
For CREATE/UPDATE/DELETE_ACCOUNTNUMBERFORMAT_CHECKER, entity_name is set to
|
||||||
|
"ACCOUNTNUMBERFORMAT" for all three (matching CREATE_ACCOUNTNUMBERFORMAT and
|
||||||
|
UPDATE_ACCOUNTNUMBERFORMAT). The pre-existing base permission DELETE_ACCOUNTNUMBERFORMAT has
|
||||||
|
entity_name="HOOK" (a pre-existing data bug, confirmed via read-only query, left untouched -
|
||||||
|
fixing an existing permission row's value was out of scope for this change). This checker row
|
||||||
|
deliberately uses the correct entity name rather than propagating that bug. -->
|
||||||
|
<changeSet id="0586_add_system_module_checker_permissions" author="cbs-anshul">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'CREATE_ACCOUNTNUMBERFORMAT_CHECKER'</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="configuration"/>
|
||||||
|
<column name="code" value="CREATE_ACCOUNTNUMBERFORMAT_CHECKER"/>
|
||||||
|
<column name="entity_name" value="ACCOUNTNUMBERFORMAT"/>
|
||||||
|
<column name="action_name" value="CREATE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="configuration"/>
|
||||||
|
<column name="code" value="UPDATE_ACCOUNTNUMBERFORMAT_CHECKER"/>
|
||||||
|
<column name="entity_name" value="ACCOUNTNUMBERFORMAT"/>
|
||||||
|
<column name="action_name" value="UPDATE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="configuration"/>
|
||||||
|
<column name="code" value="DELETE_ACCOUNTNUMBERFORMAT_CHECKER"/>
|
||||||
|
<column name="entity_name" value="ACCOUNTNUMBERFORMAT"/>
|
||||||
|
<column name="action_name" value="DELETE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="infrastructure"/>
|
||||||
|
<column name="code" value="CREATE_ENTITYMAPPING_CHECKER"/>
|
||||||
|
<column name="entity_name" value="ENTITYMAPPING"/>
|
||||||
|
<column name="action_name" value="CREATE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="infrastructure"/>
|
||||||
|
<column name="code" value="UPDATE_ENTITYMAPPING_CHECKER"/>
|
||||||
|
<column name="entity_name" value="ENTITYMAPPING"/>
|
||||||
|
<column name="action_name" value="UPDATE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="infrastructure"/>
|
||||||
|
<column name="code" value="DELETE_ENTITYMAPPING_CHECKER"/>
|
||||||
|
<column name="entity_name" value="ENTITYMAPPING"/>
|
||||||
|
<column name="action_name" value="DELETE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="organisation"/>
|
||||||
|
<column name="code" value="CREATE_USERAGREEMENT_CHECKER"/>
|
||||||
|
<column name="entity_name" value="USERAGREEMENT"/>
|
||||||
|
<column name="action_name" value="CREATE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="organisation"/>
|
||||||
|
<column name="code" value="UPDATE_BATCH_BUSINESS_STEP_CHECKER"/>
|
||||||
|
<column name="entity_name" value="BATCH_BUSINESS_STEP"/>
|
||||||
|
<column name="action_name" value="UPDATE_CHECKER"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<!-- Granted to whichever roles already hold the corresponding base permission - the same
|
||||||
|
"grant to roles that already hold the base permission" convention used in
|
||||||
|
0583_add_loan_originator_checker_permissions.xml. -->
|
||||||
|
<changeSet id="0586_grant_system_module_checker_permissions" author="cbs-anshul">
|
||||||
|
<sql>
|
||||||
|
INSERT INTO m_role_permission (role_id, permission_id)
|
||||||
|
SELECT rp.role_id, checker.id
|
||||||
|
FROM m_role_permission rp
|
||||||
|
JOIN m_permission base ON base.id = rp.permission_id
|
||||||
|
JOIN m_permission checker ON checker.code = base.code || '_CHECKER'
|
||||||
|
WHERE base.code IN ('CREATE_ACCOUNTNUMBERFORMAT', 'UPDATE_ACCOUNTNUMBERFORMAT', 'DELETE_ACCOUNTNUMBERFORMAT',
|
||||||
|
'CREATE_ENTITYMAPPING', 'UPDATE_ENTITYMAPPING', 'DELETE_ENTITYMAPPING',
|
||||||
|
'CREATE_USERAGREEMENT', 'UPDATE_BATCH_BUSINESS_STEP')
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM m_role_permission rp2
|
||||||
|
WHERE rp2.role_id = rp.role_id AND rp2.permission_id = checker.id
|
||||||
|
)
|
||||||
|
</sql>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
Reference in New Issue
Block a user