Credit_Bureau_Phase3 (FINERACT-734)

This commit is contained in:
rrpawar96
2021-01-04 18:42:13 +01:00
committed by Michael Vorburger ⛑️
parent b6127368ca
commit 85e3c4dcb2
38 changed files with 2679 additions and 10 deletions
@@ -76,6 +76,31 @@ public class CommandWrapperBuilder {
return this;
}
public CommandWrapperBuilder getCreditReport() {
this.actionName = "GET";
this.entityName = "CREDITREPORT";
this.entityId = null;
this.href = "/getCreditReport/template";
return this;
}
public CommandWrapperBuilder saveCreditReport(final long creditBureauId, final String nationalId) {
this.actionName = "SAVE";
this.entityName = "CREDITREPORT";
this.entityId = creditBureauId;
this.transactionId = nationalId;
this.href = "/saveCreditReport/";
return this;
}
public CommandWrapperBuilder deleteCreditReport(final Long creditBureauId) {
this.actionName = "DELETE";
this.entityName = "CREDITREPORT";
this.entityId = creditBureauId;
this.href = "/deleteCreditReport/";
return this;
}
public CommandWrapperBuilder createCreditBureauLoanProductMapping(final long creditBureauId) {
this.actionName = "CREATE";
this.entityName = "CREDITBUREAU_LOANPRODUCT_MAPPING";
@@ -85,6 +110,22 @@ public class CommandWrapperBuilder {
return this;
}
public CommandWrapperBuilder addCreditBureauConfiguration(final long creditBureauId) {
this.actionName = "CREATE";
this.entityName = "CREDITBUREAU_CONFIGURATION";
this.entityId = creditBureauId;
this.href = "/creditBureauConfigurationData/";
return this;
}
public CommandWrapperBuilder updateCreditBureauConfiguration(final long configurationId) {
this.actionName = "UPDATE";
this.entityName = "CREDITBUREAU_CONFIGURATION";
this.entityId = configurationId;
this.href = "/creditBureauConfigurationData/";
return this;
}
public CommandWrapperBuilder addClientAddress(final long clientId, final long addressTypeId) {
this.actionName = "CREATE";
this.entityName = "ADDRESS";
@@ -444,6 +444,12 @@ public final class JsonCommand {
return value;
}
public Map<String, Object> mapObjectValueOfParameterNamed(final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
final Map<String, Object> value = this.fromApiJsonHelper.extractObjectMap(typeOfMap, json);
return value;
}
public boolean isChangeInBigDecimalParameterNamedDefaultingZeroToNull(final String parameterName, final BigDecimal existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.core.data;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
/**
* Represents the successful result of an REST API call that results in processing a command.
@@ -37,6 +38,7 @@ public class CommandProcessingResult implements Serializable {
private final Long subResourceId;
private final String transactionId;
private final Map<String, Object> changes;
private final CreditBureauReportData creditBureauReportData;
@SuppressWarnings("unused")
private final String resourceIdentifier;
private final Long productId;
@@ -48,15 +50,15 @@ public class CommandProcessingResult implements Serializable {
return new CommandProcessingResult(commandResult.commandId, commandResult.officeId, commandResult.groupId, commandResult.clientId,
commandResult.loanId, commandResult.savingsId, commandResult.resourceIdentifier, commandResult.resourceId,
commandResult.transactionId, commandResult.changes, commandResult.productId, commandResult.gsimId, commandResult.glimId,
commandResult.rollbackTransaction, commandResult.subResourceId);
commandResult.creditBureauReportData, commandResult.rollbackTransaction, commandResult.subResourceId);
}
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId,
final Long loanId, final Long savingsId, final String resourceIdentifier, final Long entityId, final Long gsimId,
final Long glimId, final String transactionId, final Map<String, Object> changes, final Long productId,
final Boolean rollbackTransaction, final Long subResourceId) {
final Long glimId, final CreditBureauReportData creditBureauReportData, final String transactionId,
final Map<String, Object> changes, final Long productId, final Boolean rollbackTransaction, final Long subResourceId) {
return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId,
transactionId, changes, productId, gsimId, glimId, rollbackTransaction, subResourceId);
transactionId, changes, productId, gsimId, glimId, creditBureauReportData, rollbackTransaction, subResourceId);
}
public static CommandProcessingResult commandOnlyResult(final Long commandId) {
@@ -108,13 +110,14 @@ public class CommandProcessingResult implements Serializable {
this.productId = null;
this.gsimId = null;
this.glimId = null;
this.creditBureauReportData = null;
this.subResourceId = null;
}
private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId,
final Long savingsId, final String resourceIdentifier, final Long resourceId, final String transactionId,
final Map<String, Object> changesOnly, final Long productId, final Long gsimId, final Long glimId, Boolean rollbackTransaction,
final Long subResourceId) {
final Map<String, Object> changesOnly, final Long productId, final Long gsimId, final Long glimId,
final CreditBureauReportData creditBureauReportData, Boolean rollbackTransaction, final Long subResourceId) {
this.commandId = commandId;
this.officeId = officeId;
this.groupId = groupId;
@@ -128,6 +131,7 @@ public class CommandProcessingResult implements Serializable {
this.productId = productId;
this.gsimId = gsimId;
this.glimId = glimId;
this.creditBureauReportData = creditBureauReportData;
this.rollbackTransaction = rollbackTransaction;
this.subResourceId = subResourceId;
}
@@ -151,12 +155,13 @@ public class CommandProcessingResult implements Serializable {
this.productId = null;
this.gsimId = null;
this.glimId = null;
this.creditBureauReportData = null;
this.subResourceId = null;
}
protected CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId,
final Map<String, Object> changesOnly, long clientId) {
this(commandId, officeId, null, clientId, null, null, null, resourceId, null, changesOnly, null, null, null, null, null);
this(commandId, officeId, null, clientId, null, null, null, resourceId, null, changesOnly, null, null, null, null, null, null);
}
public Long commandId() {
@@ -195,6 +200,10 @@ public class CommandProcessingResult implements Serializable {
return this.transactionId;
}
public CreditBureauReportData getCreditReport() {
return this.creditBureauReportData;
}
public Map<String, Object> getChanges() {
Map<String, Object> checkIfEmpty = null;
if (this.changes != null && !this.changes.isEmpty()) {
@@ -19,6 +19,7 @@
package org.apache.fineract.infrastructure.core.data;
import java.util.Map;
import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
/**
* Represents the successful result of an REST API call that results in processing a command.
@@ -38,13 +39,14 @@ public class CommandProcessingResultBuilder {
private Long glimId;
private String transactionId;
private Map<String, Object> changes;
private CreditBureauReportData creditBureauReportData;
private Long productId;
private boolean rollbackTransaction = false;
public CommandProcessingResult build() {
return CommandProcessingResult.fromDetails(this.commandId, this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId,
this.resourceIdentifier, this.entityId, this.gsimId, this.glimId, this.transactionId, this.changes, this.productId,
this.rollbackTransaction, this.subEntityId);
this.resourceIdentifier, this.entityId, this.gsimId, this.glimId, this.creditBureauReportData, this.transactionId,
this.changes, this.productId, this.rollbackTransaction, this.subEntityId);
}
public CommandProcessingResultBuilder withCommandId(final Long withCommandId) {
@@ -117,6 +119,11 @@ public class CommandProcessingResultBuilder {
return this;
}
public CommandProcessingResultBuilder withCreditReport(final CreditBureauReportData withCreditReport) {
this.creditBureauReportData = withCreditReport;
return this;
}
public CommandProcessingResultBuilder setRollbackTransaction(final boolean rollbackTransaction) {
this.rollbackTransaction = this.rollbackTransaction || rollbackTransaction;
return this;
@@ -77,6 +77,7 @@ public class CreditBureauConfigurationAPI {
public CreditBureauConfigurationAPI(final PlatformSecurityContext context, final CreditBureauReadPlatformService readPlatformService,
final DefaultToApiJsonSerializer<CreditBureauData> toApiJsonSerializer,
final CreditBureauLoanProductMappingReadPlatformService readPlatformServiceCreditBureauLoanProduct,
final CreditBureauReadConfigurationService readPlatformServiceCreditBureauConfiguration,
final DefaultToApiJsonSerializer<CreditBureauLoanProductMappingData> toApiJsonSerializerCreditBureauLoanProduct,
final OrganisationCreditBureauReadPlatformService readPlatformServiceOrganisationCreditBureau,
final DefaultToApiJsonSerializer<OrganisationCreditBureauData> toApiJsonSerializerOrganisationCreditBureau,
@@ -172,6 +173,21 @@ public class CreditBureauConfigurationAPI {
this.responseDataParameters);
}
@GET
@Path("/loanProduct/{loanProductId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String fetchMappingByLoanProductId(@Context final UriInfo uriInfo, @PathParam("loanProductId") final Long loanProductId) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
final CreditBureauLoanProductMappingData creditBureauLoanProductMapping = this.readPlatformServiceCreditBureauLoanProduct
.readMappingByLoanId(loanProductId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializerCreditBureauLoanProduct.serialize(settings, creditBureauLoanProductMapping,
this.responseDataParameters);
}
@PUT
@Path("/organisationCreditBureau")
@Consumes({ MediaType.APPLICATION_JSON })
@@ -229,4 +245,34 @@ public class CreditBureauConfigurationAPI {
return this.toApiJsonSerializer.serialize(result);
}
@POST
@Path("/configuration/{creditBureauId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createCreditBureauConfiguration(@PathParam("creditBureauId") final Long creditBureauId,
final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().addCreditBureauConfiguration(creditBureauId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("/configuration/{configurationId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateCreditBureauConfiguration(@PathParam("configurationId") final Long configurationId,
final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateCreditBureauConfiguration(configurationId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,157 @@
/**
* 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.infrastructure.creditbureau.api;
import com.google.gson.Gson;
import io.swagger.v3.oas.annotations.Parameter;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
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.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
@Path("/creditBureauIntegration")
@Component
@Scope("singleton")
public class CreditBureauIntegrationAPI {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
private final PlatformSecurityContext context;
private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final CreditReportReadPlatformService creditReportReadPlatformService;
private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
@Autowired
public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper,
final CreditReportWritePlatformService creditReportWritePlatformService,
final CreditReportReadPlatformService creditReportReadPlatformService,
final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
this.context = context;
this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.creditReportReadPlatformService = creditReportReadPlatformService;
this.toApiJsonSerializer = toApiJsonSerializer;
}
@POST
@Path("creditReport")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String fetchCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {
Gson gson = new Gson();
final String json = gson.toJson(params);
final CommandWrapper commandRequest = new CommandWrapperBuilder().getCreditReport().withJson(json).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toCreditReportApiJsonSerializer.serialize(result);
}
// saves fetched-creditreport into database
@POST
@Path("saveCreditReport")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String saveCreditReport(@Parameter(hidden = true) final String apiRequestBodyAsJson,
@QueryParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
@QueryParam("nationalId") @Parameter(description = "nationalId") final String nationalId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.saveCreditReport(creditBureauId, nationalId).withJson(apiRequestBodyAsJson) // apiRequestBodyAsJson is
// a creditReport
.build(); //
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toCreditReportApiJsonSerializer.serialize(result);
}
// fetch saved creditReports(NRC) from DB by creditBureauId, to select for downloading and deleting the reports
@GET
@Path("creditReport/{creditBureauId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String getSavedCreditReport(@PathParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser();
final Collection<CreditReportData> creditReport = this.creditReportReadPlatformService.retrieveCreditReportDetails(creditBureauId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, creditReport, RESPONSE_DATA_PARAMETERS);
}
// deletes saved creditReports from database
@DELETE
@Path("deleteCreditReport/{creditBureauId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String deleteCreditReport(@PathParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteCreditReport(creditBureauId).withJson(apiRequestBodyAsJson)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toCreditReportApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,25 @@
/**
* 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.infrastructure.creditbureau.data;
public enum CreditBureauConfigurations {
THITSAWORKS, SUBSCRIPTIONID, SUBSCRIPTIONKEY, USERNAME, PASSWORD, TOKENURL, SEARCHURL, CREDITREPORTURL;
}
@@ -0,0 +1,57 @@
/**
* 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.infrastructure.creditbureau.data;
import java.io.Serializable;
public final class CreditBureauReportData implements Serializable {
@SuppressWarnings("unused")
private final String name;
private final String gender;
private final String address;
private final String creditScore;
private final String borrowerInfo;
private final String[] openAccounts;
private final String[] closedAccounts;
public static CreditBureauReportData instance(final String name, final String gender, final String address, final String creditScore,
final String borrowerInfo, final String[] openAccounts, final String[] closedAccounts) {
return new CreditBureauReportData(name, gender, address, creditScore, borrowerInfo, openAccounts, closedAccounts);
}
public CreditBureauReportData(final String name, final String gender, final String address, final String creditScore,
final String borrowerInfo, final String[] openAccounts, final String[] closedAccounts) {
this.name = name;
this.gender = gender;
this.address = address;
this.creditScore = creditScore;
this.borrowerInfo = borrowerInfo;
this.openAccounts = openAccounts;
this.closedAccounts = closedAccounts;
}
}
@@ -0,0 +1,41 @@
/**
* 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.infrastructure.creditbureau.data;
import java.io.Serializable;
public final class CreditReportData implements Serializable {
private final Long id;
@SuppressWarnings("unused")
private final Long creditBureauId;
@SuppressWarnings("unused")
private final String nationalId;
public static CreditReportData instance(final Long id, final Long creditBureauId, final String nationalId) {
return new CreditReportData(id, creditBureauId, nationalId);
}
private CreditReportData(final Long id, final Long creditBureauId, final String nationalId) {
this.id = id;
this.creditBureauId = creditBureauId;
this.nationalId = nationalId;
}
}
@@ -0,0 +1,74 @@
/**
* 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.infrastructure.creditbureau.data;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class CreditReportReadPlatformServiceImpl implements CreditReportReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
@Autowired
public CreditReportReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
private static final class CreditReportDataMapper implements RowMapper<CreditReportData> {
public String schema() {
return " c.id as id, c.creditBureauId as creditBureauId , c.nationalId as nationalId from m_creditreport c ";
}
@Override
public CreditReportData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = rs.getLong("id");
final Long creditBureauId = rs.getLong("creditBureauId");
final String nationalId = rs.getString("nationalId");
// final byte[] creditReports = rs.getBytes("creditReports");
return CreditReportData.instance(id, creditBureauId, nationalId);// , creditReports);
}
}
@Override
public Collection<CreditReportData> retrieveCreditReportDetails(Long creditBureauId) {
this.context.authenticatedUser();
final CreditReportDataMapper rm = new CreditReportDataMapper();
final String sql = " select " + rm.schema() + " where c.creditBureauId = ? ";
return this.jdbcTemplate.query(sql, rm, new Object[] { creditBureauId });
}
}
@@ -18,11 +18,14 @@
*/
package org.apache.fineract.infrastructure.creditbureau.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
@@ -56,7 +59,7 @@ public class CreditBureauConfiguration extends AbstractPersistableCustom {
}
public CreditBureauConfiguration fromJson(JsonCommand command, OrganisationCreditBureau organisation_creditbureau) {
public static CreditBureauConfiguration fromJson(JsonCommand command, OrganisationCreditBureau organisation_creditbureau) {
final String configkey = command.stringValueOfParameterNamed("configkey");
final String value = command.stringValueOfParameterNamed("value");
final String description = command.stringValueOfParameterNamed("description");
@@ -97,4 +100,33 @@ public class CreditBureauConfiguration extends AbstractPersistableCustom {
this.organisationCreditbureau = organisation_creditbureau;
}
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<>(1);
final String configurationKey = "configurationKey";
if (command.isChangeInStringParameterNamed(configurationKey, this.configurationKey)) {
final String newValue = command.stringValueOfParameterNamed(configurationKey);
actualChanges.put(configurationKey, newValue);
this.configurationKey = StringUtils.defaultIfEmpty(newValue, null);
}
final String value = "value";
if (command.isChangeInStringParameterNamed(value, this.value)) {
final String newValue = command.stringValueOfParameterNamed(value);
actualChanges.put(value, newValue);
this.value = StringUtils.defaultIfEmpty(newValue, null);
}
final String description = "description";
if (command.isChangeInStringParameterNamed(description, this.configurationKey)) {
final String newValue = command.stringValueOfParameterNamed(description);
actualChanges.put(description, newValue);
this.description = StringUtils.defaultIfEmpty(newValue, null);
}
return actualChanges;
}
}
@@ -0,0 +1,39 @@
/**
* 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.infrastructure.creditbureau.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface CreditBureauConfigurationRepository
extends JpaRepository<CreditBureauConfiguration, Long>, JpaSpecificationExecutor<CreditBureauConfiguration> {
@Query("SELECT creditBureauConfig from CreditBureauConfiguration creditBureauConfig where creditBureauConfig.organisationCreditbureau.id = :creditBureauID and creditBureauConfig.configurationKey = :configurationKey ")
CreditBureauConfiguration getCreditBureauConfigData(@Param("creditBureauID") Integer creditBureauID,
@Param("configurationKey") String parameterName);
@Query("SELECT creditBureauConfig from CreditBureauConfiguration creditBureauConfig where creditBureauConfig.organisationCreditbureau.id = :creditBureauID")
CreditBureauConfiguration getCreditBureauConfigurationData(@Param("creditBureauID") Integer creditBureauID);
@Query("SELECT creditBureauConfig from CreditBureauConfiguration creditBureauConfig where creditBureauConfig.configurationKey = :configurationKey")
CreditBureauConfiguration getCreditBureauConfigurationValueData(@Param("configurationKey") String parameterName);
}
@@ -0,0 +1,39 @@
/**
* 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.infrastructure.creditbureau.domain;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CreditBureauConfigurationRepositoryWrapper {
private final CreditBureauConfigurationRepository creditBureauConfigurationRepository;
@Autowired
public CreditBureauConfigurationRepositoryWrapper(final CreditBureauConfigurationRepository creditBureauConfigurationRepository) {
this.creditBureauConfigurationRepository = creditBureauConfigurationRepository;
}
public CreditBureauConfiguration getCreditBureauConfigData(final Integer creditBureauID, final String parameterName) {
return this.creditBureauConfigurationRepository.getCreditBureauConfigData(creditBureauID, parameterName);
}
}
@@ -18,10 +18,15 @@
*/
package org.apache.fineract.infrastructure.creditbureau.domain;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface CreditBureauLoanProductMappingRepository
extends JpaRepository<CreditBureauLoanProductMapping, Long>, JpaSpecificationExecutor<CreditBureauLoanProductMapping> {
CreditBureauLoanProductMapping findOneByLoanProduct(LoanProduct loanProduct);
CreditBureauLoanProductMapping findOneByLoanProductId(Long loanProductID);
}
@@ -0,0 +1,116 @@
/**
* 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.infrastructure.creditbureau.domain;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Entity
@Table(name = "m_creditbureau_token")
public class CreditBureauToken extends AbstractPersistableCustom {
private static final Logger LOG = LoggerFactory.getLogger(CreditBureauToken.class);
@Column(name = "username")
private String userName;
@Column(name = "token")
private String accessToken;
@Column(name = "tokenType")
private String tokenType;
@Column(name = "expiresIn")
private String expiresIn;
@Column(name = "issued")
private String issued;
@Column(name = "expiryDate")
private Date expires;
public static CreditBureauToken fromJson(final JsonCommand command) {
final String userName = command.stringValueOfParameterNamed("userName");
final String accessToken = command.stringValueOfParameterNamed("access_token");
final String tokenType = command.stringValueOfParameterNamed("token_type");
final String expiresIn = command.stringValueOfParameterNamed("expires_in");
final String issued = command.stringValueOfParameterNamed(".issued");
final String expiry = command.stringValueOfParameterNamed(".expires");
SimpleDateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
Date expires = null;
try {
expires = dateformat.parse(expiry);
} catch (ParseException Ex) {
LOG.error("Error occured while converting Date(String) to SimpleDateFormat", Ex);
}
return new CreditBureauToken(userName, accessToken, tokenType, expiresIn, issued, expires);
}
public CreditBureauToken(String userName, String accessToken, String tokenType, String expiresIn, String issued, Date expires) {
this.userName = userName;
this.accessToken = accessToken;
this.tokenType = tokenType;
this.expiresIn = expiresIn;
this.issued = issued;
this.expires = expires;
}
public CreditBureauToken() {
this.userName = null;
this.accessToken = null;
this.tokenType = null;
this.expiresIn = null;
this.issued = null;
this.expires = null;
}
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getCurrentToken() {
return this.accessToken;
}
public void setTokens(String tokens) {
this.accessToken = tokens;
}
public Date getTokenExpiryDate() {
return this.expires;
}
}
@@ -0,0 +1,59 @@
/**
* 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.infrastructure.creditbureau.domain;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Table;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
@Entity
@Table(name = "m_creditreport")
public final class CreditReport extends AbstractPersistableCustom {
@Column(name = "creditBureauId")
private Long creditBureauId;
@Column(name = "nationalId")
private String nationalId;
@Basic(fetch = FetchType.LAZY)
@Column(name = "creditReports")
private byte[] creditReports;
private CreditReport() {}
public static CreditReport instance(final Long creditBureauId, final String nationalId, final byte[] creditReports) {
return new CreditReport(creditBureauId, nationalId, creditReports);
}
private CreditReport(final Long creditBureauId, final String nationalId, final byte[] creditReports) {
this.creditBureauId = creditBureauId;
this.nationalId = nationalId;
this.creditReports = creditReports;
}
public byte[] getCreditReport() {
return this.creditReports;
}
}
@@ -0,0 +1,31 @@
/**
* 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.infrastructure.creditbureau.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface CreditReportRepository extends JpaRepository<CreditReport, Long>, JpaSpecificationExecutor<CreditReport> {
@Query("SELECT creditBureauReport from CreditReport creditBureauReport where creditBureauReport.nationalId = :nationalId and creditBureauReport.creditBureauId = :creditBureauId ")
CreditReport getThitsaWorksCreditReport(@Param("creditBureauId") Long creditBureauId, @Param("nationalId") String nationalId);
}
@@ -0,0 +1,31 @@
/**
* 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.infrastructure.creditbureau.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
public interface TokenRepository extends JpaRepository<CreditBureauToken, Long>, JpaSpecificationExecutor<CreditBureauToken> {
@Query("select creditbureautoken from CreditBureauToken creditbureautoken")
CreditBureauToken getToken();
}
@@ -0,0 +1,50 @@
/**
* 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.infrastructure.creditbureau.domain;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TokenRepositoryWrapper {
private final TokenRepository repository;
private final PlatformSecurityContext context;
@Autowired
public TokenRepositoryWrapper(final TokenRepository repository, final PlatformSecurityContext context) {
this.repository = repository;
this.context = context;
}
public void save(final CreditBureauToken token) {
this.repository.save(token);
}
public void delete(final CreditBureauToken token) {
this.repository.delete(token);
}
public CreditBureauToken getToken() {
return this.repository.getToken();
}
}
@@ -0,0 +1,30 @@
/**
* 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.infrastructure.creditbureau.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class CreditReportNotFoundException extends AbstractPlatformResourceNotFoundException {
public CreditReportNotFoundException(final Long searchId) {
super("error.msg.creditreport.identifier.not.found", "CreditReport with identifier `" + searchId + "` does not exist", searchId);
}
}
@@ -0,0 +1,48 @@
/**
* 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.infrastructure.creditbureau.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.creditbureau.service.CreditBureauConfigurationWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "CREDITBUREAU_CONFIGURATION", action = "CREATE")
public class AddCreditBureauConfigurationDataCommandHandler implements NewCommandSourceHandler {
private final CreditBureauConfigurationWritePlatformService writePlatformService;
@Autowired
public AddCreditBureauConfigurationDataCommandHandler(final CreditBureauConfigurationWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.addCreditBureauConfiguration(command.entityId(), command);
}
}
@@ -0,0 +1,46 @@
/**
* 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.infrastructure.creditbureau.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.creditbureau.service.CreditReportWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@CommandType(entity = "CREDITREPORT", action = "DELETE")
public class DeleteCreditReportCommandHandler implements NewCommandSourceHandler {
private final CreditReportWritePlatformService writePlatformService;
@Autowired
public DeleteCreditReportCommandHandler(final CreditReportWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(JsonCommand command) {
return this.writePlatformService.deleteCreditReport(command.entityId(), command);
}
}
@@ -0,0 +1,47 @@
/**
* 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.infrastructure.creditbureau.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.creditbureau.service.CreditReportWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "CREDITREPORT", action = "GET")
public class GetCreditReportCommandHandler implements NewCommandSourceHandler {
private final CreditReportWritePlatformService writePlatformService;
@Autowired
public GetCreditReportCommandHandler(final CreditReportWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.getCreditReport(command);
}
}
@@ -0,0 +1,45 @@
/**
* 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.infrastructure.creditbureau.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.creditbureau.service.CreditReportWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@CommandType(entity = "CREDITREPORT", action = "SAVE")
public class SaveCreditReportCommandHandler implements NewCommandSourceHandler {
private final CreditReportWritePlatformService writePlatformService;
@Autowired
public SaveCreditReportCommandHandler(final CreditReportWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Override
public CommandProcessingResult processCommand(JsonCommand command) {
return this.writePlatformService.saveCreditReport(command.entityId(), command.getTransactionId(), command);
}
}
@@ -0,0 +1,48 @@
/**
* 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.infrastructure.creditbureau.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.creditbureau.service.CreditBureauConfigurationWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "CREDITBUREAU_CONFIGURATION", action = "UPDATE")
public class UpdateCreditBureauConfigurationDataCommandHandler implements NewCommandSourceHandler {
private final CreditBureauConfigurationWritePlatformService writePlatformService;
@Autowired
public UpdateCreditBureauConfigurationDataCommandHandler(final CreditBureauConfigurationWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.updateCreditBureauConfiguration(command.entityId(), command);
}
}
@@ -0,0 +1,113 @@
/**
* 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.infrastructure.creditbureau.serialization;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public final class CreditBureauConfigurationCommandFromApiJsonDeserializer {
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList("configkey", "value", "description"));
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public CreditBureauConfigurationCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForCreate(final String json, final Long creditBureauId) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource("CREDITBUREAU_CONFIGURATION");
final JsonElement element = this.fromApiJsonHelper.parse(json);
baseDataValidator.reset().value(creditBureauId).notBlank().integerGreaterThanZero();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final String configkey = this.fromApiJsonHelper.extractStringNamed("configkey", element);
baseDataValidator.reset().parameter("configkey").value(configkey).notBlank().notExceedingLengthOf(100);
final String value = this.fromApiJsonHelper.extractStringNamed("value", element);
baseDataValidator.reset().parameter("value").value(value).notBlank().notExceedingLengthOf(100);
final String description = this.fromApiJsonHelper.extractStringNamed("description", element);
baseDataValidator.reset().parameter("description").value(description).notBlank().notExceedingLengthOf(100);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("config");
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists("value", element)) {
final String value = this.fromApiJsonHelper.extractStringNamed("value", element);
baseDataValidator.reset().parameter("value").value(value).notBlank().notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists("description", element)) {
final String description = this.fromApiJsonHelper.extractStringNamed("description", element);
baseDataValidator.reset().parameter("description").value(description).notBlank().notExceedingLengthOf(100);
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
@@ -0,0 +1,128 @@
/**
* 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.infrastructure.creditbureau.serialization;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CreditBureauTokenCommandFromApiJsonDeserializer {
private static final Logger LOG = LoggerFactory.getLogger(CreditBureauTokenCommandFromApiJsonDeserializer.class);
private final Set<String> supportedParameters = new HashSet<>(
Arrays.asList("access_token", "token_type", "expires_in", "userName", ".issued", ".expires"));
private final Set<String> supportedTokenConfigParameters = new HashSet<>(
Arrays.asList("userName", "password", "subscriptionId", "subscriptionKey"));
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public CreditBureauTokenCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tokens");
final JsonElement element = this.fromApiJsonHelper.parse(json);
final String access_token = this.fromApiJsonHelper.extractStringNamed("access_token", element);
baseDataValidator.reset().parameter("access_token").value(access_token).notBlank().notExceedingLengthOf(1000);
final String token_type = this.fromApiJsonHelper.extractStringNamed("token_type", element);
baseDataValidator.reset().parameter("token_type").value(token_type).notBlank().notExceedingLengthOf(100);
final String expires_in = this.fromApiJsonHelper.extractStringNamed("expires_in", element);
baseDataValidator.reset().parameter("expires_in").value(expires_in).notBlank().notExceedingLengthOf(100);
final String userName = this.fromApiJsonHelper.extractStringNamed("userName", element);
baseDataValidator.reset().parameter("userName").value(userName).notBlank().notExceedingLengthOf(100);
final String issued = this.fromApiJsonHelper.extractStringNamed(".issued", element);
baseDataValidator.reset().parameter(".issued").value(issued).notBlank().notExceedingLengthOf(100);
final String expires = this.fromApiJsonHelper.extractStringNamed(".expires", element);
baseDataValidator.reset().parameter(".expires").value(expires).notBlank().notExceedingLengthOf(100);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForUsingTokenConfig(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedTokenConfigParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("configdata");
final JsonElement element = this.fromApiJsonHelper.parse(json);
final String userName = this.fromApiJsonHelper.extractStringNamed("userName", element);
baseDataValidator.reset().parameter("userName").value(userName).notBlank().notExceedingLengthOf(1000);
final String password = this.fromApiJsonHelper.extractStringNamed("password", element);
baseDataValidator.reset().parameter("password").value(password).notBlank().notExceedingLengthOf(100);
final String subscriptionId = this.fromApiJsonHelper.extractStringNamed("subscriptionId", element);
baseDataValidator.reset().parameter("subscriptionId").value(subscriptionId).notBlank().notExceedingLengthOf(100);
final String subscriptionKey = this.fromApiJsonHelper.extractStringNamed("subscriptionKey", element);
baseDataValidator.reset().parameter("subscriptionKey").value(subscriptionKey).notBlank().notExceedingLengthOf(100);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
@@ -0,0 +1,30 @@
/**
* 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.infrastructure.creditbureau.service;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
public interface CreditBureauConfigurationWritePlatformService {
CommandProcessingResult addCreditBureauConfiguration(Long creditBureauId, JsonCommand command);
CommandProcessingResult updateCreditBureauConfiguration(Long configurationId, JsonCommand command);
}
@@ -0,0 +1,110 @@
/**
* 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.infrastructure.creditbureau.service;
import java.util.Map;
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.infrastructure.creditbureau.domain.CreditBureauConfiguration;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepository;
import org.apache.fineract.infrastructure.creditbureau.domain.OrganisationCreditBureau;
import org.apache.fineract.infrastructure.creditbureau.domain.OrganisationCreditBureauRepository;
import org.apache.fineract.infrastructure.creditbureau.exception.CreditReportNotFoundException;
import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauConfigurationCommandFromApiJsonDeserializer;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreditBureauConfigurationWritePlatformServiceImpl implements CreditBureauConfigurationWritePlatformService {
private final PlatformSecurityContext context;
private final CreditBureauConfigurationCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final CreditBureauConfigurationRepository creditBureauConfigurationRepository;
private final OrganisationCreditBureauRepository organisationCreditBureauRepository;
@Autowired
public CreditBureauConfigurationWritePlatformServiceImpl(final PlatformSecurityContext context,
final CreditBureauConfigurationCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final CreditBureauConfigurationRepository creditBureauConfigurationRepository,
OrganisationCreditBureauRepository organisationCreditBureauRepository) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.creditBureauConfigurationRepository = creditBureauConfigurationRepository;
this.organisationCreditBureauRepository = organisationCreditBureauRepository;
}
@Transactional
@Override
public CommandProcessingResult addCreditBureauConfiguration(Long creditBureauId, JsonCommand command) {
this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForCreate(command.json(), creditBureauId);
final OrganisationCreditBureau orgcb = this.organisationCreditBureauRepository.getOne(creditBureauId);
final CreditBureauConfiguration cb_config = CreditBureauConfiguration.fromJson(command, orgcb);
this.creditBureauConfigurationRepository.save(cb_config);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(cb_config.getId()).build();
}
@Transactional
@Override
public CommandProcessingResult updateCreditBureauConfiguration(Long configurationId, JsonCommand command) {
try {
this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForUpdate(command.json());
final CreditBureauConfiguration config = retrieveConfigBy(configurationId);
final Map<String, Object> changes = config.update(command);
if (!changes.isEmpty()) {
this.creditBureauConfigurationRepository.save(config);
}
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(configurationId) //
.with(changes) //
.build();
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + dve.getMostSpecificCause(), dve);
}
}
private CreditBureauConfiguration retrieveConfigBy(final Long creditBureauId) {
return this.creditBureauConfigurationRepository.findById(creditBureauId)
.orElseThrow(() -> new CreditReportNotFoundException(creditBureauId));
}
}
@@ -0,0 +1,28 @@
/**
* 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.infrastructure.creditbureau.service;
import java.util.Collection;
import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
public interface CreditReportReadPlatformService {
Collection<CreditReportData> retrieveCreditReportDetails(Long creditBureauId);
}
@@ -0,0 +1,35 @@
/**
* 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.infrastructure.creditbureau.service;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
public interface CreditReportWritePlatformService {
// gets CreditReport from CreditBureau
CommandProcessingResult getCreditReport(JsonCommand command);
// saves fetched-CreditReport to database
CommandProcessingResult saveCreditReport(Long organisationCreditBureauId, String nationalId, JsonCommand command);
// deletes creditReports which are saved in database
CommandProcessingResult deleteCreditReport(Long creditBureauId, JsonCommand command);
}
@@ -0,0 +1,214 @@
/**
* 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.infrastructure.creditbureau.service;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.persistence.PersistenceException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauConfigurations;
import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
private final PlatformSecurityContext context;
private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
private final CreditBureauRepository creditBureauRepository;
private final CreditReportRepository creditReportRepository;
private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
private final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
private final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
private final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource("creditBureauIntegration");
@Autowired
public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
final CreditBureauConfigurationRepositoryWrapper configDataRepository,
final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService,
final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl) {
this.context = context;
this.configDataRepository = configDataRepository;
this.creditBureauRepository = creditBureauRepository;
this.creditReportRepository = creditReportRepository;
this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
}
@Override
@Transactional
public CommandProcessingResult getCreditReport(JsonCommand command) {
try {
Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
Optional<String> creditBureauName = getCreditBureau(creditBureauID);
if (creditBureauName.isEmpty()) {
baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
dataValidationErrors);
}
if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
// CreditBureauToken creditBureauToken = this.thitsaWorksCreditBureauIntegrationWritePlatformService
// .createToken(creditBureauID);
CreditBureauReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
.getCreditReportFromThitsaWorks(command);
// return new
// CommandProcessingResultBuilder().withCreditReport(reportobj).withCreditBureauToken(creditBureauToken).build();
return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
}
baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
dataValidationErrors);
} catch (final DataIntegrityViolationException dve) {
handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
return CommandProcessingResult.empty();
} catch (final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
handleTokenDataIntegrityIssues(command, throwable, ee);
return CommandProcessingResult.empty();
}
}
private Optional<String> getCreditBureau(Long creditBureauID) {
if (creditBureauID != null) {
Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
if (creditBureau.isEmpty()) {
return Optional.empty();
}
return Optional.of(creditBureau.get().getName());
}
return Optional.empty();
}
// saving the fetched creditreport in database
@Override
@Transactional
public CommandProcessingResult saveCreditReport(Long creditBureauId, String nationalId, JsonCommand command) {
try {
this.context.authenticatedUser();
Optional<String> creditBureauName = getCreditBureau(creditBureauId);
CreditReport creditReport = null;
if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
// checks whether creditReport for same nationalId was saved before. if yes, then deletes it & replaces
// with new one.
creditReport = creditReportRepository.getThitsaWorksCreditReport(creditBureauId, nationalId);
if (creditReport != null) {
this.creditReportRepository.delete(creditReport);
}
String reportData = command.stringValueOfParameterNamed("apiRequestBodyAsJson");
byte[] creditReportArray = reportData.getBytes(StandardCharsets.UTF_8);
creditReport = CreditReport.instance(creditBureauId, nationalId, creditReportArray);
this.creditReportRepository.saveAndFlush(creditReport);
}
return new CommandProcessingResultBuilder().withEntityId(creditReport.getId()).build();
} catch (final DataIntegrityViolationException dve) {
handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
return CommandProcessingResult.empty();
} catch (final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
handleTokenDataIntegrityIssues(command, throwable, ee);
return CommandProcessingResult.empty();
}
}
@Transactional
@Override
public CommandProcessingResult deleteCreditReport(Long creditBureauId, JsonCommand command) {
this.context.authenticatedUser();
Optional<String> creditBureauName = getCreditBureau(creditBureauId);
CreditReport creditReport = null;
if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
String nationalId = command.stringValueOfParameterNamed("nationalId");
creditReport = creditReportRepository.getThitsaWorksCreditReport(creditBureauId, nationalId);
try {
this.creditReportRepository.delete(creditReport);
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + dve.getMostSpecificCause(), dve);
}
}
return new CommandProcessingResultBuilder().withEntityId(creditReport.getId()).build();
}
private void handleTokenDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) {
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + realCause.getMessage());
}
}
@@ -0,0 +1,37 @@
/**
* 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.infrastructure.creditbureau.service;
import java.io.File;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
public interface ThitsaWorksCreditBureauIntegrationWritePlatformService {
CreditBureauToken createToken(Long creditBureauID);
Long extractUniqueId(String jsonResult);
String okHttpConnectionMethod(String userName, String password, String subscriptionKey, String subscriptionId, String url, String token,
File report, Long uniqueId, String nrcId, String process);
CreditBureauReportData getCreditReportFromThitsaWorks(JsonCommand command);
}
@@ -0,0 +1,465 @@
/**
* 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.infrastructure.creditbureau.service;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauConfigurations;
import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepository;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Component
@Service
public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
private final PlatformSecurityContext context;
private final FromJsonHelper fromApiJsonHelper;
private final TokenRepositoryWrapper tokenRepositoryWrapper;
private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
private final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource("ThitsaWorksCreditBureauIntegration");
@Autowired
public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepositoryWrapper,
final CreditBureauConfigurationRepositoryWrapper configDataRepository,
final CreditBureauConfigurationRepository configurationDataRepository,
final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final CreditReportRepository creditReportRepository) {
this.context = context;
this.tokenRepositoryWrapper = tokenRepositoryWrapper;
this.configDataRepository = configDataRepository;
this.fromApiJsonHelper = fromApiJsonHelper;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
}
private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
@Transactional
@Override
@SuppressWarnings("deprecation")
public String okHttpConnectionMethod(String userName, String password, String subscriptionKey, String subscriptionId, String url,
String token, File file, Long uniqueId, String nrcId, String process) {
String reponseMessage = null;
RequestBody requestBody = null;
OkHttpClient client = new OkHttpClient();
if (process.equals("token")) {
final MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
String jsonBody = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+ password + "&\r";
requestBody = RequestBody.create(jsonBody, mediaType);
} else if (process.equals("NRC")) {
final MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
String jsonBody = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
requestBody = RequestBody.create(jsonBody, mediaType);
}
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
String urlokhttp = urlBuilder.build().toString();
Request request = null;
if (token == null) {
request = new Request.Builder().header("mcix-subscription-key", subscriptionKey).header("mcix-subscription-id", subscriptionId)
.header("Content-Type", "application/x-www-form-urlencoded").url(urlokhttp).post(requestBody).build();
}
if (token != null) {
if (process.equals("CreditReport")) { // GET method for fetching credit report
request = new Request.Builder().header("mcix-subscription-key", subscriptionKey)
.header("mcix-subscription-id", subscriptionId).header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization", "Bearer " + token).url(urlokhttp).get().build();
} else { // POST method for application/x-www-form-urlencoded
request = new Request.Builder().header("mcix-subscription-key", subscriptionKey)
.header("mcix-subscription-id", subscriptionId).header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization", "Bearer " + token).url(urlokhttp).post(requestBody).build();
}
}
Response response;
Integer responseCode = 0;
try {
response = client.newCall(request).execute();
responseCode = response.code();
reponseMessage = response.body().string();
} catch (IOException e) {
LOG.error("error occured in HTTP request-response method.", e);
}
if (responseCode != HttpURLConnection.HTTP_OK) {
this.httpResponse(responseCode, reponseMessage);
}
return reponseMessage;
}
private void httpResponse(Integer responseCode, String responseMessage) {
if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
String httpResponse = "HTTP_UNAUTHORIZED";
this.handleAPIIntegrityIssues(httpResponse);
} else if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
String httpResponse = "HTTP_FORBIDDEN";
this.handleAPIIntegrityIssues(httpResponse);
} else {
String responseResult = "HTTP Response Code: " + responseCode + "/" + "Response Message: " + responseMessage;
this.handleAPIIntegrityIssues(responseResult);
}
}
@Transactional
@Override
public CreditBureauReportData getCreditReportFromThitsaWorks(final JsonCommand command) {
this.context.authenticatedUser();
String nrcId = command.stringValueOfParameterNamed("NRC");
String bureauID = command.stringValueOfParameterNamed("creditBureauID");
Integer creditBureauId = Integer.parseInt(bureauID);
String token = null;
String userName = getCreditBureauConfiguration(creditBureauId, CreditBureauConfigurations.USERNAME.toString());
String password = getCreditBureauConfiguration(creditBureauId, CreditBureauConfigurations.PASSWORD.toString());
String subscriptionId = getCreditBureauConfiguration(creditBureauId, CreditBureauConfigurations.SUBSCRIPTIONID.toString());
String subscriptionKey = getCreditBureauConfiguration(creditBureauId, CreditBureauConfigurations.SUBSCRIPTIONKEY.toString());
CreditBureauToken creditbureautoken = createToken(creditBureauId.longValue());
token = creditbureautoken.getCurrentToken();
// will use only "NRC" part of code from common http method to get data based on nrc
String process = "NRC";
String url = getCreditBureauConfiguration(creditBureauId, CreditBureauConfigurations.SEARCHURL.toString());
String nrcUrl = url + nrcId;
String searchResult = this.okHttpConnectionMethod(userName, password, subscriptionKey, subscriptionId, nrcUrl, token, null, 0L,
nrcId, process);
if (process.equals("NRC")) {
Long uniqueID = this.extractUniqueId(searchResult);
process = "CreditReport";
url = getCreditBureauConfiguration(creditBureauId, CreditBureauConfigurations.CREDITREPORTURL.toString());
String creditReportUrl = url + uniqueID;
searchResult = this.okHttpConnectionMethod(userName, password, subscriptionKey, subscriptionId, creditReportUrl, token, null,
uniqueID, null, process);
}
// after getting the result(creditreport) from httpconnection-response it will assign creditreport to generic
// creditreportdata object
JsonObject reportObject = JsonParser.parseString(searchResult).getAsJsonObject();
// Credit Reports Stored into Generic CreditReportData
JsonObject jsonData = null;
JsonElement element = reportObject.get("Data");
if (!(element instanceof JsonNull)) { // NOTE : "element instanceof JsonNull" is for handling empty values (and
// assigning null) while fetching data from results
jsonData = (JsonObject) element;
}
JsonObject borrowerInfos = null;
String borrowerInfo = null;
element = jsonData.get("BorrowerInfo");
if (!(element instanceof JsonNull)) {
borrowerInfos = (JsonObject) element;
Gson gson = new Gson();
borrowerInfo = gson.toJson(borrowerInfos);
}
String Name = borrowerInfos.get("Name").toString();
String Gender = borrowerInfos.get("Gender").toString();
String Address = borrowerInfos.get("Address").toString();
String creditScore = "CreditScore";
creditScore = getJsonObjectToString(creditScore, element, jsonData);
String activeLoans = "ActiveLoans";
JsonArray activeLoansArray = getJsonObjectToArray(activeLoans, element, jsonData);
String[] activeLoanStringArray = null;
if (activeLoansArray != null) {
activeLoanStringArray = convertArrayintoStringArray(activeLoansArray);
}
String writeOffLoans = "WriteOffLoans";
JsonArray writeOffLoansArray = getJsonObjectToArray(writeOffLoans, element, jsonData);
String[] writeoffLoanStringArray = null;
if (writeOffLoansArray != null) {
writeoffLoanStringArray = convertArrayintoStringArray(writeOffLoansArray);
}
return CreditBureauReportData.instance(Name, Gender, Address, creditScore, borrowerInfo, activeLoanStringArray,
writeoffLoanStringArray);
}
private String[] convertArrayintoStringArray(JsonArray jsonResult) {
String[] loanAccounts = new String[jsonResult.size()];
Integer i = 0;
for (JsonElement ele : jsonResult) {
loanAccounts[i++] = ele.toString();
}
return loanAccounts;
}
@Override
@Transactional
public Long extractUniqueId(String jsonResult) {
JsonObject reportObject = JsonParser.parseString(jsonResult).getAsJsonObject();
JsonElement element = reportObject.get("Data");
if (element.isJsonNull()) {
String ResponseMessage = reportObject.get("ResponseMessage").getAsString();
handleAPIIntegrityIssues(ResponseMessage);
}
// to fetch the Unique ID from Result
JsonObject jsonObject = JsonParser.parseString(jsonResult).getAsJsonObject();
Long uniqueID = 0L;
try {
JsonArray dataArray = jsonObject.getAsJsonArray("Data");
if (dataArray.size() == 1) {
JsonObject jobject = dataArray.get(0).getAsJsonObject();
String uniqueIdString = jobject.get("UniqueID").toString();
String TrimUniqueId = uniqueIdString.substring(1, uniqueIdString.length() - 1);
uniqueID = Long.parseLong(TrimUniqueId);
} else if (dataArray.size() == 0) {
String ResponseMessage = reportObject.get("ResponseMessage").getAsString();
handleAPIIntegrityIssues(ResponseMessage);
} else {
String nrc = null;
List<String> arrlist = new ArrayList<String>();
for (int i = 0; i < dataArray.size(); ++i) {
JsonObject data = dataArray.get(i).getAsJsonObject();
nrc = data.get("NRC").toString();
arrlist.add(nrc);
}
String listString = String.join(", ", arrlist);
this.handleMultipleNRC(listString);
}
} catch (IndexOutOfBoundsException e) {
String ResponseMessage = jsonObject.get("ResponseMessage").getAsString();
handleAPIIntegrityIssues(ResponseMessage);
}
return uniqueID;
}
private String getJsonObjectToString(String fetchData, JsonElement element, JsonObject jsonData) {
String jsonString = null;
element = jsonData.get(fetchData);
if (!(element instanceof JsonNull)) {
JsonObject fetchJson = (JsonObject) element;
Gson gson = new Gson();
jsonString = gson.toJson(fetchJson);
}
return jsonString;
}
private JsonArray getJsonObjectToArray(String fetchData, JsonElement element, JsonObject jsonData) {
JsonArray fetchJson = null;
element = jsonData.get(fetchData);
if (!(element instanceof JsonNull)) {
fetchJson = (JsonArray) element;
}
return fetchJson;
}
@Transactional
@Override
public CreditBureauToken createToken(Long bureauID) {
CreditBureauToken creditBureauToken = this.tokenRepositoryWrapper.getToken();
// check the expiry date of the previous token.
if (creditBureauToken != null) {
Date current = new Date();
Date getExpiryDate = creditBureauToken.getTokenExpiryDate();
if (getExpiryDate.before(current)) {
this.tokenRepositoryWrapper.delete(creditBureauToken);
creditBureauToken = null;
}
}
// storing token if it is valid token(not expired)
if (creditBureauToken != null) {
creditBureauToken = this.tokenRepositoryWrapper.getToken();
}
String userName = getCreditBureauConfiguration(bureauID.intValue(), CreditBureauConfigurations.USERNAME.toString());
String password = getCreditBureauConfiguration(bureauID.intValue(), CreditBureauConfigurations.PASSWORD.toString());
String subscriptionId = getCreditBureauConfiguration(bureauID.intValue(), CreditBureauConfigurations.SUBSCRIPTIONID.toString());
String subscriptionKey = getCreditBureauConfiguration(bureauID.intValue(), CreditBureauConfigurations.SUBSCRIPTIONKEY.toString());
if (creditBureauToken == null) {
String url = getCreditBureauConfiguration(bureauID.intValue(), CreditBureauConfigurations.TOKENURL.toString());
String process = "token";
String nrcId = null;
Long uniqueID = 0L;
String result = this.okHttpConnectionMethod(userName, password, subscriptionKey, subscriptionId, url, null, null, uniqueID,
nrcId, process);
// created token will be storing it into database
final CommandWrapper wrapper = new CommandWrapperBuilder().withJson(result).build();
final String json = wrapper.getJson();
JsonCommand apicommand = null;
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
apicommand = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getEntityId(),
wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getSavingsId(),
wrapper.getTransactionId(), wrapper.getHref(), wrapper.getProductId(), wrapper.getCreditBureauId(),
wrapper.getOrganisationCreditBureauId());
this.fromApiJsonDeserializer.validateForCreate(apicommand.json());
final CreditBureauToken generatedtoken = CreditBureauToken.fromJson(apicommand);
final CreditBureauToken credittoken = this.tokenRepositoryWrapper.getToken();
if (credittoken != null) {
this.tokenRepositoryWrapper.delete(credittoken);
}
this.tokenRepositoryWrapper.save(generatedtoken);
creditBureauToken = this.tokenRepositoryWrapper.getToken();
}
return creditBureauToken;
}
public String getCreditBureauConfiguration(Integer creditBureauId, String configurationParameterName) {
String creditBureauConfigurationValue = null;
try {
CreditBureauConfiguration configurationParameterValue = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
configurationParameterName);
creditBureauConfigurationValue = configurationParameterValue.getValue();
if (creditBureauConfigurationValue.isEmpty()) {
baseDataValidator.reset().failWithCode("creditBureau.configuration." + configurationParameterName + ".is.not.available");
throw new PlatformApiDataValidationException(
"creditBureau.Configuration." + configurationParameterName + ".is.not.available",
"creditBureau.Configuration.is.not.available", dataValidationErrors);
}
} catch (NullPointerException ex) {
baseDataValidator.reset().failWithCode("creditBureau.configuration.is.not.available");
throw new PlatformApiDataValidationException("creditBureau.Configuration.is.not.available" + ex,
"creditBureau.Configuration.is.not.available", dataValidationErrors);
}
return creditBureauConfigurationValue;
}
private void handleAPIIntegrityIssues(String httpResponse) {
throw new PlatformDataIntegrityException(httpResponse, httpResponse);
}
private void handleMultipleNRC(String nrc) {
String showMessageForMultipleNRC = "Found Multiple NRC's, Enter one from the given:" + nrc + "." + "";
throw new PlatformDataIntegrityException(showMessageForMultipleNRC, showMessageForMultipleNRC);
}
}
@@ -0,0 +1,80 @@
--
-- 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.
--
CREATE TABLE `m_creditbureau_token` (
`id` INT(128) NOT NULL AUTO_INCREMENT,
`username` varchar(128) DEFAULT NULL,
`token` MEDIUMTEXT DEFAULT NULL,
`tokenType` varchar(128) DEFAULT NULL,
`expiresIn` varchar(128) DEFAULT NULL,
`issued` varchar(128) DEFAULT NULL,
`expiryDate` DATE DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;
CREATE TABLE `m_creditreport` (
`id` INT(128) NOT NULL AUTO_INCREMENT,
`creditBureauId` BIGINT(128) DEFAULT NULL,
`nationalId` varchar(128) DEFAULT NULL,
`creditReports` BLOB DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `cbId` FOREIGN KEY (`creditBureauId`) REFERENCES `m_creditbureau` (`id`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;
ALTER TABLE m_creditbureau_configuration
DROP FOREIGN KEY cbConfigfk1;
ALTER TABLE m_creditbureau_configuration
ADD CONSTRAINT cbConfigfk1
FOREIGN KEY (organisation_creditbureau_id) REFERENCES `m_creditbureau` (`id`);
ALTER TABLE m_creditbureau_configuration MODIFY COLUMN value longtext;
ALTER TABLE m_organisation_creditbureau CHANGE is_active isActive TINYINT(4) NOT NULL;
ALTER TABLE m_creditbureau_loanproduct_mapping CHANGE is_active isActive TINYINT(4) NULL;
-- Integrated credit bureau added
INSERT INTO `m_creditbureau` (`id`, `name`, `product`, `country`, `implementationKey`) VALUES ('1', 'THITSAWORKS', '1', 'Myanmar', '1');
-- permissions added
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('configuration', 'GET_CREDITREPORT', 'CREDITREPORT', 'GET', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('configuration', 'CREATE_CREDITBUREAU_CONFIGURATION', 'CREDITBUREAU_CONFIGURATION', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('configuration', 'UPDATE_CREDITBUREAU_CONFIGURATION', 'CREDITBUREAU_CONFIGURATION', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('configuration', 'SAVE_CREDITREPORT', 'CREDITREPORT', 'SAVE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('configuration', 'DELETE_CREDITREPORT', 'CREDITREPORT', 'DELETE', 0);
-- configkeys added
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('1', 'Password', '', '1', '');
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('2', 'SubscriptionId', '', '1', '');
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('3', 'SubscriptionKey', '', '1', '');
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('4', 'Username', '', '1', '');
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('5', 'tokenurl', '', '1', '');
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('6', 'searchurl', '', '1', '');
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('7', 'creditReporturl', '', '1', '');
INSERT INTO `m_creditbureau_configuration` (`id`, `configkey`, `value`, `organisation_creditbureau_id`, `description`) VALUES ('8', 'addCreditReporturl', '', '1', '');
@@ -0,0 +1,128 @@
/**
* 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.portfolio.loanaccount;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.File;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformServiceImpl;
import org.apache.fineract.infrastructure.creditbureau.service.ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class ThitsaworksCreditBureauTest {
private FromJsonHelper fromApiJsonHelper = new FromJsonHelper();
@Mock
private ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
@InjectMocks
private final CreditReportWritePlatformServiceImpl creditReportWritePlatformServiceImpl = null;
/*
* @Autowired CreditBureauIntegrationTest(final FromJsonHelper fromApiJsonHelper) { this.fromApiJsonHelper =
* fromApiJsonHelper; }
*/
static String process = "process";
static String nrcID = "13/MiFoS(N)163525";
static String userName = "demomfi1@mifos.com";
static String password = "password";
static String subscriptionKey = "15c15ff17493acb44cb223f2feab2fe4";
static String subscriptionId = "4A7C-317A41BA-1FF8-8A64-F8EDBE0F625D";
static String url = "url";
static String token = "token";
static Long uniqueId = 8113399260L;
static File file;
static String testresult = "{ 'Data': {'BorrowerInfo': {'MainIdentifier': '2113439293', 'Name': 'Aung Khant Min',"
+ " 'NRC': '13/MiFoS(N)163525', 'Gender': '', 'DOB': '1990-01-20', 'FatherName': '', 'Address': '',"
+ " 'LastUpdatedDtm': 'Jul 8 2020 9:27AM', 'PrintedDtm': 'Aug 2 2020 2:54AM' }, "
+ " 'ActiveLoanStatus': 'Record found', 'ActiveLoans': [{'ReportingDate': '2020-03-01',"
+ " 'LoanGUID': 'BC309AD3-0444-4EFD-807E-79ECB99EE999',"
+ " 'Institution': 'Demo 1', 'Division': 'YANGON ',"
+ " 'Township': 'YANKIN ', 'DisbursedDate': 'xxxx',"
+ " 'DisbursedAmount': '500000', 'PrincipalOutstandingAmount': '300000',"
+ " 'TotalOutstandingAmount': 'xxxx', 'PrincipalOverdueAmount': '100000',"
+ " 'TotalOverdueAmount': '', 'DaysInDelay': '10',"
+ " 'UpdatedDtm': 'Apr 27 2020 9:41AM', 'SortColumn': '2020-03-01T00:00:00'}], "
+ " 'WriteOffLoanStatus': 'No record found', 'WriteOffLoans': null,"
+ " 'CreditScore': { 'Score': 'N/A','Class': 'N/A', 'Note': ''},"
+ " 'InquiryStatus': 'Record found', 'Inquiries': [{ 'InquiryDate': '', 'Institution': '','NoOfInquiry': ''} ] },"
+ " 'MessageDtm': '8/1/2020 8:24:20 PM UTC','SubscriptionID': '4A7C-317A41BA-1FF8-8A64-F8EDBE0F625D',"
+ " 'CallerIP': '207.46.228.155',"
+ " 'URI': 'https://qa-mmcix-api.azurewebsites.net/20200324/api/Dashboard/GetCreditReport?uniqueId=2113439292',"
+ " 'ResponseMessage': 'Record found'}";
@Test
public void getUniqueIdFromSearchMethodTest() {
String searchResult = "{\"Data\":[{\"UniqueID\":\"8113399260\",\"NRC\":\"12/KaMaRa(N)253426\",\"FullName\":\"Aye Aye\",\"DOB\":\"1990-05-22,1991-05-22\",\"FatherFullName\":\"U Aye Myint Maung\",\"Location\":\"Yangon-Thongwa,Twantay,Yankin\",\"Flag\":\"[{\\\"WriteOff\\\":1}]\",\"Active\":\"Y\"}],\"MessageDtm\":\"8/1/2020 6:39:00 PM UTC\",\"SubscriptionID\":\"317A1FF8-625D-41BA-BE0F-F8ED8A644A7C\",\"CallerIP\":\"207.46.228.155\",\"URI\":\"https://qa-mmcix-api.azurewebsites.net/20200324/api/Search/SimpleSearch?nrc=253426\",\"ResponseMessage\":\"Record found\"}";
when(this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password, subscriptionKey,
subscriptionId, url, token, file, uniqueId, nrcID, process)).thenReturn(searchResult);
final String search = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password,
subscriptionKey, subscriptionId, url, token, file, uniqueId, nrcID, process);
when(thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.extractUniqueId(search)).thenCallRealMethod();
Long uniqueId = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.extractUniqueId(searchResult);
Long expectedUniqueId = 8113399260L;
assertEquals(expectedUniqueId, uniqueId);
}
@Test
public void getCreditReportTest() {
String curentNrc = "13/MiFoS(N)163525";
when(this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password, subscriptionKey,
subscriptionId, url, token, file, uniqueId, nrcID, process)).thenReturn(testresult);
String creditReport = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password,
subscriptionKey, subscriptionId, url, token, file, uniqueId, nrcID, process);
JsonObject resultObject = JsonParser.parseString(creditReport).getAsJsonObject();
String data = resultObject.get("Data").toString();
JsonObject dataObject = JsonParser.parseString(data).getAsJsonObject();
String borrowerInfo = dataObject.get("BorrowerInfo").toString();
JsonObject borrowerObject = JsonParser.parseString(borrowerInfo).getAsJsonObject();
String nrc = borrowerObject.get("NRC").toString();
nrc = nrc.substring(1, nrc.length() - 1);
assertEquals(nrc, curentNrc);
}
}
@@ -0,0 +1,70 @@
/**
* 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.integrationtests;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import org.apache.fineract.integrationtests.common.CreditBureauConfigurationHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CreditBureauConfigurationTest {
private static final Logger LOG = LoggerFactory.getLogger(CreditBureauConfigurationTest.class);
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private LoanTransactionHelper loanTransactionHelper;
private static final String NO_ACCOUNTING = "1";
static final int MYTHREADS = 30;
@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
}
@Test
public void creditBureauConfigurationTest() {
// create creditBureauConfiguration
final Integer configurationId = CreditBureauConfigurationHelper.createCreditBureauConfiguration(this.requestSpec,
this.responseSpec);
Assertions.assertNotNull(configurationId);
// update creditBureauConfiguration
final String updateconfiguration = CreditBureauConfigurationHelper.updateCreditBureauConfiguration(this.requestSpec,
this.responseSpec, configurationId);
Assertions.assertEquals("updateConfigKeyValue", updateconfiguration);
}
}
@@ -0,0 +1,102 @@
/**
* 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.integrationtests.common;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CreditBureauConfigurationHelper {
private static final String CREATE_CREDITBUREAUCONFIGURATION_URL = "/fineract-provider/api/v1/CreditBureauConfiguration/configuration?"
+ Utils.TENANT_IDENTIFIER;
private static final Logger LOG = LoggerFactory.getLogger(CreditBureauConfigurationHelper.class);
private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec;
public CreditBureauConfigurationHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
this.requestSpec = requestSpec;
this.responseSpec = responseSpec;
}
public static Integer createCreditBureauConfiguration(final RequestSpecification requestSpec,
final ResponseSpecification responseSpec) {
return createCreditBureauConfiguration(requestSpec, responseSpec, "1");
}
public static Integer createCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String creditBureauId) {
LOG.info("---------------------------------CREATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------");
final String CREDITBUREAU_CONFIGURATION_URL = " /fineract-provider/api/v1/CreditBureauConfiguration/configuration/" + creditBureauId
+ "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerPost(requestSpec, responseSpec, CREDITBUREAU_CONFIGURATION_URL,
creditBureauConfigurationAsJson("testConfigKey", "testConfigKeyValue", "description"), "resourceId");
}
/*
* public static Object updateCreditBureauConfiguration(final RequestSpecification requestSpec, final
* ResponseSpecification responseSpec, final Integer ConfigurationId) { return
* updateCreditBureauConfiguration(requestSpec, responseSpec, ConfigurationId); }
*/
public static String updateCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer ConfigurationId) {
Object configurationObject = updateCreditBureauConfiguration(requestSpec, responseSpec, ConfigurationId, "updateConfigKeyValue");
// Convert the Object to String and fetch updated value
Gson gson = new Gson();
String result = gson.toJson(configurationObject);
JsonObject reportObject = JsonParser.parseString(result).getAsJsonObject();
String value = reportObject.get("value").getAsString();
return value;
}
public static Object updateCreditBureauConfiguration(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer ConfigurationId, final String updateConfigKeyValue) {
LOG.info("---------------------------------UPDATING A CREDIT_BUREAU_CONFIGURATION---------------------------------------------");
final String CREDITBUREAU_CONFIGURATION_URL = " /fineract-provider/api/v1/CreditBureauConfiguration/configuration/"
+ ConfigurationId + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerPut(requestSpec, responseSpec, CREDITBUREAU_CONFIGURATION_URL,
updateCreditBureauConfigurationAsJson("updateConfigKeyValue", "description"), "changes");
}
public static String creditBureauConfigurationAsJson(final String configkey, final String value, final String description) {
final HashMap<String, String> map = new HashMap<>();
map.put("configkey", configkey);
map.put("value", value);
map.put("description", description);
LOG.info("map : {}", map);
return new Gson().toJson(map);
}
public static String updateCreditBureauConfigurationAsJson(final String value, final String description) {
final HashMap<String, String> map = new HashMap<>();
map.put("value", value);
map.put("description", description);
LOG.info("map : {}", map);
return new Gson().toJson(map);
}
}