GLIM_GSIM enhancement (FINERACT-603)

This commit is contained in:
rrpawar96
2020-05-05 12:43:40 +02:00
committed by Michael Vorburger ⛑️
parent edfcb931e9
commit 489faf96b0
95 changed files with 5067 additions and 227 deletions
@@ -68,6 +68,7 @@ public class ClientSavingsIntegrationTest {
public static final String WITHDRAW_AMOUNT_ADJUSTED = "500"; public static final String WITHDRAW_AMOUNT_ADJUSTED = "500";
public static final String MINIMUM_OPENING_BALANCE = "1000.0"; public static final String MINIMUM_OPENING_BALANCE = "1000.0";
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL"; public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public static final String DATE_FORMAT = "dd MMMM yyyy";
private ResponseSpecification responseSpec; private ResponseSpecification responseSpec;
private RequestSpecification requestSpec; private RequestSpecification requestSpec;
@@ -2294,4 +2295,5 @@ public class ClientSavingsIntegrationTest {
assertEquals("Verifying opening Balance is -300", balance, summary.get("accountBalance")); assertEquals("Verifying opening Balance is -300", balance, summary.get("accountBalance"));
} }
} }
@@ -28,14 +28,21 @@ import io.restassured.specification.ResponseSpecification;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.GroupHelper; import org.apache.fineract.integrationtests.common.GroupHelper;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder; import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper; import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Group Loan Integration Test for checking Loan Application Repayment Schedule. * Group Loan Integration Test for checking Loan Application Repayment Schedule.
@@ -46,6 +53,7 @@ public class GroupLoanIntegrationTest {
private ResponseSpecification responseSpec; private ResponseSpecification responseSpec;
private RequestSpecification requestSpec; private RequestSpecification requestSpec;
private LoanTransactionHelper loanTransactionHelper; private LoanTransactionHelper loanTransactionHelper;
private final static Logger LOG = LoggerFactory.getLogger(GroupLoanIntegrationTest.class);
@Before @Before
public void setup() { public void setup() {
@@ -66,13 +74,121 @@ public class GroupLoanIntegrationTest {
final Integer loanProductID = createLoanProduct(); final Integer loanProductID = createLoanProduct();
final Integer loanID = applyForLoanApplication(groupID, loanProductID); final Integer loanID = applyForLoanApplication(groupID, loanProductID);
final ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, final ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec,
loanID); loanID);
verifyLoanRepaymentSchedule(loanSchedule); verifyLoanRepaymentSchedule(loanSchedule);
}
@Test
public void checkGlimAccountCommands() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
final Integer loanProductID = createLoanProduct();
HashMap<String,Integer> glim = applyForGlimApplication(clientID, groupID, loanProductID);
LOG.info("Glim Loan Application: {} ", glim);
final Integer glimId=glim.get("glimId");
LOG.info("GlimId : {} ", glimId);
final Integer loanId=glim.get("loanId");
LOG.info("LoanId : {} ", loanId);
List<Map<String, Object>> approvalFormData = new ArrayList<>();
approvalFormData.add(approvalFormData(loanId,"22 September 2011"));
HashMap loanStatusHashMap = this.loanTransactionHelper.approveGlimAccount(this.requestSpec, this.responseSpec,
approvalFormData, glimId);
LOG.info("glim approval loanSchedule: {} ", loanStatusHashMap);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.disburseGlimAccount("25 September 2011", glimId);
LOG.info("glim disbursement loanSchedule: {} ", loanStatusHashMap);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.undoDisburseGlimAccount(glimId);
LOG.info("glim undodisbursement loanSchedule: {} ", loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.undoApprovalGlimAccount(glimId);
LOG.info("glim undoApproval loanSchedule: {} ", loanStatusHashMap);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.rejectGlimAccount("22 September 2011",glimId);
LOG.info("glim reject loanSchedule: {} ", loanStatusHashMap);
LoanStatusChecker.verifyLoanAccountRejected(loanStatusHashMap);
}
@Test
public void getGlimAccountByGroupId() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
Assert.assertNotNull(groupID);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
Assert.assertNotNull(groupID);
final Integer loanProductID = createLoanProduct();
Assert.assertNotNull(loanProductID);
HashMap<String,Integer> glim = applyForGlimApplication(clientID, groupID, loanProductID);
LOG.info("Glim Loan Application: {} ", glim);
final Integer glimId=glim.get("glimId");
LOG.info("GlimId: {} ", glimId);
final Integer loanId=glim.get("loanId");
LOG.info("LoanId: {} ", loanId);
final List<String> retrievedGlimId=GroupHelper.verifyRetrieveGlimAccountsByGroupId(this.requestSpec, this.responseSpec, groupID);
Assert.assertNotNull(retrievedGlimId.toString());
}
@Test
public void getGlimAccountByGlimId() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
Assert.assertNotNull(groupID);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
Assert.assertNotNull(groupID);
final Integer loanProductID = createLoanProduct();
Assert.assertNotNull(loanProductID);
HashMap<String,Integer> glim = applyForGlimApplication(clientID, groupID, loanProductID);
LOG.info("Glim Loan Application: {} ", glim);
final Integer glimId=glim.get("glimId");
LOG.info("GlimId: {} ", glimId);
final Integer loanId=glim.get("loanId");
LOG.info("LoanId: {} ", loanId);
final List<String> retrievedGlimAccountId=GroupHelper.verifyRetrieveGlimAccountsByGlimId(this.requestSpec, this.responseSpec, glimId);
Assert.assertNotNull(retrievedGlimAccountId);
}
private Map<String, Object> approvalFormData(final Integer loanId, final String approvedOnDate) {
Map<String, Object> map = new HashMap<>();
map.put("loanId", loanId);
map.put("approvedOnDate", approvedOnDate);
map.put("dateFormat", CommonConstants.dateFormat);
map.put("locale", "en");
return map;
} }
private Integer createLoanProduct() { private Integer createLoanProduct() {
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------"); LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
final String loanProductJSON = new LoanProductTestBuilder() // final String loanProductJSON = new LoanProductTestBuilder() //
.withPrincipal("12,000.00") // .withPrincipal("12,000.00") //
.withNumberOfRepayments("4") // .withNumberOfRepayments("4") //
@@ -87,7 +203,7 @@ public class GroupLoanIntegrationTest {
} }
private Integer applyForLoanApplication(final Integer groupID, final Integer loanProductID) { private Integer applyForLoanApplication(final Integer groupID, final Integer loanProductID) {
System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final String loanApplicationJSON = new LoanApplicationTestBuilder() // final String loanApplicationJSON = new LoanApplicationTestBuilder() //
.withPrincipal("12,000.00") // .withPrincipal("12,000.00") //
.withLoanTermFrequency("4") // .withLoanTermFrequency("4") //
@@ -102,12 +218,34 @@ public class GroupLoanIntegrationTest {
.withExpectedDisbursementDate("20 September 2011") // .withExpectedDisbursementDate("20 September 2011") //
.withSubmittedOnDate("20 September 2011") // .withSubmittedOnDate("20 September 2011") //
.withLoanType("group").build(groupID.toString(), loanProductID.toString(), null); .withLoanType("group").build(groupID.toString(), loanProductID.toString(), null);
System.out.println(loanApplicationJSON); LOG.info(loanApplicationJSON);
return this.loanTransactionHelper.getLoanId(loanApplicationJSON); return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
} }
private HashMap<String,Integer> applyForGlimApplication(final Integer clientID, final Integer groupID, final Integer loanProductID) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final String GlimApplicationJSON = new LoanApplicationTestBuilder() //
.withPrincipal("12,000.00") //
.withLoanTermFrequency("4") //
.withLoanTermFrequencyAsMonths() //
.withNumberOfRepayments("4") //
.withRepaymentEveryAfter("1") //
.withRepaymentFrequencyTypeAsMonths() //
.withInterestRatePerPeriod("2") //
.withAmortizationTypeAsEqualInstallments() //
.withInterestTypeAsDecliningBalance() //
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
.withExpectedDisbursementDate("20 September 2011") //
.withSubmittedOnDate("20 September 2011")
.withLoanType("glim")
.withtotalLoan("10000")
.withParentAccount("1").build(clientID.toString(), groupID.toString(), loanProductID.toString(), null);
LOG.info(GlimApplicationJSON);
return this.loanTransactionHelper.getGlimId(GlimApplicationJSON);
}
private void verifyLoanRepaymentSchedule(final ArrayList<HashMap> loanSchedule) { private void verifyLoanRepaymentSchedule(final ArrayList<HashMap> loanSchedule) {
System.out.println("--------------------VERIFYING THE PRINCIPAL DUES,INTEREST DUE AND DUE DATE--------------------------"); LOG.info("--------------------VERIFYING THE PRINCIPAL DUES,INTEREST DUE AND DUE DATE--------------------------");
assertEquals("Checking for Due Date for 1st Month", new ArrayList<>(Arrays.asList(2011, 10, 20)), assertEquals("Checking for Due Date for 1st Month", new ArrayList<>(Arrays.asList(2011, 10, 20)),
loanSchedule.get(1).get("dueDate")); loanSchedule.get(1).get("dueDate"));
@@ -33,9 +33,11 @@ import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants; import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.GroupHelper; import org.apache.fineract.integrationtests.common.GroupHelper;
import org.apache.fineract.integrationtests.common.PaymentTypeHelper;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.charges.ChargesHelper; import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper; import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
@@ -45,6 +47,8 @@ import org.joda.time.LocalDate;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Group Savings Integration Test for checking Savings Application. * Group Savings Integration Test for checking Savings Application.
@@ -61,6 +65,7 @@ public class GroupSavingsIntegrationTest {
private ResponseSpecification responseSpec; private ResponseSpecification responseSpec;
private RequestSpecification requestSpec; private RequestSpecification requestSpec;
private SavingsAccountHelper savingsAccountHelper; private SavingsAccountHelper savingsAccountHelper;
private final static Logger LOG = LoggerFactory.getLogger(GroupSavingsIntegrationTest.class);
@Before @Before
public void setup() { public void setup() {
@@ -115,6 +120,7 @@ public class GroupSavingsIntegrationTest {
Assert.assertFalse(summaryBefore.equals(summary)); Assert.assertFalse(summaryBefore.equals(summary));
final Object savingsInterest = this.savingsAccountHelper.getSavingsInterest(savingsId); final Object savingsInterest = this.savingsAccountHelper.getSavingsInterest(savingsId);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -164,6 +170,7 @@ public class GroupSavingsIntegrationTest {
withdrawBalance = "true"; withdrawBalance = "true";
savingsStatusHashMap = this.savingsAccountHelper.closeSavingsAccount(savingsId, withdrawBalance); savingsStatusHashMap = this.savingsAccountHelper.closeSavingsAccount(savingsId, withdrawBalance);
SavingsStatusChecker.verifySavingsAccountIsClosed(savingsStatusHashMap); SavingsStatusChecker.verifySavingsAccountIsClosed(savingsStatusHashMap);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -214,6 +221,226 @@ public class GroupSavingsIntegrationTest {
} }
//gsimcommands testing
@SuppressWarnings("unchecked")
@Test
public void testGsimSavingsAccount_REJECT_APPLICATION() {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
SavingsAccountHelper savingsAccountHelperValidationError = new SavingsAccountHelper(this.requestSpec,
new ResponseSpecBuilder().build());
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
Assert.assertNotNull(groupID);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
Assert.assertNotNull(groupID);
final String minBalanceForInterestCalculation = null;
final String minRequiredBalance = null;
final String enforceMinRequiredBalance = "false";
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance);
Assert.assertNotNull(savingsProductID);
List<Map<String, Object>> clientArray = new ArrayList<>();
clientArray.add(clientArray(clientID, groupID, savingsProductID,"08 January 2013"));
final Integer gsimID = this.savingsAccountHelper.applyForGsimApplication(clientArray);
HashMap savingsStatusHashMap = this.savingsAccountHelper.approveGsimSavings(gsimID);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
List<HashMap> error1 = savingsAccountHelperValidationError.rejectGsimApplicationWithErrorCode(gsimID,
SavingsAccountHelper.CREATED_DATE_PLUS_ONE);
assertEquals("validation.msg.savingsaccount.reject.not.in.submittedandpendingapproval.state",
error1.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
savingsStatusHashMap = this.savingsAccountHelper.undoApprovalGsimSavings(gsimID);
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
error1 = savingsAccountHelperValidationError.rejectGsimApplicationWithErrorCode(gsimID, SavingsAccountHelper.getFutureDate());
assertEquals("validation.msg.savingsaccount.reject.cannot.be.a.future.date",
error1.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
error1 = savingsAccountHelperValidationError.rejectGsimApplicationWithErrorCode(gsimID, SavingsAccountHelper.CREATED_DATE_MINUS_ONE);
assertEquals("validation.msg.savingsaccount.reject.cannot.be.before.submittal.date",
error1.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
savingsStatusHashMap = this.savingsAccountHelper.rejectGsimApplication(gsimID);
SavingsStatusChecker.verifySavingsIsRejected(savingsStatusHashMap);
}
@Test
public void testGsimSavingsAccount_DEPOSIT_APPLICATION() {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
Assert.assertNotNull(groupID);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
Assert.assertNotNull(groupID);
final String minBalanceForInterestCalculation = null;
final String minRequiredBalance = null;
final String enforceMinRequiredBalance = "false";
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance);
Assert.assertNotNull(savingsProductID);
List<Map<String, Object>> clientArray = new ArrayList<>();
clientArray.add(clientArray(clientID, groupID, savingsProductID,"08 January 2013"));
LOG.info("client Array : {} ", clientArray);
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(groupID, savingsProductID, ACCOUNT_TYPE_GROUP);
Assert.assertNotNull(savingsId);
String name = PaymentTypeHelper.randomNameGenerator("P_T", 5);
String description = PaymentTypeHelper.randomNameGenerator("PT_Desc", 15);
Boolean isCashPayment = true;
Integer position = 1;
Integer paymentTypeId = PaymentTypeHelper.createPaymentType(requestSpec, responseSpec, name, description, isCashPayment, position);
Assert.assertNotNull(paymentTypeId);
List<Map<String, Object>> savingsArray = new ArrayList<>();
final Integer transactionAmount=2500;
savingsArray.add(savingsArray(paymentTypeId, savingsId, transactionAmount, "10 March 2013"));
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId);
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
savingsStatusHashMap = this.savingsAccountHelper.approveSavings(savingsId);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
final Integer depositId = this.savingsAccountHelper.depositGsimApplication(savingsId, savingsArray);
Assert.assertNotNull(depositId);
}
@SuppressWarnings("unchecked")
@Test
public void testGsimSavingsAccount_CLOSE_APPLICATION() {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(400).build();
final SavingsAccountHelper validationErrorHelper = new SavingsAccountHelper(this.requestSpec, errorResponse);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
Assert.assertNotNull(groupID);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
Assert.assertNotNull(groupID);
final String minBalanceForInterestCalculation = null;
final String minRequiredBalance = "1000.0";
final String enforceMinRequiredBalance = "true";
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance);
Assert.assertNotNull(savingsProductID);
List<Map<String, Object>> clientArray = new ArrayList<>();
clientArray.add(clientArray(clientID, groupID, savingsProductID,"08 January 2013"));
final Integer gsimID = this.savingsAccountHelper.applyForGsimApplication(clientArray);
HashMap savingsStatusHashMap = this.savingsAccountHelper.approveGsimSavings(gsimID);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = this.savingsAccountHelper.activateGsimSavings(gsimID);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
final String CLOSEDON_DATE = dateFormat.format(todaysDate.getTime());
String withdrawBalance = "false";
ArrayList<HashMap> savingsAccountErrorData = (ArrayList<HashMap>) validationErrorHelper.closeGsimSavingsAccountAndGetBackRequiredField(gsimID, withdrawBalance, CommonConstants.RESPONSE_ERROR, CLOSEDON_DATE);
assertEquals("validation.msg.savingsaccount.close.results.in.balance.not.zero",
savingsAccountErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
withdrawBalance = "true";
savingsStatusHashMap = this.savingsAccountHelper.closeGsimSavingsAccount(gsimID, withdrawBalance);
SavingsStatusChecker.verifySavingsAccountIsClosed(savingsStatusHashMap);
}
@SuppressWarnings("unchecked")
@Test
public void testGsimSavingsAccount_UPDATE_APPLICATION() {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(400).build();
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
Assert.assertNotNull(groupID);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
Assert.assertNotNull(groupID);
final String minBalanceForInterestCalculation = null;
final String minRequiredBalance = "1000.0";
final String enforceMinRequiredBalance = "true";
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance);
Assert.assertNotNull(savingsProductID);
List<Map<String, Object>> clientArray = new ArrayList<>();
clientArray.add(clientArray(clientID, groupID, savingsProductID,"08 January 2013"));
final Integer gsimID = this.savingsAccountHelper.applyForGsimApplication(clientArray);
HashMap savingsStatusHashMap = this.savingsAccountHelper.updateGsimApplication(gsimID, clientID, groupID, savingsProductID);
LOG.info("savingsStatusHashMap: {} ",savingsStatusHashMap);
Assert.assertTrue(savingsStatusHashMap.containsKey("savingsId"));
}
@Test
public void getGsimAccount() {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(400).build();
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
Assert.assertNotNull(clientID);
Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true);
Assert.assertNotNull(groupID);
groupID = GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientID.toString());
Assert.assertNotNull(groupID);
final String minBalanceForInterestCalculation = null;
final String minRequiredBalance = "1000.0";
final String enforceMinRequiredBalance = "true";
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE,
minBalanceForInterestCalculation, minRequiredBalance, enforceMinRequiredBalance);
Assert.assertNotNull(savingsProductID);
List<Map<String, Object>> clientArray = new ArrayList<>();
clientArray.add(clientArray(clientID, groupID, savingsProductID,"08 January 2013"));
final Integer gsimID = this.savingsAccountHelper.applyForGsimApplication(clientArray);
final List<String> retrievedGsimId=GroupHelper.verifyRetrieveGsimAccounts(this.requestSpec, this.responseSpec, groupID);
Assert.assertNotNull(retrievedGsimId.toString());
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void testSavingsAccount_REJECT_APPLICATION() { public void testSavingsAccount_REJECT_APPLICATION() {
@@ -266,6 +493,7 @@ public class GroupSavingsIntegrationTest {
savingsStatusHashMap = this.savingsAccountHelper.rejectApplication(savingsId); savingsStatusHashMap = this.savingsAccountHelper.rejectApplication(savingsId);
SavingsStatusChecker.verifySavingsIsRejected(savingsStatusHashMap); SavingsStatusChecker.verifySavingsIsRejected(savingsStatusHashMap);
} }
@Test @Test
@@ -536,7 +764,7 @@ public class GroupSavingsIntegrationTest {
public static Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String minOpenningBalance, final String minBalanceForInterestCalculation, final String minRequiredBalance, final String minOpenningBalance, final String minBalanceForInterestCalculation, final String minRequiredBalance,
final String enforceMinRequiredBalance) { final String enforceMinRequiredBalance) {
System.out.println("------------------------------CREATING NEW SAVINGS PRODUCT ---------------------------------------"); LOG.info("------------------------------CREATING NEW SAVINGS PRODUCT ---------------------------------------");
SavingsProductHelper savingsProductHelper = new SavingsProductHelper(); SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
final String savingsProductJSON = savingsProductHelper // final String savingsProductJSON = savingsProductHelper //
.withInterestCompoundingPeriodTypeAsDaily() // .withInterestCompoundingPeriodTypeAsDaily() //
@@ -548,4 +776,29 @@ public class GroupSavingsIntegrationTest {
.withMinimumOpenningBalance(minOpenningBalance).build(); .withMinimumOpenningBalance(minOpenningBalance).build();
return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec); return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
} }
private Map<String, Object> clientArray(final Integer clientId, final Integer groupId, final Integer productId, final String submittedOnDate) {
Map<String, Object> map = new HashMap<>();
map.put("clientId", clientId);
map.put("groupId", groupId);
map.put("productId", productId);
map.put("submittedOnDate", submittedOnDate);
map.put("dateFormat", CommonConstants.dateFormat);
map.put("locale", "en");
map.put("isParentAccount", "1");
map.put("isGSIM", "true");
return map;
}
private Map<String, Object> savingsArray(final Integer paymentId, final Integer savingsId, final Integer transactionAmount, final String transactionDate) {
Map<String, Object> map = new HashMap<>();
map.put("transactionDate", transactionDate);
map.put("dateFormat", CommonConstants.dateFormat);
map.put("locale", "en");
map.put("transactionAmount",transactionAmount);
map.put("paymentTypeId", paymentId);
map.put("childAccountId", savingsId);
return map;
}
} }
@@ -29,11 +29,14 @@ import io.restassured.specification.ResponseSpecification;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GroupHelper { public class GroupHelper {
private final RequestSpecification requestSpec; private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec; private final ResponseSpecification responseSpec;
private final static Logger LOG = LoggerFactory.getLogger(GroupHelper.class);
private static final String CREATE_GROUP_URL = "/fineract-provider/api/v1/groups?" + Utils.TENANT_IDENTIFIER; private static final String CREATE_GROUP_URL = "/fineract-provider/api/v1/groups?" + Utils.TENANT_IDENTIFIER;
public static final String DATE_FORMAT = "dd MMMM yyyy"; public static final String DATE_FORMAT = "dd MMMM yyyy";
@@ -46,30 +49,30 @@ public class GroupHelper {
public static Integer createGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static Integer createGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
@SuppressWarnings("unused") final boolean active) { @SuppressWarnings("unused") final boolean active) {
System.out.println("---------------------------------CREATING A GROUP---------------------------------------------"); LOG.info("---------------------------------CREATING A GROUP---------------------------------------------");
return createGroup(requestSpec, responseSpec, "04 March 2011"); return createGroup(requestSpec, responseSpec, "04 March 2011");
} }
public static Integer createGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static Integer createGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String activationDate) { final String activationDate) {
System.out.println("---------------------------------CREATING A GROUP---------------------------------------------"); LOG.info("---------------------------------CREATING A GROUP---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(true, activationDate), "groupId"); return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(true, activationDate), "groupId");
} }
public static Integer createGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { public static Integer createGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
System.out.println("---------------------------------CREATING A GROUP---------------------------------------------"); LOG.info("---------------------------------CREATING A GROUP---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(false, ""), "groupId"); return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(false, ""), "groupId");
} }
public Object createGroupWithError(final String jsonAttributeToGetBack) { public Object createGroupWithError(final String jsonAttributeToGetBack) {
System.out.println("---------------------------------CREATING A GROUP WITH ERROR---------------------------------------------"); LOG.info("---------------------------------CREATING A GROUP WITH ERROR---------------------------------------------");
return Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(false, ""), return Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(false, ""),
jsonAttributeToGetBack); jsonAttributeToGetBack);
} }
public static Integer createGroupPendingWithDatatable(final RequestSpecification requestSpec, public static Integer createGroupPendingWithDatatable(final RequestSpecification requestSpec,
final ResponseSpecification responseSpec, final String registeredTableName) { final ResponseSpecification responseSpec, final String registeredTableName) {
System.out.println("-------------------------- CREATING A GROUP WITH DATATABLES --------------------------------"); LOG.info("-------------------------- CREATING A GROUP WITH DATATABLES --------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL, return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL,
getTestGroupWithDatatableAsJson(registeredTableName), "groupId"); getTestGroupWithDatatableAsJson(registeredTableName), "groupId");
} }
@@ -78,7 +81,7 @@ public class GroupHelper {
final String groupId, final String clientMember) { final String groupId, final String clientMember) {
final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId
+ "?command=associateClients&" + Utils.TENANT_IDENTIFIER; + "?command=associateClients&" + Utils.TENANT_IDENTIFIER;
System.out.println("---------------------------------Associate Client To A GROUP---------------------------------------------"); LOG.info("---------------------------------Associate Client To A GROUP---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, associateClientAsJSON(clientMember), "groupId"); return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, associateClientAsJSON(clientMember), "groupId");
} }
@@ -86,39 +89,38 @@ public class GroupHelper {
final String groupId, final String clientMember) { final String groupId, final String clientMember) {
final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId
+ "?command=disassociateClients&" + Utils.TENANT_IDENTIFIER; + "?command=disassociateClients&" + Utils.TENANT_IDENTIFIER;
System.out.println("---------------------------------Disassociate Client To A GROUP---------------------------------------------"); LOG.info("---------------------------------Disassociate Client To A GROUP---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, associateClientAsJSON(clientMember), "groupId"); return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, associateClientAsJSON(clientMember), "groupId");
} }
public static Integer activateGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static Integer activateGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String groupId) { final String groupId) {
final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId + "?command=activate&" + Utils.TENANT_IDENTIFIER; final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId + "?command=activate&" + Utils.TENANT_IDENTIFIER;
System.out.println("---------------------------------Activate A GROUP---------------------------------------------"); LOG.info("---------------------------------Activate A GROUP---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, activateGroupAsJSON(""), "groupId"); return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, activateGroupAsJSON(""), "groupId");
} }
public static Integer updateGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String name, public static Integer updateGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String name,
final String groupId) { final String groupId) {
final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER; final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER;
System.out.println("---------------------------------UPDATE GROUP---------------------------------------------"); LOG.info("---------------------------------UPDATE GROUP---------------------------------------------");
return Utils.performServerPut(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, updateGroupAsJSON(name), "groupId"); return Utils.performServerPut(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, updateGroupAsJSON(name), "groupId");
} }
public static Integer deleteGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String groupId) { public static Integer deleteGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String groupId) {
final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER; final String GROUP_ASSOCIATE_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER;
System.out.println("---------------------------------DELETE GROUP---------------------------------------------"); LOG.info("---------------------------------DELETE GROUP---------------------------------------------");
return Utils.performServerDelete(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, "groupId"); return Utils.performServerDelete(requestSpec, responseSpec, GROUP_ASSOCIATE_URL, "groupId");
} }
public static Object assignStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String groupId,final Long staffId){ public static Object assignStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String groupId,final Long staffId){
final String GROUP_ASSIGN_STAFF_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER + "&command=assignStaff"; final String GROUP_ASSIGN_STAFF_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER + "&command=assignStaff";
System.out.println("---------------------------------DELETE GROUP---------------------------------------------"); LOG.info("---------------------------------DELETE GROUP---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSIGN_STAFF_URL,assignStaffAsJSON(staffId),"changes"); return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSIGN_STAFF_URL,assignStaffAsJSON(staffId),"changes");
} }
public static Object assignStaffInheritStaffForClientAccounts(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String groupId,final String staffId){ public static Object assignStaffInheritStaffForClientAccounts(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String groupId,final String staffId){
final String GROUP_ASSIGN_STAFF_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER + "&command=assignStaff"; final String GROUP_ASSIGN_STAFF_URL = "/fineract-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER + "&command=assignStaff";
System.out.println("---------------------------------DELETE GROUP---------------------------------------------"); LOG.info("---------------------------------DELETE GROUP---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSIGN_STAFF_URL,assignStaffAndInheritStaffForClientAccountsAsJSON(staffId),"changes"); return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSIGN_STAFF_URL,assignStaffAndInheritStaffForClientAccountsAsJSON(staffId),"changes");
} }
@@ -136,10 +138,9 @@ public class GroupHelper {
} else { } else {
map.put("active", "false"); map.put("active", "false");
map.put("submittedOnDate", "04 March 2011"); map.put("submittedOnDate", "04 March 2011");
System.out.println("defaulting to inactive group: 04 March 2011"); LOG.info("defaulting to inactive group: 04 March 2011");
} }
LOG.debug("map : {} ", map);
System.out.println("map : " + map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
@@ -148,7 +149,7 @@ public class GroupHelper {
final List<String> list = new ArrayList<>(); final List<String> list = new ArrayList<>();
list.add(clientMember); list.add(clientMember);
map.put("clientMembers", list); map.put("clientMembers", list);
System.out.println("map : " + map); LOG.debug("map : {}", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
@@ -160,36 +161,36 @@ public class GroupHelper {
map.put("activationDate", activationDate); map.put("activationDate", activationDate);
} else { } else {
map.put("activationDate", "04 March 2011"); map.put("activationDate", "04 March 2011");
System.out.println("defaulting to fixed date: 04 March 2011"); LOG.info("defaulting to fixed date: 04 March 2011");
} }
System.out.println("map : " + map); LOG.debug("map : {}", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
public static String updateGroupAsJSON(final String name) { public static String updateGroupAsJSON(final String name) {
final HashMap<String, String> map = new HashMap<>(); final HashMap<String, String> map = new HashMap<>();
map.put("name", name); map.put("name", name);
System.out.println("map : " + map); LOG.debug("map : {}", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
public static String assignStaffAsJSON(final Long staffId) { public static String assignStaffAsJSON(final Long staffId) {
final HashMap<String, Object> map = new HashMap<>(); final HashMap<String, Object> map = new HashMap<>();
map.put("staffId", staffId); map.put("staffId", staffId);
System.out.println("map : " + map); LOG.debug("map : {}", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
public static String assignStaffAndInheritStaffForClientAccountsAsJSON(final String staffId) { public static String assignStaffAndInheritStaffForClientAccountsAsJSON(final String staffId) {
final HashMap<String, String> map = new HashMap<>(); final HashMap<String, String> map = new HashMap<>();
map.put("staffId", staffId); map.put("staffId", staffId);
map.put("inheritStaffForClientAccounts","true"); map.put("inheritStaffForClientAccounts","true");
System.out.println("map : " + map); LOG.debug("map : {}", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
public static void verifyGroupCreatedOnServer(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static void verifyGroupCreatedOnServer(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer generatedGroupID) { final Integer generatedGroupID) {
System.out.println("------------------------------CHECK GROUP DETAILS------------------------------------\n"); LOG.info("------------------------------CHECK GROUP DETAILS------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID + "?" + Utils.TENANT_IDENTIFIER; final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID + "?" + Utils.TENANT_IDENTIFIER;
final Integer responseGroupID = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "id"); final Integer responseGroupID = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "id");
assertEquals("ERROR IN CREATING THE GROUP", generatedGroupID, responseGroupID); assertEquals("ERROR IN CREATING THE GROUP", generatedGroupID, responseGroupID);
@@ -197,7 +198,7 @@ public class GroupHelper {
public static void verifyGroupDetails(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static void verifyGroupDetails(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer generatedGroupID, final String field, final String expectedValue) { final Integer generatedGroupID, final String field, final String expectedValue) {
System.out.println("------------------------------CHECK GROUP DETAILS------------------------------------\n"); LOG.info("------------------------------CHECK GROUP DETAILS------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID + "?" + Utils.TENANT_IDENTIFIER; final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID + "?" + Utils.TENANT_IDENTIFIER;
final String responseValue = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, field); final String responseValue = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, field);
assertEquals("ERROR IN CREATING THE GROUP", expectedValue, responseValue); assertEquals("ERROR IN CREATING THE GROUP", expectedValue, responseValue);
@@ -205,7 +206,7 @@ public class GroupHelper {
public static void verifyGroupActivatedOnServer(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static void verifyGroupActivatedOnServer(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer generatedGroupID, final boolean generatedGroupStatus) { final Integer generatedGroupID, final boolean generatedGroupStatus) {
System.out.println("------------------------------CHECK GROUP STATUS------------------------------------\n"); LOG.info("------------------------------CHECK GROUP STATUS------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID + "?" + Utils.TENANT_IDENTIFIER; final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID + "?" + Utils.TENANT_IDENTIFIER;
final Boolean responseGroupStatus = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "active"); final Boolean responseGroupStatus = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "active");
assertEquals("ERROR IN ACTIVATING THE GROUP", generatedGroupStatus, responseGroupStatus); assertEquals("ERROR IN ACTIVATING THE GROUP", generatedGroupStatus, responseGroupStatus);
@@ -214,33 +215,65 @@ public class GroupHelper {
public static void verifyGroupMembers(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static void verifyGroupMembers(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer generatedGroupID, final Integer groupMember) { final Integer generatedGroupID, final Integer groupMember) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
System.out.println("------------------------------CHECK GROUP MEMBERS------------------------------------\n"); LOG.info("------------------------------CHECK GROUP MEMBERS------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID
+ "?associations=clientMembers&" + Utils.TENANT_IDENTIFIER; + "?associations=clientMembers&" + Utils.TENANT_IDENTIFIER;
list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "clientMembers"); list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "clientMembers");
LOG.debug("the list of verifyEmptyGroupMembers : {} ", list);
assertTrue("ERROR IN GROUP MEMBER", list.toString().contains("id=" + groupMember.toString())); assertTrue("ERROR IN GROUP MEMBER", list.toString().contains("id=" + groupMember.toString()));
} }
public static void verifyEmptyGroupMembers(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static void verifyEmptyGroupMembers(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer generatedGroupID) { final Integer generatedGroupID) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
System.out.println("------------------------------CHECK EMPTY GROUP MEMBER LIST------------------------------------\n"); LOG.info("------------------------------CHECK EMPTY GROUP MEMBER LIST------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID
+ "?associations=clientMembers&" + Utils.TENANT_IDENTIFIER; + "?associations=clientMembers&" + Utils.TENANT_IDENTIFIER;
list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "clientMembers"); list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "clientMembers");
LOG.debug("the list of verifyEmptyGroupMembers : {} ", list);
assertEquals("GROUP MEMBER LIST NOT EMPTY", list, null); assertEquals("GROUP MEMBER LIST NOT EMPTY", list, null);
} }
public static void verifyGroupDeleted(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static void verifyGroupDeleted(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer generatedGroupID) { final Integer generatedGroupID) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
System.out.println("------------------------------CHECK GROUP DELETED------------------------------------\n"); LOG.info("------------------------------CHECK GROUP DELETED------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/?" + Utils.TENANT_IDENTIFIER; final String GROUP_URL = "/fineract-provider/api/v1/groups/?" + Utils.TENANT_IDENTIFIER;
list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "pageItems"); list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "pageItems");
assertFalse("GROUP NOT DELETED", list.toString().contains("id=" + generatedGroupID.toString())); assertFalse("GROUP NOT DELETED", list.toString().contains("id=" + generatedGroupID.toString()));
} }
//Glim_Gsim_testing
public static List<String> verifyRetrieveGlimAccountsByGroupId(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer groupID) {
List<String> list = new ArrayList<>();
LOG.info("------------------------------CHECK GROUP Retrieve Accounts------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/"+groupID+"/glimaccounts?" + Utils.TENANT_IDENTIFIER;
list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "glimId");
LOG.debug("GlimId of Retrieved Account : {} ", list);
return list;
}
public static List<String> verifyRetrieveGlimAccountsByGlimId(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer glimId) {
List<String> list = new ArrayList<>();
LOG.info("------------------------------CHECK GROUP Retrieve Accounts------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/loans/glimAccount/"+glimId+"?"+ Utils.TENANT_IDENTIFIER;
list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "glimId");
LOG.debug("GlimId of Retrieved Account: {} ", list);
return list;
}
public static List<String> verifyRetrieveGsimAccounts(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer groupID) {
List<String> list = new ArrayList<>();
LOG.info("------------------------------CHECK GROUP Retrieve Accounts------------------------------------\n");
final String GROUP_URL = "/fineract-provider/api/v1/groups/"+groupID+"/gsimaccounts?" + Utils.TENANT_IDENTIFIER;
list = Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "gsimId");
LOG.debug("GsimId Retrieved Accounts: {} ", list);
return list;
}
public static String randomNameGenerator(final String prefix, final int lenOfRandomSuffix) { public static String randomNameGenerator(final String prefix, final int lenOfRandomSuffix) {
return Utils.randomStringGenerator(prefix, lenOfRandomSuffix); return Utils.randomStringGenerator(prefix, lenOfRandomSuffix);
} }
@@ -259,7 +292,7 @@ public class GroupHelper {
map.put("active", "false"); map.put("active", "false");
map.put("submittedOnDate", "04 March 2011"); map.put("submittedOnDate", "04 March 2011");
String requestJson = getTestDatatableAsJson(map, registeredTableName); String requestJson = getTestDatatableAsJson(map, registeredTableName);
System.out.println("map : " + requestJson); LOG.debug("map : {} ", requestJson);
return requestJson; return requestJson;
} }
@@ -22,9 +22,13 @@ import com.google.gson.Gson;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoanApplicationTestBuilder { public class LoanApplicationTestBuilder {
private final static Logger LOG = LoggerFactory.getLogger(LoanApplicationTestBuilder.class);
private static final String DAYS = "0"; private static final String DAYS = "0";
private static final String WEEKS = "1"; private static final String WEEKS = "1";
private static final String MONTHS = "2"; private static final String MONTHS = "2";
@@ -34,9 +38,11 @@ public class LoanApplicationTestBuilder {
private static final String EQUAL_PRINCIPAL_PAYMENTS = "0"; private static final String EQUAL_PRINCIPAL_PAYMENTS = "0";
private static final String EQUAL_INSTALLMENTS = "1"; private static final String EQUAL_INSTALLMENTS = "1";
private static final String CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD = "1"; private static final String CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD = "1";
private static final String LOCALE = "en_GB";
public static final String DEFAULT_STRATEGY = "1"; public static final String DEFAULT_STRATEGY = "1";
public static final String RBI_INDIA_STRATEGY = "4"; public static final String RBI_INDIA_STRATEGY = "4";
private String principal = "10,000"; private String principal = "10,000";
private String loanTermFrequency = ""; private String loanTermFrequency = "";
private String loanTermFrequencyType = ""; private String loanTermFrequencyType = "";
@@ -61,10 +67,14 @@ public class LoanApplicationTestBuilder {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private List<HashMap> charges = new ArrayList<>(); private List<HashMap> charges = new ArrayList<>();
private String repaymentsStartingFromDate = null; private String repaymentsStartingFromDate = null;
private String isParentAccount = null;
private String totalLoan = "0";
private String calendarId; private String calendarId;
private boolean syncDisbursementWithMeeting = false; private boolean syncDisbursementWithMeeting = false;
private List<HashMap<String, Object>> datatables = null; private List<HashMap<String, Object>> datatables = null;
private List<Map<String, Object>> approvalFormData =null;
public String build(final String clientID, final String groupID, final String loanProductId, final String savingsID) { public String build(final String clientID, final String groupID, final String loanProductId, final String savingsID) {
final HashMap<String, Object> map = new HashMap<>(); final HashMap<String, Object> map = new HashMap<>();
@@ -76,6 +86,16 @@ public class LoanApplicationTestBuilder {
} }
map.put("syncDisbursementWithMeeting", this.syncDisbursementWithMeeting); map.put("syncDisbursementWithMeeting", this.syncDisbursementWithMeeting);
} }
if (this.loanType == "glim") {
if (isParentAccount!=null){
map.put("isParentAccount", this.isParentAccount);
}
if (totalLoan!=null){
map.put("totalLoan", this.totalLoan);
}
}
return build(map, loanProductId, savingsID); return build(map, loanProductId, savingsID);
} }
@@ -91,6 +111,19 @@ public class LoanApplicationTestBuilder {
return build(map, loanProductId, savingsID); return build(map, loanProductId, savingsID);
} }
public String build()
{
final HashMap<String, Object> map = new HashMap<>();
if(this.approvalFormData != null) {
map.put("approvalFormData", this.approvalFormData) ;
}
String approvalFormData=new Gson().toJson(map);
LOG.info("approvalFormData: {} ", approvalFormData);
return approvalFormData;
}
private String build(final HashMap<String, Object> map, final String loanProductId, final String savingsID) { private String build(final HashMap<String, Object> map, final String loanProductId, final String savingsID) {
map.put("dateFormat", "dd MMMM yyyy"); map.put("dateFormat", "dd MMMM yyyy");
map.put("locale", "en_GB"); map.put("locale", "en_GB");
@@ -137,7 +170,7 @@ public class LoanApplicationTestBuilder {
if (datatables != null) { if (datatables != null) {
map.put("datatables", this.datatables); map.put("datatables", this.datatables);
} }
System.out.println("Loan Application request : " + map); LOG.info("Loan Application request : {} ", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
@@ -256,6 +289,11 @@ public class LoanApplicationTestBuilder {
return this; return this;
} }
public LoanApplicationTestBuilder withtotalLoan(final String totalLoan) {
this.totalLoan = totalLoan;
return this;
}
public LoanApplicationTestBuilder withPrincipalGrace(final String graceOnPrincipalPayment) { public LoanApplicationTestBuilder withPrincipalGrace(final String graceOnPrincipalPayment) {
this.graceOnPrincipalPayment = graceOnPrincipalPayment; this.graceOnPrincipalPayment = graceOnPrincipalPayment;
return this; return this;
@@ -283,6 +321,17 @@ public class LoanApplicationTestBuilder {
return this; return this;
} }
public LoanApplicationTestBuilder withParentAccount(final String parentAccount) {
this.isParentAccount = parentAccount;
return this;
}
public LoanApplicationTestBuilder withApprovalFormData(final List<Map<String, Object>> approvalFormData) {
this.approvalFormData = new ArrayList<>();
this.approvalFormData.addAll(approvalFormData);
return this;
}
/** /**
* calendarID parameter is used to sync repayments with group meetings, * calendarID parameter is used to sync repayments with group meetings,
* especially when using jlg loans * especially when using jlg loans
@@ -62,6 +62,10 @@ public class LoanStatusChecker {
assertEquals("Foreclosed", getSubStatus(loanSubStatusHashMap, "value")); assertEquals("Foreclosed", getSubStatus(loanSubStatusHashMap, "value"));
} }
public static void verifyLoanAccountRejected(final HashMap loanSubStatusHashMap) {
assertEquals("Rejected", getSubStatus(loanSubStatusHashMap, "value"));
}
public static HashMap<String, Object> getStatusOfLoan(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static HashMap<String, Object> getStatusOfLoan(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanID) { final Integer loanID) {
final String url = "/fineract-provider/api/v1/loans/" + loanID + "?" + Utils.TENANT_IDENTIFIER; final String url = "/fineract-provider/api/v1/loans/" + loanID + "?" + Utils.TENANT_IDENTIFIER;
@@ -31,6 +31,7 @@ import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.apache.fineract.integrationtests.common.CommonConstants; import org.apache.fineract.integrationtests.common.CommonConstants;
@@ -38,12 +39,15 @@ import org.apache.fineract.integrationtests.common.Utils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public class LoanTransactionHelper { public class LoanTransactionHelper {
private final RequestSpecification requestSpec; private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec; private final ResponseSpecification responseSpec;
private final static Logger LOG = LoggerFactory.getLogger(LoanTransactionHelper.class);
private static final String CREATE_LOAN_PRODUCT_URL = "/fineract-provider/api/v1/loanproducts?" + Utils.TENANT_IDENTIFIER; private static final String CREATE_LOAN_PRODUCT_URL = "/fineract-provider/api/v1/loanproducts?" + Utils.TENANT_IDENTIFIER;
private static final String APPLY_LOAN_URL = "/fineract-provider/api/v1/loans?" + Utils.TENANT_IDENTIFIER; private static final String APPLY_LOAN_URL = "/fineract-provider/api/v1/loans?" + Utils.TENANT_IDENTIFIER;
@@ -53,6 +57,7 @@ public class LoanTransactionHelper {
private static final String DISBURSE_LOAN_COMMAND = "disburse"; private static final String DISBURSE_LOAN_COMMAND = "disburse";
private static final String DISBURSE_LOAN_TO_SAVINGS_COMMAND = "disburseToSavings"; private static final String DISBURSE_LOAN_TO_SAVINGS_COMMAND = "disburseToSavings";
private static final String UNDO_DISBURSE_LOAN_COMMAND = "undoDisbursal"; private static final String UNDO_DISBURSE_LOAN_COMMAND = "undoDisbursal";
private static final String REJECT_LOAN_COMMAND = "reject";
private static final String UNDO_LAST_DISBURSE_LOAN_COMMAND = "undolastdisbursal"; private static final String UNDO_LAST_DISBURSE_LOAN_COMMAND = "undolastdisbursal";
private static final String WRITE_OFF_LOAN_COMMAND = "writeoff"; private static final String WRITE_OFF_LOAN_COMMAND = "writeoff";
private static final String WAIVE_INTEREST_COMMAND = "waiveinterest"; private static final String WAIVE_INTEREST_COMMAND = "waiveinterest";
@@ -77,6 +82,16 @@ public class LoanTransactionHelper {
return Utils.performServerPost(this.requestSpec, this.responseSpec, APPLY_LOAN_URL, loanApplicationJSON, "loanId"); return Utils.performServerPost(this.requestSpec, this.responseSpec, APPLY_LOAN_URL, loanApplicationJSON, "loanId");
} }
public HashMap<String,Integer> getGlimId(final String loanApplicationJSON) {
return Utils.performServerPost(this.requestSpec, this.responseSpec, APPLY_LOAN_URL, loanApplicationJSON, "");
}
public Object getGlimLoanId(final String glimId) {
final String GET_LOAN_URL = "/fineract-provider/api/v1/loans/glimAccount/" + glimId + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerGet(this.requestSpec, this.responseSpec, GET_LOAN_URL, "childLoanId");
}
public Object getLoanError(final String loanApplicationJSON, final String responseAttribute) { public Object getLoanError(final String loanApplicationJSON, final String responseAttribute) {
return Utils.performServerPost(this.requestSpec, this.responseSpec, APPLY_LOAN_URL, loanApplicationJSON, responseAttribute); return Utils.performServerPost(this.requestSpec, this.responseSpec, APPLY_LOAN_URL, loanApplicationJSON, responseAttribute);
} }
@@ -153,8 +168,8 @@ public class LoanTransactionHelper {
public HashMap approveLoan(final String approvalDate, final Integer loanID) { public HashMap approveLoan(final String approvalDate, final Integer loanID) {
String loanApprovalCommand = createLoanOperationURL(APPROVE_LOAN_COMMAND, loanID); String loanApprovalCommand = createLoanOperationURL(APPROVE_LOAN_COMMAND, loanID);
String loanApprovalRequest = getApproveLoanAsJSON(approvalDate); String loanApprovalRequest = getApproveLoanAsJSON(approvalDate);
System.out.println("Loan approval command:" + loanApprovalCommand); LOG.info("Loan approval command: {} ", loanApprovalCommand);
System.out.println("Loan approval request:" + loanApprovalRequest); LOG.info("Loan approval request: {} ", loanApprovalRequest);
return performLoanTransaction(loanApprovalCommand, loanApprovalRequest); return performLoanTransaction(loanApprovalCommand, loanApprovalRequest);
} }
@@ -206,18 +221,50 @@ public class LoanTransactionHelper {
public HashMap undoDisbursal(final Integer loanID) { public HashMap undoDisbursal(final Integer loanID) {
final String undoDisburseJson = "{'note' : 'UNDO DISBURSAL'}"; final String undoDisburseJson = "{'note' : 'UNDO DISBURSAL'}";
System.out.println("IN DISBURSE LOAN"); LOG.info("IN DISBURSE LOAN");
final String url = createLoanOperationURL(UNDO_DISBURSE_LOAN_COMMAND, loanID); final String url = createLoanOperationURL(UNDO_DISBURSE_LOAN_COMMAND, loanID);
System.out.println("IN DISBURSE LOAN URL " + url); LOG.info("IN DISBURSE LOAN URL : {} ", url);
return performLoanTransaction(createLoanOperationURL(UNDO_DISBURSE_LOAN_COMMAND, loanID), undoDisburseJson); return performLoanTransaction(createLoanOperationURL(UNDO_DISBURSE_LOAN_COMMAND, loanID), undoDisburseJson);
} }
public Float undoLastDisbursal(final Integer loanID) { public Float undoLastDisbursal(final Integer loanID) {
final String undoLastDisburseJson = "{'note' : 'UNDO LAST DISBURSAL'}"; final String undoLastDisburseJson = "{'note' : 'UNDO LAST DISBURSAL'}";
final String url = createLoanOperationURL(UNDO_LAST_DISBURSE_LOAN_COMMAND, loanID); final String url = createLoanOperationURL(UNDO_LAST_DISBURSE_LOAN_COMMAND, loanID);
System.out.println("IN UNDO LAST DISBURSE LOAN URL " + url); LOG.info("IN UNDO LAST DISBURSE LOAN URL : {} ", url);
return performUndoLastLoanDisbursementTransaction(createLoanOperationURL(UNDO_LAST_DISBURSE_LOAN_COMMAND, loanID), undoLastDisburseJson); return performUndoLastLoanDisbursementTransaction(createLoanOperationURL(UNDO_LAST_DISBURSE_LOAN_COMMAND, loanID), undoLastDisburseJson);
} }
//glimtesting
public HashMap approveGlimAccount(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final List<Map<String, Object>> approvalFormData, final Integer glimID) {
String approvalForm = new LoanApplicationTestBuilder() //
.withApprovalFormData(approvalFormData)
.build();
final String approvalURL = createGlimAccountURL(APPROVE_LOAN_COMMAND, glimID);
return performLoanTransaction(approvalURL, approvalForm);
}
public HashMap disburseGlimAccount(final String date, final Integer glimID) {
LOG.info("--------------------------------- GLIM DISBURSEMENT APPLICATION -------------------------------");
return performLoanTransaction(createGlimAccountURL(DISBURSE_LOAN_COMMAND, glimID), getDisbursementAsJSON(date));
}
public HashMap undoDisburseGlimAccount(final Integer glimID) {
LOG.info("--------------------------------- UNDO DISBURSAL GLIM APPLICATION -------------------------------");
final String undoBodyJson = "{'note':'UNDO DISBURSAL'}";
return performLoanTransaction(createGlimAccountURL(UNDO_DISBURSE_LOAN_COMMAND, glimID), undoBodyJson);
}
public HashMap undoApprovalGlimAccount(final Integer glimID) {
LOG.info("--------------------------------- UNDO APPROVAL GLIM APPLICATION -------------------------------");
final String undoBodyJson = "{'note':'UNDO APPROVAL'}";
return performLoanTransaction(createGlimAccountURL(UNDO_APPROVAL_LOAN_COMMAND, glimID), undoBodyJson);
}
public HashMap rejectGlimAccount(final String date, final Integer glimID) {
LOG.info("--------------------------------- REJECT GLIM APPLICATION -------------------------------");
return performLoanTransaction(createGlimAccountURL(REJECT_LOAN_COMMAND, glimID), getRejectAsJSON(date));
}
public void recoverFromGuarantor(final Integer loanID) { public void recoverFromGuarantor(final Integer loanID) {
performLoanTransaction(createLoanOperationURL(RECOVER_FROM_GUARANTORS_COMMAND, loanID), "", ""); performLoanTransaction(createLoanOperationURL(RECOVER_FROM_GUARANTORS_COMMAND, loanID), "", "");
@@ -253,7 +300,7 @@ public class LoanTransactionHelper {
} }
public Integer addChargesForLoan(final Integer loanId, final String request) { public Integer addChargesForLoan(final Integer loanId, final String request) {
System.out.println("--------------------------------- ADD CHARGES FOR LOAN --------------------------------"); LOG.info("--------------------------------- ADD CHARGES FOR LOAN --------------------------------");
final String ADD_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges?" + Utils.TENANT_IDENTIFIER; final String ADD_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges?" + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, ADD_CHARGES_URL, request, ""); final HashMap response = Utils.performServerPost(requestSpec, responseSpec, ADD_CHARGES_URL, request, "");
return (Integer) response.get("resourceId"); return (Integer) response.get("resourceId");
@@ -265,7 +312,7 @@ public class LoanTransactionHelper {
} }
public Integer updateChargesForLoan(final Integer loanId, final Integer loanchargeId, final String request) { public Integer updateChargesForLoan(final Integer loanId, final Integer loanchargeId, final String request) {
System.out.println("--------------------------------- ADD CHARGES FOR LOAN --------------------------------"); LOG.info("--------------------------------- ADD CHARGES FOR LOAN --------------------------------");
final String UPDATE_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?" final String UPDATE_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?"
+ Utils.TENANT_IDENTIFIER; + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPut(requestSpec, responseSpec, UPDATE_CHARGES_URL, request, ""); final HashMap response = Utils.performServerPut(requestSpec, responseSpec, UPDATE_CHARGES_URL, request, "");
@@ -273,7 +320,7 @@ public class LoanTransactionHelper {
} }
public Integer deleteChargesForLoan(final Integer loanId, final Integer loanchargeId) { public Integer deleteChargesForLoan(final Integer loanId, final Integer loanchargeId) {
System.out.println("--------------------------------- DELETE CHARGES FOR LOAN --------------------------------"); LOG.info("--------------------------------- DELETE CHARGES FOR LOAN --------------------------------");
final String DELETE_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?" final String DELETE_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?"
+ Utils.TENANT_IDENTIFIER; + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerDelete(requestSpec, responseSpec, DELETE_CHARGES_URL, ""); final HashMap response = Utils.performServerDelete(requestSpec, responseSpec, DELETE_CHARGES_URL, "");
@@ -281,7 +328,7 @@ public class LoanTransactionHelper {
} }
public Integer waiveChargesForLoan(final Integer loanId, final Integer loanchargeId, final String json) { public Integer waiveChargesForLoan(final Integer loanId, final Integer loanchargeId, final String json) {
System.out.println("--------------------------------- WAIVE CHARGES FOR LOAN --------------------------------"); LOG.info("--------------------------------- WAIVE CHARGES FOR LOAN --------------------------------");
final String CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?command=waive&" final String CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?command=waive&"
+ Utils.TENANT_IDENTIFIER; + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, ""); final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
@@ -289,7 +336,7 @@ public class LoanTransactionHelper {
} }
public Integer payChargesForLoan(final Integer loanId, final Integer loanchargeId, final String json) { public Integer payChargesForLoan(final Integer loanId, final Integer loanchargeId, final String json) {
System.out.println("--------------------------------- WAIVE CHARGES FOR LOAN --------------------------------"); LOG.info("--------------------------------- WAIVE CHARGES FOR LOAN --------------------------------");
final String CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?command=pay&" final String CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?command=pay&"
+ Utils.TENANT_IDENTIFIER; + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, ""); final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
@@ -305,7 +352,7 @@ public class LoanTransactionHelper {
if (transactionAmount != null) { if (transactionAmount != null) {
map.put("transactionAmount", transactionAmount); map.put("transactionAmount", transactionAmount);
} }
System.out.println("Loan Application disburse request : " + map); LOG.info("Loan Application disburse request : {} ", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
@@ -319,7 +366,7 @@ public class LoanTransactionHelper {
if (transactionAmount != null) { if (transactionAmount != null) {
map.put("transactionAmount", transactionAmount); map.put("transactionAmount", transactionAmount);
} }
System.out.println("Loan Application disburse request : " + map); LOG.info("Loan Application disburse request : {} ", map);
return new Gson().toJson(map); return new Gson().toJson(map);
} }
@@ -346,6 +393,22 @@ public class LoanTransactionHelper {
return new Gson().toJson(map); return new Gson().toJson(map);
} }
private String getDisbursementAsJSON(final String date) {
final HashMap<String, String> map = new HashMap<>();
map.put("actualDisbursementDate", date);
map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy");
return new Gson().toJson(map);
}
private String getRejectAsJSON(final String date) {
final HashMap<String, String> map = new HashMap<>();
map.put("rejectedOnDate", date);
map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy");
return new Gson().toJson(map);
}
private String getRepaymentBodyAsJSON(final String transactionDate, final Float transactionAmount) { private String getRepaymentBodyAsJSON(final String transactionDate, final Float transactionAmount) {
final HashMap<String, String> map = new HashMap<>(); final HashMap<String, String> map = new HashMap<>();
map.put("locale", "en"); map.put("locale", "en");
@@ -363,7 +426,7 @@ public class LoanTransactionHelper {
map.put("transactionDate", transactionDate); map.put("transactionDate", transactionDate);
map.put("note", "Foreclosure Made!!!"); map.put("note", "Foreclosure Made!!!");
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info(json);
return json; return json;
} }
@@ -408,7 +471,7 @@ public class LoanTransactionHelper {
map.put("dueDate", dueDate); map.put("dueDate", dueDate);
map.put("chargeId", chargeId); map.put("chargeId", chargeId);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -423,7 +486,7 @@ public class LoanTransactionHelper {
map.put("amount", amount); map.put("amount", amount);
map.put("chargeId", chargeId); map.put("chargeId", chargeId);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -434,7 +497,7 @@ public class LoanTransactionHelper {
map.put("amount", amount); map.put("amount", amount);
map.put("chargeId", chargeId); map.put("chargeId", chargeId);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -444,7 +507,7 @@ public class LoanTransactionHelper {
map.put("dateFormat", "dd MMMM yyyy"); map.put("dateFormat", "dd MMMM yyyy");
map.put("amount", amount); map.put("amount", amount);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -457,7 +520,7 @@ public class LoanTransactionHelper {
map.put("installmentNumber", installmentNumber); map.put("installmentNumber", installmentNumber);
} }
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -466,7 +529,7 @@ public class LoanTransactionHelper {
map.put("locale", "en_GB"); map.put("locale", "en_GB");
map.put("installmentNumber", installmentNumber); map.put("installmentNumber", installmentNumber);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -499,6 +562,10 @@ public class LoanTransactionHelper {
return "/fineract-provider/api/v1/loans/" + loanID + "/transactions?command=" + command + "&" + Utils.TENANT_IDENTIFIER; return "/fineract-provider/api/v1/loans/" + loanID + "/transactions?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
} }
private String createGlimAccountURL(final String command, final Integer glimID) {
return "/fineract-provider/api/v1/loans/glimAccount/" + glimID + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
}
private HashMap performLoanTransaction(final String postURLForLoanTransaction, final String jsonToBeSent) { private HashMap performLoanTransaction(final String postURLForLoanTransaction, final String jsonToBeSent) {
final HashMap response = Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForLoanTransaction, jsonToBeSent, final HashMap response = Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForLoanTransaction, jsonToBeSent,
@@ -540,7 +607,7 @@ public class LoanTransactionHelper {
map.put("transactionDate", date); map.put("transactionDate", date);
map.put("transactionAmount", transactionAmount); map.put("transactionAmount", transactionAmount);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info(json);
return json; return json;
} }
@@ -556,7 +623,7 @@ public class LoanTransactionHelper {
} }
public void verifyRepaymentScheduleEntryFor(final int repaymentNumber, final float expectedPrincipalOutstanding, final Integer loanID) { public void verifyRepaymentScheduleEntryFor(final int repaymentNumber, final float expectedPrincipalOutstanding, final Integer loanID) {
System.out.println("---------------------------GETTING LOAN REPAYMENT SCHEDULE--------------------------------"); LOG.info("---------------------------GETTING LOAN REPAYMENT SCHEDULE--------------------------------");
final ArrayList<HashMap> repaymentPeriods = getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); final ArrayList<HashMap> repaymentPeriods = getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
assertEquals("Mismatch in Principal Loan Balance Outstanding ", expectedPrincipalOutstanding, repaymentPeriods.get(repaymentNumber) assertEquals("Mismatch in Principal Loan Balance Outstanding ", expectedPrincipalOutstanding, repaymentPeriods.get(repaymentNumber)
.get("principalLoanBalanceOutstanding")); .get("principalLoanBalanceOutstanding"));
@@ -675,7 +742,7 @@ public class LoanTransactionHelper {
map.put("updatedExpectedDisbursementDate", updatedExpectedDisbursementDate); map.put("updatedExpectedDisbursementDate", updatedExpectedDisbursementDate);
map.put("updatedPrincipal", updatedPrincipal); map.put("updatedPrincipal", updatedPrincipal);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -688,7 +755,7 @@ public class LoanTransactionHelper {
map.put("expectedDisbursementDate", expectedDisbursementDate); map.put("expectedDisbursementDate", expectedDisbursementDate);
map.put("disbursementData", disbursementData); map.put("disbursementData", disbursementData);
String json = new Gson().toJson(map); String json = new Gson().toJson(map);
System.out.println(json); LOG.info("{}",json);
return json; return json;
} }
@@ -32,6 +32,7 @@ import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.apache.fineract.integrationtests.common.CommonConstants; import org.apache.fineract.integrationtests.common.CommonConstants;
@@ -39,12 +40,15 @@ import org.apache.fineract.integrationtests.common.Utils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Assert; import org.junit.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({ "rawtypes" }) @SuppressWarnings({ "rawtypes" })
public class SavingsAccountHelper { public class SavingsAccountHelper {
private final RequestSpecification requestSpec; private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec; private final ResponseSpecification responseSpec;
private final static Logger LOG = LoggerFactory.getLogger(SavingsAccountHelper.class);
private static final String SAVINGS_ACCOUNT_URL = "/fineract-provider/api/v1/savingsaccounts"; private static final String SAVINGS_ACCOUNT_URL = "/fineract-provider/api/v1/savingsaccounts";
private static final String APPROVE_SAVINGS_COMMAND = "approve"; private static final String APPROVE_SAVINGS_COMMAND = "approve";
@@ -60,6 +64,9 @@ public class SavingsAccountHelper {
private static final String DEPOSIT_SAVINGS_COMMAND = "deposit"; private static final String DEPOSIT_SAVINGS_COMMAND = "deposit";
private static final String WITHDRAW_SAVINGS_COMMAND = "withdrawal"; private static final String WITHDRAW_SAVINGS_COMMAND = "withdrawal";
private static final String GSIM_SAVINGS = "/gsim";
private static final String GSIM_SAVINGS_COMMAND = "/gsimcommands";
private static final String GSIM_DEPOSIT_SAVINGS_COMMAND = "gsimDeposit";
private static final String MODIFY_TRASACTION_COMMAND = "modify"; private static final String MODIFY_TRASACTION_COMMAND = "modify";
private static final String UNDO_TRASACTION_COMMAND = "undo"; private static final String UNDO_TRASACTION_COMMAND = "undo";
@@ -111,7 +118,7 @@ public class SavingsAccountHelper {
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType, public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
String externalId, boolean withdrawalFeeForTransfers, final String submittedOnDate) { String externalId, boolean withdrawalFeeForTransfers, final String submittedOnDate) {
System.out.println("--------------------------------APPLYING FOR SAVINGS APPLICATION--------------------------------"); LOG.info("--------------------------------APPLYING FOR SAVINGS APPLICATION--------------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() // final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withExternalId(externalId) // .withExternalId(externalId) //
.withWithdrawalFeeForTransfers(withdrawalFeeForTransfers) // .withWithdrawalFeeForTransfers(withdrawalFeeForTransfers) //
@@ -123,7 +130,7 @@ public class SavingsAccountHelper {
public Integer applyForSavingsApplicationWithDatatables(final Integer ID, final Integer savingsProductID, final String accountType, public Integer applyForSavingsApplicationWithDatatables(final Integer ID, final Integer savingsProductID, final String accountType,
final String submittedOnDate, final String datatableName) { final String submittedOnDate, final String datatableName) {
System.out.println("----------------------------APPLYING FOR SAVINGS APPLICATION WITH DATATABLES----------------------------"); LOG.info("----------------------------APPLYING FOR SAVINGS APPLICATION WITH DATATABLES----------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() // final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withSubmittedOnDate(submittedOnDate) // .withSubmittedOnDate(submittedOnDate) //
.withDatatables(getTestDatatableAsJson(datatableName)) // .withDatatables(getTestDatatableAsJson(datatableName)) //
@@ -134,7 +141,7 @@ public class SavingsAccountHelper {
public Object applyForSavingsApplicationWithFailure(final Integer ID, final Integer savingsProductID, final String accountType, public Object applyForSavingsApplicationWithFailure(final Integer ID, final Integer savingsProductID, final String accountType,
final String submittedOnDate, final String responseAttribute) { final String submittedOnDate, final String responseAttribute) {
System.out.println("----------------------------APPLYING FOR SAVINGS APPLICATION WITH ERROR----------------------------"); LOG.info("----------------------------APPLYING FOR SAVINGS APPLICATION WITH ERROR----------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() // final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withSubmittedOnDate(submittedOnDate) // .withSubmittedOnDate(submittedOnDate) //
.build(ID.toString(), savingsProductID.toString(), accountType); .build(ID.toString(), savingsProductID.toString(), accountType);
@@ -150,6 +157,21 @@ public class SavingsAccountHelper {
return Utils.performServerPut(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "/" + savingsId + "?" return Utils.performServerPut(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "/" + savingsId + "?"
+ Utils.TENANT_IDENTIFIER, savingsApplicationJSON, CommonConstants.RESPONSE_CHANGES); + Utils.TENANT_IDENTIFIER, savingsApplicationJSON, CommonConstants.RESPONSE_CHANGES);
} }
//GLIM_GSIM_TESTING
public Integer applyForGsimApplication(List<Map<String, Object>> clientArray) {
LOG.info("----------------------------APPLYING FOR GSIM SAVINGS APPLICATION----------------------------");
LOG.info("clientArray is : {} ", clientArray);
String clientArrays = new SavingsApplicationTestBuilder() //
.withClientArray(clientArray)
.build();
return SavingsAccountHelper.applyForGsimApplication(clientArrays, requestSpec, responseSpec);
}
public static Integer applyForGsimApplication(final String clientArrays, final RequestSpecification requestSpec,
final ResponseSpecification responseSpec) {
return Utils.performServerPost(requestSpec,responseSpec, SAVINGS_ACCOUNT_URL + GSIM_SAVINGS +"?" + Utils.TENANT_IDENTIFIER,
clientArrays, "gsimId");
}
public HashMap updateSavingsAccountWithHoldTaxStatus(final Integer savingsId, final boolean value) { public HashMap updateSavingsAccountWithHoldTaxStatus(final Integer savingsId, final boolean value) {
final HashMap<String, Object> map = new HashMap<>(); final HashMap<String, Object> map = new HashMap<>();
@@ -165,7 +187,7 @@ public class SavingsAccountHelper {
} }
public HashMap approveSavingsOnDate(final Integer savingsID, final String approvalDate) { public HashMap approveSavingsOnDate(final Integer savingsID, final String approvalDate) {
System.out.println("--------------------------------- APPROVING SAVINGS APPLICATION ------------------------------------"); LOG.info("--------------------------------- APPROVING SAVINGS APPLICATION ------------------------------------");
final String savingsOperationURL = createSavingsOperationURL(APPROVE_SAVINGS_COMMAND, savingsID); final String savingsOperationURL = createSavingsOperationURL(APPROVE_SAVINGS_COMMAND, savingsID);
if (approvalDate == null || approvalDate.equals("")) if (approvalDate == null || approvalDate.equals(""))
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJSON(), isBlock); return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJSON(), isBlock);
@@ -173,85 +195,85 @@ public class SavingsAccountHelper {
} }
public HashMap undoApproval(final Integer savingsID) { public HashMap undoApproval(final Integer savingsID) {
System.out.println("--------------------------------- UNDO APPROVING SAVINGS APPLICATION -------------------------------"); LOG.info("--------------------------------- UNDO APPROVING SAVINGS APPLICATION -------------------------------");
final String undoBodyJson = "{'note':'UNDO APPROVAL'}"; final String undoBodyJson = "{'note':'UNDO APPROVAL'}";
return performSavingApplicationActions(createSavingsOperationURL(UNDO_APPROVAL_SAVINGS_COMMAND, savingsID), undoBodyJson, isBlock); return performSavingApplicationActions(createSavingsOperationURL(UNDO_APPROVAL_SAVINGS_COMMAND, savingsID), undoBodyJson, isBlock);
} }
public HashMap rejectApplication(final Integer savingsID) { public HashMap rejectApplication(final Integer savingsID) {
System.out.println("--------------------------------- REJECT SAVINGS APPLICATION -------------------------------"); LOG.info("--------------------------------- REJECT SAVINGS APPLICATION -------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(REJECT_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(REJECT_SAVINGS_COMMAND, savingsID),
getRejectedSavingsAsJSON(CREATED_DATE_PLUS_ONE), isBlock); getRejectedSavingsAsJSON(CREATED_DATE_PLUS_ONE), isBlock);
} }
public List rejectApplicationWithErrorCode(final Integer savingsId, final String date) { public List rejectApplicationWithErrorCode(final Integer savingsId, final String date) {
System.out.println("--------------------------------- REJECT SAVINGS APPLICATION -------------------------------"); LOG.info("--------------------------------- REJECT SAVINGS APPLICATION -------------------------------");
return (List) performSavingActions(createSavingsOperationURL(REJECT_SAVINGS_COMMAND, savingsId), getRejectedSavingsAsJSON(date), return (List) performSavingActions(createSavingsOperationURL(REJECT_SAVINGS_COMMAND, savingsId), getRejectedSavingsAsJSON(date),
CommonConstants.RESPONSE_ERROR); CommonConstants.RESPONSE_ERROR);
} }
public HashMap withdrawApplication(final Integer savingsID) { public HashMap withdrawApplication(final Integer savingsID) {
System.out.println("--------------------------------- Withdraw SAVINGS APPLICATION -------------------------------"); LOG.info("--------------------------------- Withdraw SAVINGS APPLICATION -------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(WITHDRAWN_BY_CLIENT_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(WITHDRAWN_BY_CLIENT_SAVINGS_COMMAND, savingsID),
getWithdrawnSavingsAsJSON(), isBlock); getWithdrawnSavingsAsJSON(), isBlock);
} }
public HashMap activateSavings(final Integer savingsID) { public HashMap activateSavings(final Integer savingsID) {
System.out.println("---------------------------------- ACTIVATING SAVINGS APPLICATION ----------------------------------"); LOG.info("---------------------------------- ACTIVATING SAVINGS APPLICATION ----------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(ACTIVATE_SAVINGS_COMMAND, savingsID), getActivatedSavingsAsJSON(), isBlock); return performSavingApplicationActions(createSavingsOperationURL(ACTIVATE_SAVINGS_COMMAND, savingsID), getActivatedSavingsAsJSON(), isBlock);
} }
public HashMap closeSavingsAccount(final Integer savingsID, String withdrawBalance) { public HashMap closeSavingsAccount(final Integer savingsID, String withdrawBalance) {
System.out.println("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------"); LOG.info("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID),
getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE), isBlock); getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE), isBlock);
} }
public Object deleteSavingsApplication(final Integer savingsId, final String jsonAttributeToGetBack) { public Object deleteSavingsApplication(final Integer savingsId, final String jsonAttributeToGetBack) {
System.out.println("---------------------------------- DELETE SAVINGS APPLICATION ----------------------------------"); LOG.info("---------------------------------- DELETE SAVINGS APPLICATION ----------------------------------");
return Utils.performServerDelete(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "/" + savingsId + "?" return Utils.performServerDelete(this.requestSpec, this.responseSpec, SAVINGS_ACCOUNT_URL + "/" + savingsId + "?"
+ Utils.TENANT_IDENTIFIER, jsonAttributeToGetBack); + Utils.TENANT_IDENTIFIER, jsonAttributeToGetBack);
} }
public Object depositToSavingsAccount(final Integer savingsID, final String amount, String date, String jsonAttributeToGetback) { public Object depositToSavingsAccount(final Integer savingsID, final String amount, String date, String jsonAttributeToGetback) {
System.out.println("--------------------------------- SAVINGS TRANSACTION DEPOSIT --------------------------------"); LOG.info("--------------------------------- SAVINGS TRANSACTION DEPOSIT --------------------------------");
return performSavingActions(createSavingsTransactionURL(DEPOSIT_SAVINGS_COMMAND, savingsID), return performSavingActions(createSavingsTransactionURL(DEPOSIT_SAVINGS_COMMAND, savingsID),
getSavingsTransactionJSON(amount, date), jsonAttributeToGetback); getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
} }
public Object withdrawalFromSavingsAccount(final Integer savingsId, final String amount, String date, String jsonAttributeToGetback) { public Object withdrawalFromSavingsAccount(final Integer savingsId, final String amount, String date, String jsonAttributeToGetback) {
System.out.println("\n--------------------------------- SAVINGS TRANSACTION WITHDRAWAL --------------------------------"); LOG.info("\n--------------------------------- SAVINGS TRANSACTION WITHDRAWAL --------------------------------");
return performSavingActions(createSavingsTransactionURL(WITHDRAW_SAVINGS_COMMAND, savingsId), return performSavingActions(createSavingsTransactionURL(WITHDRAW_SAVINGS_COMMAND, savingsId),
getSavingsTransactionJSON(amount, date), jsonAttributeToGetback); getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
} }
public Integer updateSavingsAccountTransaction(final Integer savingsId, final Integer transactionId, final String amount) { public Integer updateSavingsAccountTransaction(final Integer savingsId, final Integer transactionId, final String amount) {
System.out.println("\n--------------------------------- MODIFY SAVINGS TRANSACTION --------------------------------"); LOG.info("\n--------------------------------- MODIFY SAVINGS TRANSACTION --------------------------------");
return (Integer) performSavingActions(createAdjustTransactionURL(MODIFY_TRASACTION_COMMAND, savingsId, transactionId), return (Integer) performSavingActions(createAdjustTransactionURL(MODIFY_TRASACTION_COMMAND, savingsId, transactionId),
getSavingsTransactionJSON(amount, LAST_TRANSACTION_DATE), CommonConstants.RESPONSE_RESOURCE_ID); getSavingsTransactionJSON(amount, LAST_TRANSACTION_DATE), CommonConstants.RESPONSE_RESOURCE_ID);
} }
public Integer undoSavingsAccountTransaction(final Integer savingsId, final Integer transactionId) { public Integer undoSavingsAccountTransaction(final Integer savingsId, final Integer transactionId) {
System.out.println("\n--------------------------------- UNDO SAVINGS TRANSACTION --------------------------------"); LOG.info("\n--------------------------------- UNDO SAVINGS TRANSACTION --------------------------------");
return (Integer) performSavingActions(createAdjustTransactionURL(UNDO_TRASACTION_COMMAND, savingsId, transactionId), return (Integer) performSavingActions(createAdjustTransactionURL(UNDO_TRASACTION_COMMAND, savingsId, transactionId),
getSavingsTransactionJSON("0", LAST_TRANSACTION_DATE), CommonConstants.RESPONSE_RESOURCE_ID); getSavingsTransactionJSON("0", LAST_TRANSACTION_DATE), CommonConstants.RESPONSE_RESOURCE_ID);
} }
public void calculateInterestForSavings(final Integer savingsId) { public void calculateInterestForSavings(final Integer savingsId) {
System.out.println("--------------------------------- CALCULATING INTEREST FOR SAVINGS --------------------------------"); LOG.info("--------------------------------- CALCULATING INTEREST FOR SAVINGS --------------------------------");
performSavingActions(createSavingsCalculateInterestURL(CALCULATE_INTEREST_SAVINGS_COMMAND, savingsId), performSavingActions(createSavingsCalculateInterestURL(CALCULATE_INTEREST_SAVINGS_COMMAND, savingsId),
getCalculatedInterestForSavingsApplicationAsJSON(), ""); getCalculatedInterestForSavingsApplicationAsJSON(), "");
} }
public void postInterestForSavings(final Integer savingsId) { public void postInterestForSavings(final Integer savingsId) {
System.out.println("--------------------------------- POST INTEREST FOR SAVINGS --------------------------------"); LOG.info("--------------------------------- POST INTEREST FOR SAVINGS --------------------------------");
performSavingActions(createSavingsCalculateInterestURL(POST_INTEREST_SAVINGS_COMMAND, savingsId), performSavingActions(createSavingsCalculateInterestURL(POST_INTEREST_SAVINGS_COMMAND, savingsId),
getCalculatedInterestForSavingsApplicationAsJSON(), ""); getCalculatedInterestForSavingsApplicationAsJSON(), "");
} }
public void postInterestAsOnSavings(final Integer savingsId, final String today) { public void postInterestAsOnSavings(final Integer savingsId, final String today) {
System.out.println("--------------------------------- POST INTEREST AS ON FOR SAVINGS --------------------------------"); LOG.info("--------------------------------- POST INTEREST AS ON FOR SAVINGS --------------------------------");
performSavingActions(createSavingsPostInterestAsOnURL(POST_INTEREST_AS_ON_SAVINGS_COMMAND, savingsId), performSavingActions(createSavingsPostInterestAsOnURL(POST_INTEREST_AS_ON_SAVINGS_COMMAND, savingsId),
getCalculatedInterestForSavingsApplicationAsJSON(today), CommonConstants.RESPONSE_RESOURCE_ID); getCalculatedInterestForSavingsApplicationAsJSON(today), CommonConstants.RESPONSE_RESOURCE_ID);
} }
@@ -261,7 +283,7 @@ public class SavingsAccountHelper {
} }
public Integer addChargesForSavings(final Integer savingsId, final Integer chargeId, boolean addDueDate, BigDecimal amount) { public Integer addChargesForSavings(final Integer savingsId, final Integer chargeId, boolean addDueDate, BigDecimal amount) {
System.out.println("--------------------------------- ADD CHARGES FOR SAVINGS --------------------------------"); LOG.info("--------------------------------- ADD CHARGES FOR SAVINGS --------------------------------");
return (Integer) performSavingActions(SAVINGS_ACCOUNT_URL + "/" + savingsId + "/charges?" + Utils.TENANT_IDENTIFIER, return (Integer) performSavingActions(SAVINGS_ACCOUNT_URL + "/" + savingsId + "/charges?" + Utils.TENANT_IDENTIFIER,
getPeriodChargeRequestJSON(chargeId, addDueDate, amount), CommonConstants.RESPONSE_RESOURCE_ID); getPeriodChargeRequestJSON(chargeId, addDueDate, amount), CommonConstants.RESPONSE_RESOURCE_ID);
} }
@@ -292,55 +314,55 @@ public class SavingsAccountHelper {
} }
public HashMap blockSavings(final Integer savingsID) { public HashMap blockSavings(final Integer savingsID) {
System.out.println("---------------------------------- BLOCKING SAVINGS ACCOUNT ----------------------------------"); LOG.info("---------------------------------- BLOCKING SAVINGS ACCOUNT ----------------------------------");
Boolean isBlock = true; Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(BLOCK_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(BLOCK_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock); getActivatedSavingsAsJSON(), isBlock);
} }
public HashMap unblockSavings(final Integer savingsID) { public HashMap unblockSavings(final Integer savingsID) {
System.out.println("---------------------------------- UNBLOCKING SAVINGS ACCOUNT ----------------------------------"); LOG.info("---------------------------------- UNBLOCKING SAVINGS ACCOUNT ----------------------------------");
Boolean isBlock = true; Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock); getActivatedSavingsAsJSON(), isBlock);
} }
public HashMap blockDebit(final Integer savingsID) { public HashMap blockDebit(final Integer savingsID) {
System.out.println("---------------------------------- BLOCKING DEBIT TRANSACTIONS ----------------------------------"); LOG.info("---------------------------------- BLOCKING DEBIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true; Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(BLOCK_DEBITS_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(BLOCK_DEBITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock); getActivatedSavingsAsJSON(), isBlock);
} }
public HashMap unblockDebit(final Integer savingsID) { public HashMap unblockDebit(final Integer savingsID) {
System.out.println("---------------------------------- UNBLOCKING DEBIT TRANSACTIONS ----------------------------------"); LOG.info("---------------------------------- UNBLOCKING DEBIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true; Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_DEBITS_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_DEBITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock); getActivatedSavingsAsJSON(), isBlock);
} }
public HashMap blockCredit(final Integer savingsID) { public HashMap blockCredit(final Integer savingsID) {
System.out.println("---------------------------------- BLOCKING CREDIT TRANSACTIONS ----------------------------------"); LOG.info("---------------------------------- BLOCKING CREDIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true; Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(BLOCK_CREDITS_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(BLOCK_CREDITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock); getActivatedSavingsAsJSON(), isBlock);
} }
public HashMap unblockCredit(final Integer savingsID) { public HashMap unblockCredit(final Integer savingsID) {
System.out.println("---------------------------------- UNBLOCKING CREDIT TRANSACTIONS ----------------------------------"); LOG.info("---------------------------------- UNBLOCKING CREDIT TRANSACTIONS ----------------------------------");
Boolean isBlock = true; Boolean isBlock = true;
return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_CREDITS_SAVINGS_COMMAND, savingsID), return performSavingApplicationActions(createSavingsOperationURL(UNBLOCK_CREDITS_SAVINGS_COMMAND, savingsID),
getActivatedSavingsAsJSON(), isBlock); getActivatedSavingsAsJSON(), isBlock);
} }
public Object holdAmountInSavingsAccount(final Integer savingsID, final String amount, String date, String jsonAttributeToGetback) { public Object holdAmountInSavingsAccount(final Integer savingsID, final String amount, String date, String jsonAttributeToGetback) {
System.out.println("--------------------------------- SAVINGS TRANSACTION HOLD AMOUNT--------------------------------"); LOG.info("--------------------------------- SAVINGS TRANSACTION HOLD AMOUNT--------------------------------");
return performSavingActions(createSavingsTransactionURL(HOLD_AMOUNT_SAVINGS_COMMAND, savingsID), return performSavingActions(createSavingsTransactionURL(HOLD_AMOUNT_SAVINGS_COMMAND, savingsID),
getSavingsTransactionJSON(amount, date), jsonAttributeToGetback); getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
} }
public Integer releaseAmount(final Integer savingsId, final Integer transactionId) { public Integer releaseAmount(final Integer savingsId, final Integer transactionId) {
System.out.println("\n--------------------------------- SAVINGS TRANSACTION RELEASE AMOUNT--------------------------------"); LOG.info("\n--------------------------------- SAVINGS TRANSACTION RELEASE AMOUNT--------------------------------");
return (Integer) performSavingActions(createAdjustTransactionURL(RELEASE_AMOUNT_SAVINGS_COMMAND, savingsId, transactionId), return (Integer) performSavingActions(createAdjustTransactionURL(RELEASE_AMOUNT_SAVINGS_COMMAND, savingsId, transactionId),
getSavingsTransactionJSON("1000", LAST_TRANSACTION_DATE), CommonConstants.RESPONSE_RESOURCE_ID); getSavingsTransactionJSON("1000", LAST_TRANSACTION_DATE), CommonConstants.RESPONSE_RESOURCE_ID);
} }
@@ -356,7 +378,7 @@ public class SavingsAccountHelper {
map.put("approvedOnDate", approvalDate); map.put("approvedOnDate", approvalDate);
map.put("note", "Approval NOTE"); map.put("note", "Approval NOTE");
String savingsAccountApproveJson = new Gson().toJson(map); String savingsAccountApproveJson = new Gson().toJson(map);
System.out.println(savingsAccountApproveJson); LOG.info(savingsAccountApproveJson);
return savingsAccountApproveJson; return savingsAccountApproveJson;
} }
@@ -367,7 +389,7 @@ public class SavingsAccountHelper {
map.put("rejectedOnDate", rejectedOnDate); map.put("rejectedOnDate", rejectedOnDate);
map.put("note", "Rejected NOTE"); map.put("note", "Rejected NOTE");
String savingsAccountJson = new Gson().toJson(map); String savingsAccountJson = new Gson().toJson(map);
System.out.println(savingsAccountJson); LOG.info(savingsAccountJson);
return savingsAccountJson; return savingsAccountJson;
} }
@@ -378,7 +400,7 @@ public class SavingsAccountHelper {
map.put("withdrawnOnDate", CREATED_DATE_PLUS_ONE); map.put("withdrawnOnDate", CREATED_DATE_PLUS_ONE);
map.put("note", "Rejected NOTE"); map.put("note", "Rejected NOTE");
String savingsAccountJson = new Gson().toJson(map); String savingsAccountJson = new Gson().toJson(map);
System.out.println(savingsAccountJson); LOG.info(savingsAccountJson);
return savingsAccountJson; return savingsAccountJson;
} }
@@ -388,7 +410,7 @@ public class SavingsAccountHelper {
map.put("dateFormat", CommonConstants.dateFormat); map.put("dateFormat", CommonConstants.dateFormat);
map.put("activatedOnDate", TRANSACTION_DATE); map.put("activatedOnDate", TRANSACTION_DATE);
String savingsAccountActivateJson = new Gson().toJson(map); String savingsAccountActivateJson = new Gson().toJson(map);
System.out.println(savingsAccountActivateJson); LOG.info(savingsAccountActivateJson);
return savingsAccountActivateJson; return savingsAccountActivateJson;
} }
@@ -399,14 +421,14 @@ public class SavingsAccountHelper {
map.put("transactionDate", transactionDate); map.put("transactionDate", transactionDate);
map.put("transactionAmount", amount); map.put("transactionAmount", amount);
String savingsAccountWithdrawalJson = new Gson().toJson(map); String savingsAccountWithdrawalJson = new Gson().toJson(map);
System.out.println(savingsAccountWithdrawalJson); LOG.info(savingsAccountWithdrawalJson);
return savingsAccountWithdrawalJson; return savingsAccountWithdrawalJson;
} }
private String getCalculatedInterestForSavingsApplicationAsJSON() { private String getCalculatedInterestForSavingsApplicationAsJSON() {
final HashMap<String, String> map = new HashMap<>(); final HashMap<String, String> map = new HashMap<>();
String savingsAccountCalculatedInterestJson = new Gson().toJson(map); String savingsAccountCalculatedInterestJson = new Gson().toJson(map);
System.out.println(savingsAccountCalculatedInterestJson); LOG.info(savingsAccountCalculatedInterestJson);
return savingsAccountCalculatedInterestJson; return savingsAccountCalculatedInterestJson;
} }
@@ -472,10 +494,25 @@ public class SavingsAccountHelper {
return josn; return josn;
} }
private String updateGsimJSON(String clientID, String groupID, String productID) {
final HashMap<String, String> map = new HashMap<>();
map.put("clientId", clientID);
map.put("groupId", groupID);
map.put("productId", productID);
String savingsAccountJson = new Gson().toJson(map);
LOG.info(savingsAccountJson);
return savingsAccountJson;
}
private String createSavingsOperationURL(final String command, final Integer savingsID) { private String createSavingsOperationURL(final String command, final Integer savingsID) {
return SAVINGS_ACCOUNT_URL + "/" + savingsID + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER; return SAVINGS_ACCOUNT_URL + "/" + savingsID + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
} }
private String createSavingsGsimOperationURL(final String command, final Integer gsimID) {
return SAVINGS_ACCOUNT_URL + GSIM_SAVINGS_COMMAND +"/" + gsimID + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
}
private String createSavingsTransactionURL(final String command, final Integer savingsID) { private String createSavingsTransactionURL(final String command, final Integer savingsID) {
return SAVINGS_ACCOUNT_URL + "/" + savingsID + "/transactions?command=" + command + "&" + Utils.TENANT_IDENTIFIER; return SAVINGS_ACCOUNT_URL + "/" + savingsID + "/transactions?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
} }
@@ -568,14 +605,14 @@ public class SavingsAccountHelper {
public Object closeSavingsAccountAndGetBackRequiredField(final Integer savingsID, String withdrawBalance, public Object closeSavingsAccountAndGetBackRequiredField(final Integer savingsID, String withdrawBalance,
final String jsonAttributeToGetBack, final String closedOnDate) { final String jsonAttributeToGetBack, final String closedOnDate) {
System.out.println("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------"); LOG.info("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
return performSavingActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID), return performSavingActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID),
getCloseAccountJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack); getCloseAccountJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack);
} }
public Object closeSavingsAccountPostInterestAndGetBackRequiredField(final Integer savingsID, String withdrawBalance, public Object closeSavingsAccountPostInterestAndGetBackRequiredField(final Integer savingsID, String withdrawBalance,
final String jsonAttributeToGetBack, final String closedOnDate) { final String jsonAttributeToGetBack, final String closedOnDate) {
System.out.println("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------"); LOG.info("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
return performSavingActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID), return performSavingActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID),
getCloseAccountPostInterestJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack); getCloseAccountPostInterestJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack);
} }
@@ -656,7 +693,7 @@ public class SavingsAccountHelper {
private static Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, private static Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String minOpenningBalance) { final String minOpenningBalance) {
System.out.println("------------------------------CREATING NEW SAVINGS PRODUCT ---------------------------------------"); LOG.info("------------------------------CREATING NEW SAVINGS PRODUCT ---------------------------------------");
SavingsProductHelper savingsProductHelper = new SavingsProductHelper(); SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
final String savingsProductJSON = savingsProductHelper // final String savingsProductJSON = savingsProductHelper //
.withInterestCompoundingPeriodTypeAsDaily() // .withInterestCompoundingPeriodTypeAsDaily() //
@@ -705,4 +742,80 @@ public class SavingsAccountHelper {
return Utils.performServerOutputTemplateLocationGet(requestSpec,responseSpec,"/fineract-provider/api/v1/imports/getOutputTemplateLocation"+"?" return Utils.performServerOutputTemplateLocationGet(requestSpec,responseSpec,"/fineract-provider/api/v1/imports/getOutputTemplateLocation"+"?"
+Utils.TENANT_IDENTIFIER,importDocumentId); +Utils.TENANT_IDENTIFIER,importDocumentId);
} }
//gsim testing
public HashMap approveGsimSavings(final Integer gsimID) {
LOG.info("---------------GSIM APPROVAL---------------");
return approveGsimSavingsOnDate(gsimID, null);
}
public HashMap approveGsimSavingsOnDate(final Integer gsimID, final String approvalDate) {
LOG.info("--------------------------------- APPROVING GSIM SAVINGS APPLICATION ------------------------------------");
final String savingsOperationURL = createSavingsGsimOperationURL(APPROVE_SAVINGS_COMMAND, gsimID);
if (approvalDate == null || approvalDate.equals(""))
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJSON(), isBlock);
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJsonOnDate(approvalDate), isBlock);
}
public HashMap rejectGsimApplication(final Integer gsimID) {
LOG.info("--------------------------------- REJECT SAVINGS APPLICATION -------------------------------");
return performSavingApplicationActions(createSavingsGsimOperationURL(REJECT_SAVINGS_COMMAND, gsimID),
getRejectedSavingsAsJSON(CREATED_DATE_PLUS_ONE), isBlock);
}
public List rejectGsimApplicationWithErrorCode(final Integer gsimID, final String date) {
LOG.info("--------------------------------- REJECT SAVINGS APPLICATION -------------------------------");
return (List) performSavingActions(createSavingsGsimOperationURL(REJECT_SAVINGS_COMMAND, gsimID), getRejectedSavingsAsJSON(date),
CommonConstants.RESPONSE_ERROR);
}
public HashMap undoApprovalGsimSavings(final Integer gsimId) {
LOG.info("--------------------------------- UNDO APPROVING GSIM SAVINGS APPLICATION -------------------------------");
final String undoBodyJson = "{'note':'UNDO APPROVAL'}";
return performSavingApplicationActions(createSavingsGsimOperationURL(UNDO_APPROVAL_SAVINGS_COMMAND, gsimId), undoBodyJson, isBlock);
}
public Integer depositGsimApplication(Integer savingsID, List<Map<String, Object>> savingsArray) {
LOG.info("--------------------------------- DEPOSIT GSIM SAVINGS APPLICATION -------------------------------");
String savingsArrays = new SavingsApplicationTestBuilder() //
.withSavingsArray(savingsArray)
.build();
LOG.info("savingsArray : {} ", savingsArrays);
return SavingsAccountHelper.depositGsimApplication(savingsID, savingsArrays, requestSpec, responseSpec);
}
public static Integer depositGsimApplication(Integer savingsID, final String savingsArrays, final RequestSpecification requestSpec,
final ResponseSpecification responseSpec) {
final String depositGsimURL= SAVINGS_ACCOUNT_URL +"/"+savingsID+"/transactions"+"?"+"command="+GSIM_DEPOSIT_SAVINGS_COMMAND +"&"+ Utils.TENANT_IDENTIFIER;
LOG.info("depositGsimURL : {} ", depositGsimURL);
return Utils.performServerPost(requestSpec,responseSpec,depositGsimURL,savingsArrays, CommonConstants.RESPONSE_RESOURCE_ID);
}
public HashMap activateGsimSavings(final Integer gsimID) {
LOG.info("---------------------------------- ACTIVATING GSIM SAVINGS APPLICATION ----------------------------------");
return performSavingApplicationActions(createSavingsGsimOperationURL(ACTIVATE_SAVINGS_COMMAND, gsimID), getActivatedSavingsAsJSON(), isBlock);
}
public HashMap closeGsimSavingsAccount(final Integer gsimID, String withdrawBalance) {
LOG.info("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
return performSavingApplicationActions(createSavingsGsimOperationURL(CLOSE_SAVINGS_COMMAND, gsimID),
getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE), isBlock);
}
public Object closeGsimSavingsAccountAndGetBackRequiredField(final Integer gsimId, String withdrawBalance,
final String jsonAttributeToGetBack, final String closedOnDate) {
LOG.info("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
return performSavingActions(createSavingsGsimOperationURL(CLOSE_SAVINGS_COMMAND, gsimId),
getCloseAccountJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack);
}
public HashMap updateGsimApplication(final Integer gsimID, final Integer clientID, final Integer groupID, final Integer productID) {
LOG.info("--------------------------------- UPDATE GSIM SAVINGS APPLICATION -------------------------------");
final String GSIM_URL = "/fineract-provider/api/v1/savingsaccounts/gsim/" + gsimID + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerPut(requestSpec, responseSpec, GSIM_URL, updateGsimJSON(clientID.toString(), groupID.toString(), productID.toString()), "");
}
} }
@@ -19,11 +19,17 @@
package org.apache.fineract.integrationtests.common.savings; package org.apache.fineract.integrationtests.common.savings;
import com.google.gson.Gson; import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SavingsApplicationTestBuilder { public class SavingsApplicationTestBuilder {
private final static Logger LOG = LoggerFactory.getLogger(SavingsApplicationTestBuilder.class);
private static final String LOCALE = "en_GB"; private static final String LOCALE = "en_GB";
private String submittedOnDate = ""; private String submittedOnDate = "";
@@ -35,6 +41,9 @@ public class SavingsApplicationTestBuilder {
private List<HashMap<String, Object>> datatables = null; private List<HashMap<String, Object>> datatables = null;
private List<Map<String, Object>> clientArray =null;
private List<Map<String, Object>> savingsArray =null;
public String build(final String ID, final String savingsProductId, final String accountType) { public String build(final String ID, final String savingsProductId, final String accountType) {
final HashMap<String, Object> map = new HashMap<>(); final HashMap<String, Object> map = new HashMap<>();
@@ -55,11 +64,26 @@ public class SavingsApplicationTestBuilder {
if (datatables != null) { if (datatables != null) {
map.put("datatables", this.datatables); map.put("datatables", this.datatables);
} }
String savingsApplicationJSON = new Gson().toJson(map); String savingsApplicationJSON = new Gson().toJson(map);
System.out.println(savingsApplicationJSON); LOG.info("{}",savingsApplicationJSON);
return savingsApplicationJSON; return savingsApplicationJSON;
} }
public String build()
{
final HashMap<String, Object> map = new HashMap<>();
if(this.clientArray != null) {
map.put("clientArray", this.clientArray) ;
}
if(this.savingsArray != null) {
map.put("savingsArray", this.savingsArray) ;
}
String GsimApplicationJSON = new Gson().toJson(map);
return GsimApplicationJSON;
}
public SavingsApplicationTestBuilder withSubmittedOnDate(final String savingsApplicationSubmittedDate) { public SavingsApplicationTestBuilder withSubmittedOnDate(final String savingsApplicationSubmittedDate) {
this.submittedOnDate = savingsApplicationSubmittedDate; this.submittedOnDate = savingsApplicationSubmittedDate;
return this; return this;
@@ -84,4 +108,17 @@ public class SavingsApplicationTestBuilder {
this.datatables = datatables; this.datatables = datatables;
return this; return this;
} }
public SavingsApplicationTestBuilder withClientArray(final List<Map<String,Object>> clientArray) {
this.clientArray = new ArrayList<>();
this.clientArray.addAll(clientArray);
return this;
}
public SavingsApplicationTestBuilder withSavingsArray(final List<Map<String,Object>> savingsArray) {
this.savingsArray = new ArrayList<>();
this.savingsArray.addAll(savingsArray);
return this;
}
} }
@@ -28,10 +28,13 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account; import org.apache.fineract.integrationtests.common.accounting.Account;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class SavingsProductHelper { public class SavingsProductHelper {
private final static Logger LOG = LoggerFactory.getLogger(SavingsProductHelper.class);
private static final String SAVINGS_PRODUCT_URL = "/fineract-provider/api/v1/savingsproducts"; private static final String SAVINGS_PRODUCT_URL = "/fineract-provider/api/v1/savingsproducts";
private static final String CREATE_SAVINGS_PRODUCT_URL = SAVINGS_PRODUCT_URL + "?" + Utils.TENANT_IDENTIFIER; private static final String CREATE_SAVINGS_PRODUCT_URL = SAVINGS_PRODUCT_URL + "?" + Utils.TENANT_IDENTIFIER;
@@ -89,6 +92,9 @@ public class SavingsProductHelper {
private String daysToInactive = null; private String daysToInactive = null;
private String daysToDormancy = null; private String daysToDormancy = null;
private String daysToEscheat = null; private String daysToEscheat = null;
private Boolean withgsimID = null;
private Integer gsimID = null;
public String build() { public String build() {
final HashMap<String, String> map = new HashMap<>(); final HashMap<String, String> map = new HashMap<>();
@@ -125,6 +131,7 @@ public class SavingsProductHelper {
map.put("minRequiredBalance", this.minRequiredBalance); map.put("minRequiredBalance", this.minRequiredBalance);
map.put("enforceMinRequiredBalance", this.enforceMinRequiredBalance); map.put("enforceMinRequiredBalance", this.enforceMinRequiredBalance);
map.put("withHoldTax", this.withHoldTax.toString()); map.put("withHoldTax", this.withHoldTax.toString());
if (withHoldTax) { if (withHoldTax) {
map.put("taxGroupId", taxGroupId); map.put("taxGroupId", taxGroupId);
} }
@@ -138,8 +145,9 @@ public class SavingsProductHelper {
map.put("daysToEscheat", this.daysToEscheat); map.put("daysToEscheat", this.daysToEscheat);
} }
String savingsProductCreateJson = new Gson().toJson(map); String savingsProductCreateJson = new Gson().toJson(map);
System.out.println(savingsProductCreateJson); LOG.info("{}",savingsProductCreateJson);
return savingsProductCreateJson; return savingsProductCreateJson;
} }
@@ -228,6 +236,13 @@ public class SavingsProductHelper {
return this; return this;
} }
public SavingsProductHelper withgsimID(final Integer gsimID) {
if(withgsimID !=null) {
this.gsimID = gsimID;
}
return this;
}
public SavingsProductHelper withCurrencyCode(String currency) { public SavingsProductHelper withCurrencyCode(String currency) {
this.currencyCode = currency; this.currencyCode = currency;
return this; return this;
@@ -275,7 +290,7 @@ public class SavingsProductHelper {
public static void verifySavingsProductCreatedOnServer(final RequestSpecification requestSpec, public static void verifySavingsProductCreatedOnServer(final RequestSpecification requestSpec,
final ResponseSpecification responseSpec, final Integer generatedProductID) { final ResponseSpecification responseSpec, final Integer generatedProductID) {
System.out.println("------------------------------CHECK CLIENT DETAILS------------------------------------\n"); LOG.info("------------------------------CHECK CLIENT DETAILS------------------------------------\n");
final String GET_SAVINGS_PRODUCT_URL = SAVINGS_PRODUCT_URL + "/" + generatedProductID + "?" + Utils.TENANT_IDENTIFIER; final String GET_SAVINGS_PRODUCT_URL = SAVINGS_PRODUCT_URL + "/" + generatedProductID + "?" + Utils.TENANT_IDENTIFIER;
final Integer responseSavingsProductID = Utils.performServerGet(requestSpec, responseSpec, GET_SAVINGS_PRODUCT_URL, "id"); final Integer responseSavingsProductID = Utils.performServerGet(requestSpec, responseSpec, GET_SAVINGS_PRODUCT_URL, "id");
assertEquals("ERROR IN CREATING THE Savings Product", generatedProductID, responseSavingsProductID); assertEquals("ERROR IN CREATING THE Savings Product", generatedProductID, responseSavingsProductID);
@@ -286,7 +301,6 @@ public class SavingsProductHelper {
this.daysToInactive = "30"; this.daysToInactive = "30";
this.daysToDormancy = "60"; this.daysToDormancy = "60";
this.daysToEscheat = "90"; this.daysToEscheat = "90";
return this; return this;
} }
@@ -883,6 +883,15 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder rejectGLIMApplication(final Long glimId) {
this.actionName = "REJECT";
this.entityName = "GLIMLOAN";
this.entityId = glimId;
this.loanId = glimId;
this.href = "/loans/" + glimId;
return this;
}
public CommandWrapperBuilder withdrawLoanApplication(final Long loanId) { public CommandWrapperBuilder withdrawLoanApplication(final Long loanId) {
this.actionName = "WITHDRAW"; this.actionName = "WITHDRAW";
this.entityName = "LOAN"; this.entityName = "LOAN";
@@ -901,6 +910,50 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder approveGLIMLoanApplication(final Long glimId) {
this.actionName = "APPROVE";
this.entityName = "GLIMLOAN";
this.entityId = glimId;
this.loanId = glimId;
this.href = "/loans/" + glimId;
return this;
}
public CommandWrapperBuilder disburseGlimLoanApplication(final Long glimId) {
this.actionName = "DISBURSE";
this.entityName = "GLIMLOAN";
this.entityId = glimId;
this.loanId = glimId;
this.href = "/loans/" + glimId;
return this;
}
public CommandWrapperBuilder repaymentGlimLoanApplication(final Long glimId) {
this.actionName = "REPAYMENT";
this.entityName = "GLIMLOAN";
this.entityId = glimId;
this.loanId = glimId;
this.href = "/loans/" + glimId;
return this;
}
public CommandWrapperBuilder undoGLIMLoanDisbursal(final Long glimId) {
this.actionName = "UNDODISBURSAL";
this.entityName = "GLIMLOAN";
this.entityId = glimId;
this.loanId = glimId;
this.href = "/loans/" + glimId;
return this;
}
public CommandWrapperBuilder undoGLIMLoanApproval(final Long glimId) {
this.actionName = "UNDOAPPROVAL";
this.entityName = "GLIMLOAN";
this.entityId = glimId;
this.loanId = glimId;
this.href = "/loans/" + glimId;
return this;
}
public CommandWrapperBuilder disburseLoanApplication(final Long loanId) { public CommandWrapperBuilder disburseLoanApplication(final Long loanId) {
this.actionName = "DISBURSE"; this.actionName = "DISBURSE";
this.entityName = "LOAN"; this.entityName = "LOAN";
@@ -1126,6 +1179,14 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder createGSIMAccount() {
this.actionName = "CREATE";
this.entityName = "GSIMACCOUNT";
this.entityId = null;
this.href = "/gsimaccounts/template";
return this;
}
public CommandWrapperBuilder updateSavingsAccount(final Long accountId) { public CommandWrapperBuilder updateSavingsAccount(final Long accountId) {
this.actionName = "UPDATE"; this.actionName = "UPDATE";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
@@ -1134,6 +1195,14 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder updateGSIMAccount(final Long accountId) {
this.actionName = "UPDATE";
this.entityName = "GSIMACCOUNT";
this.entityId = accountId;
this.href = "/gsimaccounts/" + accountId;
return this;
}
public CommandWrapperBuilder deleteSavingsAccount(final Long accountId) { public CommandWrapperBuilder deleteSavingsAccount(final Long accountId) {
this.actionName = "DELETE"; this.actionName = "DELETE";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
@@ -1151,6 +1220,15 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder rejectGSIMAccountApplication(final Long accountId) {
this.actionName = "REJECT";
this.entityName = "GSIMACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.href = "/savingsaccounts/" + accountId + "?command=reject";
return this;
}
public CommandWrapperBuilder withdrawSavingsAccountApplication(final Long accountId) { public CommandWrapperBuilder withdrawSavingsAccountApplication(final Long accountId) {
this.actionName = "WITHDRAW"; this.actionName = "WITHDRAW";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
@@ -1169,6 +1247,15 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder approveGSIMAccountApplication(final Long accountId) {
this.actionName = "APPROVE";
this.entityName = "GSIMACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.href = "/gsimsaccounts/" + accountId + "?command=approve";
return this;
}
public CommandWrapperBuilder undoSavingsAccountApplication(final Long accountId) { public CommandWrapperBuilder undoSavingsAccountApplication(final Long accountId) {
this.actionName = "APPROVALUNDO"; this.actionName = "APPROVALUNDO";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
@@ -1178,6 +1265,15 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder undoGSIMApplicationApproval(final Long accountId) {
this.actionName = "APPROVALUNDO";
this.entityName = "GSIMACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.href = "/savingsaccounts/" + accountId + "?command=undoapproval";
return this;
}
public CommandWrapperBuilder savingsAccountActivation(final Long accountId) { public CommandWrapperBuilder savingsAccountActivation(final Long accountId) {
this.actionName = "ACTIVATE"; this.actionName = "ACTIVATE";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
@@ -1187,6 +1283,15 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder gsimAccountActivation(final Long accountId) {
this.actionName = "ACTIVATE";
this.entityName = "GSIMACCOUNT";
this.savingsId = accountId;
this.entityId = null;
this.href = "/savingsaccounts/" + accountId + "?command=activate";
return this;
}
public CommandWrapperBuilder closeSavingsAccountApplication(final Long accountId) { public CommandWrapperBuilder closeSavingsAccountApplication(final Long accountId) {
this.actionName = "CLOSE"; this.actionName = "CLOSE";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
@@ -1196,6 +1301,15 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder closeGSIMApplication(final Long accountId) {
this.actionName = "CLOSE";
this.entityName = "GSIMACCOUNT";
this.entityId = accountId;
this.savingsId = accountId;
this.href = "/savingsaccounts/" + accountId + "?command=close";
return this;
}
public CommandWrapperBuilder createAccountTransfer() { public CommandWrapperBuilder createAccountTransfer() {
this.actionName = "CREATE"; this.actionName = "CREATE";
this.entityName = "ACCOUNTTRANSFER"; this.entityName = "ACCOUNTTRANSFER";
@@ -1237,6 +1351,15 @@ public class CommandWrapperBuilder {
return this; return this;
} }
public CommandWrapperBuilder gsimSavingsAccountDeposit(final Long accountId) {
this.actionName = "DEPOSIT";
this.entityName = "GSIMACCOUNT";
this.savingsId = accountId;
this.entityId = null;
this.href = "/savingsaccounts/" + accountId + "/transactions";
return this;
}
public CommandWrapperBuilder savingsAccountWithdrawal(final Long accountId) { public CommandWrapperBuilder savingsAccountWithdrawal(final Long accountId) {
this.actionName = "WITHDRAWAL"; this.actionName = "WITHDRAWAL";
this.entityName = "SAVINGSACCOUNT"; this.entityName = "SAVINGSACCOUNT";
@@ -97,6 +97,13 @@ public final class JsonCommand {
command.transactionId, command.url, command.productId,command.creditBureauId,command.organisationCreditBureauId); command.transactionId, command.url, command.productId,command.creditBureauId,command.organisationCreditBureauId);
} }
public static JsonCommand fromExistingCommand(JsonCommand command, final JsonElement parsedCommand,final Long clientId) {
final String jsonCommand = command.fromApiJsonHelper.toJson(parsedCommand);
return new JsonCommand(command.commandId, jsonCommand, parsedCommand, command.fromApiJsonHelper, command.entityName,
command.resourceId, command.subresourceId, command.groupId, clientId, command.loanId, command.savingsId,
command.transactionId, command.url, command.productId,command.creditBureauId,command.organisationCreditBureauId);
}
public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand,
final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId, final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId,
final Long groupId, final Long clientId, final Long loanId, final Long savingsId, final String transactionId, final String url, final Long groupId, final Long clientId, final Long loanId, final Long savingsId, final String transactionId, final String url,
@@ -41,13 +41,15 @@ public class CommandProcessingResult implements Serializable {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String resourceIdentifier; private final String resourceIdentifier;
private final Long productId; private final Long productId;
private final Long gsimId;
private final Long glimId;
private Boolean rollbackTransaction; private Boolean rollbackTransaction;
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId, 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 String transactionId, 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 Map<String, Object> changes, final Long productId, final Boolean rollbackTransaction, final Long subResourceId) {
return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId, return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId,
transactionId, changes, productId, rollbackTransaction, subResourceId); transactionId, changes, productId, gsimId, glimId, rollbackTransaction, subResourceId);
} }
public static CommandProcessingResult commandOnlyResult(final Long commandId) { public static CommandProcessingResult commandOnlyResult(final Long commandId) {
@@ -97,12 +99,14 @@ public class CommandProcessingResult implements Serializable {
this.transactionId = null; this.transactionId = null;
this.changes = new HashMap<>(); this.changes = new HashMap<>();
this.productId = null; this.productId = null;
this.gsimId=null;
this.glimId=null;
this.subResourceId = null; this.subResourceId = null;
} }
private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId, 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 Long savingsId, final String resourceIdentifier, final Long resourceId, final String transactionId,
final Map<String, Object> changesOnly, final Long productId, Boolean rollbackTransaction, final Long subResourceId) { final Map<String, Object> changesOnly, final Long productId, final Long gsimId, final Long glimId, Boolean rollbackTransaction, final Long subResourceId) {
this.commandId = commandId; this.commandId = commandId;
this.officeId = officeId; this.officeId = officeId;
this.groupId = groupId; this.groupId = groupId;
@@ -114,6 +118,8 @@ public class CommandProcessingResult implements Serializable {
this.changes = changesOnly; this.changes = changesOnly;
this.transactionId = transactionId; this.transactionId = transactionId;
this.productId = productId; this.productId = productId;
this.gsimId=gsimId;
this.glimId=glimId;
this.rollbackTransaction = rollbackTransaction; this.rollbackTransaction = rollbackTransaction;
this.subResourceId = subResourceId; this.subResourceId = subResourceId;
} }
@@ -134,6 +140,8 @@ public class CommandProcessingResult implements Serializable {
this.commandId = commandId; this.commandId = commandId;
this.changes = changesOnly; this.changes = changesOnly;
this.productId = null; this.productId = null;
this.gsimId=null;
this.glimId=null;
this.subResourceId = null; this.subResourceId = null;
} }
@@ -190,6 +198,14 @@ public class CommandProcessingResult implements Serializable {
return this.productId; return this.productId;
} }
public Long getGsimId() {
return this.gsimId;
}
public Long getGlimId() {
return this.glimId;
}
public boolean isRollbackTransaction() { public boolean isRollbackTransaction() {
return this.rollbackTransaction != null && this.rollbackTransaction; return this.rollbackTransaction != null && this.rollbackTransaction;
} }
@@ -35,6 +35,8 @@ public class CommandProcessingResultBuilder {
private String resourceIdentifier; private String resourceIdentifier;
private Long entityId; private Long entityId;
private Long subEntityId; private Long subEntityId;
private Long gsimId;
private Long glimId;
private String transactionId; private String transactionId;
private Map<String, Object> changes; private Map<String, Object> changes;
private Long productId; private Long productId;
@@ -42,7 +44,7 @@ public class CommandProcessingResultBuilder {
public CommandProcessingResult build() { public CommandProcessingResult build() {
return CommandProcessingResult.fromDetails(this.commandId, this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, return CommandProcessingResult.fromDetails(this.commandId, this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId,
this.resourceIdentifier, this.entityId, this.transactionId, this.changes, this.productId, this.rollbackTransaction, this.resourceIdentifier, this.entityId, this.gsimId, this.glimId, this.transactionId, this.changes, this.productId, this.rollbackTransaction,
this.subEntityId); this.subEntityId);
} }
@@ -106,6 +108,16 @@ public class CommandProcessingResultBuilder {
return this; return this;
} }
public CommandProcessingResultBuilder withGsimId(final Long gsimId) {
this.gsimId = gsimId;
return this;
}
public CommandProcessingResultBuilder withGlimId(final Long glimId) {
this.glimId = glimId;
return this;
}
public CommandProcessingResultBuilder setRollbackTransaction(final boolean rollbackTransaction) { public CommandProcessingResultBuilder setRollbackTransaction(final boolean rollbackTransaction) {
this.rollbackTransaction = this.rollbackTransaction || rollbackTransaction; this.rollbackTransaction = this.rollbackTransaction || rollbackTransaction;
return this; return this;
@@ -52,6 +52,8 @@ import org.apache.fineract.portfolio.loanaccount.service.LoanAssembler;
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService; import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
import org.apache.fineract.portfolio.savings.SavingsTransactionBooleanValues; import org.apache.fineract.portfolio.savings.SavingsTransactionBooleanValues;
import org.apache.fineract.portfolio.savings.domain.GSIMRepositoy;
import org.apache.fineract.portfolio.savings.domain.GroupSavingsIndividualMonitoring;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler; import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountDomainService; import org.apache.fineract.portfolio.savings.domain.SavingsAccountDomainService;
@@ -77,6 +79,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
private final SavingsAccountWritePlatformService savingsAccountWritePlatformService; private final SavingsAccountWritePlatformService savingsAccountWritePlatformService;
private final AccountTransferDetailRepository accountTransferDetailRepository; private final AccountTransferDetailRepository accountTransferDetailRepository;
private final LoanReadPlatformService loanReadPlatformService; private final LoanReadPlatformService loanReadPlatformService;
private final GSIMRepositoy gsimRepository;
@Autowired @Autowired
public AccountTransfersWritePlatformServiceImpl(final AccountTransfersDataValidator accountTransfersDataValidator, public AccountTransfersWritePlatformServiceImpl(final AccountTransfersDataValidator accountTransfersDataValidator,
@@ -85,7 +88,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final LoanAssembler loanAssembler, final LoanAccountDomainService loanAccountDomainService, final LoanAssembler loanAssembler, final LoanAccountDomainService loanAccountDomainService,
final SavingsAccountWritePlatformService savingsAccountWritePlatformService, final SavingsAccountWritePlatformService savingsAccountWritePlatformService,
final AccountTransferDetailRepository accountTransferDetailRepository, final AccountTransferDetailRepository accountTransferDetailRepository,
final LoanReadPlatformService loanReadPlatformService) { final LoanReadPlatformService loanReadPlatformService,
final GSIMRepositoy gsimRepository) {
this.accountTransfersDataValidator = accountTransfersDataValidator; this.accountTransfersDataValidator = accountTransfersDataValidator;
this.accountTransferAssembler = accountTransferAssembler; this.accountTransferAssembler = accountTransferAssembler;
this.accountTransferRepository = accountTransferRepository; this.accountTransferRepository = accountTransferRepository;
@@ -96,6 +100,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
this.savingsAccountWritePlatformService = savingsAccountWritePlatformService; this.savingsAccountWritePlatformService = savingsAccountWritePlatformService;
this.accountTransferDetailRepository = accountTransferDetailRepository; this.accountTransferDetailRepository = accountTransferDetailRepository;
this.loanReadPlatformService = loanReadPlatformService; this.loanReadPlatformService = loanReadPlatformService;
this.gsimRepository=gsimRepository;
} }
@Transactional @Transactional
@@ -410,6 +415,16 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
toSavingsAccount, deposit, loanTransaction); toSavingsAccount, deposit, loanTransaction);
this.accountTransferDetailRepository.saveAndFlush(accountTransferDetails); this.accountTransferDetailRepository.saveAndFlush(accountTransferDetails);
transferTransactionId = accountTransferDetails.getId(); transferTransactionId = accountTransferDetails.getId();
// if the savings account is GSIM, update its parent as well
if(toSavingsAccount.getGsim()!=null)
{
GroupSavingsIndividualMonitoring gsim=gsimRepository.findById(toSavingsAccount.getGsim().getId()).get();
BigDecimal currentBalance=gsim.getParentDeposit();
BigDecimal newBalance=currentBalance.add(accountTransferDTO.getTransactionAmount());
gsim.setParentDeposit(newBalance);
gsimRepository.save(gsim);
}
} else { } else {
throw new GeneralPlatformDomainRuleException("error.msg.accounttransfer.loan.to.loan.not.supported", throw new GeneralPlatformDomainRuleException("error.msg.accounttransfer.loan.to.loan.not.supported",
"Account transfer from loan to another loan is not supported"); "Account transfer from loan to another loan is not supported");
@@ -27,6 +27,7 @@ import java.util.Collection;
public class AccountSummaryCollectionData { public class AccountSummaryCollectionData {
private final Collection<LoanAccountSummaryData> loanAccounts; private final Collection<LoanAccountSummaryData> loanAccounts;
private final Collection<LoanAccountSummaryData> groupLoanIndividualMonitoringAccounts;
private final Collection<SavingsAccountSummaryData> savingsAccounts; private final Collection<SavingsAccountSummaryData> savingsAccounts;
private final Collection<ShareAccountSummaryData> shareAccounts ; private final Collection<ShareAccountSummaryData> shareAccounts ;
private final Collection<GuarantorAccountSummaryData> guarantorAccounts; private final Collection<GuarantorAccountSummaryData> guarantorAccounts;
@@ -35,10 +36,15 @@ public class AccountSummaryCollectionData {
private final Collection<SavingsAccountSummaryData> memberSavingsAccounts; private final Collection<SavingsAccountSummaryData> memberSavingsAccounts;
private final Collection<GuarantorAccountSummaryData> memberGuarantorAccounts; private final Collection<GuarantorAccountSummaryData> memberGuarantorAccounts;
public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts,
final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<ShareAccountSummaryData> shareAccounts, /* METHOD SIGNATURE CHANGE NOTICE: Method's signature
final Collection<GuarantorAccountSummaryData> guarantorAccounts) { was changed for GLIM & GSIM implementation*/
public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts,final Collection<LoanAccountSummaryData> groupLoanIndividualMonitoringAccounts,
final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<ShareAccountSummaryData> shareAccounts,final Collection<GuarantorAccountSummaryData> guarantorAccounts)
{
this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts); this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts);
this.groupLoanIndividualMonitoringAccounts=groupLoanIndividualMonitoringAccounts;
this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts); this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts);
this.shareAccounts = defaultShareAccountsIfEmpty(shareAccounts) ; this.shareAccounts = defaultShareAccountsIfEmpty(shareAccounts) ;
this.guarantorAccounts = guarantorAccounts; this.guarantorAccounts = guarantorAccounts;
@@ -47,10 +53,13 @@ public class AccountSummaryCollectionData {
this.memberGuarantorAccounts = null; this.memberGuarantorAccounts = null;
} }
public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts, public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts,final Collection<LoanAccountSummaryData> groupLoanIndividualMonitoringAccounts,
final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<GuarantorAccountSummaryData> guarantorAccounts, final Collection<LoanAccountSummaryData> memberLoanAccounts, final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<GuarantorAccountSummaryData> guarantorAccounts, final Collection<LoanAccountSummaryData> memberLoanAccounts,
final Collection<SavingsAccountSummaryData> memberSavingsAccounts, final Collection<GuarantorAccountSummaryData> memberGuarantorAccounts) { final Collection<SavingsAccountSummaryData> memberSavingsAccounts, final Collection<GuarantorAccountSummaryData> memberGuarantorAccounts) {
/* Note to Self: GSIM not passed in*/
this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts); this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts);
this.groupLoanIndividualMonitoringAccounts=groupLoanIndividualMonitoringAccounts;
this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts); this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts);
this.guarantorAccounts = guarantorAccounts; this.guarantorAccounts = guarantorAccounts;
this.shareAccounts = null ; this.shareAccounts = null ;
@@ -31,6 +31,7 @@ public class LoanAccountSummaryData {
private final Long id; private final Long id;
private final String accountNo; private final String accountNo;
private final String parentAccountNumber;
private final String externalId; private final String externalId;
private final Long productId; private final Long productId;
private final String productName; private final String productName;
@@ -49,6 +50,28 @@ public class LoanAccountSummaryData {
final LoanApplicationTimelineData timeline, final Boolean inArrears,final BigDecimal originalLoan,final BigDecimal loanBalance,final BigDecimal amountPaid) { final LoanApplicationTimelineData timeline, final Boolean inArrears,final BigDecimal originalLoan,final BigDecimal loanBalance,final BigDecimal amountPaid) {
this.id = id; this.id = id;
this.accountNo = accountNo; this.accountNo = accountNo;
this.parentAccountNumber=null;
this.externalId = externalId;
this.productId = productId;
this.productName = loanProductName;
this.shortProductName = shortLoanProductName;
this.status = loanStatus;
this.loanType = loanType;
this.loanCycle = loanCycle;
this.timeline = timeline;
this.inArrears = inArrears;
this.loanBalance = loanBalance;
this.originalLoan = originalLoan;
this.amountPaid = amountPaid;
}
public LoanAccountSummaryData(final Long id, final String accountNo,final String parentAccountNumber, final String externalId, final Long productId,
final String loanProductName, final String shortLoanProductName, final LoanStatusEnumData loanStatus, final EnumOptionData loanType, final Integer loanCycle,
final LoanApplicationTimelineData timeline, final Boolean inArrears,final BigDecimal originalLoan,final BigDecimal loanBalance,final BigDecimal amountPaid) {
this.id = id;
this.accountNo = accountNo;
this.parentAccountNumber=parentAccountNumber;
this.externalId = externalId; this.externalId = externalId;
this.productId = productId; this.productId = productId;
this.productName = loanProductName; this.productName = loanProductName;
@@ -69,4 +69,12 @@ public class SavingsAccountSummaryData {
this.subStatus = subStatus; this.subStatus = subStatus;
this.lastActiveTransactionDate = lastActiveTransactionDate; this.lastActiveTransactionDate = lastActiveTransactionDate;
} }
public String getAccountNo() {
return accountNo;
}
public Long getId() {
return id;
}
} }
@@ -0,0 +1,83 @@
/**
* 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.accountdetails.data;
import java.math.BigDecimal;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountApplicationTimelineData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountStatusEnumData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountSubStatusEnumData;
import org.joda.time.LocalDate;
@SuppressWarnings("unused")
public class SavingsSummaryCustom
{
private final Long id;
private final String displayName;
private final String accountNo;
private final String externalId;
private final Long productId;
private final String productName;
private final String shortProductName;
private final SavingsAccountStatusEnumData status;
private final CurrencyData currency;
private final BigDecimal accountBalance;
//differentiate Individual, JLG or Group account
private final EnumOptionData accountType;
private final SavingsAccountApplicationTimelineData timeline;
private final SavingsAccountSubStatusEnumData subStatus;
private final LocalDate lastActiveTransactionDate;
//differentiate deposit accounts Savings, FD and RD accounts
private final EnumOptionData depositType;
public SavingsSummaryCustom(final Long id,final String displayName, final String accountNo, final String externalId, final Long productId,
final String productName, final String shortProductName, final SavingsAccountStatusEnumData status, final CurrencyData currency,
final BigDecimal accountBalance, final EnumOptionData accountType, final SavingsAccountApplicationTimelineData timeline, final EnumOptionData depositType,
final SavingsAccountSubStatusEnumData subStatus, final LocalDate lastActiveTransactionDate) {
this.id = id;
this.displayName=displayName;
this.accountNo = accountNo;
this.externalId = externalId;
this.productId = productId;
this.productName = productName;
this.shortProductName = shortProductName;
this.status = status;
this.currency = currency;
this.accountBalance = accountBalance;
this.accountType = accountType;
this.timeline = timeline;
this.depositType = depositType;
this.subStatus = subStatus;
this.lastActiveTransactionDate = lastActiveTransactionDate;
}
public String getAccountNo() {
return accountNo;
}
public Long getId() {
return id;
}
}
@@ -26,7 +26,9 @@ public enum AccountType {
INVALID(0, "accountType.invalid"), // INVALID(0, "accountType.invalid"), //
INDIVIDUAL(1, "accountType.individual"), // INDIVIDUAL(1, "accountType.individual"), //
GROUP(2, "accountType.group"), // GROUP(2, "accountType.group"), //
JLG(3, "accountType.jlg");// JLG account given in group context JLG(3, "accountType.jlg"),// JLG account given in group context
GLIM(4, "accountType.glim"),
GSIM(5, "accountType.gsim");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -49,6 +51,12 @@ public enum AccountType {
case 3: case 3:
enumeration = AccountType.JLG; enumeration = AccountType.JLG;
break; break;
case 4:
enumeration = AccountType.GLIM;
break;
case 5:
enumeration = AccountType.GSIM;
break;
} }
return enumeration; return enumeration;
} }
@@ -91,4 +99,12 @@ public enum AccountType {
public boolean isJLGAccount() { public boolean isJLGAccount() {
return this.value.equals(AccountType.JLG.getValue()); return this.value.equals(AccountType.JLG.getValue());
} }
public boolean isGLIMAccount() {
return this.value.equals(AccountType.GLIM.getValue());
}
public boolean isGSIMAccount() {
return this.value.equals(AccountType.GSIM.getValue());
}
} }
@@ -19,6 +19,7 @@
package org.apache.fineract.portfolio.accountdetails.service; package org.apache.fineract.portfolio.accountdetails.service;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import org.apache.fineract.portfolio.accountdetails.data.AccountSummaryCollectionData; import org.apache.fineract.portfolio.accountdetails.data.AccountSummaryCollectionData;
import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData; import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData;
@@ -33,4 +34,8 @@ public interface AccountDetailsReadPlatformService {
public Collection<LoanAccountSummaryData> retrieveGroupLoanAccountsByLoanOfficerId(final Long groupId, final Long loanOfficerId); public Collection<LoanAccountSummaryData> retrieveGroupLoanAccountsByLoanOfficerId(final Long groupId, final Long loanOfficerId);
public Collection<LoanAccountSummaryData> retrieveClientActiveLoanAccountSummary(final Long clientId); public Collection<LoanAccountSummaryData> retrieveClientActiveLoanAccountSummary(final Long clientId);
public List<LoanAccountSummaryData> retrieveLoanAccountDetailsByGroupIdAndGlimAccountNumber(Long groupId,final String glimAccount);
AccountSummaryCollectionData retrieveGroupAccountDetails(Long groupId, Long gsimId);
} }
@@ -74,15 +74,20 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
// Check if client exists // Check if client exists
this.clientReadPlatformService.retrieveOne(clientId); this.clientReadPlatformService.retrieveOne(clientId);
final String loanwhereClause = " where l.client_id = ?"; final String loanwhereClause = " where l.client_id = ?";
final String glimLoanClause=" where l.client_id = ? and l.loan_type_enum=4";
//note to self: investigate the effect of have loans stored as another type especially given that we want to maintain how the system currently handles loans of exisiting types.
final String savingswhereClause = " where sa.client_id = ? order by sa.status_enum ASC, sa.account_no ASC"; final String savingswhereClause = " where sa.client_id = ? order by sa.status_enum ASC, sa.account_no ASC";
final String guarantorWhereClause = " where g.entity_id = ? and g.is_active = 1 order by l.account_no ASC"; final String guarantorWhereClause = " where g.entity_id = ? and g.is_active = 1 order by l.account_no ASC";
final List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(glimLoanClause, new Object[] { clientId });
final List<LoanAccountSummaryData> loanAccounts = retrieveLoanAccountDetails(loanwhereClause, new Object[] { clientId }); final List<LoanAccountSummaryData> loanAccounts = retrieveLoanAccountDetails(loanwhereClause, new Object[] { clientId });
final List<SavingsAccountSummaryData> savingsAccounts = retrieveAccountDetails(savingswhereClause, new Object[] { clientId }); final List<SavingsAccountSummaryData> savingsAccounts = retrieveAccountDetails(savingswhereClause, new Object[] { clientId });
final List<ShareAccountSummaryData> shareAccounts = retrieveShareAccountDetails(clientId) ; final List<ShareAccountSummaryData> shareAccounts = retrieveShareAccountDetails(clientId) ;
final List<GuarantorAccountSummaryData> guarantorloanAccounts = retrieveGuarantorLoanAccountDetails( final List<GuarantorAccountSummaryData> guarantorloanAccounts = retrieveGuarantorLoanAccountDetails(
guarantorWhereClause, new Object[] { clientId }); guarantorWhereClause, new Object[] { clientId });
return new AccountSummaryCollectionData(loanAccounts, savingsAccounts, shareAccounts, guarantorloanAccounts); return new AccountSummaryCollectionData(loanAccounts,glimAccounts, savingsAccounts, shareAccounts,guarantorloanAccounts);
} }
@Override @Override
@@ -90,11 +95,14 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
// Check if group exists // Check if group exists
this.groupReadPlatformService.retrieveOne(groupId); this.groupReadPlatformService.retrieveOne(groupId);
final String loanWhereClauseForGroup = " where l.group_id = ? and l.client_id is null"; final String loanWhereClauseForGroup = " where l.group_id = ? and l.client_id is null";
final String loanWhereClauseForGroupAndLoanType = " where l.group_id = ? and l.loan_type_enum=4";
final String loanWhereClauseForMembers = " where l.group_id = ? and l.client_id is not null"; final String loanWhereClauseForMembers = " where l.group_id = ? and l.client_id is not null";
final String savingswhereClauseForGroup = " where sa.group_id = ? and sa.client_id is null order by sa.status_enum ASC, sa.account_no ASC"; final String savingswhereClauseForGroup = " where sa.group_id = ? and sa.client_id is null order by sa.status_enum ASC, sa.account_no ASC";
final String savingswhereClauseForMembers = " where sa.group_id = ? and sa.client_id is not null order by sa.status_enum ASC, sa.account_no ASC"; final String savingswhereClauseForMembers = " where sa.group_id = ? and sa.client_id is not null order by sa.status_enum ASC, sa.account_no ASC";
final String guarantorWhereClauseForGroup = " where l.group_id = ? and l.client_id is null and g.is_active = 1 order by l.account_no ASC"; final String guarantorWhereClauseForGroup = " where l.group_id = ? and l.client_id is null and g.is_active = 1 order by l.account_no ASC";
final String guarantorWhereClauseForMembers = " where l.group_id = ? and l.client_id is not null and g.is_active = 1 order by l.account_no ASC"; final String guarantorWhereClauseForMembers = " where l.group_id = ? and l.client_id is not null and g.is_active = 1 order by l.account_no ASC";
final List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId });
final List<LoanAccountSummaryData> groupLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroup, new Object[] { groupId }); final List<LoanAccountSummaryData> groupLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroup, new Object[] { groupId });
final List<SavingsAccountSummaryData> groupSavingsAccounts = retrieveAccountDetails(savingswhereClauseForGroup, final List<SavingsAccountSummaryData> groupSavingsAccounts = retrieveAccountDetails(savingswhereClauseForGroup,
@@ -105,9 +113,32 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
new Object[] { groupId }); new Object[] { groupId });
final List<SavingsAccountSummaryData> memberSavingsAccounts = retrieveAccountDetails(savingswhereClauseForMembers, final List<SavingsAccountSummaryData> memberSavingsAccounts = retrieveAccountDetails(savingswhereClauseForMembers,
new Object[] { groupId }); new Object[] { groupId });
final List<GuarantorAccountSummaryData> memberGuarantorloanAccounts = retrieveGuarantorLoanAccountDetails( final List<GuarantorAccountSummaryData> memberGuarantorloanAccounts = retrieveGuarantorLoanAccountDetails(
guarantorWhereClauseForMembers, new Object[] { groupId }); guarantorWhereClauseForMembers, new Object[] { groupId });
return new AccountSummaryCollectionData(groupLoanAccounts, groupSavingsAccounts, groupGuarantorloanAccounts, memberLoanAccounts, memberSavingsAccounts, memberGuarantorloanAccounts); return new AccountSummaryCollectionData(groupLoanAccounts,glimAccounts, groupSavingsAccounts, groupGuarantorloanAccounts, memberLoanAccounts, memberSavingsAccounts, memberGuarantorloanAccounts);
}
@Override
public AccountSummaryCollectionData retrieveGroupAccountDetails(final Long groupId,final Long gsimId) {
// Check if group exists
this.groupReadPlatformService.retrieveOne(groupId);
final String loanWhereClauseForGroup = " where l.group_id = ? and l.client_id is null";
final String loanWhereClauseForGroupAndLoanType = " where l.group_id = ? and l.loan_type_enum=4";
final String loanWhereClauseForMembers = " where l.group_id = ? and l.client_id is not null";
final String savingswhereClauseForGroup = " where sa.group_id = ? and sa.gsim_id = ? sa.client_id is null order by sa.status_enum ASC, sa.account_no ASC";
final String savingswhereClauseForMembers = " where sa.group_id = ? and sa.client_id is not null order by sa.status_enum ASC, sa.account_no ASC";
final List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId });
final List<LoanAccountSummaryData> groupLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroup, new Object[] { groupId });
final List<SavingsAccountSummaryData> gsimSavingsAccounts = retrieveAccountDetails(savingswhereClauseForGroup,
new Object[] { groupId,gsimId });
final List<LoanAccountSummaryData> memberLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForMembers,
new Object[] { groupId });
final List<SavingsAccountSummaryData> memberSavingsAccounts = retrieveAccountDetails(savingswhereClauseForMembers,
new Object[] { groupId });
return new AccountSummaryCollectionData(groupLoanAccounts, glimAccounts,gsimSavingsAccounts, null,memberLoanAccounts, memberSavingsAccounts,null);
} }
@Override @Override
@@ -131,6 +162,16 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
return retrieveLoanAccountDetails(loanWhereClause, new Object[] { clientId }); return retrieveLoanAccountDetails(loanWhereClause, new Object[] { clientId });
} }
@Override
public List<LoanAccountSummaryData> retrieveLoanAccountDetailsByGroupIdAndGlimAccountNumber(final Long groupId,final String glimAccount) {
final LoanAccountSummaryDataMapper rm = new LoanAccountSummaryDataMapper();
final String loanWhereClauseForGroupAndLoanType = " where l.group_id =? and glim.account_number=? and l.loan_type_enum=4";
final String sql = "select " + rm.loanAccountSummarySchema() + loanWhereClauseForGroupAndLoanType;
// this.columnValidator.validateSqlInjection(rm.loanAccountSummarySchema(), loanWhereClauseForGroupAndLoanType);
return this.jdbcTemplate.query(sql, rm, new Object[]{groupId , glimAccount});
}
private List<LoanAccountSummaryData> retrieveLoanAccountDetails(final String loanwhereClause, final Object[] inputs) { private List<LoanAccountSummaryData> retrieveLoanAccountDetails(final String loanwhereClause, final Object[] inputs) {
final LoanAccountSummaryDataMapper rm = new LoanAccountSummaryDataMapper(); final LoanAccountSummaryDataMapper rm = new LoanAccountSummaryDataMapper();
final String sql = "select " + rm.loanAccountSummarySchema() + loanwhereClause; final String sql = "select " + rm.loanAccountSummarySchema() + loanwhereClause;
@@ -404,6 +445,8 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
.append(" l.product_id as productId, lp.name as productName, lp.short_name as shortProductName,") .append(" l.product_id as productId, lp.name as productName, lp.short_name as shortProductName,")
.append(" l.loan_status_id as statusId, l.loan_type_enum as loanType,") .append(" l.loan_status_id as statusId, l.loan_type_enum as loanType,")
.append(" glim.account_number as parentAccountNumber,")
.append("l.principal_disbursed_derived as originalLoan,") .append("l.principal_disbursed_derived as originalLoan,")
.append("l.total_outstanding_derived as loanBalance,") .append("l.total_outstanding_derived as loanBalance,")
.append("l.total_repayment_derived as amountPaid,") .append("l.total_repayment_derived as amountPaid,")
@@ -437,7 +480,8 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
.append(" left join m_appuser abu on abu.id = l.approvedon_userid") .append(" left join m_appuser abu on abu.id = l.approvedon_userid")
.append(" left join m_appuser dbu on dbu.id = l.disbursedon_userid") .append(" left join m_appuser dbu on dbu.id = l.disbursedon_userid")
.append(" left join m_appuser cbu on cbu.id = l.closedon_userid") .append(" left join m_appuser cbu on cbu.id = l.closedon_userid")
.append(" left join m_loan_arrears_aging la on la.loan_id = l.id"); .append(" left join m_loan_arrears_aging la on la.loan_id = l.id")
.append(" left join glim_accounts glim on glim.id=l.glim_id");
return accountsSummary.toString(); return accountsSummary.toString();
} }
@@ -447,6 +491,7 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
final Long id = JdbcSupport.getLong(rs, "id"); final Long id = JdbcSupport.getLong(rs, "id");
final String accountNo = rs.getString("accountNo"); final String accountNo = rs.getString("accountNo");
final String parentAccountNumber=rs.getString("parentAccountNumber");
final String externalId = rs.getString("externalId"); final String externalId = rs.getString("externalId");
final Long productId = JdbcSupport.getLong(rs, "productId"); final Long productId = JdbcSupport.getLong(rs, "productId");
final String loanProductName = rs.getString("productName"); final String loanProductName = rs.getString("productName");
@@ -509,7 +554,7 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
disbursedByFirstname, disbursedByLastname, closedOnDate, closedByUsername, closedByFirstname, closedByLastname, disbursedByFirstname, disbursedByLastname, closedOnDate, closedByUsername, closedByFirstname, closedByLastname,
expectedMaturityDate, writtenOffOnDate, closedByUsername, closedByFirstname, closedByLastname); expectedMaturityDate, writtenOffOnDate, closedByUsername, closedByFirstname, closedByLastname);
return new LoanAccountSummaryData(id, accountNo, externalId, productId, loanProductName, shortLoanProductName, loanStatus, loanType, loanCycle, return new LoanAccountSummaryData(id, accountNo,parentAccountNumber, externalId, productId, loanProductName, shortLoanProductName, loanStatus, loanType, loanCycle,
timeline, inArrears,originalLoan,loanBalance,amountPaid); timeline, inArrears,originalLoan,loanBalance,amountPaid);
} }
@@ -47,6 +47,9 @@ public class AccountEnumerations {
case JLG: case JLG:
optionData = new EnumOptionData(AccountType.JLG.getValue().longValue(), AccountType.JLG.getCode(), "JLG"); optionData = new EnumOptionData(AccountType.JLG.getValue().longValue(), AccountType.JLG.getCode(), "JLG");
break; break;
case GLIM:
optionData = new EnumOptionData(AccountType.GLIM.getValue().longValue(), AccountType.GLIM.getCode(), "GLIM");
break;
} }
return optionData; return optionData;
@@ -51,4 +51,6 @@ public interface CalendarReadPlatformService {
Boolean isCalendarAssociatedWithEntity(final Long entityId, final Long calendarId, Long entityTypeId); Boolean isCalendarAssociatedWithEntity(final Long entityId, final Long calendarId, Long entityTypeId);
} }
@@ -33,6 +33,7 @@ import io.swagger.annotations.Tag;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -88,15 +89,18 @@ import org.apache.fineract.portfolio.group.data.GroupRoleData;
import org.apache.fineract.portfolio.group.service.CenterReadPlatformService; import org.apache.fineract.portfolio.group.service.CenterReadPlatformService;
import org.apache.fineract.portfolio.group.service.GroupReadPlatformService; import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
import org.apache.fineract.portfolio.group.service.GroupRolesReadPlatformService; import org.apache.fineract.portfolio.group.service.GroupRolesReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.data.GLIMContainer;
import org.apache.fineract.portfolio.loanaccount.service.GLIMAccountInfoReadPlatformService;
import org.apache.fineract.portfolio.meeting.data.MeetingData; import org.apache.fineract.portfolio.meeting.data.MeetingData;
import org.apache.fineract.portfolio.meeting.service.MeetingReadPlatformService; import org.apache.fineract.portfolio.meeting.service.MeetingReadPlatformService;
import org.apache.fineract.portfolio.savings.data.GSIMContainer;
import org.apache.fineract.portfolio.savings.service.GSIMReadPlatformService;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@Path("/groups") @Path("/groups")
@Component @Component
@Scope("singleton") @Scope("singleton")
@@ -113,6 +117,8 @@ public class GroupsApiResource {
private final ToApiJsonSerializer<Object> toApiJsonSerializer; private final ToApiJsonSerializer<Object> toApiJsonSerializer;
private final ToApiJsonSerializer<GroupGeneralData> groupGeneralApiJsonSerializer; private final ToApiJsonSerializer<GroupGeneralData> groupGeneralApiJsonSerializer;
private final ToApiJsonSerializer<AccountSummaryCollectionData> groupSummaryToApiJsonSerializer; private final ToApiJsonSerializer<AccountSummaryCollectionData> groupSummaryToApiJsonSerializer;
private final ToApiJsonSerializer<GLIMContainer> glimContainerToApiJsonSerializer;
private final ToApiJsonSerializer<GSIMContainer> gsimContainerToApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final CollectionSheetReadPlatformService collectionSheetReadPlatformService; private final CollectionSheetReadPlatformService collectionSheetReadPlatformService;
@@ -124,6 +130,8 @@ public class GroupsApiResource {
private final EntityDatatableChecksReadService entityDatatableChecksReadService; private final EntityDatatableChecksReadService entityDatatableChecksReadService;
private final BulkImportWorkbookService bulkImportWorkbookService; private final BulkImportWorkbookService bulkImportWorkbookService;
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService; private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
private final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService;
private final GSIMReadPlatformService gsimReadPlatformService;
@Autowired @Autowired
@@ -132,6 +140,8 @@ public class GroupsApiResource {
final ToApiJsonSerializer<Object> toApiJsonSerializer, final ToApiJsonSerializer<Object> toApiJsonSerializer,
final ToApiJsonSerializer<GroupGeneralData> groupTopOfHierarchyApiJsonSerializer, final ToApiJsonSerializer<GroupGeneralData> groupTopOfHierarchyApiJsonSerializer,
final ToApiJsonSerializer<AccountSummaryCollectionData> groupSummaryToApiJsonSerializer, final ToApiJsonSerializer<AccountSummaryCollectionData> groupSummaryToApiJsonSerializer,
final ToApiJsonSerializer<GLIMContainer> glimContainerToApiJsonSerializer,
final ToApiJsonSerializer<GSIMContainer> gsimContainerToApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final CollectionSheetReadPlatformService collectionSheetReadPlatformService, final FromJsonHelper fromJsonHelper, final CollectionSheetReadPlatformService collectionSheetReadPlatformService, final FromJsonHelper fromJsonHelper,
@@ -140,15 +150,18 @@ public class GroupsApiResource {
final CalendarReadPlatformService calendarReadPlatformService, final MeetingReadPlatformService meetingReadPlatformService, final CalendarReadPlatformService calendarReadPlatformService, final MeetingReadPlatformService meetingReadPlatformService,
final EntityDatatableChecksReadService entityDatatableChecksReadService, final EntityDatatableChecksReadService entityDatatableChecksReadService,
final BulkImportWorkbookService bulkImportWorkbookService, final BulkImportWorkbookService bulkImportWorkbookService,
final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService) { final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService,
final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService,
this.context = context; final GSIMReadPlatformService gsimReadPlatformService) {
this.context = context;
this.groupReadPlatformService = groupReadPlatformService; this.groupReadPlatformService = groupReadPlatformService;
this.centerReadPlatformService = centerReadPlatformService; this.centerReadPlatformService = centerReadPlatformService;
this.clientReadPlatformService = clientReadPlatformService; this.clientReadPlatformService = clientReadPlatformService;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.groupGeneralApiJsonSerializer = groupTopOfHierarchyApiJsonSerializer; this.groupGeneralApiJsonSerializer = groupTopOfHierarchyApiJsonSerializer;
this.groupSummaryToApiJsonSerializer = groupSummaryToApiJsonSerializer; this.groupSummaryToApiJsonSerializer = groupSummaryToApiJsonSerializer;
this.glimContainerToApiJsonSerializer=glimContainerToApiJsonSerializer;
this.gsimContainerToApiJsonSerializer=gsimContainerToApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.collectionSheetReadPlatformService = collectionSheetReadPlatformService; this.collectionSheetReadPlatformService = collectionSheetReadPlatformService;
@@ -160,6 +173,9 @@ public class GroupsApiResource {
this.entityDatatableChecksReadService = entityDatatableChecksReadService; this.entityDatatableChecksReadService = entityDatatableChecksReadService;
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService; this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
this.bulkImportWorkbookService=bulkImportWorkbookService; this.bulkImportWorkbookService=bulkImportWorkbookService;
this.glimAccountInfoReadPlatformService=glimAccountInfoReadPlatformService;
this.gsimReadPlatformService=gsimReadPlatformService;
} }
@GET @GET
@@ -482,13 +498,14 @@ public class GroupsApiResource {
final AccountSummaryCollectionData groupAccount = this.accountDetailsReadPlatformService.retrieveGroupAccountDetails(groupId); final AccountSummaryCollectionData groupAccount = this.accountDetailsReadPlatformService.retrieveGroupAccountDetails(groupId);
final Set<String> GROUP_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("loanAccounts", "savingsAccounts", final Set<String> GROUP_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("loanAccounts", "groupLoanIndividualMonitoringAccounts","savingsAccounts",
"memberLoanAccounts", "memberSavingsAccounts")); "memberLoanAccounts", "memberSavingsAccounts"));
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.groupSummaryToApiJsonSerializer.serialize(settings, groupAccount, GROUP_ACCOUNTS_DATA_PARAMETERS); return this.groupSummaryToApiJsonSerializer.serialize(settings, groupAccount, GROUP_ACCOUNTS_DATA_PARAMETERS);
} }
@GET @GET
@Path("downloadtemplate") @Path("downloadtemplate")
@Produces("application/vnd.ms-excel") @Produces("application/vnd.ms-excel")
@@ -508,4 +525,64 @@ public class GroupsApiResource {
uploadedInputStream,fileDetail,locale,dateFormat); uploadedInputStream,fileDetail,locale,dateFormat);
return this.toApiJsonSerializer.serialize(importDocumentId); return this.toApiJsonSerializer.serialize(importDocumentId);
} }
@GET
@Path("{groupId}/glimaccounts")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveglimAccounts(@PathParam("groupId") final Long groupId, @QueryParam("parentLoanAccountNo")final String parentLoanAccountNo, @Context final UriInfo uriInfo)
{
this.context.authenticatedUser().validateHasReadPermission("GROUP");
List<GLIMContainer> glimContainer = Collections.emptyList();
if(parentLoanAccountNo==null)
{
glimContainer=(List)glimAccountInfoReadPlatformService.findGlimAccount(groupId);
}
else
{
glimContainer=(List)glimAccountInfoReadPlatformService.findGlimAccountbyGroupAndAccount(groupId,parentLoanAccountNo);
}
final Set<String> GLIM_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("groupId", "accountNumber","childGLIMAccounts","memberLoanAccounts", "parentPrincipalAmount"));
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.glimContainerToApiJsonSerializer.serialize(settings, glimContainer, GLIM_ACCOUNTS_DATA_PARAMETERS);
}
@GET
@Path("{groupId}/gsimaccounts")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveGsimAccounts(@PathParam("groupId") final Long groupId, @QueryParam("parentGSIMAccountNo")final String parentGSIMAccountNo,
@QueryParam("parentGSIMId")final Long parentGSIMId,@Context final UriInfo uriInfo)
{
List<GSIMContainer> gsimContainer;
this.context.authenticatedUser().validateHasReadPermission("GROUP");
if(parentGSIMAccountNo==null && parentGSIMId!=null)
{
gsimContainer= (List<GSIMContainer>)this.gsimReadPlatformService.findGsimAccountContainerbyGsimAccountId(parentGSIMId);
}
else if(parentGSIMAccountNo !=null && parentGSIMId==null )
{
gsimContainer= (List)this.gsimReadPlatformService.findGsimAccountContainerbyGsimAccountNumber(parentGSIMAccountNo);
}
else
{
gsimContainer= (List)this.gsimReadPlatformService.findGSIMAccountContainerByGroupId(groupId);
}
final Set<String> GSIM_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("gsimId","groupId", "accountNumber","childGSIMAccounts",
"parentBalance", "savingsStatus"));
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.gsimContainerToApiJsonSerializer.serialize(settings, gsimContainer, GSIM_ACCOUNTS_DATA_PARAMETERS);
}
} }
@@ -58,6 +58,7 @@ import org.apache.fineract.portfolio.group.exception.ClientNotInGroupException;
import org.apache.fineract.portfolio.group.exception.GroupExistsInCenterException; import org.apache.fineract.portfolio.group.exception.GroupExistsInCenterException;
import org.apache.fineract.portfolio.group.exception.GroupNotExistsInCenterException; import org.apache.fineract.portfolio.group.exception.GroupNotExistsInCenterException;
import org.apache.fineract.portfolio.group.exception.InvalidGroupStateTransitionException; import org.apache.fineract.portfolio.group.exception.InvalidGroupStateTransitionException;
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
@@ -144,6 +145,9 @@ public final class Group extends AbstractPersistableCustom {
@OneToMany(mappedBy="group",cascade = CascadeType.REMOVE) @OneToMany(mappedBy="group",cascade = CascadeType.REMOVE)
private Set<GroupRole> groupRole; private Set<GroupRole> groupRole;
@OneToMany(mappedBy = "group")
private List<GroupLoanIndividualMonitoringAccount> glimLoan;
// JPA default constructor for entity // JPA default constructor for entity
protected Group() { protected Group() {
@@ -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.portfolio.group.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class GroupMemberNotFoundInGSIMException extends AbstractPlatformDomainRuleException
{
public GroupMemberNotFoundInGSIMException(final Long clientId)
{
super("error.msg.Group.member.not.found.in.linked.gsim", "The client with id `" + clientId + "` is not present in GSIM", clientId);
}
}
@@ -31,6 +31,7 @@ public interface LoanApiConstants {
public static final String loanChargeIdParameterName = "loanChargeId"; public static final String loanChargeIdParameterName = "loanChargeId";
public static final String principalDisbursedParameterName = "transactionAmount"; public static final String principalDisbursedParameterName = "transactionAmount";
public static final String chargesParameterName = "charges"; public static final String chargesParameterName = "charges";
public static final String loanIdTobeApproved="loanId";
public static final String approvedLoanAmountParameterName = "approvedLoanAmount"; public static final String approvedLoanAmountParameterName = "approvedLoanAmount";
public static final String approvedOnDateParameterName = "approvedOnDate"; public static final String approvedOnDateParameterName = "approvedOnDate";
@@ -109,6 +110,8 @@ public interface LoanApiConstants {
public static final String dueDateParamName = "dueDate"; public static final String dueDateParamName = "dueDate";
public static final String modifiedDueDateParamName = "modifiedDueDate"; public static final String modifiedDueDateParamName = "modifiedDueDate";
public static final String principalParamName = "principal"; public static final String principalParamName = "principal";
public static final String parentAccountParamName="isParentAccount";
public static final String totalLoanParamName="totalLoan";
public static final String installmentAmountParamName = "installmentAmount"; public static final String installmentAmountParamName = "installmentAmount";
//loan write off //loan write off
public static final String WRITEOFFREASONS = "WriteOffReasons"; public static final String WRITEOFFREASONS = "WriteOffReasons";
@@ -126,4 +129,7 @@ public interface LoanApiConstants {
public static final String datatables = "datatables"; public static final String datatables = "datatables";
public static final String isEqualAmortizationParam = "isEqualAmortization"; public static final String isEqualAmortizationParam = "isEqualAmortization";
public static final String applicationId = "applicationId";
public static final String lastApplication = "lastApplication";
} }
@@ -105,6 +105,7 @@ import org.apache.fineract.portfolio.fund.service.FundReadPlatformService;
import org.apache.fineract.portfolio.group.data.GroupGeneralData; import org.apache.fineract.portfolio.group.data.GroupGeneralData;
import org.apache.fineract.portfolio.group.service.GroupReadPlatformService; import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData; import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
import org.apache.fineract.portfolio.loanaccount.data.GlimRepaymentTemplate;
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData; import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
import org.apache.fineract.portfolio.loanaccount.data.LoanApprovalData; import org.apache.fineract.portfolio.loanaccount.data.LoanApprovalData;
import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData; import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
@@ -121,6 +122,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleD
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel; import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService; import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService;
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryReadPlatformService; import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.service.GLIMAccountInfoReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.service.LoanChargeReadPlatformService; import org.apache.fineract.portfolio.loanaccount.service.LoanChargeReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService; import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
@@ -265,6 +267,8 @@ public class LoansApiResource {
LoanApiConstants.datatables, LoanProductConstants.ratesParamName)); LoanApiConstants.datatables, LoanProductConstants.ratesParamName));
private final Set<String> LOAN_APPROVAL_DATA_PARAMETERS = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount")); private final Set<String> LOAN_APPROVAL_DATA_PARAMETERS = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount"));
final Set<String> GLIM_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("glimId","groupId", "clientId","parentLoanAccountNo","parentPrincipalAmount",
"childLoanAccountNo", "childPrincipalAmount","clientName"));
private final String resourceNameForPermissions = "LOAN"; private final String resourceNameForPermissions = "LOAN";
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
@@ -296,6 +300,8 @@ public class LoansApiResource {
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService; private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
private final RateReadService rateReadService; private final RateReadService rateReadService;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
private final DefaultToApiJsonSerializer<GlimRepaymentTemplate> glimTemplateToApiJsonSerializer;
private final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService;
@Autowired @Autowired
public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService, public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
@@ -319,7 +325,8 @@ public class LoansApiResource {
final EntityDatatableChecksReadService entityDatatableChecksReadService, final EntityDatatableChecksReadService entityDatatableChecksReadService,
final BulkImportWorkbookService bulkImportWorkbookService, final BulkImportWorkbookService bulkImportWorkbookService,
final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService, final RateReadService rateReadService, final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService, final RateReadService rateReadService,
final ConfigurationDomainService configurationDomainService) { final ConfigurationDomainService configurationDomainService, final DefaultToApiJsonSerializer<GlimRepaymentTemplate> glimTemplateToApiJsonSerializer,
final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService) {
this.context = context; this.context = context;
this.loanReadPlatformService = loanReadPlatformService; this.loanReadPlatformService = loanReadPlatformService;
this.loanProductReadPlatformService = loanProductReadPlatformService; this.loanProductReadPlatformService = loanProductReadPlatformService;
@@ -349,6 +356,8 @@ public class LoansApiResource {
this.bulkImportWorkbookService=bulkImportWorkbookService; this.bulkImportWorkbookService=bulkImportWorkbookService;
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService; this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
this.configurationDomainService = configurationDomainService; this.configurationDomainService = configurationDomainService;
this.glimTemplateToApiJsonSerializer=glimTemplateToApiJsonSerializer;
this.glimAccountInfoReadPlatformService=glimAccountInfoReadPlatformService;
} }
/* /*
@@ -918,6 +927,57 @@ public class LoansApiResource {
return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.LOANS.toString(), officeId, staffId,dateFormat); return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.LOANS.toString(), officeId, staffId,dateFormat);
} }
@GET
@Path("glimAccount/{glimId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String getGlimRepaymentTemplate(@PathParam("glimId") final Long glimId,@Context final UriInfo uriInfo)
{
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
Collection<GlimRepaymentTemplate> glimRepaymentTemplate=this.glimAccountInfoReadPlatformService.findglimRepaymentTemplate(glimId);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.glimTemplateToApiJsonSerializer.serialize(settings, glimRepaymentTemplate, this.GLIM_ACCOUNTS_DATA_PARAMETERS);
}
@POST
@Path("glimAccount/{glimId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Approve GLIM Application | Undo GLIM Application Approval | Reject GLIM Application | Disburse Loan Disburse Loan To Savings Account | Undo Loan Disbursal", httpMethod = "POST", notes = "Approve GLIM Application:\n" + "Mandatory Fields: approvedOnDate\n" + "Optional Fields: approvedLoanAmount and expectedDisbursementDate\n" + "Approves the GLIM application\n\n" + "Undo GLIM Application Approval:\n" + "Undoes the GLIM Application Approval\n\n" + "Reject GLIM Application:\n" + "Mandatory Fields: rejectedOnDate\n" + "Allows you to reject the GLIM application\n\n" + "Disburse Loan:\n" + "Mandatory Fields: actualDisbursementDate\n" + "Optional Fields: transactionAmount and fixedEmiAmount\n" + "Disburses the Loan\n\n" + "Disburse Loan To Savings Account:\n" + "Mandatory Fields: actualDisbursementDate\n" + "Optional Fields: transactionAmount and fixedEmiAmount\n" + "Disburses the loan to Saving Account\n\n" + "Undo Loan Disbursal:\n" + "Undoes the Loan Disbursal\n")
@ApiImplicitParams({@ApiImplicitParam(value = "body", required = true, paramType = "body", dataType = "body", format = "body", dataTypeClass = LoansApiResourceSwagger.PostLoansLoanIdRequest.class)})
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = LoansApiResourceSwagger.PostLoansLoanIdResponse.class)})
public String glimStateTransitions(@PathParam("glimId") final Long glimId, @QueryParam("command") final String commandParam,
final String apiRequestBodyAsJson) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandProcessingResult result = null;
if (is(commandParam, "reject")) {
final CommandWrapper commandRequest = builder.rejectGLIMApplication(glimId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "approve")) {
final CommandWrapper commandRequest = builder.approveGLIMLoanApplication(glimId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "disburse")) {
final CommandWrapper commandRequest = builder.disburseGlimLoanApplication(glimId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "glimrepayment")) {
final CommandWrapper commandRequest = builder.repaymentGlimLoanApplication(glimId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "undodisbursal")) {
final CommandWrapper commandRequest = builder.undoGLIMLoanDisbursal(glimId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "undoapproval")) {
final CommandWrapper commandRequest = builder.undoGLIMLoanApproval(glimId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam); }
return this.toApiJsonSerializer.serialize(result);
}
@GET @GET
@Path("repayments/downloadtemplate") @Path("repayments/downloadtemplate")
@Produces("application/vnd.ms-excel") @Produces("application/vnd.ms-excel")
@@ -0,0 +1,73 @@
/**
* 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.data;
import java.math.BigDecimal;
import java.util.List;
import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData;
public class GLIMContainer {
private final BigDecimal glimId;
private final BigDecimal groupId;
private final String accountNumber;
private final List<LoanAccountSummaryData> childGLIMAccounts;
private final BigDecimal parentPrincipalAmount;
private final String loanStatus;
public GLIMContainer(final BigDecimal glimId,final BigDecimal groupId,final String accountNumber,final List<LoanAccountSummaryData> childGLIMAccounts,
final BigDecimal parentPrincipalAmount,final String loanStatus) {
this.glimId=glimId;
this.groupId=groupId;
this.accountNumber = accountNumber;
this.childGLIMAccounts=childGLIMAccounts;
this.parentPrincipalAmount = parentPrincipalAmount;
this.loanStatus=loanStatus;
}
public BigDecimal getGlimId() {
return glimId;
}
public BigDecimal getGroupId() {
return groupId;
}
public String getAccountNumber() {
return accountNumber;
}
public List<LoanAccountSummaryData> getChildGLIMAccounts() {
return childGLIMAccounts;
}
public BigDecimal getParentPrincipalAmount() {
return parentPrincipalAmount;
}
public String getLoanStatus() {
return loanStatus;
}
}
@@ -0,0 +1,105 @@
/**
* 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.data;
import java.math.BigDecimal;
public class GlimRepaymentTemplate
{
private final BigDecimal glimId;
private final BigDecimal groupId;
private final BigDecimal clientId;
private final String clientName;
private final BigDecimal childLoanId;
private final String parentAccountNo;
private final BigDecimal parentPrincipalAmount;
private final String childLoanAccountNo;
private final BigDecimal childPrincipalAmount ;
private GlimRepaymentTemplate(final BigDecimal glimId,final BigDecimal groupId,final BigDecimal clientId,
final String clientName,final BigDecimal childLoanId,final String parentAccountNo,final BigDecimal parentPrincipalAmount,
final String childLoanAccountNo,final BigDecimal childPrincipalAmount)
{
this.glimId=glimId;
this.groupId=groupId;
this.clientId=clientId;
this.clientName=clientName;
this.childLoanId=childLoanId;
this.parentAccountNo=parentAccountNo;
this.parentPrincipalAmount=parentPrincipalAmount;
this.childLoanAccountNo=childLoanAccountNo;
this.childPrincipalAmount=childPrincipalAmount;
}
public static GlimRepaymentTemplate getInstance(final BigDecimal glimId,final BigDecimal groupId,final BigDecimal clientId,
final String clientName,final BigDecimal childLoanId,final String parentAccountNo,final BigDecimal parentPrincipalAmount,
final String childLoanAccountNo,final BigDecimal childPrincipalAmount)
{
return new GlimRepaymentTemplate(glimId,groupId,clientId,clientName,childLoanId,parentAccountNo,
parentPrincipalAmount,childLoanAccountNo,childPrincipalAmount);
}
public BigDecimal getGlimId() {
return glimId;
}
public BigDecimal getGroupId() {
return groupId;
}
public BigDecimal getClientId() {
return clientId;
}
public String getClientName() {
return clientName;
}
public BigDecimal getChildLoanId() {
return childLoanId;
}
public String getParentAccountNo() {
return parentAccountNo;
}
public BigDecimal getParentPrincipalAmount() {
return parentPrincipalAmount;
}
public String getChildLoanAccountNo() {
return childLoanAccountNo;
}
public BigDecimal getChildPrincipalAmount() {
return childPrincipalAmount;
}
}
@@ -0,0 +1,103 @@
/**
* 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.data;
import java.math.BigDecimal;
public class GroupLoanIndividualMonitoringAccountData
{
private final BigDecimal glimId;
private final BigDecimal groupId;
private final String accountNumber;
private final String childAccountNumber;
private final BigDecimal childPrincipalAmount;
private final BigDecimal parentPrincipalAmount;
private final Long childAccountsCount;
private final String loanStatus;
private GroupLoanIndividualMonitoringAccountData(final BigDecimal glimId,final BigDecimal groupId,final String accountNumber, final String childAccountNumber,
final BigDecimal childPrincipalAmount, final BigDecimal parentPrincipalAmount,
final Long childAccountsCount,final String loanStatus) {
this.glimId=glimId;
this.groupId=groupId;
this.accountNumber = accountNumber;
this.childAccountNumber = childAccountNumber;
this.childPrincipalAmount = childPrincipalAmount;
this.parentPrincipalAmount = parentPrincipalAmount;
this.childAccountsCount = childAccountsCount;
this.loanStatus=loanStatus;
}
public static GroupLoanIndividualMonitoringAccountData getInstance(final BigDecimal glimId, final BigDecimal groupId,final String accountNumber, final String childAccountNumber,
final BigDecimal childPrincipalAmount, final BigDecimal parentPrincipalAmount,
final Long childAccountsCount,final String loanStatus)
{
return new GroupLoanIndividualMonitoringAccountData(glimId,groupId,accountNumber,childAccountNumber,
childPrincipalAmount,parentPrincipalAmount,childAccountsCount,loanStatus);
}
public static GroupLoanIndividualMonitoringAccountData getInstance1(final BigDecimal glimId,final BigDecimal groupId,final String accountNumber,
final BigDecimal parentPrincipalAmount,final String loanStatus)
{
return new GroupLoanIndividualMonitoringAccountData(glimId,groupId,accountNumber,null,null,parentPrincipalAmount,null,loanStatus);
}
public BigDecimal getGlimId() {
return glimId;
}
public BigDecimal getGroupId() {
return groupId;
}
public String getAccountNumber() {
return accountNumber;
}
public String getChildAccountNumber() {
return childAccountNumber;
}
public BigDecimal getChildPrincipalAmount() {
return childPrincipalAmount;
}
public BigDecimal getParentPrincipalAmount() {
return parentPrincipalAmount;
}
public Long getChildAccountsCount() {
return childAccountsCount;
}
public String getLoanStatus() {
return loanStatus;
}
}
@@ -0,0 +1,34 @@
/**
* 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.domain;
import java.math.BigDecimal;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface GLIMAccountInfoRepository extends JpaRepository<GroupLoanIndividualMonitoringAccount, Long>,
JpaSpecificationExecutor<GroupLoanIndividualMonitoringAccount> {
GroupLoanIndividualMonitoringAccount findOneByIsAcceptingChild(boolean acceptingChild);
GroupLoanIndividualMonitoringAccount findOneByIsAcceptingChildAndApplicationId(boolean acceptingChild,
BigDecimal applicationId);
GroupLoanIndividualMonitoringAccount findOneByAccountNumber(String accountNumber);
}
@@ -0,0 +1,146 @@
/**
* 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.domain;
import java.math.BigDecimal;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.portfolio.group.domain.Group;
@Entity
@Table(name = "glim_accounts", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_number" }, name = "FK_glim_id")})
public class GroupLoanIndividualMonitoringAccount extends AbstractPersistableCustom {
@ManyToOne
@JoinColumn(name = "group_id", nullable = false)
private Group group;
@Column(name = "account_number", nullable = false)
private String accountNumber;
@Column(name = "principal_amount")
private BigDecimal principalAmount;
@Column(name = "child_accounts_count")
private Long childAccountsCount;
@Column(name = "accepting_child")
private Boolean isAcceptingChild;
@OneToMany
private Set<Loan> childLoan;
@Column(name = "loan_status_id", nullable = false)
private Integer loanStatus;
@Column(name = "application_id", nullable = true)
private BigDecimal applicationId;
private GroupLoanIndividualMonitoringAccount(String accountNumber,Group group,BigDecimal principalAmount,Long childAccountsCount,
Boolean isAcceptingChild,Integer loanStatus,BigDecimal applicationId)
{
this.accountNumber=accountNumber;
this.group=group;
this.principalAmount=principalAmount;
this.childAccountsCount=childAccountsCount;
this.isAcceptingChild=isAcceptingChild;
this.loanStatus=loanStatus;
this.applicationId=applicationId;
}
public static GroupLoanIndividualMonitoringAccount getInstance(String accountNumber,Group group,BigDecimal principalAmount,Long childAccountsCount,
Boolean isAcceptingChild,Integer loanStatus,BigDecimal applicationId)
{
return new GroupLoanIndividualMonitoringAccount(accountNumber,group,principalAmount,childAccountsCount,
isAcceptingChild,loanStatus,applicationId);
}
public String getAccountNumber() {
return accountNumber;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public Set<Loan> getChildLoan() {
return childLoan;
}
public void setChildLoan(Set<Loan> childLoan) {
this.childLoan = childLoan;
}
public BigDecimal getPrincipalAmount() {
return principalAmount;
}
public void setPrincipalAmount(BigDecimal principalAmount) {
this.principalAmount = principalAmount;
}
public Long getChildAccountsCount() {
return childAccountsCount;
}
public void setChildAccountsCount(Long childAccountsCount) {
this.childAccountsCount = childAccountsCount;
}
public Boolean getIsAcceptingChild() {
return isAcceptingChild;
}
public void setIsAcceptingChild(Boolean isAcceptingChild) {
this.isAcceptingChild = isAcceptingChild;
}
public Integer getLoanStatus() {
return loanStatus;
}
public void setLoanStatus(Integer loanStatus) {
this.loanStatus = loanStatus;
}
public BigDecimal getApplicationId() {
return applicationId;
}
public void setApplicationId(BigDecimal applicationId) {
this.applicationId = applicationId;
}
}
@@ -167,6 +167,10 @@ public class Loan extends AbstractPersistableCustom {
@JoinColumn(name = "group_id", nullable = true) @JoinColumn(name = "group_id", nullable = true)
private Group group; private Group group;
@ManyToOne
@JoinColumn(name = "glim_id", nullable = true)
private GroupLoanIndividualMonitoringAccount glim;
@Column(name = "loan_type_enum", nullable = false) @Column(name = "loan_type_enum", nullable = false)
private Integer loanType; private Integer loanType;
@@ -627,6 +631,7 @@ public class Loan extends AbstractPersistableCustom {
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges());
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
mapEntry.getValue().updateLoan(this); mapEntry.getValue().updateLoan(this);
} }
this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values()); this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values());
@@ -675,6 +680,7 @@ public class Loan extends AbstractPersistableCustom {
final LoanTransaction applyLoanChargeTransaction = LoanTransaction.accrueLoanCharge(this, getOffice(), chargeAmount, final LoanTransaction applyLoanChargeTransaction = LoanTransaction.accrueLoanCharge(this, getOffice(), chargeAmount,
transactionDate, feeCharges, penaltyCharges, DateUtils.getLocalDateTimeOfTenant(), currentUser); transactionDate, feeCharges, penaltyCharges, DateUtils.getLocalDateTimeOfTenant(), currentUser);
Integer installmentNumber = null; Integer installmentNumber = null;
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(applyLoanChargeTransaction, loanCharge, loanCharge.getAmount( final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(applyLoanChargeTransaction, loanCharge, loanCharge.getAmount(
getCurrency()).getAmount(), installmentNumber); getCurrency()).getAmount(), installmentNumber);
@@ -701,6 +707,7 @@ public class Loan extends AbstractPersistableCustom {
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments() ; List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments() ;
for (final LoanRepaymentScheduleInstallment installment : installments) { for (final LoanRepaymentScheduleInstallment installment : installments) {
if (installmentNumber == null && charge.isDueForCollectionFromAndUpToAndIncluding(startDate, installment.getDueDate())) { if (installmentNumber == null && charge.isDueForCollectionFromAndUpToAndIncluding(startDate, installment.getDueDate())) {
chargePaymentInstallments.add(installment); chargePaymentInstallments.add(installment);
break; break;
} else if (installmentNumber != null && installment.getInstallmentNumber().equals(installmentNumber)) { } else if (installmentNumber != null && installment.getInstallmentNumber().equals(installmentNumber)) {
@@ -712,6 +719,7 @@ public class Loan extends AbstractPersistableCustom {
final Set<LoanCharge> loanCharges = new HashSet<>(1); final Set<LoanCharge> loanCharges = new HashSet<>(1);
loanCharges.add(charge); loanCharges.add(charge);
loanRepaymentScheduleTransactionProcessor.handleTransaction(chargesPayment, getCurrency(), chargePaymentInstallments, loanCharges); loanRepaymentScheduleTransactionProcessor.handleTransaction(chargesPayment, getCurrency(), chargePaymentInstallments, loanCharges);
updateLoanSummaryDerivedFields(); updateLoanSummaryDerivedFields();
doPostLoanTransactionChecks(chargesPayment.getTransactionDate(), loanLifecycleStateMachine); doPostLoanTransactionChecks(chargesPayment.getTransactionDate(), loanLifecycleStateMachine);
} }
@@ -720,6 +728,7 @@ public class Loan extends AbstractPersistableCustom {
if (isClosed()) { if (isClosed()) {
final String defaultUserMessage = "This charge cannot be added as the loan is already closed."; final String defaultUserMessage = "This charge cannot be added as the loan is already closed.";
throw new LoanChargeCannotBeAddedException("loanCharge", "loan.is.closed", defaultUserMessage, getId(), loanCharge.name()); throw new LoanChargeCannotBeAddedException("loanCharge", "loan.is.closed", defaultUserMessage, getId(), loanCharge.name());
} }
} }
@@ -727,6 +736,7 @@ public class Loan extends AbstractPersistableCustom {
if (loanCharge.isWaived()) { if (loanCharge.isWaived()) {
final String defaultUserMessage = "This loan charge cannot be removed as the charge as already been waived."; final String defaultUserMessage = "This loan charge cannot be removed as the charge as already been waived.";
throw new LoanChargeCannotBeAddedException("loanCharge", "loanCharge.is.waived", defaultUserMessage, getId(), loanCharge.name()); throw new LoanChargeCannotBeAddedException("loanCharge", "loanCharge.is.waived", defaultUserMessage, getId(), loanCharge.name());
} }
} }
@@ -805,6 +815,7 @@ public class Loan extends AbstractPersistableCustom {
final Money penaltychargesPortion = Money.zero(currency); final Money penaltychargesPortion = Money.zero(currency);
transaction.updateComponentsAndTotal(principalPortion, interestPortion, chargeAmount, penaltychargesPortion); transaction.updateComponentsAndTotal(principalPortion, interestPortion, chargeAmount, penaltychargesPortion);
} else { } else {
transactionToRemove = transaction; transactionToRemove = transaction;
} }
@@ -1072,6 +1083,14 @@ public class Loan extends AbstractPersistableCustom {
return this.client; return this.client;
} }
public GroupLoanIndividualMonitoringAccount getGlim() {
return glim;
}
public void setGlim(GroupLoanIndividualMonitoringAccount glim) {
this.glim = glim;
}
public LoanProduct loanProduct() { public LoanProduct loanProduct() {
return this.loanProduct; return this.loanProduct;
} }
@@ -4203,6 +4222,14 @@ public class Loan extends AbstractPersistableCustom {
return groupId; return groupId;
} }
public Long getGlimId() {
Long glimId = null;
if (this.glim != null) {
glimId = this.glim.getId();
}
return glimId;
}
public Long getOfficeId() { public Long getOfficeId() {
Long officeId = null; Long officeId = null;
if (this.client != null) { if (this.client != null) {
@@ -6558,4 +6585,13 @@ public class Loan extends AbstractPersistableCustom {
public List<Rate> getRates() { public List<Rate> getRates() {
return rates; return rates;
} }
public Integer getLoanType() {
return loanType;
}
public void setLoanType(Integer loanType) {
this.loanType = loanType;
}
} }
@@ -120,6 +120,9 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
@Query("select loan from Loan loan where loan.group.id = :groupId and loan.client.id is null") @Query("select loan from Loan loan where loan.group.id = :groupId and loan.client.id is null")
List<Loan> findByGroupId(@Param("groupId") Long groupId); List<Loan> findByGroupId(@Param("groupId") Long groupId);
@Query("select loan from Loan loan where loan.glim.id = :glimId")
List<Loan> findByGlimId(@Param("glimId") Long glimId);
@Query("select loan from Loan loan where loan.id IN :ids and loan.loanStatus IN :loanStatuses and loan.loanType IN :loanTypes") @Query("select loan from Loan loan where loan.id IN :ids and loan.loanStatus IN :loanStatuses and loan.loanType IN :loanTypes")
List<Loan> findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection<Long> ids, List<Loan> findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection<Long> ids,
@Param("loanStatuses") Collection<Integer> loanStatuses, @Param("loanTypes") Collection<Integer> loanTypes); @Param("loanStatuses") Collection<Integer> loanStatuses, @Param("loanTypes") Collection<Integer> loanTypes);
@@ -153,4 +156,5 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
@Query(FIND_NON_CLOSED_LOAN_THAT_BELONGS_TO_CLIENT) @Query(FIND_NON_CLOSED_LOAN_THAT_BELONGS_TO_CLIENT)
Loan findNonClosedLoanThatBelongsToClient(@Param("loanId") Long loanId, @Param("clientId") Long clientId); Loan findNonClosedLoanThatBelongsToClient(@Param("loanId") Long loanId, @Param("clientId") Long clientId);
} }
@@ -59,6 +59,7 @@ public class LoanRepositoryWrapper {
return loan; return loan;
} }
//Root Entities are enough //Root Entities are enough
public Collection<Loan> findActiveLoansByLoanIdAndGroupId(Long clientId, Long groupId) { public Collection<Loan> findActiveLoansByLoanIdAndGroupId(Long clientId, Long groupId) {
final Collection<Integer> loanStatuses = new ArrayList<>(Arrays.asList(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(), final Collection<Integer> loanStatuses = new ArrayList<>(Arrays.asList(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(),
@@ -45,4 +45,5 @@ public interface GuarantorReadPlatformService {
List<ObligeeData> retrieveObligeeDetails(Long clientId); List<ObligeeData> retrieveObligeeDetails(Long clientId);
} }
@@ -88,6 +88,7 @@ public class GuarantorReadPlatformServiceImpl implements GuarantorReadPlatformSe
return mergedGuarantorDatas; return mergedGuarantorDatas;
} }
@Override @Override
public GuarantorData retrieveGuarantor(final Long loanId, final Long guarantorId) { public GuarantorData retrieveGuarantor(final Long loanId, final Long guarantorId) {
final GuarantorMapper rm = new GuarantorMapper(); final GuarantorMapper rm = new GuarantorMapper();
@@ -0,0 +1,49 @@
/**
* 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.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.portfolio.loanaccount.service.LoanApplicationWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GLIMLOAN", action = "REJECT")
public class GLIMApplicationRejectionCommandHandler implements NewCommandSourceHandler
{
private final LoanApplicationWritePlatformService writePlatformService;
@Autowired
public GLIMApplicationRejectionCommandHandler(final LoanApplicationWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.rejectGLIMApplicationApproval(command.entityId(), command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.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.portfolio.loanaccount.service.LoanWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GLIMLOAN", action = "REPAYMENT")
public class GLIMBulkRepaymentCommandHandler implements NewCommandSourceHandler {
private final LoanWritePlatformService writePlatformService;
@Autowired
public GLIMBulkRepaymentCommandHandler(final LoanWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.makeGLIMLoanRepayment(command.entityId(), command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.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.portfolio.loanaccount.service.LoanApplicationWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GLIMLOAN", action = "APPROVE")
public class GLIMLoanApplicationApprovalCommandHandler implements NewCommandSourceHandler {
private final LoanApplicationWritePlatformService writePlatformService;
@Autowired
public GLIMLoanApplicationApprovalCommandHandler(final LoanApplicationWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.approveGLIMLoanAppication(command.entityId(), command);
}
}
@@ -0,0 +1,52 @@
/**
* 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.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.portfolio.loanaccount.service.LoanWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GLIMLOAN", action = "DISBURSE")
public class GlimLoanApplicationDisburseCommandHandler implements NewCommandSourceHandler
{
private final LoanWritePlatformService writePlatformService;
@Autowired
public GlimLoanApplicationDisburseCommandHandler(final LoanWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.disburseGLIMLoan(command.entityId(), command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.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.portfolio.loanaccount.service.LoanApplicationWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GLIMLOAN", action = "UNDOAPPROVAL")
public class UndoGLIMLoanApplicationApproval implements NewCommandSourceHandler
{
private final LoanApplicationWritePlatformService writePlatformService;
@Autowired
public UndoGLIMLoanApplicationApproval(final LoanApplicationWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.undoGLIMLoanApplicationApproval(command.entityId(), command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.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.portfolio.loanaccount.service.LoanWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GLIMLOAN", action = "UNDODISBURSAL")
public class UndoGLIMLoanDisbursalCommandHandler implements NewCommandSourceHandler
{
private final LoanWritePlatformService writePlatformService;
@Autowired
public UndoGLIMLoanDisbursalCommandHandler(final LoanWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.undoGLIMLoanDisbursal(command.entityId(), command);
}
}
@@ -29,4 +29,5 @@ public interface LoanScheduleCalculationPlatformService {
void updateFutureSchedule(LoanScheduleData loanScheduleData, Long loanId); void updateFutureSchedule(LoanScheduleData loanScheduleData, Long loanId);
LoanScheduleData generateLoanScheduleForVariableInstallmentRequest(Long loanId, String json); LoanScheduleData generateLoanScheduleForVariableInstallmentRequest(Long loanId, String json);
} }
@@ -137,6 +137,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
return this.loanScheduleAssembler.assembleLoanScheduleFrom(query.parsedJson()); return this.loanScheduleAssembler.assembleLoanScheduleFrom(query.parsedJson());
} }
@Override @Override
public void updateFutureSchedule(LoanScheduleData loanScheduleData, final Long loanId) { public void updateFutureSchedule(LoanScheduleData loanScheduleData, final Long loanId) {
@@ -62,7 +62,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
final Set<String> supportedParameters = new HashSet<>(Arrays.asList(LoanApiConstants.dateFormatParameterName, final Set<String> supportedParameters = new HashSet<>(Arrays.asList(LoanApiConstants.dateFormatParameterName,
LoanApiConstants.localeParameterName, LoanApiConstants.idParameterName, LoanApiConstants.clientIdParameterName, LoanApiConstants.localeParameterName, LoanApiConstants.idParameterName, LoanApiConstants.clientIdParameterName,
LoanApiConstants.groupIdParameterName, LoanApiConstants.loanTypeParameterName, LoanApiConstants.productIdParameterName, LoanApiConstants.groupIdParameterName, LoanApiConstants.loanTypeParameterName, LoanApiConstants.productIdParameterName,
LoanApiConstants.principalParamName, LoanApiConstants.loanTermFrequencyParameterName, LoanApiConstants.principalParamName,LoanApiConstants.totalLoanParamName,LoanApiConstants.parentAccountParamName, LoanApiConstants.loanTermFrequencyParameterName,
LoanApiConstants.loanTermFrequencyTypeParameterName, LoanApiConstants.numberOfRepaymentsParameterName, LoanApiConstants.loanTermFrequencyTypeParameterName, LoanApiConstants.numberOfRepaymentsParameterName,
LoanApiConstants.repaymentEveryParameterName, LoanApiConstants.repaymentFrequencyTypeParameterName, LoanApiConstants.repaymentEveryParameterName, LoanApiConstants.repaymentFrequencyTypeParameterName,
LoanApiConstants.repaymentFrequencyNthDayTypeParameterName, LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName, LoanApiConstants.repaymentFrequencyNthDayTypeParameterName, LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName,
@@ -91,7 +91,9 @@ public final class LoanApplicationCommandFromApiJsonHelper {
LoanApiConstants.linkAccountIdParameterName, LoanApiConstants.disbursementDataParameterName, LoanApiConstants.linkAccountIdParameterName, LoanApiConstants.disbursementDataParameterName,
LoanApiConstants.emiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName, LoanApiConstants.emiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName,
LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName, LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName,
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.datatables, LoanApiConstants.isEqualAmortizationParam, LoanProductConstants.ratesParamName)); LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.datatables, LoanApiConstants.isEqualAmortizationParam,LoanProductConstants.ratesParamName,
LoanApiConstants.applicationId, // glim specific
LoanApiConstants.lastApplication)); // glim specific
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final CalculateLoanScheduleQueryFromApiJsonHelper apiJsonHelper; private final CalculateLoanScheduleQueryFromApiJsonHelper apiJsonHelper;
@@ -120,7 +122,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
if (!StringUtils.isBlank(loanTypeStr)) { if (!StringUtils.isBlank(loanTypeStr)) {
final AccountType loanType = AccountType.fromName(loanTypeStr); final AccountType loanType = AccountType.fromName(loanTypeStr);
baseDataValidator.reset().parameter(loanTypeParameterName).value(loanType.getValue()).inMinMaxRange(1, 3); baseDataValidator.reset().parameter(loanTypeParameterName).value(loanType.getValue()).inMinMaxRange(1, 4);
final Long clientId = this.fromApiJsonHelper.extractLongNamed("clientId", element); final Long clientId = this.fromApiJsonHelper.extractLongNamed("clientId", element);
final Long groupId = this.fromApiJsonHelper.extractLongNamed("groupId", element); final Long groupId = this.fromApiJsonHelper.extractLongNamed("groupId", element);
@@ -58,7 +58,7 @@ public final class LoanApplicationTransitionApiJsonValidator {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Set<String> disbursementParameters = new HashSet<>(Arrays.asList(LoanApiConstants.approvedLoanAmountParameterName, final Set<String> disbursementParameters = new HashSet<>(Arrays.asList(LoanApiConstants.loanIdTobeApproved,LoanApiConstants.approvedLoanAmountParameterName,
LoanApiConstants.approvedOnDateParameterName, LoanApiConstants.noteParameterName, LoanApiConstants.localeParameterName, LoanApiConstants.approvedOnDateParameterName, LoanApiConstants.noteParameterName, LoanApiConstants.localeParameterName,
LoanApiConstants.dateFormatParameterName,LoanApiConstants.disbursementDataParameterName,LoanApiConstants.disbursementDateParameterName)); LoanApiConstants.dateFormatParameterName,LoanApiConstants.disbursementDataParameterName,LoanApiConstants.disbursementDateParameterName));
@@ -155,7 +155,7 @@ public final class LoanEventApiJsonValidator {
final Set<String> transactionParameters = new HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", final Set<String> transactionParameters = new HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId",
"note", "locale", "dateFormat", "paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber", "note", "locale", "dateFormat", "paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber",
"bankNumber")); "bankNumber","loanId"));
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, transactionParameters); this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, transactionParameters);
@@ -0,0 +1,44 @@
/**
* 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.service;
import java.util.Collection;
import org.apache.fineract.portfolio.loanaccount.data.GLIMContainer;
import org.apache.fineract.portfolio.loanaccount.data.GlimRepaymentTemplate;
import org.apache.fineract.portfolio.loanaccount.data.GroupLoanIndividualMonitoringAccountData;
public interface GLIMAccountInfoReadPlatformService
{
Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountsByGroupId(String groupId);
Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountByGroupId(String groupId);
Collection<GLIMContainer> findGlimAccount(Long groupId);
Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountByGroupIdandAccountNo(String groupId, String accountNo);
Collection<GLIMContainer> findGlimAccountbyGroupAndAccount(Long groupId, String accountNo);
Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountByParentAccountId(String parentAccountIds);
Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountsByGLIMId(Long glimId);
Collection<GlimRepaymentTemplate> findglimRepaymentTemplate(Long glimId);
}
@@ -0,0 +1,262 @@
/**
* 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.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData;
import org.apache.fineract.portfolio.accountdetails.service.AccountDetailsReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.data.GLIMContainer;
import org.apache.fineract.portfolio.loanaccount.data.GlimRepaymentTemplate;
import org.apache.fineract.portfolio.loanaccount.data.GroupLoanIndividualMonitoringAccountData;
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
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 GLIMAccountInfoReadPlatformServiceImpl implements GLIMAccountInfoReadPlatformService
{
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
private final AccountDetailsReadPlatformService accountDetailsReadPlatforService;
@Autowired
public GLIMAccountInfoReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
final AccountDetailsReadPlatformService accountDetailsReadPlatforService) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.accountDetailsReadPlatforService=accountDetailsReadPlatforService;
}
private static final class GLIMFieldsMapper implements RowMapper<GroupLoanIndividualMonitoringAccountData> {
public String schema() {
return "glim.id as glimId,ln.group_id as groupId,glim.account_number as accountNumber, ln.account_no as childAccountNumber,ln.principal_amount as childPrincipalAmount,glim.principal_amount as parentPrincipalAmount,glim.child_accounts_count as childAccountsCount,"
+"glim.loan_status_id as loanStatus from glim_accounts glim,m_loan ln where glim.id=ln.glim_id";
}
@Override
public GroupLoanIndividualMonitoringAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
throws SQLException {
final BigDecimal glimId=rs.getBigDecimal("glimId");
final BigDecimal groupId=rs.getBigDecimal("groupId");
final String accountNumber=rs.getString("accountNumber");
final String childAccountNumber=rs.getString("childAccountNumber");
final Long childAccountsCount=rs.getLong("childAccountsCount");
final BigDecimal parentPrincipalAmount=rs.getBigDecimal("parentPrincipalAmount");
final BigDecimal childPrincipalAmount=rs.getBigDecimal("childPrincipalAmount");
final String loanStatus=LoanStatus.fromInt((int)rs.getLong("loanStatus")).toString();
return GroupLoanIndividualMonitoringAccountData.getInstance(glimId,groupId,accountNumber,childAccountNumber,childPrincipalAmount,parentPrincipalAmount,
childAccountsCount,loanStatus);
}
}
@Override
public Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountsByGLIMId(final Long glimId) {
this.context.authenticatedUser();
final GLIMFieldsMapper rm = new GLIMFieldsMapper();
final String sql = "select " + rm.schema() + " and glim.id=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { glimId });
}
@Override
public Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountsByGroupId(String groupId) {
this.context.authenticatedUser();
final GLIMFieldsMapper rm = new GLIMFieldsMapper();
final String sql = "select " + rm.schema() + " and ln.group_id=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { groupId });
}
@Override
public Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountByGroupId(String groupId) {
this.context.authenticatedUser();
GLIMMapper rm=new GLIMMapper();
final String sql="select "+rm.schema()+" where glim.group_id=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { groupId });
}
@Override
public Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountByParentAccountId(String parentAccountIds) {
this.context.authenticatedUser();
final GLIMFieldsMapper rm = new GLIMFieldsMapper();
final String sql = "select " + rm.schema() + " and glim.accountNumber=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { parentAccountIds });
}
@Override
public Collection<GroupLoanIndividualMonitoringAccountData> findGlimAccountByGroupIdandAccountNo(String groupId,String accountNo) {
this.context.authenticatedUser();
GLIMMapper rm=new GLIMMapper();
final String sql="select "+rm.schema()+" where glim.group_id=? and glim.account_number=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { groupId,accountNo });
}
@Override
public Collection<GLIMContainer> findGlimAccount(Long groupId) {
this.context.authenticatedUser();
Collection<GroupLoanIndividualMonitoringAccountData> glimInfo=findGlimAccountByGroupId(groupId+"");
//List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId });
List<GLIMContainer> glimAccounts=new ArrayList<GLIMContainer>();
for(GroupLoanIndividualMonitoringAccountData glimAccount:glimInfo)
{
List<LoanAccountSummaryData> childLoans=accountDetailsReadPlatforService.retrieveLoanAccountDetailsByGroupIdAndGlimAccountNumber(groupId,glimAccount.getAccountNumber());
glimAccounts.add(new GLIMContainer(glimAccount.getGlimId(),glimAccount.getGroupId(), glimAccount.getAccountNumber(),
childLoans, glimAccount.getParentPrincipalAmount(),glimAccount.getLoanStatus()));
}
return glimAccounts;
}
@Override
public Collection<GLIMContainer> findGlimAccountbyGroupAndAccount(Long groupId,String accountNo) {
this.context.authenticatedUser();
Collection<GroupLoanIndividualMonitoringAccountData> glimInfo=findGlimAccountByGroupIdandAccountNo(groupId+"", accountNo+"");
//List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId });
List<GLIMContainer> glimAccounts=new ArrayList<GLIMContainer>();
for(GroupLoanIndividualMonitoringAccountData glimAccount:glimInfo)
{
List<LoanAccountSummaryData> childLoans=accountDetailsReadPlatforService.retrieveLoanAccountDetailsByGroupIdAndGlimAccountNumber(groupId,glimAccount.getAccountNumber());
glimAccounts.add(new GLIMContainer(glimAccount.getGlimId(),glimAccount.getGroupId(), glimAccount.getAccountNumber(),
childLoans, glimAccount.getParentPrincipalAmount(),glimAccount.getLoanStatus()));
}
return glimAccounts;
}
@Override
public Collection<GlimRepaymentTemplate> findglimRepaymentTemplate(final Long glimId)
{
this.context.authenticatedUser();
GLIMRepaymentMapper rm=new GLIMRepaymentMapper();
final String sql="select "+rm.schema()+" where glim.id=?";
return this.jdbcTemplate.query(sql, rm, new Object[] {glimId});
}
private static final class GLIMMapper implements RowMapper<GroupLoanIndividualMonitoringAccountData> {
public String schema() {
return "glim.id as glimId,glim.group_id as groupId,glim.account_number as accountNumber,glim.principal_amount as principalAmount,glim.child_accounts_count as childAccountsCount,"+
"glim.loan_status_id as loanStatus from glim_accounts glim";
}
@Override
public GroupLoanIndividualMonitoringAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
throws SQLException {
final BigDecimal glimId=rs.getBigDecimal("glimId");
final BigDecimal groupId=rs.getBigDecimal("groupId");
final String accountNumber=rs.getString("accountNumber");
final BigDecimal principalAmount=rs.getBigDecimal("principalAmount");
final String loanStatus=LoanStatus.fromInt((int)rs.getLong("loanStatus")).toString();
return GroupLoanIndividualMonitoringAccountData.getInstance1(glimId,groupId, accountNumber, principalAmount,loanStatus);
}
}
private static final class GLIMRepaymentMapper implements RowMapper<GlimRepaymentTemplate> {
public String schema() {
return "glim.id as glimId,loan.group_id as groupId,client.id as clientId,glim.account_number as parentLoanAccountNo,"+
"glim.principal_amount as parentPrincipalAmount,loan.id as childLoanId,loan.account_no as childLoanAccountNo,loan.approved_principal as childPrincipalAmount,"+
"client.display_name as clientName from glim_accounts glim left join m_loan loan on loan.glim_id=glim.id "+
"left join m_client client on client.id=loan.client_id";
}
@Override
public GlimRepaymentTemplate mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
throws SQLException {
final BigDecimal glimId=rs.getBigDecimal("glimId");
final BigDecimal groupId=rs.getBigDecimal("groupId");
final BigDecimal clientId=rs.getBigDecimal("clientId");
final String clientName=rs.getString("clientName");
final BigDecimal childLoanId=rs.getBigDecimal("childLoanId");
final String parentLoanAccountNo=rs.getString("parentLoanAccountNo");
final BigDecimal parentPrincipalAmount=rs.getBigDecimal("parentPrincipalAmount");
final String childLoanAccountNo=rs.getString("childLoanAccountNo");
final BigDecimal childPrincipalAmount=rs.getBigDecimal("childPrincipalAmount");
return GlimRepaymentTemplate.getInstance(glimId,groupId,clientId,clientName,childLoanId,parentLoanAccountNo,
parentPrincipalAmount,childLoanAccountNo,childPrincipalAmount);
}
}
}
@@ -0,0 +1,36 @@
/**
* 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.service;
import java.math.BigDecimal;
import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
public interface GLIMAccountInfoWritePlatformService {
void setIsAcceptingChild(GroupLoanIndividualMonitoringAccount glimAccount);
void resetIsAcceptingChild(GroupLoanIndividualMonitoringAccount glimAccount);
void incrementChildAccountCount(GroupLoanIndividualMonitoringAccount glimAccount);
void addGLIMAccountInfo(String accountNumber, Group group, BigDecimal principalAmount, Long childAccountsCount,
Boolean isAcceptingChild, Integer loanStatus, BigDecimal applicationId);
}
@@ -0,0 +1,94 @@
/**
* 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.service;
import java.math.BigDecimal;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepository;
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class GLIMAccountInfoWritePlatformServiceImpl implements GLIMAccountInfoWritePlatformService
{
private final PlatformSecurityContext context;
private final GLIMAccountInfoRepository glimAccountRepository;
private final LoanRepository loanRepository;
@Autowired
public GLIMAccountInfoWritePlatformServiceImpl(final PlatformSecurityContext context,final GLIMAccountInfoRepository glimAccountRepository,
final LoanRepository loanRepository)
{
this.context=context;
this.glimAccountRepository=glimAccountRepository;
this.loanRepository=loanRepository;
}
@Override
public void addGLIMAccountInfo(String accountNumber,Group group,BigDecimal principalAmount,Long childAccountsCount,
Boolean isAcceptingChild,Integer loanStatus,BigDecimal applicationId)
{
childAccountsCount=2L;
GroupLoanIndividualMonitoringAccount glimAccountInfo=GroupLoanIndividualMonitoringAccount.getInstance(accountNumber,group,principalAmount,childAccountsCount,
isAcceptingChild,loanStatus,applicationId);
this.glimAccountRepository.save(glimAccountInfo );
}
@Override
public void setIsAcceptingChild(GroupLoanIndividualMonitoringAccount glimAccount)
{
glimAccount.setIsAcceptingChild(true);
glimAccountRepository.save(glimAccount);
}
@Override
public void resetIsAcceptingChild(GroupLoanIndividualMonitoringAccount glimAccount)
{
glimAccount.setIsAcceptingChild(false);
glimAccountRepository.save(glimAccount);
}
@Override
public void incrementChildAccountCount(GroupLoanIndividualMonitoringAccount glimAccount)
{
long count=glimAccount.getChildAccountsCount();
glimAccount.setChildAccountsCount(count+1);
glimAccountRepository.save(glimAccount);
}
}
@@ -36,4 +36,10 @@ public interface LoanApplicationWritePlatformService {
CommandProcessingResult rejectApplication(Long loanId, JsonCommand command); CommandProcessingResult rejectApplication(Long loanId, JsonCommand command);
CommandProcessingResult applicantWithdrawsFromApplication(Long loanId, JsonCommand command); CommandProcessingResult applicantWithdrawsFromApplication(Long loanId, JsonCommand command);
CommandProcessingResult approveGLIMLoanAppication(Long loanId, JsonCommand command);
CommandProcessingResult undoGLIMLoanApplicationApproval(Long loanId, JsonCommand command);
CommandProcessingResult rejectGLIMApplicationApproval(Long loanId, JsonCommand command);
} }
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.loanaccount.service;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -87,11 +88,14 @@ import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService
import org.apache.fineract.portfolio.fund.domain.Fund; import org.apache.fineract.portfolio.fund.domain.Fund;
import org.apache.fineract.portfolio.group.domain.Group; import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.group.domain.GroupRepositoryWrapper; import org.apache.fineract.portfolio.group.domain.GroupRepositoryWrapper;
import org.apache.fineract.portfolio.group.exception.GroupMemberNotFoundInGSIMException;
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException; import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants; import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData; import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO; import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.apache.fineract.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepository;
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge; import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails; import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails;
@@ -99,6 +103,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachin
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus; import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummaryWrapper; import org.apache.fineract.portfolio.loanaccount.domain.LoanSummaryWrapper;
@@ -115,6 +120,7 @@ import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationCo
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionApiJsonValidator; import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionApiJsonValidator;
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
import org.apache.fineract.portfolio.loanproduct.data.LoanProductData; import org.apache.fineract.portfolio.loanproduct.data.LoanProductData;
//import org.apache.fineract.portfolio.loanproduct.domain.*;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail; import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository; import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
@@ -127,8 +133,10 @@ import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatform
import org.apache.fineract.portfolio.note.domain.Note; import org.apache.fineract.portfolio.note.domain.Note;
import org.apache.fineract.portfolio.note.domain.NoteRepository; import org.apache.fineract.portfolio.note.domain.NoteRepository;
import org.apache.fineract.portfolio.rate.service.RateAssembler; import org.apache.fineract.portfolio.rate.service.RateAssembler;
import org.apache.fineract.portfolio.savings.data.GroupSavingsIndividualMonitoringAccountData;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler; import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
import org.apache.fineract.portfolio.savings.service.GSIMReadPlatformService;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -139,6 +147,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@Service @Service
public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements LoanApplicationWritePlatformService { public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements LoanApplicationWritePlatformService {
@@ -179,7 +188,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
private final FineractEntityToEntityMappingRepository repository; private final FineractEntityToEntityMappingRepository repository;
private final FineractEntityRelationRepository fineractEntityRelationRepository; private final FineractEntityRelationRepository fineractEntityRelationRepository;
private final LoanProductReadPlatformService loanProductReadPlatformService; private final LoanProductReadPlatformService loanProductReadPlatformService;
private final RateAssembler rateAssembler; private final RateAssembler rateAssembler;
private final GLIMAccountInfoWritePlatformService glimAccountInfoWritePlatformService;
private final GLIMAccountInfoRepository glimRepository;
private final LoanRepository loanRepository;
private final GSIMReadPlatformService gsimReadPlatformService;
@Autowired @Autowired
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper, public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
@@ -202,8 +216,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService, final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService,
final CalendarReadPlatformService calendarReadPlatformService, final GlobalConfigurationRepositoryWrapper globalConfigurationRepository, final CalendarReadPlatformService calendarReadPlatformService, final GlobalConfigurationRepositoryWrapper globalConfigurationRepository,
final FineractEntityToEntityMappingRepository repository, final FineractEntityRelationRepository fineractEntityRelationRepository, final FineractEntityToEntityMappingRepository repository, final FineractEntityRelationRepository fineractEntityRelationRepository,
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, final LoanProductReadPlatformService loanProductReadPlatformService, final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService,
final RateAssembler rateAssembler) { final GLIMAccountInfoWritePlatformService glimAccountInfoWritePlatformService,
final GLIMAccountInfoRepository glimRepository,final LoanRepository loanRepository,
final GSIMReadPlatformService gsimReadPlatformService, final RateAssembler rateAssembler,
final LoanProductReadPlatformService loanProductReadPlatformService
) {
this.context = context; this.context = context;
this.fromJsonHelper = fromJsonHelper; this.fromJsonHelper = fromJsonHelper;
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator; this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
@@ -240,6 +258,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.fineractEntityRelationRepository = fineractEntityRelationRepository; this.fineractEntityRelationRepository = fineractEntityRelationRepository;
this.loanProductReadPlatformService = loanProductReadPlatformService; this.loanProductReadPlatformService = loanProductReadPlatformService;
this.rateAssembler = rateAssembler; this.rateAssembler = rateAssembler;
this.glimAccountInfoWritePlatformService=glimAccountInfoWritePlatformService;
this.glimRepository=glimRepository;
this.loanRepository=loanRepository;
this.gsimReadPlatformService=gsimReadPlatformService;
} }
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -365,11 +387,106 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
createAndPersistCalendarInstanceForInterestRecalculation(newLoanApplication); createAndPersistCalendarInstanceForInterestRecalculation(newLoanApplication);
} }
// loan account number generation
String accountNumber="";
GroupLoanIndividualMonitoringAccount glimAccount;
BigDecimal applicationId=BigDecimal.ZERO;
Boolean isLastChildApplication=false;
if (newLoanApplication.isAccountNumberRequiresAutoGeneration()) { if (newLoanApplication.isAccountNumberRequiresAutoGeneration()) {
final AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository
.findByAccountType(EntityAccountType.LOAN); final AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(EntityAccountType.LOAN);
newLoanApplication.updateAccountNo(this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat)); // if application is of GLIM type
this.loanRepositoryWrapper.save(newLoanApplication); if(newLoanApplication.getLoanType()==4)
{
Group group= this.groupRepository.findOneWithNotFoundDetection(groupId);
//GLIM specific parameters
if(command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("applicationId")!=null)
{
applicationId=command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("applicationId");
}
if(command.booleanObjectValueOfParameterNamed("lastApplication")!=null)
{
isLastChildApplication=command.booleanPrimitiveValueOfParameterNamed("lastApplication");
}
if(command.booleanObjectValueOfParameterNamed("isParentAccount")!=null)
{
//empty table check
if(glimRepository.count()!=0)
{
//**************Parent-Not an empty table********************
accountNumber=this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat);
newLoanApplication.updateAccountNo(accountNumber+"1");
glimAccountInfoWritePlatformService.addGLIMAccountInfo(accountNumber,group, command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("totalLoan"),Long.valueOf(1),true,
LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(),applicationId);
newLoanApplication.setGlim(glimRepository.findOneByAccountNumber(accountNumber));
this.loanRepositoryWrapper.save(newLoanApplication);
}
else
{
//************** Parent-empty table********************
accountNumber=this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat);
newLoanApplication.updateAccountNo(accountNumber+"1");
glimAccountInfoWritePlatformService.addGLIMAccountInfo(accountNumber,group, command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("totalLoan"),Long.valueOf(1),true,
LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(),applicationId);
newLoanApplication.setGlim(glimRepository.findOneByAccountNumber(accountNumber));
this.loanRepositoryWrapper.save(newLoanApplication);
}
}
else
{
if(glimRepository.count()!=0)
{
// Child-Not an empty table
glimAccount=glimRepository.findOneByIsAcceptingChildAndApplicationId(true,applicationId);
accountNumber=glimAccount.getAccountNumber()+(glimAccount.getChildAccountsCount()+1);
newLoanApplication.updateAccountNo(accountNumber);
this.glimAccountInfoWritePlatformService.incrementChildAccountCount(glimAccount);
newLoanApplication.setGlim(glimAccount);
this.loanRepositoryWrapper.save(newLoanApplication);
}
else
{
//**************Child-empty table********************
// if the glim info is empty set the current account as parent
accountNumber=this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat);
newLoanApplication.updateAccountNo(accountNumber+"1");
glimAccountInfoWritePlatformService.addGLIMAccountInfo(accountNumber,group, command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("totalLoan"),Long.valueOf(1),true,
LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(),applicationId);
newLoanApplication.setGlim(glimRepository.findOneByAccountNumber(accountNumber));
this.loanRepositoryWrapper.save(newLoanApplication);
}
// reset in cases of last child application of glim
if(isLastChildApplication)
{
this.glimAccountInfoWritePlatformService.resetIsAcceptingChild(glimRepository.findOneByIsAcceptingChildAndApplicationId(true,applicationId));
}
}
}
else // for applications other than GLIM
{
newLoanApplication.updateAccountNo(this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat));
this.loanRepositoryWrapper.save(newLoanApplication);
}
} }
final String submittedOnNote = command.stringValueOfParameterNamed("submittedOnNote"); final String submittedOnNote = command.stringValueOfParameterNamed("submittedOnNote");
@@ -411,17 +528,53 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
} }
} }
// Save linked account information // Save linked account information
SavingsAccount savingsAccount;
AccountAssociations accountAssociations;
final Long savingsAccountId = command.longValueOfParameterNamed("linkAccountId"); final Long savingsAccountId = command.longValueOfParameterNamed("linkAccountId");
if (savingsAccountId != null) { if (savingsAccountId != null) {
final SavingsAccount savingsAccount = this.savingsAccountAssembler.assembleFrom(savingsAccountId); if(newLoanApplication.getLoanType()==4)
this.fromApiJsonDeserializer.validatelinkedSavingsAccount(savingsAccount, newLoanApplication); {
boolean isActive = true;
final AccountAssociations accountAssociations = AccountAssociations.associateSavingsAccount(newLoanApplication,
savingsAccount, AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive);
this.accountAssociationsRepository.save(accountAssociations);
}
List<GroupSavingsIndividualMonitoringAccountData> childSavings= (List<GroupSavingsIndividualMonitoringAccountData>)gsimReadPlatformService.findGSIMAccountsByGSIMId(savingsAccountId);
//List<SavingsAccountSummaryData> childSavings=gsimAccount.getChildGSIMAccounts();
List<BigDecimal> gsimClientMembers=new ArrayList<BigDecimal>();
Map<BigDecimal,BigDecimal> clientAccountMappings=new HashMap<>();
for(GroupSavingsIndividualMonitoringAccountData childSaving:childSavings)
{
gsimClientMembers.add(childSaving.getClientId());
clientAccountMappings.put(childSaving.getClientId(), childSaving.getChildAccountId());
}
if(gsimClientMembers.contains(BigDecimal.valueOf(newLoanApplication.getClientId())))
{
savingsAccount = this.savingsAccountAssembler.assembleFrom((clientAccountMappings.get(BigDecimal.valueOf(newLoanApplication.getClientId()))).longValue());
this.fromApiJsonDeserializer.validatelinkedSavingsAccount(savingsAccount, newLoanApplication);
boolean isActive = true;
accountAssociations = AccountAssociations.associateSavingsAccount(newLoanApplication,
savingsAccount, AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive);
this.accountAssociationsRepository.save(accountAssociations);
}else
{
throw new GroupMemberNotFoundInGSIMException(newLoanApplication.getClientId());
}
}
else
{
savingsAccount = this.savingsAccountAssembler.assembleFrom(savingsAccountId);
this.fromApiJsonDeserializer.validatelinkedSavingsAccount(savingsAccount, newLoanApplication);
boolean isActive = true;
accountAssociations = AccountAssociations.associateSavingsAccount(newLoanApplication,
savingsAccount, AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive);
this.accountAssociationsRepository.save(accountAssociations);
}
}
if(command.parameterExists(LoanApiConstants.datatables)){ if(command.parameterExists(LoanApiConstants.datatables)){
this.entityDatatableChecksWritePlatformService.saveDatatables(StatusEnum.CREATE.getCode().longValue(), this.entityDatatableChecksWritePlatformService.saveDatatables(StatusEnum.CREATE.getCode().longValue(),
EntityTables.LOAN.getName(), newLoanApplication.getId(), newLoanApplication.productId(), EntityTables.LOAN.getName(), newLoanApplication.getId(), newLoanApplication.productId(),
@@ -441,7 +594,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
.withOfficeId(newLoanApplication.getOfficeId()) // .withOfficeId(newLoanApplication.getOfficeId()) //
.withClientId(newLoanApplication.getClientId()) // .withClientId(newLoanApplication.getClientId()) //
.withGroupId(newLoanApplication.getGroupId()) // .withGroupId(newLoanApplication.getGroupId()) //
.withLoanId(newLoanApplication.getId()) // .withLoanId(newLoanApplication.getId())
.withGlimId(newLoanApplication.getGlimId())
.build(); .build();
} catch (final DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
@@ -1131,6 +1285,60 @@ public void checkForProductMixRestrictions(final Loan loan) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
} }
@Transactional
@Override
public CommandProcessingResult approveGLIMLoanAppication(final Long loanId, final JsonCommand command)
{
final Long parentLoanId=loanId;
GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
JsonArray approvalFormData=command.arrayOfParameterNamed("approvalFormData");
JsonObject jsonObject=null;
JsonCommand childCommand=null;
Long[] childLoanId=new Long[approvalFormData.size()];
BigDecimal parentPrincipalAmount=command.bigDecimalValueOfParameterNamed("glimPrincipal");
for (int i = 0; i < approvalFormData.size(); i++) {
jsonObject=approvalFormData.get(i).getAsJsonObject();
childLoanId[i]=jsonObject.get("loanId").getAsLong();
}
CommandProcessingResult result=null;
int count=0,j=0;
for(JsonElement approvals:approvalFormData)
{
childCommand=JsonCommand.fromExistingCommand(command,approvals);
result=approveApplication(childLoanId[j++],childCommand);
if(result.getLoanId()!=null)
{
count++;
// if all the child loans are approved, mark the parent loan as approved
if(count==parentLoan.getChildAccountsCount())
{
parentLoan.setPrincipalAmount(parentPrincipalAmount);
parentLoan.setLoanStatus(LoanStatus.APPROVED.getValue());
glimRepository.save(parentLoan);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult approveApplication(final Long loanId, final JsonCommand command) { public CommandProcessingResult approveApplication(final Long loanId, final JsonCommand command) {
@@ -1177,6 +1385,8 @@ public void checkForProductMixRestrictions(final Loan loan) {
final Map<String, Object> changes = loan.loanApplicationApproval(currentUser, command, disbursementDataArray, final Map<String, Object> changes = loan.loanApplicationApproval(currentUser, command, disbursementDataArray,
defaultLoanLifecycleStateMachine()); defaultLoanLifecycleStateMachine());
entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId, EntityTables.LOAN.getName(), entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId, EntityTables.LOAN.getName(),
StatusEnum.APPROVE.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId()); StatusEnum.APPROVE.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
@@ -1239,6 +1449,42 @@ public void checkForProductMixRestrictions(final Loan loan) {
.build(); .build();
} }
@Transactional
@Override
public CommandProcessingResult undoGLIMLoanApplicationApproval(final Long loanId, final JsonCommand command)
{
//GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId);
final Long parentLoanId=loanId;
GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
List<Loan> childLoans=this.loanRepository.findByGlimId(loanId);
CommandProcessingResult result=null;
int count=0;
for(Loan loan:childLoans)
{
result=undoApplicationApproval(loan.getId(),command);
if(result.getLoanId()!=null)
{
count++;
// if all the child loans are approved, mark the parent loan as approved
if(count==parentLoan.getChildAccountsCount())
{
parentLoan.setLoanStatus(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue());
glimRepository.save(parentLoan);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult undoApplicationApproval(final Long loanId, final JsonCommand command) { public CommandProcessingResult undoApplicationApproval(final Long loanId, final JsonCommand command) {
@@ -1285,6 +1531,41 @@ public void checkForProductMixRestrictions(final Loan loan) {
.build(); .build();
} }
@Transactional
@Override
public CommandProcessingResult rejectGLIMApplicationApproval(final Long glimId, final JsonCommand command)
{
//GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId);
final Long parentLoanId=glimId;
GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
List<Loan> childLoans=this.loanRepository.findByGlimId(glimId);
CommandProcessingResult result=null;
int count=0;
for(Loan loan:childLoans)
{
result=rejectApplication(loan.getId(),command);
if(result.getLoanId()!=null)
{
count++;
// if all the child loans are Rejected, mark the parent loan as rejected
if(count==parentLoan.getChildAccountsCount())
{
parentLoan.setLoanStatus(LoanStatus.REJECTED.getValue());
glimRepository.save(parentLoan);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult rejectApplication(final Long loanId, final JsonCommand command) { public CommandProcessingResult rejectApplication(final Long loanId, final JsonCommand command) {
@@ -148,6 +148,7 @@ public class LoanAssembler {
return loanAccount; return loanAccount;
} }
public void setHelpers(final Loan loanAccount) { public void setHelpers(final Loan loanAccount) {
loanAccount.setHelpers(defaultLoanLifecycleStateMachine(), this.loanSummaryWrapper, loanAccount.setHelpers(defaultLoanLifecycleStateMachine(), this.loanSummaryWrapper,
this.loanRepaymentScheduleTransactionProcessorFactory); this.loanRepaymentScheduleTransactionProcessorFactory);
@@ -133,7 +133,6 @@ public interface LoanReadPlatformService {
LoanTransactionData retrieveLoanForeclosureTemplate(final Long loanId, final LocalDate transactionDate); LoanTransactionData retrieveLoanForeclosureTemplate(final Long loanId, final LocalDate transactionDate);
LoanAccountData retrieveLoanByLoanAccount(String loanAccountNumber); LoanAccountData retrieveLoanByLoanAccount(String loanAccountNumber);
Long retrieveLoanIdByAccountNumber(String loanAccountNumber); Long retrieveLoanIdByAccountNumber(String loanAccountNumber);
@@ -142,4 +141,6 @@ public interface LoanReadPlatformService {
Integer retrieveNumberOfActiveLoans(); Integer retrieveNumberOfActiveLoans();
List<LoanAccountData> retrieveGLIMChildLoansByGLIMParentAccount(String parentloanAccountNumber);
} }
@@ -233,6 +233,23 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
} }
@Override
public List<LoanAccountData> retrieveGLIMChildLoansByGLIMParentAccount(String parentloanAccountNumber)
{
//final AppUser currentUser = this.context.authenticatedUser();
this.context.authenticatedUser();
final LoanMapper rm = new LoanMapper();
String sql="select "+rm.loanSchema()+" left join glim_parent_child_mapping as glim on glim.glim_child_account_id=l.account_no "+
"where glim.glim_parent_account_id=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { parentloanAccountNumber });
}
@Override @Override
public LoanScheduleData retrieveRepaymentSchedule(final Long loanId, public LoanScheduleData retrieveRepaymentSchedule(final Long loanId,
final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedLoanData, Collection<DisbursementData> disbursementData, final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedLoanData, Collection<DisbursementData> disbursementData,
@@ -108,4 +108,10 @@ public interface LoanWritePlatformService {
CommandProcessingResult forecloseLoan(final Long loanId, JsonCommand command); CommandProcessingResult forecloseLoan(final Long loanId, JsonCommand command);
CommandProcessingResult disburseGLIMLoan(Long loanId, JsonCommand command);
CommandProcessingResult undoGLIMLoanDisbursal(Long loanId, JsonCommand command);
CommandProcessingResult makeGLIMLoanRepayment(Long loanId, JsonCommand command);
} }
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.loanaccount.service;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -127,6 +128,8 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanInstallmentChargeData;
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO; import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail; import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
import org.apache.fineract.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.apache.fineract.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepository;
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService; import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge; import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
@@ -140,6 +143,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanOverdueInstallmentCh
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus; import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
import org.apache.fineract.portfolio.loanaccount.domain.LoanSubStatus; import org.apache.fineract.portfolio.loanaccount.domain.LoanSubStatus;
@@ -191,6 +195,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService { public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService {
@@ -234,6 +239,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy; private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy;
private final CodeValueRepositoryWrapper codeValueRepository; private final CodeValueRepositoryWrapper codeValueRepository;
private final CashierTransactionDataValidator cashierTransactionDataValidator; private final CashierTransactionDataValidator cashierTransactionDataValidator;
private final GLIMAccountInfoRepository glimRepository;
private final LoanRepository loanRepository;
@Autowired @Autowired
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -264,7 +271,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy, final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy,
final CodeValueRepositoryWrapper codeValueRepository, final CodeValueRepositoryWrapper codeValueRepository,
final LoanRepositoryWrapper loanRepositoryWrapper, final LoanRepositoryWrapper loanRepositoryWrapper,
final CashierTransactionDataValidator cashierTransactionDataValidator) { final CashierTransactionDataValidator cashierTransactionDataValidator,
final GLIMAccountInfoRepository glimRepository,
final LoanRepository loanRepository
) {
this.context = context; this.context = context;
this.loanEventApiJsonValidator = loanEventApiJsonValidator; this.loanEventApiJsonValidator = loanEventApiJsonValidator;
this.loanAssembler = loanAssembler; this.loanAssembler = loanAssembler;
@@ -303,6 +313,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.entityDatatableChecksWritePlatformService = entityDatatableChecksWritePlatformService; this.entityDatatableChecksWritePlatformService = entityDatatableChecksWritePlatformService;
this.codeValueRepository = codeValueRepository; this.codeValueRepository = codeValueRepository;
this.cashierTransactionDataValidator = cashierTransactionDataValidator; this.cashierTransactionDataValidator = cashierTransactionDataValidator;
this.loanRepository=loanRepository;
this.glimRepository=glimRepository;
} }
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -310,6 +322,32 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses); return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses);
} }
@Transactional
@Override
public CommandProcessingResult disburseGLIMLoan(final Long loanId, final JsonCommand command)
{
final Long parentLoanId=loanId;
GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
List<Loan> childLoans=this.loanRepository.findByGlimId(loanId);
CommandProcessingResult result=null;
int count=0;
for(Loan loan:childLoans)
{
result=disburseLoan(loan.getId(),command,false);
if(result.getLoanId()!=null)
{
count++;
// if all the child loans are approved, mark the parent loan as approved
if(count==parentLoan.getChildAccountsCount())
{
parentLoan.setLoanStatus(LoanStatus.ACTIVE.getValue());
glimRepository.save(parentLoan);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult disburseLoan(final Long loanId, final JsonCommand command, Boolean isAccountTransfer) { public CommandProcessingResult disburseLoan(final Long loanId, final JsonCommand command, Boolean isAccountTransfer) {
@@ -729,18 +767,44 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
return changes; return changes;
} }
@Transactional
@Override
public CommandProcessingResult undoGLIMLoanDisbursal(final Long loanId, final JsonCommand command)
{
//GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId);
final Long parentLoanId=loanId;
GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
List<Loan> childLoans=this.loanRepository.findByGlimId(loanId);
CommandProcessingResult result=null;
int count=0;
for(Loan loan:childLoans)
{
result=undoLoanDisbursal(loan.getId(),command);
if(result.getLoanId()!=null)
{
count++;
// if all the child loans are approved, mark the parent loan as approved
if(count==parentLoan.getChildAccountsCount())
{
parentLoan.setLoanStatus(LoanStatus.APPROVED.getValue());
glimRepository.save(parentLoan);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult undoLoanDisbursal(final Long loanId, final JsonCommand command) { public CommandProcessingResult undoLoanDisbursal(final Long loanId, final JsonCommand command) {
final AppUser currentUser = getAppUserIfPresent(); final AppUser currentUser = getAppUserIfPresent();
final Loan loan = this.loanAssembler.assembleFrom(loanId); final Loan loan = this.loanAssembler.assembleFrom(loanId);
checkClientOrGroupActive(loan); checkClientOrGroupActive(loan);
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_UNDO_DISBURSAL, this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_UNDO_DISBURSAL,
constructEntityMap(BUSINESS_ENTITY.LOAN, loan)); constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
removeLoanCycle(loan); removeLoanCycle(loan);
final List<Long> existingTransactionIds = new ArrayList<>(); final List<Long> existingTransactionIds = new ArrayList<>();
final List<Long> existingReversedTransactionIds = new ArrayList<>(); final List<Long> existingReversedTransactionIds = new ArrayList<>();
// //
@@ -784,6 +848,36 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
.build(); .build();
} }
@Transactional
@Override
public CommandProcessingResult makeGLIMLoanRepayment(final Long loanId, final JsonCommand command)
{
final Long parentLoanId=loanId;
GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
JsonArray repayments= command.arrayOfParameterNamed("formDataArray");
JsonCommand childCommand=null;
CommandProcessingResult result=null;
JsonObject jsonObject=null;
Long[] childLoanId=new Long[repayments.size()];
for (int i = 0; i < repayments.size(); i++) {
jsonObject=repayments.get(i).getAsJsonObject();
LOG.info("{}",jsonObject.toString());
childLoanId[i]=jsonObject.get("loanId").getAsLong();
}
int j=0;
for(JsonElement element:repayments )
{
childCommand=JsonCommand.fromExistingCommand(command,element);
result=makeLoanRepayment(childLoanId[j++],childCommand,false);
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult makeLoanRepayment(final Long loanId, final JsonCommand command, final boolean isRecoveryRepayment) { public CommandProcessingResult makeLoanRepayment(final Long loanId, final JsonCommand command, final boolean isRecoveryRepayment) {
@@ -3020,4 +3114,4 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
} }
} }
} }
@@ -18,7 +18,7 @@
*/ */
package org.apache.fineract.portfolio.savings; package org.apache.fineract.portfolio.savings;
public class SavingsApiConstants { public class SavingsApiConstants {
public static final String SAVINGS_PRODUCT_RESOURCE_NAME = "savingsproduct"; public static final String SAVINGS_PRODUCT_RESOURCE_NAME = "savingsproduct";
public static final String SAVINGS_ACCOUNT_RESOURCE_NAME = "savingsaccount"; public static final String SAVINGS_ACCOUNT_RESOURCE_NAME = "savingsaccount";
@@ -72,11 +72,20 @@ public class SavingsApiConstants {
// savings product and account parameters // savings product and account parameters
public static final String idParamName = "id"; public static final String idParamName = "id";
public static final String isGSIM="isGSIM";
public static final String isParentAccount="isParentAccount";
public static final String accountNoParamName = "accountNo"; public static final String accountNoParamName = "accountNo";
public static final String externalIdParamName = "externalId"; public static final String externalIdParamName = "externalId";
public static final String statusParamName = "status"; public static final String statusParamName = "status";
public static final String subStatusParamName = "subStatus"; public static final String subStatusParamName = "subStatus";
public static final String clientIdParamName = "clientId"; public static final String clientIdParamName = "clientId";
public static final String isRetailAccountParamName = "isRetailAccount";
public static final String autogenerateTransactionIdParamName="autogenerateTransactionId";
public static final String transactionUpperLimitParamName="transactionUpperLimit";
public static final String transactionLowerLimitParamName="transactionLowerLimit";
public static final String retailEntriesParamName="retailEntries";
public static final String childAccountIdParamName="childAccountId";
public static final String groupIdParamName = "groupId"; public static final String groupIdParamName = "groupId";
public static final String productIdParamName = "productId"; public static final String productIdParamName = "productId";
public static final String fieldOfficerIdParamName = "fieldOfficerId"; public static final String fieldOfficerIdParamName = "fieldOfficerId";
@@ -178,5 +187,7 @@ public class SavingsApiConstants {
public static final String datatables = "datatables"; public static final String datatables = "datatables";
public static final String gsimApplicationId = "applicationId";
public static final String gsimLastApplication = "lastApplication";
public static final String ERROR_MSG_SAVINGS_ACCOUNT_NOT_ACTIVE = "not.in.active.state"; public static final String ERROR_MSG_SAVINGS_ACCOUNT_NOT_ACTIVE = "not.in.active.state";
} }
@@ -137,6 +137,11 @@ public class SavingsAccountTransactionsApiResource {
if (is(commandParam, "deposit")) { if (is(commandParam, "deposit")) {
final CommandWrapper commandRequest = builder.savingsAccountDeposit(savingsId).build(); final CommandWrapper commandRequest = builder.savingsAccountDeposit(savingsId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
else if(is(commandParam, "gsimDeposit"))
{
final CommandWrapper commandRequest = builder.gsimSavingsAccountDeposit(savingsId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "withdrawal")) { } else if (is(commandParam, "withdrawal")) {
final CommandWrapper commandRequest = builder.savingsAccountWithdrawal(savingsId).build(); final CommandWrapper commandRequest = builder.savingsAccountWithdrawal(savingsId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
@@ -170,6 +170,19 @@ public class SavingsAccountsApiResource {
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@POST
@Path("/gsim")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String submitGSIMApplication(final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGSIMAccount().withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@GET @GET
@Path("{accountId}") @Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@@ -265,6 +278,83 @@ public class SavingsAccountsApiResource {
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@PUT
@Path("/gsim/{parentAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
/* public String updateGsim(@PathParam("parentAccountId") final Long parentAccountId, final String apiRequestBodyAsJson,
@QueryParam("command") final String commandParam) {*/
public String updateGsim(@PathParam("parentAccountId") final Long parentAccountId, final String apiRequestBodyAsJson)
{
/* if (is(commandParam, "updateWithHoldTax")) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson).updateWithHoldTax(accountId)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}*/
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGSIMAccount(parentAccountId).withJson(apiRequestBodyAsJson)
.build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@POST
@Path("/gsimcommands/{parentAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String handleGSIMCommands(@PathParam("parentAccountId") final Long parentAccountId, @QueryParam("command") final String commandParam,
final String apiRequestBodyAsJson) {
String jsonApiRequest = apiRequestBodyAsJson;
if (StringUtils.isBlank(jsonApiRequest)) {
jsonApiRequest = "{}";
}
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(jsonApiRequest);
CommandProcessingResult result = null;
if (is(commandParam, "reject")) {
final CommandWrapper commandRequest = builder.rejectGSIMAccountApplication(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "withdrawnByApplicant")) {
final CommandWrapper commandRequest = builder.withdrawSavingsAccountApplication(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "approve")) {
final CommandWrapper commandRequest = builder.approveGSIMAccountApplication(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "undoapproval")) {
final CommandWrapper commandRequest = builder.undoGSIMApplicationApproval(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "activate")) {
final CommandWrapper commandRequest = builder.gsimAccountActivation(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "calculateInterest")) {
final CommandWrapper commandRequest = builder.withNoJsonBody().savingsAccountInterestCalculation(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "postInterest")) {
final CommandWrapper commandRequest = builder.savingsAccountInterestPosting(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "applyAnnualFees")) {
final CommandWrapper commandRequest = builder.savingsAccountApplyAnnualFees(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "close")) {
final CommandWrapper commandRequest = builder.closeGSIMApplication(parentAccountId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) {
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "reject", "withdrawnByApplicant", "approve",
"undoapproval", "activate", "calculateInterest", "postInterest", "close", "assignSavingsOfficer",
"unassignSavingsOfficer", SavingsApiConstants.COMMAND_BLOCK_DEBIT, SavingsApiConstants.COMMAND_UNBLOCK_DEBIT,
SavingsApiConstants.COMMAND_BLOCK_CREDIT, SavingsApiConstants.COMMAND_UNBLOCK_CREDIT,
SavingsApiConstants.COMMAND_BLOCK_ACCOUNT, SavingsApiConstants.COMMAND_UNBLOCK_ACCOUNT });
}
return this.toApiJsonSerializer.serialize(result);
}
@POST @POST
@Path("{accountId}") @Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@@ -0,0 +1,75 @@
/**
* 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.savings.data;
import java.math.BigDecimal;
import java.util.List;
import org.apache.fineract.portfolio.accountdetails.data.SavingsSummaryCustom;
public class GSIMContainer {
private final BigDecimal gsimId;
private final BigDecimal groupId;
private final String accountNumber;
private final List<SavingsSummaryCustom> childGSIMAccounts;
private final BigDecimal parentBalance;
private final String savingsStatus;
public GSIMContainer(final BigDecimal gsimId, final BigDecimal groupId, final String accountNumber,
final List<SavingsSummaryCustom> childGSIMAccounts, final BigDecimal parentBalance,
final String savingsStatus) {
this.gsimId = gsimId;
this.groupId = groupId;
this.accountNumber = accountNumber;
this.childGSIMAccounts = childGSIMAccounts;
this.parentBalance = parentBalance;
this.savingsStatus = savingsStatus;
}
public BigDecimal getGsimId() {
return gsimId;
}
public BigDecimal getGroupId() {
return groupId;
}
public String getAccountNumber() {
return accountNumber;
}
public List<SavingsSummaryCustom> getChildGSIMAccounts() {
return childGSIMAccounts;
}
public BigDecimal getparentBalance() {
return parentBalance;
}
public String getSavingsStatus() {
return savingsStatus;
}
}
@@ -0,0 +1,125 @@
/**
* 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.savings.data;
import java.math.BigDecimal;
public class GroupSavingsIndividualMonitoringAccountData
{
private final BigDecimal gsimId;
private final BigDecimal groupId;
private final BigDecimal clientId;
private final String accountNumber;
private final BigDecimal childAccountId;
private final String childAccountNumber;
private final BigDecimal childDeposit;
private final BigDecimal parentDeposit;
private final Long childAccountsCount;
private final String savingsStatus;
private GroupSavingsIndividualMonitoringAccountData(final BigDecimal glimId,final BigDecimal groupId,final BigDecimal clientId,final String accountNumber,final BigDecimal childAccountId, final String childAccountNumber,
final BigDecimal childDeposit, final BigDecimal parentDeposit,
final Long childAccountsCount,final String savingsStatus) {
this.gsimId=glimId;
this.groupId=groupId;
this.clientId=clientId;
this.accountNumber = accountNumber;
this.childAccountId=childAccountId;
this.childAccountNumber = childAccountNumber;
this.childDeposit = childDeposit;
this.parentDeposit = parentDeposit;
this.childAccountsCount = childAccountsCount;
this.savingsStatus=savingsStatus;
}
public static GroupSavingsIndividualMonitoringAccountData getInstance(final BigDecimal glimId, final BigDecimal groupId,final String accountNumber, final String childAccountNumber,
final BigDecimal childDeposit, final BigDecimal parentDeposit,
final Long childAccountsCount,final String savingsStatus)
{
return new GroupSavingsIndividualMonitoringAccountData(glimId,groupId,null,accountNumber,null,childAccountNumber,
childDeposit,parentDeposit,childAccountsCount,savingsStatus);
}
public static GroupSavingsIndividualMonitoringAccountData getInstance1(final BigDecimal glimId,final BigDecimal groupId,final String accountNumber,
final BigDecimal parentDeposit,final String savingsStatus)
{
return new GroupSavingsIndividualMonitoringAccountData(glimId,groupId,null,accountNumber,null,null,null,parentDeposit,null,savingsStatus);
}
public static GroupSavingsIndividualMonitoringAccountData getInstance2(final BigDecimal glimId, final BigDecimal groupId,final BigDecimal clientId,final String accountNumber, final BigDecimal childAccountId,final String childAccountNumber,
final BigDecimal childDeposit, final BigDecimal parentDeposit,
final Long childAccountsCount,final String savingsStatus)
{
return new GroupSavingsIndividualMonitoringAccountData(glimId,groupId,clientId,accountNumber,childAccountId,childAccountNumber,
childDeposit,parentDeposit,childAccountsCount,savingsStatus);
}
public BigDecimal getGsimId() {
return gsimId;
}
public BigDecimal getGroupId() {
return groupId;
}
public BigDecimal getClientId() {
return clientId;
}
public String getAccountNumber() {
return accountNumber;
}
public BigDecimal getChildAccountId() {
return childAccountId;
}
public String getChildAccountNumber() {
return childAccountNumber;
}
public BigDecimal getChildDeposit() {
return childDeposit;
}
public BigDecimal getParentDeposit() {
return parentDeposit;
}
public Long getChildAccountsCount() {
return childAccountsCount;
}
public String getSavingsStatus() {
return savingsStatus;
}
}
@@ -31,7 +31,7 @@ public class SavingsAccountConstant extends SavingsApiConstants {
* parameters to match those of request parameters. * parameters to match those of request parameters.
*/ */
protected static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList( protected static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(
localeParamName, dateFormatParamName, monthDayFormatParamName, staffIdParamName, accountNoParamName, localeParamName, dateFormatParamName, monthDayFormatParamName, staffIdParamName, isGSIM, isParentAccount,accountNoParamName,
externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName, fieldOfficerIdParamName, externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName, fieldOfficerIdParamName,
submittedOnDateParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, submittedOnDateParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName,
interestPostingPeriodTypeParamName, interestCalculationTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
@@ -41,7 +41,8 @@ public class SavingsAccountConstant extends SavingsApiConstants {
withdrawalFeeForTransfersParamName, feeAmountParamName, feeOnMonthDayParamName, chargesParamName, withdrawalFeeForTransfersParamName, feeAmountParamName, feeOnMonthDayParamName, chargesParamName,
allowOverdraftParamName, overdraftLimitParamName, minRequiredBalanceParamName, allowOverdraftParamName, overdraftLimitParamName, minRequiredBalanceParamName,
enforceMinRequiredBalanceParamName, nominalAnnualInterestRateOverdraftParamName, enforceMinRequiredBalanceParamName, nominalAnnualInterestRateOverdraftParamName,
minOverdraftForInterestCalculationParamName, withHoldTaxParamName, datatables)); minOverdraftForInterestCalculationParamName, withHoldTaxParamName, datatables, gsimApplicationId,
gsimLastApplication));
/** /**
* These parameters will match the class level parameters of * These parameters will match the class level parameters of
@@ -52,7 +53,8 @@ public class SavingsAccountConstant extends SavingsApiConstants {
protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<>( protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName, Arrays.asList(localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName,
paymentTypeIdParamName, transactionAccountNumberParamName, checkNumberParamName, paymentTypeIdParamName, transactionAccountNumberParamName, checkNumberParamName,
routingCodeParamName, receiptNumberParamName, bankNumberParamName, noteParamName)); routingCodeParamName, receiptNumberParamName, bankNumberParamName, retailEntriesParamName,
childAccountIdParamName, noteParamName));
protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>( protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, accountNoParamName)); Arrays.asList(idParamName, accountNoParamName));
@@ -0,0 +1,32 @@
/**
* 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.savings.domain;
import java.math.BigDecimal;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface GSIMRepositoy extends JpaRepository<GroupSavingsIndividualMonitoring, Long>, JpaSpecificationExecutor<GroupSavingsIndividualMonitoring>
{
GroupSavingsIndividualMonitoring findOneByIsAcceptingChild(boolean acceptingChild);
GroupSavingsIndividualMonitoring findOneByIsAcceptingChildAndApplicationId(boolean acceptingChild,BigDecimal applicationId);
GroupSavingsIndividualMonitoring findOneByAccountNumber(String accountNumber);
}
@@ -0,0 +1,140 @@
/**
* 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.savings.domain;
import java.math.BigDecimal;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.portfolio.group.domain.Group;
@Entity
@Table(name = "gsim_accounts", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_number" }, name = "gsim_id")})
public class GroupSavingsIndividualMonitoring extends AbstractPersistableCustom
{
@ManyToOne
@JoinColumn(name = "group_id", nullable = false)
private Group group;
@Column(name = "account_number", nullable = false)
private String accountNumber;
@Column(name = "parent_deposit")
private BigDecimal parentDeposit;
@Column(name = "child_accounts_count")
private Long childAccountsCount;
@Column(name = "accepting_child")
private Boolean isAcceptingChild;
@OneToMany
private Set<SavingsAccount> childSaving;
@Column(name = "savings_status_id", nullable = false)
private Integer savingsStatus;
@Column(name = "application_id", nullable = true)
private BigDecimal applicationId;
private GroupSavingsIndividualMonitoring(String accountNumber,Group group,BigDecimal parentDeposit,Long childAccountsCount,
Boolean isAcceptingChild,Integer savingsStatus,BigDecimal applicationId)
{
this.accountNumber=accountNumber;
this.group=group;
this.parentDeposit=parentDeposit;
this.childAccountsCount=childAccountsCount;
this.isAcceptingChild=isAcceptingChild;
this.savingsStatus=savingsStatus;
this.applicationId=applicationId;
}
public static GroupSavingsIndividualMonitoring getInstance(String accountNumber,Group group,BigDecimal parentDeposit,Long childAccountsCount,
Boolean isAcceptingChild,Integer savingsStatus,BigDecimal applicationId)
{
return new GroupSavingsIndividualMonitoring(accountNumber,group,parentDeposit,childAccountsCount,
isAcceptingChild,savingsStatus,applicationId);
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public BigDecimal getParentDeposit() {
return parentDeposit;
}
public void setParentDeposit(BigDecimal parentDeposit) {
this.parentDeposit = parentDeposit;
}
public Long getChildAccountsCount() {
return childAccountsCount;
}
public void setChildAccountsCount(Long childAccountsCount) {
this.childAccountsCount = childAccountsCount;
}
public Boolean getIsAcceptingChild() {
return isAcceptingChild;
}
public void setIsAcceptingChild(Boolean isAcceptingChild) {
this.isAcceptingChild = isAcceptingChild;
}
public Set<SavingsAccount> getChildSaving() {
return childSaving;
}
public void setChildSaving(Set<SavingsAccount> childSaving) {
this.childSaving = childSaving;
}
public Integer getSavingsStatus() {
return savingsStatus;
}
public void setSavingsStatus(Integer savingsStatus) {
this.savingsStatus = savingsStatus;
}
}
@@ -140,10 +140,14 @@ public class SavingsAccount extends AbstractPersistableCustom {
@JoinColumn(name = "client_id", nullable = true) @JoinColumn(name = "client_id", nullable = true)
protected Client client; protected Client client;
@ManyToOne(optional = true) @ManyToOne(optional = true, fetch=FetchType.LAZY)
@JoinColumn(name = "group_id", nullable = true) @JoinColumn(name = "group_id", nullable = true)
protected Group group; protected Group group;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "gsim_id", nullable = true)
private GroupSavingsIndividualMonitoring gsim;
@ManyToOne @ManyToOne
@JoinColumn(name = "product_id", nullable = false) @JoinColumn(name = "product_id", nullable = false)
protected SavingsProduct product; protected SavingsProduct product;
@@ -1612,7 +1616,15 @@ public class SavingsAccount extends AbstractPersistableCustom {
return id; return id;
} }
public Long hasSavingsOfficerId() { public GroupSavingsIndividualMonitoring getGsim() {
return gsim;
}
public void setGsim(GroupSavingsIndividualMonitoring gsim) {
this.gsim = gsim;
}
public Long hasSavingsOfficerId() {
Long id = null; Long id = null;
if (this.savingsOfficer != null) { if (this.savingsOfficer != null) {
id = this.savingsOfficer.getId(); id = this.savingsOfficer.getId();
@@ -2691,10 +2703,6 @@ public class SavingsAccount extends AbstractPersistableCustom {
return getActivationLocalDate() == null ? getSubmittedOnLocalDate() : getActivationLocalDate(); return getActivationLocalDate() == null ? getSubmittedOnLocalDate() : getActivationLocalDate();
} }
public AccountType getAccountType() {
return AccountType.fromInt(accountType);
}
public DepositAccountType depositAccountType() { public DepositAccountType depositAccountType() {
return DepositAccountType.fromInt(depositType); return DepositAccountType.fromInt(depositType);
} }
@@ -3137,8 +3145,19 @@ public class SavingsAccount extends AbstractPersistableCustom {
this.savingsOnHoldAmount = getSavingsHoldAmount().subtract(amount); this.savingsOnHoldAmount = getSavingsHoldAmount().subtract(amount);
} }
public AccountType getAccountType() {
return AccountType.fromInt(accountType);
}
public Integer getAccountTypes() {
return accountType;
}
public void setAccountType(Integer accountType) {
this.accountType = accountType;
}
private boolean isOverdraft() { private boolean isOverdraft() {
return allowOverdraft; return allowOverdraft;
} }
} }
@@ -71,12 +71,15 @@ import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException; import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class SavingsAccountAssembler { public class SavingsAccountAssembler {
private final static Logger LOG = LoggerFactory.getLogger(SavingsAccountAssembler.class);
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper; private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
private final SavingsHelper savingsHelper; private final SavingsHelper savingsHelper;
private final ClientRepositoryWrapper clientRepository; private final ClientRepositoryWrapper clientRepository;
@@ -125,6 +128,8 @@ public class SavingsAccountAssembler {
Group group = null; Group group = null;
Staff fieldOfficer = null; Staff fieldOfficer = null;
AccountType accountType = AccountType.INVALID; AccountType accountType = AccountType.INVALID;
final Long clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element); final Long clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
if (clientId != null) { if (clientId != null) {
client = this.clientRepository.findOneWithNotFoundDetection(clientId); client = this.clientRepository.findOneWithNotFoundDetection(clientId);
@@ -147,6 +152,15 @@ public class SavingsAccountAssembler {
accountType = AccountType.JLG; accountType = AccountType.JLG;
} }
if((Boolean)command.booleanPrimitiveValueOfParameterNamed("isGSIM")!=null)
{
LOG.info("setting system to gsim");
if(command.booleanPrimitiveValueOfParameterNamed("isGSIM"))
{
accountType = AccountType.GSIM;
}
}
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element); final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element);
if (fieldOfficerId != null) { if (fieldOfficerId != null) {
fieldOfficer = this.staffRepository.findOneWithNotFoundDetection(fieldOfficerId); fieldOfficer = this.staffRepository.findOneWithNotFoundDetection(fieldOfficerId);
@@ -298,6 +312,7 @@ public class SavingsAccountAssembler {
return account; return account;
} }
public void setHelpers(final SavingsAccount account) { public void setHelpers(final SavingsAccount account) {
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper); account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
} }
@@ -36,4 +36,5 @@ public interface SavingsAccountDomainService {
void postJournalEntries(SavingsAccount savingsAccount, Set<Long> existingTransactionIds, Set<Long> existingReversedTransactionIds); void postJournalEntries(SavingsAccount savingsAccount, Set<Long> existingTransactionIds, Set<Long> existingReversedTransactionIds);
SavingsAccountTransaction handleDividendPayout(SavingsAccount account, LocalDate transactionDate, BigDecimal transactionAmount); SavingsAccountTransaction handleDividendPayout(SavingsAccount account, LocalDate transactionDate, BigDecimal transactionAmount);
} }
@@ -134,6 +134,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
return user; return user;
} }
@Transactional @Transactional
@Override @Override
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt, public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
@@ -176,7 +177,6 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate); financialYearBeginningMonth, postInterestOnDate);
} }
saveTransactionToGenerateTransactionId(deposit); saveTransactionToGenerateTransactionId(deposit);
this.savingsAccountRepository.saveAndFlush(account); this.savingsAccountRepository.saveAndFlush(account);
@@ -32,6 +32,9 @@ public interface SavingsAccountRepository extends JpaRepository<SavingsAccount,
@Query("select s_acc from SavingsAccount s_acc where s_acc.client.id = :clientId") @Query("select s_acc from SavingsAccount s_acc where s_acc.client.id = :clientId")
List<SavingsAccount> findSavingAccountByClientId(@Param("clientId") Long clientId); List<SavingsAccount> findSavingAccountByClientId(@Param("clientId") Long clientId);
@Query("select s_acc from SavingsAccount s_acc where s_acc.gsim.id = :gsimId")
List<SavingsAccount> findSavingAccountByGsimId(@Param("gsimId") Long gsimId);
@Query("select s_acc from SavingsAccount s_acc where s_acc.status = :status") @Query("select s_acc from SavingsAccount s_acc where s_acc.status = :status")
List<SavingsAccount> findSavingAccountByStatus(@Param("status") Integer status); List<SavingsAccount> findSavingAccountByStatus(@Param("status") Integer status);
@@ -102,6 +102,10 @@ public class SavingsAccountRepositoryWrapper {
return this.repository.findByGroupId(groupId) ; return this.repository.findByGroupId(groupId) ;
} }
public List<SavingsAccount> findByGsimId(@Param("gsimId") Long gsimId) {
return this.repository.findSavingAccountByGsimId(gsimId);
}
//Root Entity is enough //Root Entity is enough
public SavingsAccount findNonClosedAccountByAccountNumber(@Param("accountNumber") String accountNumber) { public SavingsAccount findNonClosedAccountByAccountNumber(@Param("accountNumber") String accountNumber) {
return this.repository.findNonClosedAccountByAccountNumber(accountNumber) ; return this.repository.findNonClosedAccountByAccountNumber(accountNumber) ;
@@ -117,6 +117,10 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
@Column(name = "is_manual", length = 1, nullable = true) @Column(name = "is_manual", length = 1, nullable = true)
private boolean isManualTransaction; private boolean isManualTransaction;
@Column(name = "is_loan_disbursement", length = 1, nullable = true)
private boolean isLoanDisbursement;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER)
@JoinColumn(name = "savings_transaction_id", referencedColumnName = "id", nullable = false) @JoinColumn(name = "savings_transaction_id", referencedColumnName = "id", nullable = false)
private List<SavingsAccountTransactionTaxDetails> taxDetails = new ArrayList<>(); private List<SavingsAccountTransactionTaxDetails> taxDetails = new ArrayList<>();
@@ -407,6 +411,10 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
return getTransactionLocalDate().isEqual(occursOnDate); return getTransactionLocalDate().isEqual(occursOnDate);
} }
public void setLoanDisbursement(boolean isLoanDisbursement) {
this.isLoanDisbursement = isLoanDisbursement;
}
public void zeroBalanceFields() { public void zeroBalanceFields() {
this.runningBalance = null; this.runningBalance = null;
this.cumulativeBalance = null; this.cumulativeBalance = null;
@@ -0,0 +1,51 @@
/**
* 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.savings.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.portfolio.savings.service.SavingsAccountWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "CLOSE")
public class CloseGSIMCommandHandler implements NewCommandSourceHandler
{
private final SavingsAccountWritePlatformService writePlatformService;
@Autowired
public CloseGSIMCommandHandler(final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
this.writePlatformService = savingAccountWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.bulkGSIMClose(command.getSavingsId(), 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.portfolio.savings.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.portfolio.savings.service.SavingsAccountWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "ACTIVATE")
public class GSIMAccountActivationCommandHandler implements NewCommandSourceHandler {
private final SavingsAccountWritePlatformService savingAccountWritePlatformService;
@Autowired
public GSIMAccountActivationCommandHandler(
final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.savingAccountWritePlatformService.gsimActivate(command.getSavingsId(),command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.savings.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.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "APPROVE")
public class GSIMApplicationApprovalCommandHandler implements NewCommandSourceHandler
{
private final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService;
@Autowired
public GSIMApplicationApprovalCommandHandler(
final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService) {
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.savingAccountWritePlatformService.approveGSIMApplication(command.getSavingsId(),command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.savings.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.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "UPDATE")
public class GSIMApplicationModificationCommandHandler implements NewCommandSourceHandler
{
private final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService;
@Autowired
public GSIMApplicationModificationCommandHandler(
final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService) {
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.savingAccountWritePlatformService.modifyGSIMApplication(command.entityId(), command);
}
}
@@ -0,0 +1,51 @@
/**
* 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.savings.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.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "REJECT")
public class GSIMApplicationRejectionHandler implements NewCommandSourceHandler
{
private final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService;
@Autowired
public GSIMApplicationRejectionHandler(
final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService) {
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.savingAccountWritePlatformService.rejectGSIMApplication(command.entityId(),command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.savings.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.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "CREATE")
public class GSIMApplicationSubmittalCommandHandler implements NewCommandSourceHandler
{
private final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService;
@Autowired
public GSIMApplicationSubmittalCommandHandler(
final SavingsApplicationProcessWritePlatformService savingAccountWritePlatformService) {
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.savingAccountWritePlatformService.submitGSIMApplication(command);
}
}
@@ -0,0 +1,49 @@
/**
* 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.savings.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.portfolio.savings.service.SavingsAccountWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "DEPOSIT")
public class GSIMDepositCommandHandler implements NewCommandSourceHandler {
private final SavingsAccountWritePlatformService writePlatformService;
@Autowired
public GSIMDepositCommandHandler(final SavingsAccountWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.gsimDeposit(command.getSavingsId(), command);
}
}
@@ -0,0 +1,51 @@
/**
* 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.savings.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.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "GSIMACCOUNT", action = "APPROVALUNDO")
public class GSIMUndoApprovalCommandHandler implements NewCommandSourceHandler
{
private final SavingsApplicationProcessWritePlatformService writePlatformService;
@Autowired
public GSIMUndoApprovalCommandHandler(final SavingsApplicationProcessWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.undoGSIMApplicationApproval(command.entityId(), 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.portfolio.savings.service;
import java.util.Collection;
import java.util.List;
import org.apache.fineract.portfolio.savings.data.GSIMContainer;
import org.apache.fineract.portfolio.savings.data.GroupSavingsIndividualMonitoringAccountData;
public interface GSIMReadPlatformService {
Collection<GroupSavingsIndividualMonitoringAccountData> findGsimAccountByParentAccountNumber(String parentAccountIds);
Collection<GroupSavingsIndividualMonitoringAccountData> findGSIMAccountsByGSIMId(Long glimId);
Collection<GroupSavingsIndividualMonitoringAccountData> findGSIMAccountsByGroupId(String groupId);
Collection<GSIMContainer> findGSIMAccountContainerByGroupId(Long groupId);
Collection<GSIMContainer> findGsimAccountContainerbyGsimAccountNumber(String accountNumber);
Collection<GroupSavingsIndividualMonitoringAccountData> findGsimAccountByGroupIdandAccountNo(String groupId,
String accountNo);
List<GSIMContainer> findGsimAccountContainerbyGsimAccountId(Long parentAccountId);
GroupSavingsIndividualMonitoringAccountData findGSIMAccountByGSIMId(Long gsimId);
}
@@ -0,0 +1,389 @@
/**
* 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.savings.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.accountdetails.data.SavingsSummaryCustom;
import org.apache.fineract.portfolio.accountdetails.service.AccountEnumerations;
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
import org.apache.fineract.portfolio.savings.data.GSIMContainer;
import org.apache.fineract.portfolio.savings.data.GroupSavingsIndividualMonitoringAccountData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountApplicationTimelineData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountStatusEnumData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountSubStatusEnumData;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType;
import org.joda.time.LocalDate;
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 GSIMReadPlatformServiceImpl implements GSIMReadPlatformService
{
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
private final ColumnValidator columnValidator;
@Autowired
public GSIMReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource
,final ColumnValidator columnValidator) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.columnValidator = columnValidator;
}
private static final class GSIMFieldsMapper implements RowMapper<GroupSavingsIndividualMonitoringAccountData> {
public String schema() {
return "gsim.id as gsimId,sv.group_id as groupId,sv.client_id as clientId,gsim.account_number as accountNumber, sv.id as childAccountId,sv.account_no as childAccountNumber,sv.account_balance_derived as childBalance,gsim.parent_deposit as parentBalance,gsim.child_accounts_count as childAccountsCount,"
+"gsim.savings_status_id as savingsStatus from gsim_accounts gsim,m_savings_account sv where gsim.id=sv.gsim_id";
}
@Override
public GroupSavingsIndividualMonitoringAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
throws SQLException {
final BigDecimal gsimId=rs.getBigDecimal("gsimId");
final BigDecimal groupId=rs.getBigDecimal("groupId");
final BigDecimal clientId=rs.getBigDecimal("clientId");
final String accountNumber=rs.getString("accountNumber");
final BigDecimal childAccountId=rs.getBigDecimal("childAccountId");
final String childAccountNumber=rs.getString("childAccountNumber");
final Long childAccountsCount=rs.getLong("childAccountsCount");
final BigDecimal parentBalance=rs.getBigDecimal("parentBalance");
final BigDecimal childBalance=rs.getBigDecimal("childBalance");
final String savingsStatus=SavingsAccountStatusType.fromInt((int)rs.getLong("savingsStatus")).toString();
return GroupSavingsIndividualMonitoringAccountData.getInstance2(gsimId,groupId,clientId,accountNumber,childAccountId,childAccountNumber,parentBalance,childBalance,
childAccountsCount,savingsStatus);
}
}
private static final class GSIMMapper implements RowMapper<GroupSavingsIndividualMonitoringAccountData> {
public String schema() {
return "gsim.id as gsimId,gsim.group_id as groupId,gsim.account_number as accountNumber,gsim.parent_deposit as parentDeposit,gsim.child_accounts_count as childAccountsCount,"
+"gsim.savings_status_id as savingsStatus from gsim_accounts gsim";
}
@Override
public GroupSavingsIndividualMonitoringAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
throws SQLException {
final BigDecimal glimId=rs.getBigDecimal("gsimId");
final BigDecimal groupId=rs.getBigDecimal("groupId");
final String accountNumber=rs.getString("accountNumber");
final BigDecimal parentDeposit=rs.getBigDecimal("parentDeposit");
final String loanStatus=LoanStatus.fromInt((int)rs.getLong("savingsStatus")).toString();
return GroupSavingsIndividualMonitoringAccountData.getInstance1(glimId,groupId, accountNumber, parentDeposit,loanStatus);
}
}
@Override
public Collection<GSIMContainer> findGSIMAccountContainerByGroupId(Long groupId) {
this.context.authenticatedUser();
Collection<GroupSavingsIndividualMonitoringAccountData> gsimInfo=findGSIMAccountsByGroupId(groupId+"");
//List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId });
String savingswhereClauseForGroup;
List<GSIMContainer> gsimAccounts=new ArrayList<GSIMContainer>();
List<SavingsSummaryCustom> childSavings;
for(GroupSavingsIndividualMonitoringAccountData gsimAccount:gsimInfo)
{
BigDecimal gsimId = gsimAccount.getGsimId();
savingswhereClauseForGroup = " where sa.group_id = ? and sa.gsim_id = ? order by sa.status_enum ASC, sa.account_no ASC";
childSavings=retrieveAccountDetails(savingswhereClauseForGroup,new Object[] { groupId , gsimId});
gsimAccounts.add(new GSIMContainer(gsimAccount.getGsimId(),gsimAccount.getGroupId(), gsimAccount.getAccountNumber(),
childSavings, gsimAccount.getParentDeposit(),gsimAccount.getSavingsStatus()));
}
return gsimAccounts;
}
@Override
public Collection<GSIMContainer> findGsimAccountContainerbyGsimAccountNumber(String accountNumber) {
this.context.authenticatedUser();
Collection<GroupSavingsIndividualMonitoringAccountData> gsimInfo=findGsimAccountByParentAccountNumber(accountNumber);
//List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId });
final String savingswhereClauseForGroup = " where gsim.account_number = ? order by sa.status_enum ASC, sa.account_no ASC";
List<GSIMContainer> gsimAccounts=new ArrayList<GSIMContainer>();
for(GroupSavingsIndividualMonitoringAccountData gsimAccount:gsimInfo)
{
List<SavingsSummaryCustom> childSavings=retrieveAccountDetails(savingswhereClauseForGroup,new Object[] { accountNumber });
gsimAccounts.add(new GSIMContainer(gsimAccount.getGsimId(),gsimAccount.getGroupId(), gsimAccount.getAccountNumber(),
childSavings, gsimAccount.getParentDeposit(),gsimAccount.getSavingsStatus()));
}
return gsimAccounts;
}
@Override
public List<GSIMContainer> findGsimAccountContainerbyGsimAccountId(Long parentAccountId) {
this.context.authenticatedUser();
GroupSavingsIndividualMonitoringAccountData gsimAccount=findGSIMAccountByGSIMId(parentAccountId);
//List<LoanAccountSummaryData> glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId });
final String savingswhereClauseForGroup = " where sa.gsim_id = ? order by sa.status_enum ASC, sa.account_no ASC";
List<SavingsSummaryCustom> childSavings=retrieveAccountDetails(savingswhereClauseForGroup,new Object[] { parentAccountId });
List<GSIMContainer> parentGsim=new ArrayList<GSIMContainer>();
parentGsim.add(new GSIMContainer(gsimAccount.getGsimId(),gsimAccount.getGroupId(), gsimAccount.getAccountNumber(),
childSavings, gsimAccount.getParentDeposit(),gsimAccount.getSavingsStatus()));
return parentGsim ;
}
@Override
public Collection<GroupSavingsIndividualMonitoringAccountData> findGSIMAccountsByGSIMId(final Long gsimId) {
this.context.authenticatedUser();
final GSIMFieldsMapper rm = new GSIMFieldsMapper();
final String sql = "select " + rm.schema() + " and gsim.id=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { gsimId });
}
@Override
public GroupSavingsIndividualMonitoringAccountData findGSIMAccountByGSIMId(final Long gsimId) {
this.context.authenticatedUser();
final GSIMMapper rm = new GSIMMapper();
final String sql = "select " + rm.schema() + " where gsim.id=?";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { gsimId });
}
@Override
public Collection<GroupSavingsIndividualMonitoringAccountData> findGSIMAccountsByGroupId(String groupId) {
this.context.authenticatedUser();
final GSIMMapper rm = new GSIMMapper();
final String sql = "select " + rm.schema() + " where gsim.group_id=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { groupId });
}
@Override
public Collection<GroupSavingsIndividualMonitoringAccountData> findGsimAccountByParentAccountNumber(String parentAccountIds) {
this.context.authenticatedUser();
final GSIMMapper rm = new GSIMMapper();
final String sql = "select " + rm.schema() + " where gsim.account_number=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { parentAccountIds });
}
@Override
public Collection<GroupSavingsIndividualMonitoringAccountData> findGsimAccountByGroupIdandAccountNo(String groupId,String accountNo) {
this.context.authenticatedUser();
GSIMMapper rm=new GSIMMapper();
final String sql="select "+rm.schema()+" where gsim.group_id=? and gsim.account_number=?";
return this.jdbcTemplate.query(sql, rm, new Object[] { accountNo });
}
private List<SavingsSummaryCustom> retrieveAccountDetails(final String savingswhereClause, final Object[] inputs) {
final SavingsAccountSummaryDataMapper savingsAccountSummaryDataMapper = new SavingsAccountSummaryDataMapper();
final String savingsSql = "select " + savingsAccountSummaryDataMapper.schema() + savingswhereClause;
this.columnValidator.validateSqlInjection(savingsAccountSummaryDataMapper.schema() , savingswhereClause);
return this.jdbcTemplate.query(savingsSql, savingsAccountSummaryDataMapper, inputs);
}
private static final class SavingsAccountSummaryDataMapper implements RowMapper<SavingsSummaryCustom> {
final String schemaSql;
public SavingsAccountSummaryDataMapper() {
final StringBuilder accountsSummary = new StringBuilder();
accountsSummary.append("sa.id as id, CONCAT('(',clnt.id,') ',clnt.display_name) as displayName,sa.account_no as accountNo, sa.external_id as externalId, sa.gsim_id as gsimId,gsim.account_number as parentAccountNo,sa.status_enum as statusEnum, ");
accountsSummary.append("sa.account_type_enum as accountType, ");
accountsSummary.append("sa.account_balance_derived as accountBalance, ");
accountsSummary.append("sa.submittedon_date as submittedOnDate,");
accountsSummary.append("sbu.username as submittedByUsername,");
accountsSummary.append("sbu.firstname as submittedByFirstname, sbu.lastname as submittedByLastname,");
accountsSummary.append("sa.rejectedon_date as rejectedOnDate,");
accountsSummary.append("rbu.username as rejectedByUsername,");
accountsSummary.append("rbu.firstname as rejectedByFirstname, rbu.lastname as rejectedByLastname,");
accountsSummary.append("sa.withdrawnon_date as withdrawnOnDate,");
accountsSummary.append("wbu.username as withdrawnByUsername,");
accountsSummary.append("wbu.firstname as withdrawnByFirstname, wbu.lastname as withdrawnByLastname,");
accountsSummary.append("sa.approvedon_date as approvedOnDate,");
accountsSummary.append("abu.username as approvedByUsername,");
accountsSummary.append("abu.firstname as approvedByFirstname, abu.lastname as approvedByLastname,");
accountsSummary.append("sa.activatedon_date as activatedOnDate,");
accountsSummary.append("avbu.username as activatedByUsername,");
accountsSummary.append("avbu.firstname as activatedByFirstname, avbu.lastname as activatedByLastname,");
accountsSummary.append("sa.sub_status_enum as subStatusEnum, ");
accountsSummary.append("(select IFNULL(max(sat.transaction_date),sa.activatedon_date) ");
accountsSummary.append("from m_savings_account_transaction as sat ");
accountsSummary.append("where sat.is_reversed = 0 ");
accountsSummary.append("and sat.transaction_type_enum in (1,2) ");
accountsSummary.append("and sat.savings_account_id = sa.id) as lastActiveTransactionDate, ");
accountsSummary.append("sa.closedon_date as closedOnDate,");
accountsSummary.append("cbu.username as closedByUsername,");
accountsSummary.append("cbu.firstname as closedByFirstname, cbu.lastname as closedByLastname,");
accountsSummary
.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, sa.currency_multiplesof as inMultiplesOf, ");
accountsSummary.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
accountsSummary.append("curr.display_symbol as currencyDisplaySymbol, ");
accountsSummary.append("sa.product_id as productId, p.name as productName, p.short_name as shortProductName, ");
accountsSummary.append("sa.deposit_type_enum as depositType ");
accountsSummary.append("from m_savings_account sa ");
accountsSummary.append("join m_savings_product as p on p.id = sa.product_id ");
accountsSummary.append("join m_currency curr on curr.code = sa.currency_code ");
accountsSummary.append("left join m_appuser sbu on sbu.id = sa.submittedon_userid ");
accountsSummary.append("left join m_appuser rbu on rbu.id = sa.rejectedon_userid ");
accountsSummary.append("left join m_appuser wbu on wbu.id = sa.withdrawnon_userid ");
accountsSummary.append("left join m_appuser abu on abu.id = sa.approvedon_userid ");
accountsSummary.append("left join m_appuser avbu on rbu.id = sa.activatedon_userid ");
accountsSummary.append("left join m_appuser cbu on cbu.id = sa.closedon_userid ");
accountsSummary.append("left join gsim_accounts gsim on gsim.id=sa.gsim_id ");
accountsSummary.append("left join m_client clnt on clnt.id=sa.client_id ");
this.schemaSql = accountsSummary.toString();
}
public String schema() {
return this.schemaSql;
}
@Override
public SavingsSummaryCustom mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = JdbcSupport.getLong(rs, "id");
final String accountNo = rs.getString("accountNo");
final String displayName=rs.getString("displayName");
final String externalId = rs.getString("externalId");
final Long productId = JdbcSupport.getLong(rs, "productId");
final String productName = rs.getString("productName");
final String shortProductName = rs.getString("shortProductName");
final Integer statusId = JdbcSupport.getInteger(rs, "statusEnum");
final BigDecimal accountBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "accountBalance");
final SavingsAccountStatusEnumData status = SavingsEnumerations.status(statusId);
final Integer accountType = JdbcSupport.getInteger(rs, "accountType");
final EnumOptionData accountTypeData = AccountEnumerations.loanType(accountType);
final Integer depositTypeId = JdbcSupport.getInteger(rs, "depositType");
final EnumOptionData depositTypeData = SavingsEnumerations.depositType(depositTypeId);
final String currencyCode = rs.getString("currencyCode");
final String currencyName = rs.getString("currencyName");
final String currencyNameCode = rs.getString("currencyNameCode");
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf,
currencyDisplaySymbol, currencyNameCode);
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
final String submittedByUsername = rs.getString("submittedByUsername");
final String submittedByFirstname = rs.getString("submittedByFirstname");
final String submittedByLastname = rs.getString("submittedByLastname");
final LocalDate rejectedOnDate = JdbcSupport.getLocalDate(rs, "rejectedOnDate");
final String rejectedByUsername = rs.getString("rejectedByUsername");
final String rejectedByFirstname = rs.getString("rejectedByFirstname");
final String rejectedByLastname = rs.getString("rejectedByLastname");
final LocalDate withdrawnOnDate = JdbcSupport.getLocalDate(rs, "withdrawnOnDate");
final String withdrawnByUsername = rs.getString("withdrawnByUsername");
final String withdrawnByFirstname = rs.getString("withdrawnByFirstname");
final String withdrawnByLastname = rs.getString("withdrawnByLastname");
final LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs, "approvedOnDate");
final String approvedByUsername = rs.getString("approvedByUsername");
final String approvedByFirstname = rs.getString("approvedByFirstname");
final String approvedByLastname = rs.getString("approvedByLastname");
final LocalDate activatedOnDate = JdbcSupport.getLocalDate(rs, "activatedOnDate");
final String activatedByUsername = rs.getString("activatedByUsername");
final String activatedByFirstname = rs.getString("activatedByFirstname");
final String activatedByLastname = rs.getString("activatedByLastname");
final LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, "closedOnDate");
final String closedByUsername = rs.getString("closedByUsername");
final String closedByFirstname = rs.getString("closedByFirstname");
final String closedByLastname = rs.getString("closedByLastname");
final Integer subStatusEnum = JdbcSupport.getInteger(rs, "subStatusEnum");
final SavingsAccountSubStatusEnumData subStatus = SavingsEnumerations.subStatus(subStatusEnum);
final LocalDate lastActiveTransactionDate = JdbcSupport.getLocalDate(rs, "lastActiveTransactionDate");
final SavingsAccountApplicationTimelineData timeline = new SavingsAccountApplicationTimelineData(submittedOnDate,
submittedByUsername, submittedByFirstname, submittedByLastname, rejectedOnDate, rejectedByUsername,
rejectedByFirstname, rejectedByLastname, withdrawnOnDate, withdrawnByUsername, withdrawnByFirstname,
withdrawnByLastname, approvedOnDate, approvedByUsername, approvedByFirstname, approvedByLastname, activatedOnDate,
activatedByUsername, activatedByFirstname, activatedByLastname, closedOnDate, closedByUsername, closedByFirstname,
closedByLastname);
return new SavingsSummaryCustom(id,displayName, accountNo, externalId, productId, productName, shortProductName, status, currency, accountBalance,
accountTypeData, timeline, depositTypeData, subStatus, lastActiveTransactionDate);
}
}
}
@@ -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.portfolio.savings.service;
import java.math.BigDecimal;
import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.savings.domain.GroupSavingsIndividualMonitoring;
public interface GroupSavingsIndividualMonitoringWritePlatformService
{
void setIsAcceptingChild(GroupSavingsIndividualMonitoring gsimAccount);
void resetIsAcceptingChild(GroupSavingsIndividualMonitoring gsimAccount);
void incrementChildAccountCount(GroupSavingsIndividualMonitoring gsimAccount);
GroupSavingsIndividualMonitoring addGSIMAccountInfo(String accountNumber, Group group, BigDecimal parentDeposit, Long childAccountsCount,
Boolean isAcceptingChild, Integer loanStatus, BigDecimal applicationId);
}
@@ -0,0 +1,88 @@
/**
* 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.savings.service;
import java.math.BigDecimal;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.apache.fineract.portfolio.savings.domain.GSIMRepositoy;
import org.apache.fineract.portfolio.savings.domain.GroupSavingsIndividualMonitoring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class GroupSavingsIndividualMonitoringWritePlatformServiceImpl implements GroupSavingsIndividualMonitoringWritePlatformService
{
private final PlatformSecurityContext context;
private final GSIMRepositoy gsimAccountRepository;
private final LoanRepository loanRepository;
@Autowired
public GroupSavingsIndividualMonitoringWritePlatformServiceImpl(final PlatformSecurityContext context,final GSIMRepositoy gsimAccountRepository,
final LoanRepository loanRepository)
{
this.context=context;
this.gsimAccountRepository=gsimAccountRepository;
this.loanRepository=loanRepository;
}
@Override
public GroupSavingsIndividualMonitoring addGSIMAccountInfo(String accountNumber,Group group,BigDecimal parentDeposit,Long childAccountsCount,
Boolean isAcceptingChild,Integer loanStatus,BigDecimal applicationId)
{
GroupSavingsIndividualMonitoring glimAccountInfo=GroupSavingsIndividualMonitoring.getInstance(accountNumber,group,parentDeposit,childAccountsCount,
isAcceptingChild,loanStatus,applicationId);
return this.gsimAccountRepository.save(glimAccountInfo );
}
@Override
public void setIsAcceptingChild(GroupSavingsIndividualMonitoring glimAccount)
{
glimAccount.setIsAcceptingChild(true);
gsimAccountRepository.save(glimAccount);
}
@Override
public void resetIsAcceptingChild(GroupSavingsIndividualMonitoring glimAccount)
{
glimAccount.setIsAcceptingChild(false);
gsimAccountRepository.save(glimAccount);
}
@Override
public void incrementChildAccountCount(GroupSavingsIndividualMonitoring glimAccount)
{
long count=glimAccount.getChildAccountsCount();
glimAccount.setChildAccountsCount(count+1);
gsimAccountRepository.save(glimAccount);
}
}
@@ -103,4 +103,10 @@ public interface SavingsAccountWritePlatformService {
CommandProcessingResult unblockDebits(Long savingsId); CommandProcessingResult unblockDebits(Long savingsId);
CommandProcessingResult releaseAmount(Long savingsId, Long transactionId); CommandProcessingResult releaseAmount(Long savingsId, Long transactionId);
CommandProcessingResult gsimActivate(Long gsimId, JsonCommand command);
CommandProcessingResult gsimDeposit(Long gsimId, JsonCommand command);
CommandProcessingResult bulkGSIMClose(Long gsimId, JsonCommand command);
} }
@@ -26,6 +26,8 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.dueAsOfD
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.util.ArrayList; import java.util.ArrayList;
@@ -92,6 +94,8 @@ import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionDataValidator; import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionDataValidator;
import org.apache.fineract.portfolio.savings.domain.DepositAccountOnHoldTransaction; import org.apache.fineract.portfolio.savings.domain.DepositAccountOnHoldTransaction;
import org.apache.fineract.portfolio.savings.domain.DepositAccountOnHoldTransactionRepository; import org.apache.fineract.portfolio.savings.domain.DepositAccountOnHoldTransactionRepository;
import org.apache.fineract.portfolio.savings.domain.GSIMRepositoy;
import org.apache.fineract.portfolio.savings.domain.GroupSavingsIndividualMonitoring;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler; import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountCharge; import org.apache.fineract.portfolio.savings.domain.SavingsAccountCharge;
@@ -115,6 +119,8 @@ import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -148,6 +154,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
private final AppUserRepositoryWrapper appuserRepository; private final AppUserRepositoryWrapper appuserRepository;
private final StandingInstructionRepository standingInstructionRepository; private final StandingInstructionRepository standingInstructionRepository;
private final BusinessEventNotifierService businessEventNotifierService; private final BusinessEventNotifierService businessEventNotifierService;
private final GSIMRepositoy gsimRepository;
@Autowired @Autowired
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -169,7 +176,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository, final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository,
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService,
final AppUserRepositoryWrapper appuserRepository, final StandingInstructionRepository standingInstructionRepository, final AppUserRepositoryWrapper appuserRepository, final StandingInstructionRepository standingInstructionRepository,
final BusinessEventNotifierService businessEventNotifierService) { final BusinessEventNotifierService businessEventNotifierService, final GSIMRepositoy gsimRepository) {
this.context = context; this.context = context;
this.savingAccountRepositoryWrapper = savingAccountRepositoryWrapper; this.savingAccountRepositoryWrapper = savingAccountRepositoryWrapper;
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository; this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
@@ -195,8 +202,33 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.appuserRepository = appuserRepository; this.appuserRepository = appuserRepository;
this.standingInstructionRepository = standingInstructionRepository; this.standingInstructionRepository = standingInstructionRepository;
this.businessEventNotifierService = businessEventNotifierService; this.businessEventNotifierService = businessEventNotifierService;
this.gsimRepository=gsimRepository;
} }
private final static Logger logger = LoggerFactory.getLogger(SavingsAccountWritePlatformServiceJpaRepositoryImpl.class);
@Transactional
@Override
public CommandProcessingResult gsimActivate(final Long gsimId, final JsonCommand command) {
Long parentSavingId = gsimId;
GroupSavingsIndividualMonitoring parentSavings = gsimRepository.findById(parentSavingId).get();
List<SavingsAccount> childSavings = this.savingAccountRepositoryWrapper.findByGsimId(gsimId);
CommandProcessingResult result = null;
int count = 0;
for (SavingsAccount account : childSavings) {
result = activate(account.getId(), command);
if (result != null) {
count++;
if (count == parentSavings.getChildAccountsCount()) {
parentSavings.setSavingsStatus(SavingsAccountStatusType.ACTIVE.getValue());
gsimRepository.save(parentSavings);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult activate(final Long savingsId, final JsonCommand command) { public CommandProcessingResult activate(final Long savingsId, final JsonCommand command) {
@@ -265,6 +297,28 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
depositAccountOnHoldTransactions); depositAccountOnHoldTransactions);
} }
@Transactional
@Override
public CommandProcessingResult gsimDeposit(final Long gsimId, final JsonCommand command) {
Long parentSavingId = gsimId;
// GroupSavingsIndividualMonitoringparentSavings=gsimRepository.findById(parentSavingId).get();
List<SavingsAccount> childSavings = this.savingAccountRepositoryWrapper.findByGsimId(gsimId);
JsonArray savingsArray = command.arrayOfParameterNamed("savingsArray");
JsonArray childAccounts = command.arrayOfParameterNamed("childAccounts");
int count = 0;
CommandProcessingResult result = null;
for (JsonElement element : savingsArray) {
result = deposit(element.getAsJsonObject().get("childAccountId").getAsLong(),
JsonCommand.fromExistingCommand(command, element));
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult deposit(final Long savingsId, final JsonCommand command) { public CommandProcessingResult deposit(final Long savingsId, final JsonCommand command) {
@@ -272,6 +326,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.context.authenticatedUser(); this.context.authenticatedUser();
this.savingsAccountTransactionDataValidator.validate(command); this.savingsAccountTransactionDataValidator.validate(command);
boolean isGsim = false;
if (this.savingAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsId).getGsim() != null) {
isGsim = true;
logger.info("is gsim");
}
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
@@ -288,6 +348,21 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate,
transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction); transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction);
if (isGsim && (deposit.getId() != null)) {
logger.debug("Deposit account has been created: {} ", deposit);
GroupSavingsIndividualMonitoring gsim = gsimRepository.findById(account.getGsim().getId()).get();
logger.info("parent deposit : {} ", gsim.getParentDeposit());
logger.info("child account : {} ", savingsId);
BigDecimal currentBalance = gsim.getParentDeposit();
BigDecimal newBalance = currentBalance.add(transactionAmount);
gsim.setParentDeposit(newBalance);
gsimRepository.save(gsim);
logger.info("balance after making deposit : {} ", gsimRepository.findById(account.getGsim().getId()).get().getParentDeposit());
}
final String noteText = command.stringValueOfParameterNamed("note"); final String noteText = command.stringValueOfParameterNamed("note");
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
final Note note = Note.savingsTransactionNote(account, deposit, noteText); final Note note = Note.savingsTransactionNote(account, deposit, noteText);
@@ -316,6 +391,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.savingsAccountTransactionDataValidator.validate(command); this.savingsAccountTransactionDataValidator.validate(command);
boolean isGsim = false;
if (this.savingAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsId).getGsim() != null) {
isGsim = true;
}
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount"); final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
@@ -337,6 +417,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate, final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
transactionAmount, paymentDetail, transactionBooleanValues); transactionAmount, paymentDetail, transactionBooleanValues);
if (isGsim && (withdrawal.getId() != null)) {
GroupSavingsIndividualMonitoring gsim = gsimRepository.findById(account.getGsim().getId()).get();
BigDecimal currentBalance = gsim.getParentDeposit().subtract(transactionAmount);
gsim.setParentDeposit(currentBalance);
gsimRepository.save(gsim);
}
final String noteText = command.stringValueOfParameterNamed("note"); final String noteText = command.stringValueOfParameterNamed("note");
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
final Note note = Note.savingsTransactionNote(account, withdrawal, noteText); final Note note = Note.savingsTransactionNote(account, withdrawal, noteText);
@@ -669,6 +757,29 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
} }
} }
@Override
public CommandProcessingResult bulkGSIMClose(final Long gsimId, final JsonCommand command) {
final Long parentSavingId = gsimId;
GroupSavingsIndividualMonitoring parentSavings = gsimRepository.findById(parentSavingId).get();
List<SavingsAccount> childSavings = this.savingAccountRepositoryWrapper.findByGsimId(gsimId);
CommandProcessingResult result = null;
int count = 0;
for (SavingsAccount account : childSavings) {
result = close(account.getId(), command);
if (result != null) {
count++;
if (count == parentSavings.getChildAccountsCount()) {
parentSavings.setSavingsStatus(SavingsAccountStatusType.CLOSED.getValue());
gsimRepository.save(parentSavings);
}
}
}
return result;
}
@Override @Override
public CommandProcessingResult close(final Long savingsId, final JsonCommand command) { public CommandProcessingResult close(final Long savingsId, final JsonCommand command) {
final AppUser user = this.context.authenticatedUser(); final AppUser user = this.context.authenticatedUser();
@@ -1556,4 +1667,4 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
} }
} }
} }
@@ -39,4 +39,14 @@ public interface SavingsApplicationProcessWritePlatformService {
CommandProcessingResult applicantWithdrawsFromApplication(Long savingsId, JsonCommand command); CommandProcessingResult applicantWithdrawsFromApplication(Long savingsId, JsonCommand command);
CommandProcessingResult createActiveApplication(SavingsAccountDataDTO savingsAccountDataDTO); CommandProcessingResult createActiveApplication(SavingsAccountDataDTO savingsAccountDataDTO);
CommandProcessingResult submitGSIMApplication(JsonCommand command);
CommandProcessingResult approveGSIMApplication(Long gsimId, JsonCommand command);
CommandProcessingResult rejectGSIMApplication(Long gsimId, JsonCommand command);
CommandProcessingResult undoGSIMApplicationApproval(Long gsimId, JsonCommand command);
CommandProcessingResult modifyGSIMApplication(Long gsimId, JsonCommand command);
} }
@@ -20,6 +20,9 @@ package org.apache.fineract.portfolio.savings.service;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -60,6 +63,7 @@ import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.B
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService; import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.group.domain.Group; import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.group.domain.GroupRepository; import org.apache.fineract.portfolio.group.domain.GroupRepository;
import org.apache.fineract.portfolio.group.domain.GroupRepositoryWrapper;
import org.apache.fineract.portfolio.group.exception.CenterNotActiveException; import org.apache.fineract.portfolio.group.exception.CenterNotActiveException;
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException; import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
import org.apache.fineract.portfolio.group.exception.GroupNotFoundException; import org.apache.fineract.portfolio.group.exception.GroupNotFoundException;
@@ -68,12 +72,15 @@ import org.apache.fineract.portfolio.note.domain.NoteRepository;
import org.apache.fineract.portfolio.savings.SavingsApiConstants; import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.apache.fineract.portfolio.savings.data.SavingsAccountDataDTO; import org.apache.fineract.portfolio.savings.data.SavingsAccountDataDTO;
import org.apache.fineract.portfolio.savings.data.SavingsAccountDataValidator; import org.apache.fineract.portfolio.savings.data.SavingsAccountDataValidator;
import org.apache.fineract.portfolio.savings.domain.GSIMRepositoy;
import org.apache.fineract.portfolio.savings.domain.GroupSavingsIndividualMonitoring;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler; import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountCharge; import org.apache.fineract.portfolio.savings.domain.SavingsAccountCharge;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountChargeAssembler; import org.apache.fineract.portfolio.savings.domain.SavingsAccountChargeAssembler;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountDomainService; import org.apache.fineract.portfolio.savings.domain.SavingsAccountDomainService;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepositoryWrapper; import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepositoryWrapper;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType;
import org.apache.fineract.portfolio.savings.domain.SavingsProduct; import org.apache.fineract.portfolio.savings.domain.SavingsProduct;
import org.apache.fineract.portfolio.savings.domain.SavingsProductRepository; import org.apache.fineract.portfolio.savings.domain.SavingsProductRepository;
import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException; import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
@@ -108,6 +115,9 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository; private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository;
private final BusinessEventNotifierService businessEventNotifierService; private final BusinessEventNotifierService businessEventNotifierService;
private final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService; private final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService;
private final GSIMRepositoy gsimRepository;
private final GroupRepositoryWrapper groupRepositoryWrapper;
private final GroupSavingsIndividualMonitoringWritePlatformService gsimWritePlatformService;
@Autowired @Autowired
public SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -122,7 +132,9 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final SavingsAccountWritePlatformService savingsAccountWritePlatformService, final SavingsAccountWritePlatformService savingsAccountWritePlatformService,
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
final BusinessEventNotifierService businessEventNotifierService, final BusinessEventNotifierService businessEventNotifierService,
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService) { final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService,
final GSIMRepositoy gsimRepository, final GroupRepositoryWrapper groupRepositoryWrapper,
final GroupSavingsIndividualMonitoringWritePlatformService gsimWritePlatformService) {
this.context = context; this.context = context;
this.savingAccountRepository = savingAccountRepository; this.savingAccountRepository = savingAccountRepository;
this.savingAccountAssembler = savingAccountAssembler; this.savingAccountAssembler = savingAccountAssembler;
@@ -141,6 +153,9 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.savingsAccountWritePlatformService = savingsAccountWritePlatformService; this.savingsAccountWritePlatformService = savingsAccountWritePlatformService;
this.businessEventNotifierService = businessEventNotifierService ; this.businessEventNotifierService = businessEventNotifierService ;
this.entityDatatableChecksWritePlatformService = entityDatatableChecksWritePlatformService; this.entityDatatableChecksWritePlatformService = entityDatatableChecksWritePlatformService;
this.gsimRepository = gsimRepository;
this.groupRepositoryWrapper = groupRepositoryWrapper;
this.gsimWritePlatformService = gsimWritePlatformService;
} }
/* /*
@@ -170,6 +185,27 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
throw new PlatformDataIntegrityException(errorCodeBuilder.toString(), "Unknown data integrity issue with savings account."); throw new PlatformDataIntegrityException(errorCodeBuilder.toString(), "Unknown data integrity issue with savings account.");
} }
@Transactional
@Override
public CommandProcessingResult submitGSIMApplication(final JsonCommand command) {
CommandProcessingResult result = null;
JsonArray gsimApplications = command.arrayOfParameterNamed("clientArray");
final Object lock = new Object();
synchronized (lock){
for (JsonElement gsimApplication : gsimApplications) {
// result=submitApplication(JsonCommand.fromExistingCommand(command,
// gsimApplication));
result = submitApplication(JsonCommand.fromExistingCommand(command, gsimApplication,
gsimApplication.getAsJsonObject().get("clientId").getAsLong()));
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult submitApplication(final JsonCommand command) { public CommandProcessingResult submitApplication(final JsonCommand command) {
@@ -179,9 +215,88 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command, submittedBy); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command, submittedBy);
this.savingAccountRepository.save(account); this.savingAccountRepository.save(account);
String accountNumber = "";
GroupSavingsIndividualMonitoring gsimAccount = null;
BigDecimal applicationId = BigDecimal.ZERO;
Boolean isLastChildApplication = false;
generateAccountNumber(account); //gsim
if (account.isAccountNumberRequiresAutoGeneration()) {
final AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository
.findByAccountType(EntityAccountType.SAVINGS);
// if application is of GSIM type
if (account.getAccountTypes() == 5) {
final Long groupId = command.longValueOfParameterNamed("groupId");
// GSIM specific parameters
if (command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("applicationId") != null) {
applicationId = command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("applicationId");
}
if (command.booleanObjectValueOfParameterNamed("lastApplication") != null) {
isLastChildApplication = command.booleanPrimitiveValueOfParameterNamed("lastApplication");
}
Group group = this.groupRepositoryWrapper.findOneWithNotFoundDetection(groupId);
if (command.booleanObjectValueOfParameterNamed("isParentAccount") != null)
{
// empty table check
if (gsimRepository.count() != 0) {
// Parent-Not an empty table
accountNumber = this.accountNumberGenerator.generate(account, accountNumberFormat);
account.updateAccountNo(accountNumber + "1");
gsimAccount = gsimWritePlatformService.addGSIMAccountInfo(accountNumber, group, BigDecimal.ZERO,
Long.valueOf(1), true,
SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue(),applicationId);
account.setGsim(gsimAccount);
this.savingAccountRepository.save(account);
} else {
// Parent-empty table
accountNumber = this.accountNumberGenerator.generate(account, accountNumberFormat);
account.updateAccountNo(accountNumber + "1");
gsimWritePlatformService.addGSIMAccountInfo(accountNumber, group, BigDecimal.ZERO,
Long.valueOf(1), true,
SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue(),applicationId);
account.setGsim(gsimRepository.findOneByAccountNumber(accountNumber));
this.savingAccountRepository.save(account);
}
} else {
if (gsimRepository.count() != 0) {
// Child-Not an empty table check
gsimAccount = gsimRepository.findOneByIsAcceptingChildAndApplicationId(true,applicationId);
accountNumber = gsimAccount.getAccountNumber()
+ (gsimAccount.getChildAccountsCount() + 1);
account.updateAccountNo(accountNumber);
this.gsimWritePlatformService.incrementChildAccountCount(gsimAccount);
account.setGsim(gsimAccount);
this.savingAccountRepository.save(account);
} else {
// Child-empty table
// if the gsim info is empty set the current account as parent
accountNumber = this.accountNumberGenerator.generate(account, accountNumberFormat);
account.updateAccountNo(accountNumber + "1");
gsimWritePlatformService.addGSIMAccountInfo(accountNumber, group, BigDecimal.ZERO,
Long.valueOf(1), true,
SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue(),applicationId);
account.setGsim(gsimAccount);
this.savingAccountRepository.save(account);
}
//reset isAcceptingChild when processing last application of GSIM
if (isLastChildApplication) {
this.gsimWritePlatformService.resetIsAcceptingChild(
gsimRepository.findOneByIsAcceptingChildAndApplicationId(true, applicationId));
}
}
} else // for applications other than GSIM
{
generateAccountNumber(account);
}
}
// end of gsim
final Long savingsId = account.getId(); final Long savingsId = account.getId();
if(command.parameterExists(SavingsApiConstants.datatables)){ if(command.parameterExists(SavingsApiConstants.datatables)){
this.entityDatatableChecksWritePlatformService.saveDatatables(StatusEnum.CREATE.getCode().longValue(), this.entityDatatableChecksWritePlatformService.saveDatatables(StatusEnum.CREATE.getCode().longValue(),
@@ -202,6 +317,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
.withClientId(account.clientId()) // .withClientId(account.clientId()) //
.withGroupId(account.groupId()) // .withGroupId(account.groupId()) //
.withSavingsId(savingsId) // .withSavingsId(savingsId) //
.withGsimId(gsimAccount==null ? 0 : gsimAccount.getId())
.build(); .build();
} catch (final DataAccessException dve) { } catch (final DataAccessException dve) {
handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
@@ -222,6 +338,22 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
} }
} }
@Transactional
@Override
public CommandProcessingResult modifyGSIMApplication(final Long gsimId, final JsonCommand command) {
final Long parentSavingId = gsimId;
List<SavingsAccount> childSavings = this.savingAccountRepository.findByGsimId(parentSavingId);
CommandProcessingResult result = null;
for (SavingsAccount account : childSavings) {
result = modifyApplication(account.getId(), command);
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult modifyApplication(final Long savingsId, final JsonCommand command) { public CommandProcessingResult modifyApplication(final Long savingsId, final JsonCommand command) {
@@ -347,6 +479,32 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
.build(); .build();
} }
@Transactional
@Override
public CommandProcessingResult approveGSIMApplication(final Long gsimId, final JsonCommand command) {
// GroupLoanIndividualMonitoringAccount
// glimAccount=glimRepository.findOne(loanId);
Long parentSavingId = gsimId;
GroupSavingsIndividualMonitoring parentSavings = gsimRepository.findById(parentSavingId).get();
List<SavingsAccount> childSavings = this.savingAccountRepository.findByGsimId(gsimId);
CommandProcessingResult result = null;
int count = 0;
for (SavingsAccount account : childSavings) {
result = approveApplication(account.getId(), command);
if (result != null) {
count++;
if (count == parentSavings.getChildAccountsCount()) {
parentSavings.setSavingsStatus(SavingsAccountStatusType.APPROVED.getValue());
gsimRepository.save(parentSavings);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult approveApplication(final Long savingsId, final JsonCommand command) { public CommandProcessingResult approveApplication(final Long savingsId, final JsonCommand command) {
@@ -389,6 +547,31 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
.build(); .build();
} }
@Transactional
@Override
public CommandProcessingResult undoGSIMApplicationApproval(final Long gsimId, final JsonCommand command) {
final Long parentSavingId = gsimId;
GroupSavingsIndividualMonitoring parentSavings = gsimRepository.findById(parentSavingId).get();
List<SavingsAccount> childSavings = this.savingAccountRepository.findByGsimId(gsimId);
CommandProcessingResult result = null;
int count = 0;
for (SavingsAccount account : childSavings) {
result = undoApplicationApproval(account.getId(), command);
if (result != null) {
count++;
if (count == parentSavings.getChildAccountsCount()) {
parentSavings.setSavingsStatus(SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue());
gsimRepository.save(parentSavings);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult undoApplicationApproval(final Long savingsId, final JsonCommand command) { public CommandProcessingResult undoApplicationApproval(final Long savingsId, final JsonCommand command) {
@@ -423,6 +606,30 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
.build(); .build();
} }
@Transactional
@Override
public CommandProcessingResult rejectGSIMApplication(final Long gsimId, final JsonCommand command) {
final Long parentSavingId = gsimId;
GroupSavingsIndividualMonitoring parentSavings = gsimRepository.findById(parentSavingId).get();
List<SavingsAccount> childSavings = this.savingAccountRepository.findByGsimId(gsimId);
CommandProcessingResult result = null;
int count = 0;
for (SavingsAccount account : childSavings) {
result = rejectApplication(account.getId(), command);
if (result != null) {
count++;
if (count == parentSavings.getChildAccountsCount()) {
parentSavings.setSavingsStatus(SavingsAccountStatusType.REJECTED.getValue());
gsimRepository.save(parentSavings);
}
}
}
return result;
}
@Transactional @Transactional
@Override @Override
public CommandProcessingResult rejectApplication(final Long savingsId, final JsonCommand command) { public CommandProcessingResult rejectApplication(final Long savingsId, final JsonCommand command) {
@@ -41,87 +41,82 @@ import org.springframework.stereotype.Component;
@Component @Component
public class SelfSavingsDataValidator { public class SelfSavingsDataValidator {
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@Autowired @Autowired
public SelfSavingsDataValidator(final FromJsonHelper fromApiJsonHelper) { public SelfSavingsDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
} }
private static final Set<String> allowedAssociationParameters = new HashSet<>( private static final Set<String> allowedAssociationParameters = new HashSet<>(
Arrays.asList(SavingsApiConstants.transactions, Arrays.asList(SavingsApiConstants.transactions, SavingsApiConstants.charges));
SavingsApiConstants.charges));
public void validateRetrieveSavings(final UriInfo uriInfo) { public void validateRetrieveSavings(final UriInfo uriInfo) {
List<String> unsupportedParams = new ArrayList<>(); List<String> unsupportedParams = new ArrayList<>();
validateTemplate(uriInfo, unsupportedParams); validateTemplate(uriInfo, unsupportedParams);
Set<String> associationParameters = ApiParameterHelper Set<String> associationParameters = ApiParameterHelper
.extractAssociationsForResponseIfProvided(uriInfo .extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
.getQueryParameters()); if (!associationParameters.isEmpty()) {
if (!associationParameters.isEmpty()) { associationParameters.removeAll(allowedAssociationParameters);
associationParameters.removeAll(allowedAssociationParameters); if (!associationParameters.isEmpty()) {
if (!associationParameters.isEmpty()) { unsupportedParams.addAll(associationParameters);
unsupportedParams.addAll(associationParameters); }
} }
}
if (uriInfo.getQueryParameters().getFirst("exclude") != null) { if (uriInfo.getQueryParameters().getFirst("exclude") != null) {
unsupportedParams.add("exclude"); unsupportedParams.add("exclude");
} }
throwExceptionIfReqd(unsupportedParams); throwExceptionIfReqd(unsupportedParams);
} }
public void validateRetrieveSavingsTransaction(final UriInfo uriInfo) { public void validateRetrieveSavingsTransaction(final UriInfo uriInfo) {
List<String> unsupportedParams = new ArrayList<>(); List<String> unsupportedParams = new ArrayList<>();
validateTemplate(uriInfo, unsupportedParams); validateTemplate(uriInfo, unsupportedParams);
throwExceptionIfReqd(unsupportedParams); throwExceptionIfReqd(unsupportedParams);
} }
private void throwExceptionIfReqd(final List<String> unsupportedParams) { private void throwExceptionIfReqd(final List<String> unsupportedParams) {
if (unsupportedParams.size() > 0) { if (unsupportedParams.size() > 0) {
throw new UnsupportedParameterException(unsupportedParams); throw new UnsupportedParameterException(unsupportedParams);
} }
} }
private void validateTemplate(final UriInfo uriInfo, private void validateTemplate(final UriInfo uriInfo, List<String> unsupportedParams) {
List<String> unsupportedParams) { final boolean templateRequest = ApiParameterHelper.template(uriInfo.getQueryParameters());
final boolean templateRequest = ApiParameterHelper.template(uriInfo if (templateRequest) {
.getQueryParameters()); unsupportedParams.add("template");
if (templateRequest) { }
unsupportedParams.add("template"); }
}
}
public HashMap<String, Object> validateSavingsApplication(final String json) { public HashMap<String, Object> validateSavingsApplication(final String json) {
if (StringUtils.isBlank(json)) { if (StringUtils.isBlank(json)) {
throw new InvalidJsonException(); throw new InvalidJsonException();
} }
final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SelfSavingsAccountConstants.savingsAccountResource); .resource(SelfSavingsAccountConstants.savingsAccountResource);
final JsonElement element = this.fromApiJsonHelper.parse(json); final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long clientId = this.fromApiJsonHelper.extractLongNamed(SelfSavingsAccountConstants.clientIdParameterName, final Long clientId = this.fromApiJsonHelper.extractLongNamed(SelfSavingsAccountConstants.clientIdParameterName,
element); element);
baseDataValidator.reset().parameter(SelfSavingsAccountConstants.clientIdParameterName).value(clientId).notNull() baseDataValidator.reset().parameter(SelfSavingsAccountConstants.clientIdParameterName).value(clientId).notNull()
.longGreaterThanZero(); .longGreaterThanZero();
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors); throw new PlatformApiDataValidationException(dataValidationErrors);
} }
HashMap<String, Object> parameterMap = new HashMap<>(); HashMap<String, Object> parameterMap = new HashMap<>();
parameterMap.put(SelfSavingsAccountConstants.clientIdParameterName, clientId); parameterMap.put(SelfSavingsAccountConstants.clientIdParameterName, clientId);
return parameterMap; return parameterMap;
} }
}
}
@@ -0,0 +1,63 @@
--
-- 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.
--
-- permissions added
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'CREATE_GSIMACCOUNT', 'GSIMACCOUNT', 'CREATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'APPROVE_GSIMACCOUNT', 'GSIMACCOUNT', 'APPROVE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'ACTIVATE_GSIMACCOUNT', 'GSIMACCOUNT', 'ACTIVATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'APPROVALUNDO_GSIMACCOUNT', 'GSIMACCOUNT', 'APPROVALUNDO', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UPDATE_GSIMACCOUNT', 'GSIMACCOUNT', 'UPDATE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'REJECT_GSIMACCOUNT', 'GSIMACCOUNT', 'REJECT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'DEPOSIT_GSIMACCOUNT', 'GSIMACCOUNT', 'DEPOSIT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'CLOSE_GSIMACCOUNT', 'GSIMACCOUNT', 'CLOSE', 0);
-- new gsim table
CREATE TABLE `gsim_accounts` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`group_id` BIGINT(20) NOT NULL DEFAULT '0',
`account_number` VARCHAR(50) NOT NULL,
`parent_deposit` DECIMAL(19,6) NOT NULL DEFAULT '0.000000',
`child_accounts_count` INT(11) NOT NULL,
`accepting_child` TINYINT(4) NOT NULL DEFAULT '0',
`savings_status_id` SMALLINT(5) NOT NULL DEFAULT '0',
`application_id` DECIMAL(10,0) NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE INDEX `gsim_account_no_UNIQUE` (`account_number`),
INDEX `FK_gsim_group_id` (`group_id`),
CONSTRAINT `FK_gsim_group_id` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`)
);
-- changes to savings
ALTER TABLE `m_savings_account` ADD COLUMN `gsim_id` bigint(20) DEFAULT NULL AFTER `group_id`;
ALTER TABLE `m_savings_account` ADD CONSTRAINT `FK_gsim_id` FOREIGN KEY (`gsim_id`) REFERENCES `gsim_accounts` (`id`);
-- changes to savings_Transaction
ALTER TABLE `m_savings_account_transaction` ADD COLUMN `is_loan_disbursement` bigint(20);
@@ -0,0 +1,58 @@
--
-- 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.
--
-- permissions added
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'APPROVE_GLIMLOAN', 'GLIMLOAN', 'APPROVE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'DISBURSE_GLIMLOAN', 'GLIMLOAN', 'DISBURSE', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'REPAYMENT_GLIMLOAN', 'GLIMLOAN', 'REPAYMENT', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UNDODISBURSAL_GLIMLOAN', 'GLIMLOAN', 'UNDODISBURSAL', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UNDOAPPROVAL_GLIMLOAN', 'GLIMLOAN', 'UNDOAPPROVAL', 0);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'REJECT_GLIMLOAN', 'GLIMLOAN', 'REJECT', 0);
-- new table glim_accounts added
CREATE TABLE `glim_accounts` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`group_id` BIGINT(20) NOT NULL DEFAULT '0',
`account_number` VARCHAR(50) NOT NULL,
`principal_amount` DECIMAL(19,6) NOT NULL DEFAULT '0.000000',
`child_accounts_count` INT(11) NOT NULL,
`accepting_child` TINYINT(4) NOT NULL DEFAULT '0',
`loan_status_id` SMALLINT(5) NOT NULL DEFAULT '0',
`application_id` DECIMAL(10,0) NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE INDEX `glim_account_no_UNIQUE` (`account_number`),
INDEX `FK_group_id` (`group_id`),
CONSTRAINT `FK_group_id` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`)
);
-- change m_loan table
alter table `m_loan` add COLUMN `glim_id` bigint(20) DEFAULT NULL AFTER `group_id`;
alter table `m_loan` add CONSTRAINT `FK_glim_id` FOREIGN KEY (`glim_id`) REFERENCES `glim_accounts` (`id`);