You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by av...@apache.org on 2020/09/29 17:52:31 UTC
[fineract] branch develop updated: Interop KYC and Interop Loan
Disbursement (#1330)
This is an automated email from the ASF dual-hosted git repository.
avikg pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new e5f3e87 Interop KYC and Interop Loan Disbursement (#1330)
e5f3e87 is described below
commit e5f3e8720d3c48494072bf4671080c7396a5a588
Author: SubhamPramanik <su...@gmail.com>
AuthorDate: Tue Sep 29 23:22:18 2020 +0530
Interop KYC and Interop Loan Disbursement (#1330)
* Interop get account KYC
* loan interop disbursement
* checkstyle fix
Co-authored-by: Subham Pramanik <su...@google.com>
---
.../interoperation/api/InteropApiResource.java | 26 ++++
.../fineract/interoperation/data/IdDocument.java | 69 ++++++++++
.../interoperation/data/InteropKycData.java | 145 ++++++++++++++++++++
.../data/InteropKycResponseData.java | 147 +++++++++++++++++++++
.../interoperation/data/PostalAddress.java | 89 +++++++++++++
.../fineract/interoperation/data/SubjectName.java | 68 ++++++++++
.../interoperation/service/InteropService.java | 7 +
.../interoperation/service/InteropServiceImpl.java | 119 ++++++++++++++++-
8 files changed, 667 insertions(+), 3 deletions(-)
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java
index c74d7bc..ace4dbe 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java
@@ -58,6 +58,7 @@ import org.apache.fineract.interoperation.data.InteropAccountData;
import org.apache.fineract.interoperation.data.InteropIdentifierAccountResponseData;
import org.apache.fineract.interoperation.data.InteropIdentifierRequestData;
import org.apache.fineract.interoperation.data.InteropIdentifiersResponseData;
+import org.apache.fineract.interoperation.data.InteropKycResponseData;
import org.apache.fineract.interoperation.data.InteropQuoteRequestData;
import org.apache.fineract.interoperation.data.InteropQuoteResponseData;
import org.apache.fineract.interoperation.data.InteropTransactionRequestData;
@@ -389,4 +390,29 @@ public class InteropApiResource {
return jsonSerializer.serialize(settings, result);
}
+
+ @GET
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Path("accounts/{accountId}/kyc")
+ @Operation(summary = "Query KYC by Account Id", description = "")
+ @ApiResponses({
+ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = InteropKycResponseData.class))) })
+ public String getClientKyc(@PathParam("accountId") @Parameter(description = "accountId") String accountId, @Context UriInfo uriInfo) {
+ InteropKycResponseData result = interopService.getKyc(accountId);
+ ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+
+ return jsonSerializer.serialize(settings, result);
+ }
+
+ @POST
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Path("transactions/{accountId}/disburse")
+ @Operation(summary = "Disburse Loan by Account Id", description = "")
+ public String disburseLoan(@PathParam("accountId") @Parameter(description = "accountId") String accountId,
+ @Parameter(hidden = true) final String apiRequestBodyAsJson, @Context UriInfo uriInfo) {
+ return interopService.disburseLoan(accountId, apiRequestBodyAsJson);
+ }
+
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/IdDocument.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/IdDocument.java
new file mode 100644
index 0000000..5d70633
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/IdDocument.java
@@ -0,0 +1,69 @@
+/**
+ * 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.interoperation.data;
+
+import java.io.Serializable;
+
+public class IdDocument implements Serializable {
+
+ String idType;
+ String idNumber;
+ String issuerCountry;
+ String otherIdDescription;
+
+ public IdDocument(String idType, String idNumber, String issuerCountry, String otherIdDescription) {
+ this.idType = idType;
+ this.idNumber = idNumber;
+ this.issuerCountry = issuerCountry;
+ this.otherIdDescription = otherIdDescription;
+ }
+
+ public String getIdType() {
+ return idType;
+ }
+
+ public void setIdType(String idType) {
+ this.idType = idType;
+ }
+
+ public String getIdNumber() {
+ return idNumber;
+ }
+
+ public void setIdNumber(String idNumber) {
+ this.idNumber = idNumber;
+ }
+
+ public String getIssuerCountry() {
+ return issuerCountry;
+ }
+
+ public void setIssuerCountry(String issuerCountry) {
+ this.issuerCountry = issuerCountry;
+ }
+
+ public String getOtherIdDescription() {
+ return otherIdDescription;
+ }
+
+ public void setOtherIdDescription(String otherIdDescription) {
+ this.otherIdDescription = otherIdDescription;
+ }
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/InteropKycData.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/InteropKycData.java
new file mode 100644
index 0000000..a385f93
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/InteropKycData.java
@@ -0,0 +1,145 @@
+/**
+ * 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.interoperation.data;
+
+import java.io.Serializable;
+
+public class InteropKycData implements Serializable {
+
+ private String nationality;
+ private String dateOfBirth;
+ private String contactPhone;
+ private String gender;
+ private String email;
+ private String idType;
+ private String idNo;
+ private String description;
+ private String country;
+ private String addressLine1;
+ private String addressLine2;
+ private String city;
+ private String stateProvince;
+ private String postalCode;
+ private String firstName;
+ private String middleName;
+ private String lastName;
+ private String displayName;
+
+ public InteropKycData(String nationality, String dateOfBirth, String contactPhone, String gender, String email, String idType,
+ String idNo, String description, String country, String addressLine1, String addressLine2, String city, String stateProvince,
+ String postalCode, String firstName, String middleName, String lastName, String displayName) {
+ this.nationality = nationality;
+ this.dateOfBirth = dateOfBirth;
+ this.contactPhone = contactPhone;
+ this.gender = gender;
+ this.email = email;
+ this.idType = idType;
+ this.idNo = idNo;
+ this.description = description;
+ this.country = country;
+ this.addressLine1 = addressLine1;
+ this.addressLine2 = addressLine2;
+ this.city = city;
+ this.stateProvince = stateProvince;
+ this.postalCode = postalCode;
+ this.firstName = firstName;
+ this.middleName = middleName;
+ this.lastName = lastName;
+ this.displayName = displayName;
+ }
+
+ public static InteropKycData instance(String nationality, String dateOfBirth, String contactPhone, String gender, String email,
+ String idType, String idNo, String description, String country, String address_line_1, String address_line_2, String city,
+ String stateProvince, String postalCode, String firstName, String middleName, String lastName, String displayName) {
+ return new InteropKycData(nationality, dateOfBirth, contactPhone, gender, email, idType, idNo, description, country, address_line_1,
+ address_line_2, city, stateProvince, postalCode, firstName, middleName, lastName, displayName);
+ }
+
+ public String getNationality() {
+ return nationality;
+ }
+
+ public String getDateOfBirth() {
+ return dateOfBirth;
+ }
+
+ public String getContactPhone() {
+ return contactPhone;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public String getIdType() {
+ return idType;
+ }
+
+ public String getIdNo() {
+ return idNo;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public String getAddressLine1() {
+ return addressLine1;
+ }
+
+ public String getAddressLine2() {
+ return addressLine2;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public String getStateProvince() {
+ return stateProvince;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public String getMiddleName() {
+ return middleName;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/InteropKycResponseData.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/InteropKycResponseData.java
new file mode 100644
index 0000000..309af31
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/InteropKycResponseData.java
@@ -0,0 +1,147 @@
+/**
+ * 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.interoperation.data;
+
+import java.util.Map;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+
+public class InteropKycResponseData extends CommandProcessingResult {
+
+ private String nationality;
+ private String dateOfBirth;
+ private String contactPhone;
+ private String gender;
+
+ private IdDocument[] idDocument;
+
+ private PostalAddress postalAddress;
+
+ private SubjectName subjectName;
+
+ private String emailAddress;
+ private String birthCountry;
+
+ public InteropKycResponseData(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly, String nationality,
+ String dateOfBirth, String contactPhone, String gender, IdDocument[] idDocument, PostalAddress postalAddress,
+ SubjectName subjectName, String emailAddress, String birthCountry) {
+ super(resourceId, officeId, commandId, changesOnly);
+ this.nationality = nationality;
+ this.dateOfBirth = dateOfBirth;
+ this.contactPhone = contactPhone;
+ this.gender = gender;
+ this.idDocument = idDocument;
+ this.postalAddress = postalAddress;
+ this.subjectName = subjectName;
+ this.emailAddress = emailAddress;
+ this.birthCountry = birthCountry;
+ }
+
+ public InteropKycResponseData(String nationality, String dateOfBirth, String contactPhone, String gender, IdDocument[] idDocument,
+ PostalAddress postalAddress, SubjectName subjectName, String emailAddress, String birthCountry) {
+ this(null, null, null, null, nationality, dateOfBirth, contactPhone, gender, idDocument, postalAddress, subjectName, emailAddress,
+ birthCountry);
+ }
+
+ public static InteropKycResponseData build(InteropKycData accountKyc) {
+
+ PostalAddress postalAddress = new PostalAddress(accountKyc.getAddressLine1(), accountKyc.getAddressLine2(), accountKyc.getCity(),
+ accountKyc.getStateProvince(), accountKyc.getPostalCode(), accountKyc.getCountry());
+ IdDocument idDocument = new IdDocument(accountKyc.getIdType(), accountKyc.getIdNo(), accountKyc.getCountry(),
+ accountKyc.getDescription());
+ SubjectName subjectName = new SubjectName(accountKyc.getFirstName(), accountKyc.getMiddleName(), accountKyc.getLastName(),
+ accountKyc.getDisplayName());
+
+ return new InteropKycResponseData(accountKyc.getNationality(), accountKyc.getDateOfBirth(), accountKyc.getContactPhone(),
+ accountKyc.getGender(), new IdDocument[] { idDocument }, postalAddress, subjectName, accountKyc.getEmail(),
+ accountKyc.getCountry());
+ }
+
+ public String getNationality() {
+ return nationality;
+ }
+
+ public void setNationality(String nationality) {
+ this.nationality = nationality;
+ }
+
+ public String getDateOfBirth() {
+ return dateOfBirth;
+ }
+
+ public void setDateOfBirth(String dateOfBirth) {
+ this.dateOfBirth = dateOfBirth;
+ }
+
+ public String getContactPhone() {
+ return contactPhone;
+ }
+
+ public void setContactPhone(String contactPhone) {
+ this.contactPhone = contactPhone;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public IdDocument[] getIdDocument() {
+ return idDocument;
+ }
+
+ public void setIdDocument(IdDocument[] idDocument) {
+ this.idDocument = idDocument;
+ }
+
+ public PostalAddress getPostalAddress() {
+ return postalAddress;
+ }
+
+ public void setPostalAddress(PostalAddress postalAddress) {
+ this.postalAddress = postalAddress;
+ }
+
+ public SubjectName getSubjectName() {
+ return subjectName;
+ }
+
+ public void setSubjectName(SubjectName subjectName) {
+ this.subjectName = subjectName;
+ }
+
+ public String getEmailAddress() {
+ return emailAddress;
+ }
+
+ public void setEmailAddress(String emailAddress) {
+ this.emailAddress = emailAddress;
+ }
+
+ public String getBirthCountry() {
+ return birthCountry;
+ }
+
+ public void setBirthCountry(String birthCountry) {
+ this.birthCountry = birthCountry;
+ }
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/PostalAddress.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/PostalAddress.java
new file mode 100644
index 0000000..0c8f990
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/PostalAddress.java
@@ -0,0 +1,89 @@
+/**
+ * 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.interoperation.data;
+
+import java.io.Serializable;
+
+public class PostalAddress implements Serializable {
+
+ String addressLine1;
+ String addressLine2;
+ String city;
+ String stateProvince;
+ String postalCode;
+ String country;
+
+ public PostalAddress(String addressLine1, String addressLine2, String city, String stateProvince, String postalCode, String country) {
+ this.addressLine1 = addressLine1;
+ this.addressLine2 = addressLine2;
+ this.city = city;
+ this.stateProvince = stateProvince;
+ this.postalCode = postalCode;
+ this.country = country;
+ }
+
+ public String getAddressLine1() {
+ return addressLine1;
+ }
+
+ public void setAddressLine1(String addressLine1) {
+ this.addressLine1 = addressLine1;
+ }
+
+ public String getAddressLine2() {
+ return addressLine2;
+ }
+
+ public void setAddressLine2(String addressLine2) {
+ this.addressLine2 = addressLine2;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getStateProvince() {
+ return stateProvince;
+ }
+
+ public void setStateProvince(String stateProvince) {
+ this.stateProvince = stateProvince;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/SubjectName.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/SubjectName.java
new file mode 100644
index 0000000..3c67caa
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/data/SubjectName.java
@@ -0,0 +1,68 @@
+/**
+ * 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.interoperation.data;
+
+import java.io.Serializable;
+
+public class SubjectName implements Serializable {
+
+ String firstName;
+ String middleName;
+ String lastName;
+ String displayName;
+
+ public SubjectName(String firstName, String middleName, String lastName, String displayName) {
+ this.firstName = firstName;
+ this.middleName = middleName;
+ this.lastName = lastName;
+ this.displayName = displayName;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getMiddleName() {
+ return middleName;
+ }
+
+ public void setMiddleName(String middleName) {
+ this.middleName = middleName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java
index 5746673..170b419 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java
@@ -24,6 +24,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.interoperation.data.InteropAccountData;
import org.apache.fineract.interoperation.data.InteropIdentifierAccountResponseData;
import org.apache.fineract.interoperation.data.InteropIdentifiersResponseData;
+import org.apache.fineract.interoperation.data.InteropKycResponseData;
import org.apache.fineract.interoperation.data.InteropQuoteResponseData;
import org.apache.fineract.interoperation.data.InteropTransactionRequestResponseData;
import org.apache.fineract.interoperation.data.InteropTransactionsData;
@@ -74,4 +75,10 @@ public interface InteropService {
@NotNull
InteropTransferResponseData releaseTransfer(@NotNull JsonCommand command);
+
+ @NotNull
+ InteropKycResponseData getKyc(@NotNull String accountId);
+
+ @NotNull
+ String disburseLoan(@NotNull String accountId, String apiRequestBodyAsJson);
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
index 789c6fd..4fb0fff 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
@@ -28,20 +28,30 @@ import static org.apache.fineract.portfolio.savings.domain.SavingsAccountTransac
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.function.Predicate;
import org.apache.commons.lang3.StringUtils;
+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.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.interoperation.data.InteropAccountData;
import org.apache.fineract.interoperation.data.InteropIdentifierAccountResponseData;
import org.apache.fineract.interoperation.data.InteropIdentifierRequestData;
import org.apache.fineract.interoperation.data.InteropIdentifiersResponseData;
+import org.apache.fineract.interoperation.data.InteropKycData;
+import org.apache.fineract.interoperation.data.InteropKycResponseData;
import org.apache.fineract.interoperation.data.InteropQuoteRequestData;
import org.apache.fineract.interoperation.data.InteropQuoteResponseData;
import org.apache.fineract.interoperation.data.InteropRequestData;
@@ -61,6 +71,9 @@ import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepository;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.apache.fineract.portfolio.note.domain.Note;
import org.apache.fineract.portfolio.note.domain.NoteRepository;
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
@@ -84,6 +97,9 @@ import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -102,19 +118,28 @@ public class InteropServiceImpl implements InteropService {
private final NoteRepository noteRepository;
private final PaymentTypeRepository paymentTypeRepository;
private final InteropIdentifierRepository identifierRepository;
+ private final LoanRepository loanRepository;
private final SavingsHelper savingsHelper;
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
private final SavingsAccountDomainService savingsAccountService;
+ private final JdbcTemplate jdbcTemplate;
+
+ private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+
+ private final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer;
+
@Autowired
public InteropServiceImpl(PlatformSecurityContext securityContext, InteropDataValidator interopDataValidator,
SavingsAccountRepository savingsAccountRepository, SavingsAccountTransactionRepository savingsAccountTransactionRepository,
ApplicationCurrencyRepository applicationCurrencyRepository, NoteRepository noteRepository,
- PaymentTypeRepository paymentTypeRepository, InteropIdentifierRepository identifierRepository, SavingsHelper savingsHelper,
- SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
- SavingsAccountDomainService savingsAccountService) {
+ PaymentTypeRepository paymentTypeRepository, InteropIdentifierRepository identifierRepository, LoanRepository loanRepository,
+ SavingsHelper savingsHelper, SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
+ SavingsAccountDomainService savingsAccountService, final RoutingDataSource dataSource,
+ final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+ final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer) {
this.securityContext = securityContext;
this.dataValidator = interopDataValidator;
this.savingsAccountRepository = savingsAccountRepository;
@@ -123,9 +148,56 @@ public class InteropServiceImpl implements InteropService {
this.noteRepository = noteRepository;
this.paymentTypeRepository = paymentTypeRepository;
this.identifierRepository = identifierRepository;
+ this.loanRepository = loanRepository;
this.savingsHelper = savingsHelper;
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
this.savingsAccountService = savingsAccountService;
+ this.jdbcTemplate = new JdbcTemplate(dataSource);
+ this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+ this.toApiJsonSerializer = toApiJsonSerializer;
+ }
+
+ private static final class KycMapper implements RowMapper<InteropKycData> {
+
+ public String schema() {
+ return " country.code_value as nationality, c.`date_of_birth` as dateOfBirth, c.`mobile_no` as contactPhone, gender.code_value as gender, c.`email_address` as email, "
+ + "kyc.code_value as idType, ci.`document_key` as idNo, ci.`description` as description, "
+ + "country.code_value as country, a.`address_line_1`, a.`address_line_2`, "
+ + "a.`city`, state.code_value as stateProvince, a.`postal_code` as postalCode, c.`firstname` as firstName, c.`middlename` as middleName,"
+ + "c.`lastname` as lastName, c.`display_name` as displayName" + " from " + "m_client c "
+ + "left join m_client_address ca on c.id=ca.client_id " + "left join m_address a on a.id = ca.address_id "
+ + "inner join m_code_value gender on gender.id=c.`gender_cv_id` "
+ + "left join m_code_value country on country.id=a.`country_id` "
+ + "left join m_code_value state on state.id = a.`state_province_id` "
+ + "left join m_client_identifier ci on c.id=ci.`client_id` "
+ + "left join m_code_value kyc on kyc.id = ci.`document_type_id` ";
+ }
+
+ @Override
+ public InteropKycData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
+
+ final String nationality = rs.getString("nationality");
+ final String dateOfBirth = rs.getString("dateOfBirth");
+ final String contactPhone = rs.getString("contactPhone");
+ final String gender = rs.getString("gender");
+ final String email = rs.getString("email");
+ final String idType = rs.getString("idType");
+ final String idNo = rs.getString("idNo");
+ final String description = rs.getString("description");
+ final String country = rs.getString("country");
+ final String addressLine1 = rs.getString("address_line_1");
+ final String addressLine2 = rs.getString("address_line_2");
+ final String city = rs.getString("city");
+ final String stateProvince = rs.getString("stateProvince");
+ final String postalCode = rs.getString("postalCode");
+ final String firstName = rs.getString("firstName");
+ final String middleName = rs.getString("middleName");
+ final String lastName = rs.getString("lastName");
+ final String displayName = rs.getString("displayName");
+
+ return InteropKycData.instance(nationality, dateOfBirth, contactPhone, gender, email, idType, idNo, description, country,
+ addressLine1, addressLine2, city, stateProvince, postalCode, firstName, middleName, lastName, displayName);
+ }
}
@NotNull
@@ -409,6 +481,39 @@ public class InteropServiceImpl implements InteropService {
request.getExpiration(), request.getExtensionList(), request.getTransferCode(), transactionDateTime);
}
+ @Override
+ public @NotNull InteropKycResponseData getKyc(@NotNull @NotNull String accountId) {
+
+ SavingsAccount savingsAccount = validateAndGetSavingAccount(accountId);
+ Long client_id = savingsAccount.getClient().getId();
+
+ try {
+ final InteropServiceImpl.KycMapper rm = new InteropServiceImpl.KycMapper();
+ final String sql = "select " + rm.schema() + " where c.id = ?";
+
+ final InteropKycData accountKyc = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { client_id });
+
+ return InteropKycResponseData.build(accountKyc);
+ } catch (final EmptyResultDataAccessException e) {
+ throw new UnsupportedOperationException("Error in retrieving KYC information: " + e);
+ }
+ }
+
+ @Override
+ public @NotNull String disburseLoan(@NotNull String accountId, String apiRequestBodyAsJson) {
+ Loan loan = validateAndGetLoan(accountId);
+ Long loanId = loan.getId();
+
+ LocalDateTime disbursedOnDate = DateUtils.getLocalDateTimeOfTenant();
+
+ final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
+
+ final CommandWrapper commandRequest = builder.disburseLoanApplication(loanId).build();
+ CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+ return this.toApiJsonSerializer.serialize(result);
+ }
+
private SavingsAccount validateAndGetSavingAccount(String accountId) {
SavingsAccount savingsAccount = savingsAccountRepository.findByExternalId(accountId);
if (savingsAccount == null) {
@@ -417,6 +522,14 @@ public class InteropServiceImpl implements InteropService {
return savingsAccount;
}
+ private Loan validateAndGetLoan(String accountId) {
+ Loan loan = loanRepository.findNonClosedLoanByAccountNumber(accountId);
+ if (loan == null) {
+ throw new UnsupportedOperationException("Loan not found for the given account No: " + accountId);
+ }
+ return loan;
+ }
+
private SavingsAccount validateAndGetSavingAccount(@NotNull InteropRequestData request) {
// TODO: error handling
SavingsAccount savingsAccount = validateAndGetSavingAccount(request.getAccountId());