From d99ad594de5e0ab1a7b1793ccd10a792ce31f5ce Mon Sep 17 00:00:00 2001 From: nikpawar89 Date: Thu, 24 Aug 2017 20:13:06 +0530 Subject: [PATCH] gsim and glim functionalities added --- .../service/CommandWrapperBuilder.java | 99 ++++- .../data/AccountSummaryCollectionData.java | 7 +- .../data/LoanAccountSummaryData.java | 23 + .../data/SavingsAccountSummaryData.java | 15 + .../accountdetails/domain/AccountType.java | 18 +- .../AccountDetailsReadPlatformService.java | 5 + ...sReadPlatformServiceJpaRepositoryImpl.java | 47 ++- .../service/AccountEnumerations.java | 3 + .../service/CalendarReadPlatformService.java | 2 + .../CalendarReadPlatformServiceImpl.java | 2 + .../group/api/GroupsApiResource.java | 81 +++- .../portfolio/group/domain/Group.java | 6 +- .../GroupMemberNotFoundInGSIMException.java | 32 ++ .../loanaccount/api/LoanApiConstants.java | 3 + .../loanaccount/api/LoansApiResource.java | 157 +++++-- .../loanaccount/data/GLIMContainer.java | 86 ++++ .../data/GlimRepaymentTemplate.java | 111 +++++ ...upLoanIndividualMonitoringAccountData.java | 119 ++++++ .../domain/GLIMAccountInfoRepository.java | 34 ++ .../GroupLoanIndividualMonitoringAccount.java | 149 +++++++ .../portfolio/loanaccount/domain/Loan.java | 26 +- .../loanaccount/domain/LoanRepository.java | 5 + .../domain/LoanRepositoryWrapper.java | 1 + .../service/GuarantorReadPlatformService.java | 1 + .../GuarantorReadPlatformServiceImpl.java | 1 + .../GLIMBulkRepaymentCommandHandler.java | 49 +++ ...LoanApplicationApprovalCommandHandler.java | 49 +++ ...LoanApplicationDisburseCommandHandler.java | 52 +++ .../UndoGLIMLoanApplicationApproval.java | 49 +++ .../UndoGLIMLoanDisbursalCommandHandler.java | 49 +++ ...oanScheduleCalculationPlatformService.java | 1 + ...cheduleCalculationPlatformServiceImpl.java | 3 +- ...anApplicationCommandFromApiJsonHelper.java | 4 +- ...ApplicationTransitionApiJsonValidator.java | 2 +- .../LoanEventApiJsonValidator.java | 2 +- .../GLIMAccountInfoReadPlatformService.java | 51 +++ ...LIMAccountInfoReadPlatformServiceImpl.java | 266 ++++++++++++ .../GLIMAccountInfoWritePlatformService.java | 43 ++ ...IMAccountInfoWritePlatformServiceImpl.java | 95 +++++ .../LoanApplicationWritePlatformService.java | 4 + ...WritePlatformServiceJpaRepositoryImpl.java | 385 ++++++++++++++++- .../loanaccount/service/LoanAssembler.java | 3 +- .../service/LoanReadPlatformService.java | 4 + .../service/LoanReadPlatformServiceImpl.java | 23 + .../service/LoanWritePlatformService.java | 6 + ...WritePlatformServiceJpaRepositoryImpl.java | 127 +++++- .../savings/SavingsApiConstants.java | 2 + .../api/SavingsAccountsApiResource.java | 95 +++++ .../portfolio/savings/data/GSIMContainer.java | 86 ++++ ...avingsIndividualMonitoringAccountData.java | 128 ++++++ .../savings/data/SavingsAccountConstant.java | 2 +- .../savings/domain/GSIMRepositoy.java | 31 ++ .../GroupSavingsIndividualMonitoring.java | 144 +++++++ .../savings/domain/SavingsAccount.java | 24 +- .../domain/SavingsAccountAssembler.java | 8 + .../domain/SavingsAccountRepository.java | 3 + .../SavingsAccountRepositoryWrapper.java | 4 + .../GSIMAccountActivationCommandHandler.java | 48 +++ ...GSIMApplicationApprovalCommandHandler.java | 50 +++ ...ApplicationModificationCommandHandler.java | 49 +++ .../GSIMApplicationRejectionHandler.java | 51 +++ ...SIMApplicationSubmittalCommandHandler.java | 51 +++ .../GSIMUndoApprovalCommandHandler.java | 51 +++ .../service/GSIMReadPlatformService.java | 48 +++ .../service/GSIMReadPlatformServiceImpl.java | 399 ++++++++++++++++++ ...ividualMonitoringWritePlatformService.java | 37 ++ ...ualMonitoringWritePlatformServiceImpl.java | 93 ++++ .../SavingsAccountWritePlatformService.java | 2 + ...WritePlatformServiceJpaRepositoryImpl.java | 69 ++- ...pplicationProcessWritePlatformService.java | 10 + ...WritePlatformServiceJpaRepositoryImpl.java | 307 +++++++++++++- .../core_db/V7001__GLIM_migration_script.sql | 56 +++ .../core_db/V7002__GSIM_migration_script.sql | 56 +++ 73 files changed, 4115 insertions(+), 89 deletions(-) create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/group/exception/GroupMemberNotFoundInGSIMException.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GLIMContainer.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GlimRepaymentTemplate.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GroupLoanIndividualMonitoringAccountData.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GLIMAccountInfoRepository.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GroupLoanIndividualMonitoringAccount.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMBulkRepaymentCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMLoanApplicationApprovalCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GlimLoanApplicationDisburseCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanApplicationApproval.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanDisbursalCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformService.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformServiceImpl.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformService.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformServiceImpl.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GSIMContainer.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GroupSavingsIndividualMonitoringAccountData.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GSIMRepositoy.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GroupSavingsIndividualMonitoring.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMAccountActivationCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationApprovalCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationModificationCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationRejectionHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationSubmittalCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMUndoApprovalCommandHandler.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformService.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformServiceImpl.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformService.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformServiceImpl.java create mode 100644 fineract-provider/src/main/resources/sql/migrations/core_db/V7001__GLIM_migration_script.sql create mode 100644 fineract-provider/src/main/resources/sql/migrations/core_db/V7002__GSIM_migration_script.sql diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java index 0ad36120cd5..3276afd200e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java +++ b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java @@ -899,6 +899,50 @@ public CommandWrapperBuilder approveLoanApplication(final Long loanId) { this.href = "/loans/" + loanId; 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) { this.actionName = "DISBURSE"; @@ -1124,6 +1168,14 @@ public CommandWrapperBuilder createSavingsAccount() { this.href = "/savingsaccounts/template"; 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) { this.actionName = "UPDATE"; @@ -1132,6 +1184,14 @@ public CommandWrapperBuilder updateSavingsAccount(final Long accountId) { this.href = "/savingsaccounts/" + accountId; 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) { this.actionName = "DELETE"; @@ -1149,6 +1209,15 @@ public CommandWrapperBuilder rejectSavingsAccountApplication(final Long accountI this.href = "/savingsaccounts/" + accountId + "?command=reject"; 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) { this.actionName = "WITHDRAW"; @@ -1167,6 +1236,15 @@ public CommandWrapperBuilder approveSavingsAccountApplication(final Long account this.href = "/savingsaccounts/" + accountId + "?command=approve"; 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) { this.actionName = "APPROVALUNDO"; @@ -1176,7 +1254,17 @@ public CommandWrapperBuilder undoSavingsAccountApplication(final Long accountId) this.href = "/savingsaccounts/" + accountId + "?command=undoapproval"; 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) { this.actionName = "ACTIVATE"; this.entityName = "SAVINGSACCOUNT"; @@ -1185,6 +1273,15 @@ public CommandWrapperBuilder savingsAccountActivation(final Long accountId) { this.href = "/savingsaccounts/" + accountId + "?command=activate"; 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) { this.actionName = "CLOSE"; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java index f4faacaa32a..2a194f06b00 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java @@ -27,25 +27,28 @@ public class AccountSummaryCollectionData { private final Collection loanAccounts; + private final Collection groupLoanIndividualMonitoringAccounts; private final Collection savingsAccounts; private final Collection shareAccounts ; private final Collection memberLoanAccounts; private final Collection memberSavingsAccounts; - public AccountSummaryCollectionData(final Collection loanAccounts, + public AccountSummaryCollectionData(final Collection loanAccounts,final Collection groupLoanIndividualMonitoringAccounts, final Collection savingsAccounts, final Collection shareAccounts) { this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts); + this.groupLoanIndividualMonitoringAccounts=groupLoanIndividualMonitoringAccounts; this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts); this.shareAccounts = defaultShareAccountsIfEmpty(shareAccounts) ; this.memberLoanAccounts = null; this.memberSavingsAccounts = null; } - public AccountSummaryCollectionData(final Collection loanAccounts, + public AccountSummaryCollectionData(final Collection loanAccounts,final Collection groupLoanIndividualMonitoringAccounts, final Collection savingsAccounts, final Collection memberLoanAccounts, final Collection memberSavingsAccounts) { this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts); + this.groupLoanIndividualMonitoringAccounts=groupLoanIndividualMonitoringAccounts; this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts); this.shareAccounts = null ; this.memberLoanAccounts = defaultLoanAccountsIfEmpty(memberLoanAccounts); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java index a4c7517911c..a9cb030b415 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/LoanAccountSummaryData.java @@ -32,6 +32,7 @@ public class LoanAccountSummaryData { private final Long id; private final String accountNo; + private final String parentAccountNumber; private final String externalId; private final Long productId; private final String productName; @@ -50,6 +51,28 @@ public LoanAccountSummaryData(final Long id, final String accountNo, final Strin final LoanApplicationTimelineData timeline, final Boolean inArrears,final BigDecimal originalLoan,final BigDecimal loanBalance,final BigDecimal amountPaid) { this.id = id; 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.productId = productId; this.productName = loanProductName; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java index 55e04e9727c..531b00824e5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/SavingsAccountSummaryData.java @@ -70,4 +70,19 @@ public SavingsAccountSummaryData(final Long id, final String accountNo, final St this.subStatus = subStatus; this.lastActiveTransactionDate = lastActiveTransactionDate; } + + public String getAccountNo() { + return accountNo; + } + + public Long getId() { + return id; + } + + + + + + + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/domain/AccountType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/domain/AccountType.java index 386d67c49e2..b769644ac62 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/domain/AccountType.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/domain/AccountType.java @@ -26,7 +26,9 @@ public enum AccountType { INVALID(0, "accountType.invalid"), // INDIVIDUAL(1, "accountType.individual"), // 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 String code; @@ -49,6 +51,12 @@ public static AccountType fromInt(final Integer accountTypeValue) { case 3: enumeration = AccountType.JLG; break; + case 4: + enumeration = AccountType.GLIM; + break; + case 5: + enumeration = AccountType.GSIM; + break; } return enumeration; } @@ -91,4 +99,12 @@ public boolean isGroupAccount() { public boolean isJLGAccount() { 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()); + } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformService.java index dc28a44e80b..64e3dd6be54 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformService.java @@ -19,6 +19,7 @@ package org.apache.fineract.portfolio.accountdetails.service; import java.util.Collection; +import java.util.List; import org.apache.fineract.portfolio.accountdetails.data.AccountSummaryCollectionData; import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData; @@ -34,4 +35,8 @@ public interface AccountDetailsReadPlatformService { public Collection retrieveGroupLoanAccountsByLoanOfficerId(final Long groupId, final Long loanOfficerId); public Collection retrieveClientActiveLoanAccountSummary(final Long clientId); + + public List retrieveLoanAccountDetailsByGroupIdAndGlimAccountNumber(Long groupId,final String glimAccount); + + AccountSummaryCollectionData retrieveGroupAccountDetails(Long groupId, Long gsimId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java index 0fc91036b5c..2c6796a692c 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java @@ -74,11 +74,13 @@ public AccountSummaryCollectionData retrieveClientAccountDetails(final Long clie // Check if client exists this.clientReadPlatformService.retrieveOne(clientId); final String loanwhereClause = " where l.client_id = ?"; + final String glimLoanClause=" where l.client_id = ? and l.loan_type_enum=4"; final String savingswhereClause = " where sa.client_id = ? order by sa.status_enum ASC, sa.account_no ASC"; + final List glimAccounts = retrieveLoanAccountDetails(glimLoanClause, new Object[] { clientId }); final List loanAccounts = retrieveLoanAccountDetails(loanwhereClause, new Object[] { clientId }); final List savingsAccounts = retrieveAccountDetails(savingswhereClause, new Object[] { clientId }); final List shareAccounts = retrieveShareAccountDetails(clientId) ; - return new AccountSummaryCollectionData(loanAccounts, savingsAccounts, shareAccounts); + return new AccountSummaryCollectionData(loanAccounts,glimAccounts, savingsAccounts, shareAccounts); } @Override @@ -86,9 +88,12 @@ public AccountSummaryCollectionData retrieveGroupAccountDetails(final Long group // 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.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 glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId }); final List groupLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroup, new Object[] { groupId }); final List groupSavingsAccounts = retrieveAccountDetails(savingswhereClauseForGroup, new Object[] { groupId }); @@ -96,7 +101,28 @@ public AccountSummaryCollectionData retrieveGroupAccountDetails(final Long group new Object[] { groupId }); final List memberSavingsAccounts = retrieveAccountDetails(savingswhereClauseForMembers, new Object[] { groupId }); - return new AccountSummaryCollectionData(groupLoanAccounts, groupSavingsAccounts, memberLoanAccounts, memberSavingsAccounts); + return new AccountSummaryCollectionData(groupLoanAccounts, glimAccounts,groupSavingsAccounts, memberLoanAccounts, memberSavingsAccounts); + } + + @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 glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId }); + final List groupLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroup, new Object[] { groupId }); + final List gsimSavingsAccounts = retrieveAccountDetails(savingswhereClauseForGroup, + new Object[] { groupId,gsimId }); + final List memberLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForMembers, + new Object[] { groupId }); + final List memberSavingsAccounts = retrieveAccountDetails(savingswhereClauseForMembers, + new Object[] { groupId }); + return new AccountSummaryCollectionData(groupLoanAccounts, glimAccounts,gsimSavingsAccounts, memberLoanAccounts, memberSavingsAccounts); } @Override @@ -119,7 +145,17 @@ public Collection retrieveGroupLoanAccountsByLoanOfficer final String loanWhereClause = " where l.client_id = ? and l.loan_status_id = 300 "; return retrieveLoanAccountDetails(loanWhereClause, new Object[] { clientId }); } + + @Override + public List retrieveLoanAccountDetailsByGroupIdAndGlimAccountNumber(final Long groupId,final String glimAccount) { + final LoanAccountSummaryDataMapper rm = new LoanAccountSummaryDataMapper(); + final String loanWhereClauseForGroupAndLoanType = " where l.group_id =? and glim.account_number="+glimAccount+" 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}); + } + private List retrieveLoanAccountDetails(final String loanwhereClause, final Object[] inputs) { final LoanAccountSummaryDataMapper rm = new LoanAccountSummaryDataMapper(); final String sql = "select " + rm.loanAccountSummarySchema() + loanwhereClause; @@ -384,6 +420,7 @@ public String loanAccountSummarySchema() { accountsSummary .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(" glim.account_number as parentAccountNumber,") .append("l.principal_disbursed_derived as originalLoan,") .append("l.total_outstanding_derived as loanBalance,") @@ -418,7 +455,8 @@ public String loanAccountSummarySchema() { .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 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(); } @@ -428,6 +466,7 @@ public LoanAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unus final Long id = JdbcSupport.getLong(rs, "id"); final String accountNo = rs.getString("accountNo"); + final String parentAccountNumber=rs.getString("parentAccountNumber"); final String externalId = rs.getString("externalId"); final Long productId = JdbcSupport.getLong(rs, "productId"); final String loanProductName = rs.getString("productName"); @@ -490,7 +529,7 @@ public LoanAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unus disbursedByFirstname, disbursedByLastname, closedOnDate, 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); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountEnumerations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountEnumerations.java index 0f3c1e19fac..5df984623ea 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountEnumerations.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountEnumerations.java @@ -47,6 +47,9 @@ public static EnumOptionData loanType(final AccountType type) { case JLG: optionData = new EnumOptionData(AccountType.JLG.getValue().longValue(), AccountType.JLG.getCode(), "JLG"); break; + case GLIM: + optionData = new EnumOptionData(AccountType.GLIM.getValue().longValue(), AccountType.GLIM.getCode(), "GLIM"); + break; } return optionData; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java index 5b7b28faeec..4c49fce15f9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java @@ -52,4 +52,6 @@ Collection retrieveParentCalendarsByEntity(final Long entityId, fi Boolean isCalendarAssociatedWithEntity(final Long entityId, final Long calendarId, Long entityTypeId); + + } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java index c9e706875df..2fd9352c110 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java @@ -151,6 +151,8 @@ public Collection retrieveCalendarsByEntity(final Long entityId, f } return result; } + + @Override public CalendarData retrieveCollctionCalendarByEntity(final Long entityId, final Integer entityTypeId) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResource.java index 96dc132a9be..9e8b2d49bf8 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResource.java @@ -73,8 +73,12 @@ import org.apache.fineract.portfolio.group.service.CenterReadPlatformService; import org.apache.fineract.portfolio.group.service.GroupReadPlatformService; 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.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.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @@ -95,6 +99,8 @@ public class GroupsApiResource { private final ToApiJsonSerializer toApiJsonSerializer; private final ToApiJsonSerializer groupGeneralApiJsonSerializer; private final ToApiJsonSerializer groupSummaryToApiJsonSerializer; + private final ToApiJsonSerializer glimContainerToApiJsonSerializer; + private final ToApiJsonSerializer gsimContainerToApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final CollectionSheetReadPlatformService collectionSheetReadPlatformService; @@ -104,6 +110,8 @@ public class GroupsApiResource { private final CalendarReadPlatformService calendarReadPlatformService; private final MeetingReadPlatformService meetingReadPlatformService; private final EntityDatatableChecksReadService entityDatatableChecksReadService; + private final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService; + private final GSIMReadPlatformService gsimReadPlatformService; @Autowired public GroupsApiResource(final PlatformSecurityContext context, final GroupReadPlatformService groupReadPlatformService, @@ -111,13 +119,17 @@ public GroupsApiResource(final PlatformSecurityContext context, final GroupReadP final ToApiJsonSerializer toApiJsonSerializer, final ToApiJsonSerializer groupTopOfHierarchyApiJsonSerializer, final ToApiJsonSerializer groupSummaryToApiJsonSerializer, + final ToApiJsonSerializer glimContainerToApiJsonSerializer, + final ToApiJsonSerializer gsimContainerToApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, final CollectionSheetReadPlatformService collectionSheetReadPlatformService, final FromJsonHelper fromJsonHelper, final GroupRolesReadPlatformService groupRolesReadPlatformService, final AccountDetailsReadPlatformService accountDetailsReadPlatformService, final CalendarReadPlatformService calendarReadPlatformService, final MeetingReadPlatformService meetingReadPlatformService, - final EntityDatatableChecksReadService entityDatatableChecksReadService) { + final EntityDatatableChecksReadService entityDatatableChecksReadService, + final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService, + final GSIMReadPlatformService gsimReadPlatformService) { this.context = context; this.groupReadPlatformService = groupReadPlatformService; @@ -126,6 +138,8 @@ public GroupsApiResource(final PlatformSecurityContext context, final GroupReadP this.toApiJsonSerializer = toApiJsonSerializer; this.groupGeneralApiJsonSerializer = groupTopOfHierarchyApiJsonSerializer; this.groupSummaryToApiJsonSerializer = groupSummaryToApiJsonSerializer; + this.glimContainerToApiJsonSerializer=glimContainerToApiJsonSerializer; + this.gsimContainerToApiJsonSerializer=gsimContainerToApiJsonSerializer; this.apiRequestParameterHelper = apiRequestParameterHelper; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.collectionSheetReadPlatformService = collectionSheetReadPlatformService; @@ -135,6 +149,8 @@ public GroupsApiResource(final PlatformSecurityContext context, final GroupReadP this.calendarReadPlatformService = calendarReadPlatformService; this.meetingReadPlatformService = meetingReadPlatformService; this.entityDatatableChecksReadService = entityDatatableChecksReadService; + this.glimAccountInfoReadPlatformService=glimAccountInfoReadPlatformService; + this.gsimReadPlatformService=gsimReadPlatformService; } @GET @@ -435,10 +451,71 @@ public String retrieveAccounts(@PathParam("groupId") final Long groupId, @Contex final AccountSummaryCollectionData groupAccount = this.accountDetailsReadPlatformService.retrieveGroupAccountDetails(groupId); - final Set GROUP_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("loanAccounts", "savingsAccounts", + final Set GROUP_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("loanAccounts", "groupLoanIndividualMonitoringAccounts","savingsAccounts", "memberLoanAccounts", "memberSavingsAccounts")); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.groupSummaryToApiJsonSerializer.serialize(settings, groupAccount, GROUP_ACCOUNTS_DATA_PARAMETERS); } + + + + @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; + if(parentLoanAccountNo==null) + { + glimContainer=(List)glimAccountInfoReadPlatformService.findGlimAccount(groupId); + } + else + { + glimContainer=(List)glimAccountInfoReadPlatformService.findGlimAccountbyGroupAndAccount(groupId,parentLoanAccountNo); + } + + + + final Set 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, @Context final UriInfo uriInfo) + { + List gsimContainer; + this.context.authenticatedUser().validateHasReadPermission("GROUP"); + + if(parentGSIMAccountNo==null) + { + gsimContainer= (List)this.gsimReadPlatformService.findGSIMAccountContainerByGroupId(groupId); + } + else + { + gsimContainer= (List)this.gsimReadPlatformService.findGsimAccountContainerbyGsimAccountNumber(parentGSIMAccountNo); + } + + + final Set 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); + + } + + + + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java index c3a14ae7dc7..ae468c06f06 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java @@ -46,10 +46,10 @@ import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.service.DateUtils; -import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator; import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.staff.domain.Staff; @@ -60,6 +60,7 @@ import org.apache.fineract.portfolio.group.exception.GroupExistsInCenterException; import org.apache.fineract.portfolio.group.exception.GroupNotExistsInCenterException; 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.joda.time.LocalDate; @@ -145,6 +146,9 @@ public final class Group extends AbstractPersistableCustom { @OneToMany(mappedBy="group",cascade = CascadeType.REMOVE) private Set groupRole; + + @OneToMany(mappedBy = "group") + private List glimLoan; // JPA default constructor for entity diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/exception/GroupMemberNotFoundInGSIMException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/exception/GroupMemberNotFoundInGSIMException.java new file mode 100644 index 00000000000..3d58f0793a7 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/exception/GroupMemberNotFoundInGSIMException.java @@ -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.group.exception; + +import java.math.BigDecimal; + +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); +} +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java index 6e5376a7913..2ad3b332a88 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java @@ -31,6 +31,7 @@ public interface LoanApiConstants { public static final String loanChargeIdParameterName = "loanChargeId"; public static final String principalDisbursedParameterName = "transactionAmount"; public static final String chargesParameterName = "charges"; + public static final String loanIdTobeApproved="loanId"; public static final String approvedLoanAmountParameterName = "approvedLoanAmount"; public static final String approvedOnDateParameterName = "approvedOnDate"; @@ -109,6 +110,8 @@ public interface LoanApiConstants { public static final String dueDateParamName = "dueDate"; public static final String modifiedDueDateParamName = "modifiedDueDate"; public static final String principalParamName = "principal"; + public static final String parentAccountParamName="isParentAccount"; + public static final String totalLoanParamName="totalLoan"; public static final String installmentAmountParamName = "installmentAmount"; //loan write off public static final String WRITEOFFREASONS = "WriteOffReasons"; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java index e3c51c761b8..f319753495a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java @@ -20,7 +20,14 @@ import static org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.interestType; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -82,6 +89,7 @@ import org.apache.fineract.portfolio.group.data.GroupGeneralData; import org.apache.fineract.portfolio.group.service.GroupReadPlatformService; 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.LoanApprovalData; import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData; @@ -98,6 +106,7 @@ 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.LoanScheduleHistoryReadPlatformService; +import org.apache.fineract.portfolio.loanaccount.service.GLIMAccountInfoReadPlatformService; import org.apache.fineract.portfolio.loanaccount.service.LoanChargeReadPlatformService; import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; @@ -142,6 +151,8 @@ public class LoansApiResource { LoanApiConstants.datatables)); private final Set LOAN_APPROVAL_DATA_PARAMETERS = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount")); + final Set GLIM_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("glimId","groupId", "clientId","parentLoanAccountNo","parentPrincipalAmount", + "childLoanAccountNo", "childPrincipalAmount","clientName")); private final String resourceNameForPermissions = "LOAN"; private final PlatformSecurityContext context; @@ -169,6 +180,8 @@ public class LoansApiResource { private final LoanScheduleHistoryReadPlatformService loanScheduleHistoryReadPlatformService; private final AccountDetailsReadPlatformService accountDetailsReadPlatformService; private final EntityDatatableChecksReadService entityDatatableChecksReadService; + private final DefaultToApiJsonSerializer glimTemplateToApiJsonSerializer; + private final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService; @Autowired public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService, @@ -189,7 +202,9 @@ public LoansApiResource(final PlatformSecurityContext context, final LoanReadPla final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService, final LoanScheduleHistoryReadPlatformService loanScheduleHistoryReadPlatformService, final AccountDetailsReadPlatformService accountDetailsReadPlatformService, - final EntityDatatableChecksReadService entityDatatableChecksReadService) { + final EntityDatatableChecksReadService entityDatatableChecksReadService, + final DefaultToApiJsonSerializer glimTemplateToApiJsonSerializer, + final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService) { this.context = context; this.loanReadPlatformService = loanReadPlatformService; this.loanProductReadPlatformService = loanProductReadPlatformService; @@ -215,6 +230,8 @@ public LoansApiResource(final PlatformSecurityContext context, final LoanReadPla this.loanScheduleHistoryReadPlatformService = loanScheduleHistoryReadPlatformService; this.accountDetailsReadPlatformService = accountDetailsReadPlatformService; this.entityDatatableChecksReadService = entityDatatableChecksReadService; + this.glimTemplateToApiJsonSerializer=glimTemplateToApiJsonSerializer; + this.glimAccountInfoReadPlatformService=glimAccountInfoReadPlatformService; } /* @@ -246,6 +263,8 @@ public String retrieveApprovalTemplate(@PathParam("loanId") final Long loanId, @ return this.loanApprovalDataToApiJsonSerializer.serialize(settings, loanApprovalTemplate, this.LOAN_APPROVAL_DATA_PARAMETERS); } + + @GET @Path("template") @@ -623,6 +642,9 @@ public String retrieveLoan(@PathParam("loanId") final Long loanId, System.out.println("LoansApiResource.retrieveLoan() Time took to Serialize: "+(end-start)); return toReturn ; } + + + @GET @Consumes({ MediaType.APPLICATION_JSON }) @@ -696,56 +718,115 @@ public String deleteLoanApplication(@PathParam("loanId") final Long loanId) { return this.toApiJsonSerializer.serialize(result); } - + + + @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=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("{loanId}") + @Path("glimAccount/{glimId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String stateTransitions(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam, - final String apiRequestBodyAsJson) { + 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.rejectLoanApplication(loanId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "withdrawnByApplicant")) { - final CommandWrapper commandRequest = builder.withdrawLoanApplication(loanId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "approve")) { - final CommandWrapper commandRequest = builder.approveLoanApplication(loanId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "disburse")) { - final CommandWrapper commandRequest = builder.disburseLoanApplication(loanId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "disburseToSavings")) { - final CommandWrapper commandRequest = builder.disburseLoanToSavingsApplication(loanId).build(); + + if (is(commandParam, "approve")) { + final CommandWrapper commandRequest = builder.approveGLIMLoanApplication(glimId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); } - - if (is(commandParam, "undoapproval")) { - final CommandWrapper commandRequest = builder.undoLoanApplicationApproval(loanId).build(); + else if (is(commandParam, "disburse")) { + final CommandWrapper commandRequest = builder.disburseGlimLoanApplication(glimId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "undodisbursal")) { - final CommandWrapper commandRequest = builder.undoLoanApplicationDisbursal(loanId).build(); + } else if (is(commandParam, "glimrepayment")) { + final CommandWrapper commandRequest = builder.repaymentGlimLoanApplication(glimId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - }else if (is(commandParam, "undolastdisbursal")) { - final CommandWrapper commandRequest = builder.undoLastDisbursalLoanApplication(loanId).build(); + } + else if (is(commandParam, "glimrepayment")) { + final CommandWrapper commandRequest = builder.repaymentGlimLoanApplication(glimId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } - - if (is(commandParam, "assignloanofficer")) { - final CommandWrapper commandRequest = builder.assignLoanOfficer(loanId).build(); + } + else if (is(commandParam, "undodisbursal")) { + final CommandWrapper commandRequest = builder.undoGLIMLoanDisbursal(glimId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "unassignloanofficer")) { - final CommandWrapper commandRequest = builder.unassignLoanOfficer(loanId).build(); + } + else if (is(commandParam, "undoapproval")) { + final CommandWrapper commandRequest = builder.undoGLIMLoanApproval(glimId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } else if (is(commandParam, "recoverGuarantees")) { - final CommandWrapper commandRequest = new CommandWrapperBuilder().recoverFromGuarantor(loanId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } + } + + + if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam); } + + return this.toApiJsonSerializer.serialize(result); + } + + @POST + @Path("{loanId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String stateTransitions(@PathParam("loanId") final Long loanId, @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.rejectLoanApplication(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "withdrawnByApplicant")) { + final CommandWrapper commandRequest = builder.withdrawLoanApplication(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "approve")) { + final CommandWrapper commandRequest = builder.approveLoanApplication(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "disburse")) { + final CommandWrapper commandRequest = builder.disburseLoanApplication(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "disburseToSavings")) { + final CommandWrapper commandRequest = builder.disburseLoanToSavingsApplication(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } + + if (is(commandParam, "undoapproval")) { + final CommandWrapper commandRequest = builder.undoLoanApplicationApproval(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "undodisbursal")) { + final CommandWrapper commandRequest = builder.undoLoanApplicationDisbursal(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + }else if (is(commandParam, "undolastdisbursal")) { + final CommandWrapper commandRequest = builder.undoLastDisbursalLoanApplication(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } + + if (is(commandParam, "assignloanofficer")) { + final CommandWrapper commandRequest = builder.assignLoanOfficer(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "unassignloanofficer")) { + final CommandWrapper commandRequest = builder.unassignLoanOfficer(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "recoverGuarantees")) { + final CommandWrapper commandRequest = new CommandWrapperBuilder().recoverFromGuarantor(loanId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } + + + if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GLIMContainer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GLIMContainer.java new file mode 100644 index 00000000000..e26d07d945c --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GLIMContainer.java @@ -0,0 +1,86 @@ +/** + * 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 childGLIMAccounts; + + private final BigDecimal parentPrincipalAmount; + + private final String loanStatus; + + + public GLIMContainer(final BigDecimal glimId,final BigDecimal groupId,final String accountNumber,final List 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 getChildGLIMAccounts() { + return childGLIMAccounts; + } + + public BigDecimal getParentPrincipalAmount() { + return parentPrincipalAmount; + } + + + public String getLoanStatus() { + return loanStatus; + } + + + + + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GlimRepaymentTemplate.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GlimRepaymentTemplate.java new file mode 100644 index 00000000000..6043ae33b06 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GlimRepaymentTemplate.java @@ -0,0 +1,111 @@ +/** + * 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; + } + + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GroupLoanIndividualMonitoringAccountData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GroupLoanIndividualMonitoringAccountData.java new file mode 100644 index 00000000000..3afeafdb2bc --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/GroupLoanIndividualMonitoringAccountData.java @@ -0,0 +1,119 @@ +/** + * 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; + } + + + + + + + + + + + + + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GLIMAccountInfoRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GLIMAccountInfoRepository.java new file mode 100644 index 00000000000..5c4921ab51b --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GLIMAccountInfoRepository.java @@ -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 org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface GLIMAccountInfoRepository extends JpaRepository, JpaSpecificationExecutor +{ + + GroupLoanIndividualMonitoringAccount findOneByIsAcceptingChild(boolean acceptingChild); + + GroupLoanIndividualMonitoringAccount findOneByAccountNumber(String accountNumber); + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GroupLoanIndividualMonitoringAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GroupLoanIndividualMonitoringAccount.java new file mode 100644 index 00000000000..44ea07b0751 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/GroupLoanIndividualMonitoringAccount.java @@ -0,0 +1,149 @@ +/** + * 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 childLoan; + + @Column(name = "loan_status_id", nullable = false) + private Integer loanStatus; + + + + private GroupLoanIndividualMonitoringAccount(String accountNumber,Group group,BigDecimal principalAmount,Long childAccountsCount, + Boolean isAcceptingChild,Integer loanStatus) + { + this.accountNumber=accountNumber; + this.group=group; + this.principalAmount=principalAmount; + this.childAccountsCount=childAccountsCount; + this.isAcceptingChild=isAcceptingChild; + this.loanStatus=loanStatus; + + } + + public static GroupLoanIndividualMonitoringAccount getInstance(String accountNumber,Group group,BigDecimal principalAmount,Long childAccountsCount, + Boolean isAcceptingChild,Integer loanStatus) + { + return new GroupLoanIndividualMonitoringAccount(accountNumber,group,principalAmount,childAccountsCount, + isAcceptingChild,loanStatus); + } + + 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 getChildLoan() { + return childLoan; + } + + public void setChildLoan(Set 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; + } + + + + + + + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index 480b0810884..4c5e5ad6d9c 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -167,6 +167,10 @@ public class Loan extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "group_id", nullable = true) private Group group; + + @ManyToOne + @JoinColumn(name = "glim_id", nullable = true) + private GroupLoanIndividualMonitoringAccount glim; @Column(name = "loan_type_enum", nullable = false) private Integer loanType; @@ -1057,8 +1061,16 @@ public LoanTransaction waiveLoanCharge(final LoanCharge loanCharge, final LoanLi public Client 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; } @@ -6506,6 +6518,14 @@ public void initializeRepaymentSchedule() { public boolean hasInvalidLoanType() { return AccountType.fromInt(this.loanType).isInvalid(); } - - public boolean isIndividualLoan(){return AccountType.fromInt(this.loanType).isIndividualAccount();} + + public Integer getLoanType() { + return loanType; + } + + public void setLoanType(Integer loanType) { + this.loanType = loanType; + } + + public boolean isIndividualLoan(){return AccountType.fromInt(this.loanType).isIndividualAccount();} } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java index fe17368b147..630b9f67331 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java @@ -120,6 +120,9 @@ List findByClientIdAndGroupIdAndLoanStatus(@Param("clientId") Long clientI @Query("select loan from Loan loan where loan.group.id = :groupId and loan.client.id is null") List findByGroupId(@Param("groupId") Long groupId); + + @Query("select loan from Loan loan where loan.glim.id = :glimId") + List 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") List findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection ids, @@ -154,4 +157,6 @@ List findByGroupOfficeIdsAndLoanStatus(@Param("officeIds") Collection findActiveLoansByLoanIdAndGroupId(Long clientId, Long groupId) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformService.java index 9652134635e..6bf24f740b6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformService.java @@ -43,4 +43,5 @@ public interface GuarantorReadPlatformService { GuarantorData retrieveGuarantor(Long loanId, Long guarantorId); + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java index e5dc0f5e478..cc7a722ae42 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java @@ -86,6 +86,7 @@ public List retrieveGuarantorsForLoan(final Long loanId) { } return mergedGuarantorDatas; } + @Override public GuarantorData retrieveGuarantor(final Long loanId, final Long guarantorId) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMBulkRepaymentCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMBulkRepaymentCommandHandler.java new file mode 100644 index 00000000000..6cde0536cdf --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMBulkRepaymentCommandHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMLoanApplicationApprovalCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMLoanApplicationApprovalCommandHandler.java new file mode 100644 index 00000000000..9e117792984 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GLIMLoanApplicationApprovalCommandHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GlimLoanApplicationDisburseCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GlimLoanApplicationDisburseCommandHandler.java new file mode 100644 index 00000000000..d894585b5c5 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/GlimLoanApplicationDisburseCommandHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanApplicationApproval.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanApplicationApproval.java new file mode 100644 index 00000000000..d5557e81262 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanApplicationApproval.java @@ -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); + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanDisbursalCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanDisbursalCommandHandler.java new file mode 100644 index 00000000000..17a9c92b086 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/UndoGLIMLoanDisbursalCommandHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformService.java index 91a5a8470a0..331962f44d7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformService.java @@ -29,4 +29,5 @@ public interface LoanScheduleCalculationPlatformService { void updateFutureSchedule(LoanScheduleData loanScheduleData, Long loanId); LoanScheduleData generateLoanScheduleForVariableInstallmentRequest(Long loanId, String json); + } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java index 2ebe0d4d7d2..e444b5c0b35 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java @@ -137,7 +137,8 @@ public LoanScheduleModel calculateLoanSchedule(final JsonQuery query, Boolean va return this.loanScheduleAssembler.assembleLoanScheduleFrom(query.parsedJson()); } - + + @Override public void updateFutureSchedule(LoanScheduleData loanScheduleData, final Long loanId) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java index 198f52405f7..6b01a131bd8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java @@ -64,7 +64,7 @@ public final class LoanApplicationCommandFromApiJsonHelper { final Set supportedParameters = new HashSet<>(Arrays.asList(LoanApiConstants.dateFormatParameterName, LoanApiConstants.localeParameterName, LoanApiConstants.idParameterName, LoanApiConstants.clientIdParameterName, LoanApiConstants.groupIdParameterName, LoanApiConstants.loanTypeParameterName, LoanApiConstants.productIdParameterName, - LoanApiConstants.principalParamName, LoanApiConstants.loanTermFrequencyParameterName, + LoanApiConstants.principalParamName,LoanApiConstants.totalLoanParamName,LoanApiConstants.parentAccountParamName, LoanApiConstants.loanTermFrequencyParameterName, LoanApiConstants.loanTermFrequencyTypeParameterName, LoanApiConstants.numberOfRepaymentsParameterName, LoanApiConstants.repaymentEveryParameterName, LoanApiConstants.repaymentFrequencyTypeParameterName, LoanApiConstants.repaymentFrequencyNthDayTypeParameterName, LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName, @@ -122,7 +122,7 @@ public void validateForCreate(final String json, final boolean isMeetingMandator if (!StringUtils.isBlank(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 groupId = this.fromApiJsonHelper.extractLongNamed("groupId", element); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java index 7bcda3454a0..009a63d902d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java @@ -60,7 +60,7 @@ public void validateApproval(final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - final Set disbursementParameters = new HashSet<>(Arrays.asList(LoanApiConstants.approvedLoanAmountParameterName, + final Set disbursementParameters = new HashSet<>(Arrays.asList(LoanApiConstants.loanIdTobeApproved,LoanApiConstants.approvedLoanAmountParameterName, LoanApiConstants.approvedOnDateParameterName, LoanApiConstants.noteParameterName, LoanApiConstants.localeParameterName, LoanApiConstants.dateFormatParameterName,LoanApiConstants.disbursementDataParameterName,LoanApiConstants.disbursementDateParameterName)); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java index d28413033fc..a571ace7f29 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java @@ -157,7 +157,7 @@ public void validateNewRepaymentTransaction(final String json) { final Set transactionParameters = new HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", "note", "locale", "dateFormat", "paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber", - "bankNumber")); + "bankNumber","loanId")); final Type typeOfMap = new TypeToken>() {}.getType(); this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, transactionParameters); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformService.java new file mode 100644 index 00000000000..7f6605c906b --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformService.java @@ -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.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 findGlimAccountsByGroupId(String groupId); + + Collection findGlimAccountByGroupId(String groupId); + + Collection findGlimAccount(Long groupId); + + Collection findGlimAccountByGroupIdandAccountNo(String groupId, + String accountNo); + + Collection findGlimAccountbyGroupAndAccount(Long groupId, String accountNo); + + Collection findGlimAccountByParentAccountId(String parentAccountIds); + + Collection findGlimAccountsByGLIMId(Long glimId); + + Collection findglimRepaymentTemplate(Long glimId); + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformServiceImpl.java new file mode 100644 index 00000000000..a1db1bbd69a --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoReadPlatformServiceImpl.java @@ -0,0 +1,266 @@ +/** + * 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 { + 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 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 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 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 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 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 findGlimAccount(Long groupId) { + this.context.authenticatedUser(); + Collection glimInfo=findGlimAccountByGroupId(groupId+""); + + //List glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId }); + + List glimAccounts=new ArrayList(); + for(GroupLoanIndividualMonitoringAccountData glimAccount:glimInfo) + { + + List 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 findGlimAccountbyGroupAndAccount(Long groupId,String accountNo) { + this.context.authenticatedUser(); + Collection glimInfo=findGlimAccountByGroupIdandAccountNo(groupId+"", accountNo+""); + + //List glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId }); + + List glimAccounts=new ArrayList(); + for(GroupLoanIndividualMonitoringAccountData glimAccount:glimInfo) + { + + List 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 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 { + 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 { + 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); + + } + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformService.java new file mode 100644 index 00000000000..05b38e7e0df --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformService.java @@ -0,0 +1,43 @@ +/** + * 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 addGLIMAccountInfo(String accountNumber,Group group, BigDecimal principalAmount, Long childAccountsCount, + Boolean isAcceptingChild,Integer loanStatus); + + void setIsAcceptingChild(GroupLoanIndividualMonitoringAccount glimAccount); + + void resetIsAcceptingChild(GroupLoanIndividualMonitoringAccount glimAccount); + + void incrementChildAccountCount(GroupLoanIndividualMonitoringAccount glimAccount); + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformServiceImpl.java new file mode 100644 index 00000000000..2ab17ab211f --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/GLIMAccountInfoWritePlatformServiceImpl.java @@ -0,0 +1,95 @@ +/** + * 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) + { + + GroupLoanIndividualMonitoringAccount glimAccountInfo=GroupLoanIndividualMonitoringAccount.getInstance(accountNumber,group,principalAmount,childAccountsCount, + isAcceptingChild,loanStatus); + + 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); + + } + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformService.java index 96ae8316ce6..d9ffaa099ed 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformService.java @@ -36,4 +36,8 @@ public interface LoanApplicationWritePlatformService { CommandProcessingResult rejectApplication(Long loanId, JsonCommand command); CommandProcessingResult applicantWithdrawsFromApplication(Long loanId, JsonCommand command); + + CommandProcessingResult approveGLIMLoanAppication(Long loanId, JsonCommand command); + + CommandProcessingResult undoGLIMLoanApplicationApproval(Long loanId, JsonCommand command); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index f5a78c2da4e..fcebeebecce 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -19,7 +19,12 @@ package org.apache.fineract.portfolio.loanaccount.service; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import javax.persistence.PersistenceException; @@ -46,7 +51,11 @@ import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum; import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksWritePlatformService; import org.apache.fineract.infrastructure.entityaccess.FineractEntityAccessConstants; -import org.apache.fineract.infrastructure.entityaccess.domain.*; +import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType; +import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelation; +import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelationRepository; +import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityToEntityMapping; +import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityToEntityMappingRepository; import org.apache.fineract.infrastructure.entityaccess.exception.NotOfficeSpecificProductException; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.organisation.staff.domain.Staff; @@ -54,8 +63,13 @@ import org.apache.fineract.portfolio.account.domain.AccountAssociations; import org.apache.fineract.portfolio.account.domain.AccountAssociationsRepository; import org.apache.fineract.portfolio.accountdetails.domain.AccountType; -import org.apache.fineract.portfolio.calendar.domain.*; import org.apache.fineract.portfolio.calendar.domain.Calendar; +import org.apache.fineract.portfolio.calendar.domain.CalendarEntityType; +import org.apache.fineract.portfolio.calendar.domain.CalendarFrequencyType; +import org.apache.fineract.portfolio.calendar.domain.CalendarInstance; +import org.apache.fineract.portfolio.calendar.domain.CalendarInstanceRepository; +import org.apache.fineract.portfolio.calendar.domain.CalendarRepository; +import org.apache.fineract.portfolio.calendar.domain.CalendarType; import org.apache.fineract.portfolio.calendar.exception.CalendarNotFoundException; import org.apache.fineract.portfolio.calendar.service.CalendarReadPlatformService; import org.apache.fineract.portfolio.charge.domain.Charge; @@ -72,11 +86,28 @@ import org.apache.fineract.portfolio.fund.domain.Fund; import org.apache.fineract.portfolio.group.domain.Group; 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.loanaccount.api.LoanApiConstants; +import org.apache.fineract.portfolio.loanaccount.data.GlimRepaymentTemplate; +import org.apache.fineract.portfolio.loanaccount.data.GroupLoanIndividualMonitoringAccountData; import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData; import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO; -import org.apache.fineract.portfolio.loanaccount.domain.*; +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.LoanCharge; +import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails; +import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine; +import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment; +import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository; +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.LoanStatus; +import org.apache.fineract.portfolio.loanaccount.domain.LoanSummaryWrapper; +import org.apache.fineract.portfolio.loanaccount.domain.LoanTopupDetails; import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationDateException; import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted; import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified; @@ -88,14 +119,20 @@ import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationCommandFromApiJsonHelper; import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionApiJsonValidator; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; -import org.apache.fineract.portfolio.loanproduct.domain.*; +import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; +import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail; +import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository; +import org.apache.fineract.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy; +import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType; import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException; import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException; import org.apache.fineract.portfolio.loanproduct.serialization.LoanProductDataValidator; import org.apache.fineract.portfolio.note.domain.Note; import org.apache.fineract.portfolio.note.domain.NoteRepository; +import org.apache.fineract.portfolio.savings.data.GroupSavingsIndividualMonitoringAccountData; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; 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.joda.time.LocalDate; import org.slf4j.Logger; @@ -107,6 +144,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; @Service public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements LoanApplicationWritePlatformService { @@ -147,6 +185,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa private final GlobalConfigurationRepositoryWrapper globalConfigurationRepository; private final FineractEntityToEntityMappingRepository repository; private final FineractEntityRelationRepository fineractEntityRelationRepository; + private final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService; + private final GLIMAccountInfoWritePlatformService glimAccountInfoWritePlatformService; + private final GLIMAccountInfoRepository glimRepository; + private final LoanRepository loanRepository; + private final GSIMReadPlatformService gsimReadPlatformService; + @Autowired public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper, @@ -169,7 +213,11 @@ public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecuri final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService, final CalendarReadPlatformService calendarReadPlatformService, final GlobalConfigurationRepositoryWrapper globalConfigurationRepository, final FineractEntityToEntityMappingRepository repository, final FineractEntityRelationRepository fineractEntityRelationRepository, - final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService) { + final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, + final GLIMAccountInfoReadPlatformService glimAccountInfoReadPlatformService,final GLIMAccountInfoWritePlatformService glimAccountInfoWritePlatformService, + final GLIMAccountInfoRepository glimRepository,final LoanRepository loanRepository, + final GSIMReadPlatformService gsimReadPlatformService + ) { this.context = context; this.fromJsonHelper = fromJsonHelper; this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator; @@ -204,6 +252,11 @@ public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecuri this.globalConfigurationRepository = globalConfigurationRepository; this.repository = repository; this.fineractEntityRelationRepository = fineractEntityRelationRepository; + this.glimAccountInfoReadPlatformService=glimAccountInfoReadPlatformService; + this.glimAccountInfoWritePlatformService=glimAccountInfoWritePlatformService; + this.glimRepository=glimRepository; + this.loanRepository=loanRepository; + this.gsimReadPlatformService=gsimReadPlatformService; } private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { @@ -327,11 +380,120 @@ public CommandProcessingResult submitApplication(final JsonCommand command) { createAndPersistCalendarInstanceForInterestRecalculation(newLoanApplication); } + + // loan account number generation + String accountNumber=""; + GroupLoanIndividualMonitoringAccountData glimAccountInfo; + GroupLoanIndividualMonitoringAccount glimAccount; + + + if (newLoanApplication.isAccountNumberRequiresAutoGeneration()) { - final AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository - .findByAccountType(EntityAccountType.LOAN); - newLoanApplication.updateAccountNo(this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat)); - this.loanRepositoryWrapper.save(newLoanApplication); + + final AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(EntityAccountType.LOAN); + // if application is of GLIM type + if(newLoanApplication.getLoanType()==4) + { + Group group= this.groupRepository.findOneWithNotFoundDetection(groupId); + System.out.println("*************group id:"+groupId); + if(command.booleanObjectValueOfParameterNamed("isParentAccount")!=null) + { + System.out.println("**************isParentAccount********************"); + + //empty table check + if(glimRepository.count()!=0) + { + System.out.println("**************Parent-Not an empty table********************"); + glimAccountInfoWritePlatformService.resetIsAcceptingChild(glimRepository.findOneByIsAcceptingChild(true)); + + accountNumber=this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat); + newLoanApplication.updateAccountNo(accountNumber+"-1"); + + System.out.println("account number generated:"+newLoanApplication.getAccountNumber()); + + System.out.println("group :"+group.getId()); + glimAccountInfoWritePlatformService.addGLIMAccountInfo(accountNumber,group, command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("totalLoan"),Long.valueOf(1),true,LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue()); + newLoanApplication.setGlim(glimRepository.findOneByAccountNumber(accountNumber)); + this.loanRepositoryWrapper.save(newLoanApplication); + + + + /* (String accountNumber,BigDecimal principalAmount,Long childAccountsCount, + Boolean isAcceptingChild) */ + + } + else + { + System.out.println("************** Parent-empty table********************"); + + accountNumber=this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat); + newLoanApplication.updateAccountNo(accountNumber+"-1"); + + System.out.println("account number generated:"+newLoanApplication.getAccountNumber()); + glimAccountInfoWritePlatformService.addGLIMAccountInfo(accountNumber,group, command.bigDecimalValueOfParameterNamedDefaultToNullIfZero("totalLoan"),Long.valueOf(1),true, + LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue()); + newLoanApplication.setGlim(glimRepository.findOneByAccountNumber(accountNumber)); + this.loanRepositoryWrapper.save(newLoanApplication); + + + + } + + + + + + } + else + { + + //System.out.println("Child -current child:"+glimAccountInfoReadPlatformService.findCurrentChildAccount().getParentAccountId()); + + if(glimRepository.count()!=0) + { + System.out.println("**************Child-Not an empty table********************"); + + glimAccount=glimRepository.findOneByIsAcceptingChild(true); + accountNumber=glimAccount.getAccountNumber()+"-"+(glimAccount.getChildAccountsCount()+1); + newLoanApplication.updateAccountNo(accountNumber); + + // glimAccountInfoWritePlatformService.resetIsAcceptingChild(glimAccount); + this.glimAccountInfoWritePlatformService.incrementChildAccountCount(glimAccount); + //this.glimAccountInfoWritePlatformService.addGLIMAccountInfo(glimAccount.getAccountNumber(), glimAccount.getPrincipalAmount(), glimAccount.getChildAccountsCount()+1, true); + newLoanApplication.setGlim(glimRepository.findOneByIsAcceptingChild(true)); + this.loanRepositoryWrapper.save(newLoanApplication); + + } + else + { + System.out.println("**************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()); + newLoanApplication.setGlim(glimRepository.findOneByAccountNumber(accountNumber)); + this.loanRepositoryWrapper.save(newLoanApplication); + + + + + } + + + + + } + } + else // for applications other than GLIM + { + newLoanApplication.updateAccountNo(this.accountNumberGenerator.generate(newLoanApplication, accountNumberFormat)); + this.loanRepositoryWrapper.save(newLoanApplication); + } + + + + } final String submittedOnNote = command.stringValueOfParameterNamed("submittedOnNote"); @@ -372,16 +534,88 @@ public CommandProcessingResult submitApplication(final JsonCommand command) { this.calendarInstanceRepository.save(calendarInstance); } } - - // Save linked account information + + + // Save linked account information + SavingsAccount savingsAccount; + AccountAssociations accountAssociations; final Long savingsAccountId = command.longValueOfParameterNamed("linkAccountId"); if (savingsAccountId != null) { - final SavingsAccount savingsAccount = this.savingsAccountAssembler.assembleFrom(savingsAccountId); - 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); + if(newLoanApplication.getLoanType()==4) + { + + List childSavings= (List)gsimReadPlatformService.findGSIMAccountsByGSIMId(savingsAccountId); + //List childSavings=gsimAccount.getChildGSIMAccounts(); + List gsimClientMembers=new ArrayList(); + Map clientAccountMappings=new HashMap<>(); + for(GroupSavingsIndividualMonitoringAccountData childSaving:childSavings) + { + gsimClientMembers.add(childSaving.getClientId()); + clientAccountMappings.put(childSaving.getClientId(), childSaving.getChildAccountId()); + + + } + + + System.out.println(clientAccountMappings); + + + + System.out.println("savings account being linked "+clientAccountMappings.get(BigDecimal.valueOf(newLoanApplication.getClientId()))); + + 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()); + } + + + + + /*GroupLoanIndividualMonitoringAccount currentGlim=glimRepository.findOneByIsAcceptingChild(true); + List childGlims=(List)glimAccountInfoReadPlatformService.findglimRepaymentTemplate(currentGlim.getId()); + for(GlimRepaymentTemplate childGlim:childGlims) + { + if(!gsimClientMembers.contains(childGlim.getClientId())) + { + throw new GroupMemberNotFoundInGSIMException(childGlim.getClientId()); + } + else + { + savingsAccount = this.savingsAccountAssembler.assembleFrom((clientAccountMappings.get(childGlim.getClientId())).longValue()); + this.fromApiJsonDeserializer.validatelinkedSavingsAccount(savingsAccount, newLoanApplication); + boolean isActive = true; + AccountAssociations accountAssociations = AccountAssociations.associateSavingsAccount(newLoanApplication, + savingsAccount, AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive); + this.accountAssociationsRepository.save(accountAssociations); + } + }*/ + + + } + 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)){ @@ -1059,7 +1293,78 @@ public void validateMultiDisbursementData(final JsonCommand command, LocalDate e fromApiJsonDeserializer.validateLoanMultiDisbursementdate(element, baseDataValidator, expectedDisbursementDate, principal); if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } } - + + + @Transactional + @Override + public CommandProcessingResult approveGLIMLoanAppication(final Long loanId, final JsonCommand command) + { + + //GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId); + final Long parentLoanId=loanId; + GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findOne(parentLoanId); + List childLoans=this.loanRepository.findByGlimId(loanId); + + JsonArray approvalFormData=command.arrayOfParameterNamed("approvalFormData"); + + JsonObject jsonObject=null; + JsonCommand childCommand=null; + Long[] childLoanId=new Long[approvalFormData.size()]; + BigDecimal parentPrincipalAmount=command.bigDecimalValueOfParameterNamed("glimPrincipal"); + System.out.println("approvedLoanAmount"+command.bigDecimalValueOfParameterNamed("approvedLoanAmount")); + + + + for (int i = 0; i < approvalFormData.size(); i++) { + + jsonObject=approvalFormData.get(i).getAsJsonObject(); + + childLoanId[i]=jsonObject.get("loanId").getAsLong(); + } + + /* + Set childAccountIds=new HashSet(); + + for(Loan loan:childLoans) + { + childAccountIds.add(loan.getId()); + }*/ + + 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()) + { + System.out.println("parentPrincipalAmount"+parentPrincipalAmount); + + parentLoan.setPrincipalAmount(parentPrincipalAmount); + parentLoan.setLoanStatus(LoanStatus.APPROVED.getValue()); + glimRepository.save(parentLoan); + } + + + } + + + } + + return result; + } + + @Transactional @Override public CommandProcessingResult approveApplication(final Long loanId, final JsonCommand command) { @@ -1068,9 +1373,9 @@ public CommandProcessingResult approveApplication(final Long loanId, final JsonC LocalDate expectedDisbursementDate = null; this.loanApplicationTransitionApiJsonValidator.validateApproval(command.json()); - + final Loan loan = retrieveLoanBy(loanId); - + final JsonArray disbursementDataArray = command.arrayOfParameterNamed(LoanApiConstants.disbursementDataParameterName); expectedDisbursementDate = command.localDateValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName); @@ -1105,6 +1410,8 @@ public CommandProcessingResult approveApplication(final Long loanId, final JsonC final Map changes = loan.loanApplicationApproval(currentUser, command, disbursementDataArray, defaultLoanLifecycleStateMachine()); + + entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId, EntityTables.LOAN.getName(), StatusEnum.APPROVE.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId()); @@ -1167,6 +1474,42 @@ public CommandProcessingResult approveApplication(final Long loanId, final JsonC .with(changes) // .build(); } + + + @Transactional + @Override + public CommandProcessingResult undoGLIMLoanApplicationApproval(final Long loanId, final JsonCommand command) + { + + //GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId); + final Long parentLoanId=loanId; + GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findOne(parentLoanId); + List 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 @Override diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java index 2d124bf7f21..acef21d45cb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java @@ -144,6 +144,7 @@ public Loan assembleFrom(final Long accountId) { return loanAccount; } + public void setHelpers(final Loan loanAccount) { loanAccount.setHelpers(defaultLoanLifecycleStateMachine(), this.loanSummaryWrapper, @@ -231,7 +232,7 @@ private Loan assembleApplication(final JsonElement element, final Long clientId, final String loanTypeParameterName = "loanType"; final String loanTypeStr = this.fromApiJsonHelper.extractStringNamed(loanTypeParameterName, element); final EnumOptionData loanType = AccountEnumerations.loanType(loanTypeStr); - + if (clientId != null) { client = this.clientRepository.findOneWithNotFoundDetection(clientId); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java index 73f41cfdc20..a4094ca0161 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java @@ -21,6 +21,7 @@ import java.math.BigDecimal; import java.util.Collection; import java.util.Date; +import java.util.List; import org.apache.fineract.infrastructure.core.service.Page; import org.apache.fineract.infrastructure.core.service.SearchParameters; @@ -132,4 +133,7 @@ LoanScheduleData retrieveRepaymentSchedule(Long loanId, RepaymentScheduleRelated LoanTransactionData retrieveLoanForeclosureTemplate(final Long loanId, final LocalDate transactionDate); LoanAccountData retrieveLoanByLoanAccount(String loanAccountNumber); + + List retrieveGLIMChildLoansByGLIMParentAccount(String parentloanAccountNumber); + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index ab6c3104444..53ab439b3dd 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -217,6 +217,8 @@ public LoanAccountData retrieveOne(final Long loanId) { } } + + @Override public LoanAccountData retrieveLoanByLoanAccount(String loanAccountNumber) { @@ -232,6 +234,23 @@ public LoanAccountData retrieveLoanByLoanAccount(String loanAccountNumber) return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanAccountNumber }); } + + @Override + public List 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 public LoanScheduleData retrieveRepaymentSchedule(final Long loanId, @@ -275,6 +294,7 @@ public Collection retrieveLoanTransactions(final Long loanI return null; } } + @Override public Page retrieveAll(final SearchParameters searchParameters) { @@ -1523,6 +1543,7 @@ public Collection retrieveLoanDisbursementDetails(final Long l final String sql = "select " + rm.schema() + " where dd.loan_id=? group by dd.id order by dd.expected_disburse_date"; return this.jdbcTemplate.query(sql, rm, new Object[] { loanId }); } + private static final class LoanDisbursementDetailMapper implements RowMapper { @@ -1562,6 +1583,8 @@ public Collection retrieveLoanTermVariations(Long loanId final String sql = "select " + rm.schema() + " where tv.loan_id=? and tv.term_type=?"; return this.jdbcTemplate.query(sql, rm, new Object[] { loanId, termType }); } + + private static final class LoanTermVariationsMapper implements RowMapper { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java index 858133de78d..3ec233dfd70 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java @@ -109,4 +109,10 @@ void applyMeetingDateChanges(Calendar calendar, Collection loa 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); + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 99af8cde69b..47f3437cc90 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -127,6 +127,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; @Service @@ -173,6 +174,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy; private final CodeValueRepositoryWrapper codeValueRepository; private final CashierTransactionDataValidator cashierTransactionDataValidator; + private final GLIMAccountInfoRepository glimRepository; + private final LoanRepository loanRepository; @Autowired public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, @@ -204,7 +207,10 @@ public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext c final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy, final CodeValueRepositoryWrapper codeValueRepository, final LoanRepositoryWrapper loanRepositoryWrapper, - final CashierTransactionDataValidator cashierTransactionDataValidator) { + final CashierTransactionDataValidator cashierTransactionDataValidator, + final GLIMAccountInfoRepository glimRepository, + final LoanRepository loanRepository + ) { this.context = context; this.loanEventApiJsonValidator = loanEventApiJsonValidator; this.loanAssembler = loanAssembler; @@ -244,12 +250,48 @@ public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext c this.entityDatatableChecksWritePlatformService = entityDatatableChecksWritePlatformService; this.codeValueRepository = codeValueRepository; this.cashierTransactionDataValidator = cashierTransactionDataValidator; + this.loanRepository=loanRepository; + this.glimRepository=glimRepository; } private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { final List allowedLoanStatuses = Arrays.asList(LoanStatus.values()); return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses); } + + @Transactional + @Override + public CommandProcessingResult disburseGLIMLoan(final Long loanId, final JsonCommand command) + { + final Long parentLoanId=loanId; + GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findOne(parentLoanId); + List 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 @Override @@ -673,6 +715,42 @@ public Map bulkLoanDisbursal(final JsonCommand command, final Co 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.findOne(parentLoanId); + List 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 @Override @@ -728,6 +806,53 @@ public CommandProcessingResult undoLoanDisbursal(final Long loanId, final JsonCo .with(changes) // .build(); } + + + @Transactional + @Override + public CommandProcessingResult makeGLIMLoanRepayment(final Long loanId, final JsonCommand command) + { + + final Long parentLoanId=loanId; + + GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findOne(parentLoanId); + + 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(); + System.out.println(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 @Override diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java index 1140c4daf12..9db9794685e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/SavingsApiConstants.java @@ -80,6 +80,8 @@ public class SavingsApiConstants { // savings product and account parameters 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 externalIdParamName = "externalId"; public static final String statusParamName = "status"; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java index 05feb6374a8..7ae42f87134 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/api/SavingsAccountsApiResource.java @@ -138,6 +138,19 @@ public String submitApplication(final String apiRequestBodyAsJson) { 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 @Path("{accountId}") @@ -228,6 +241,88 @@ public String update(@PathParam("accountId") final Long accountId, final String 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) { + + /* 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")) { + System.out.println("parentAccountId "+parentAccountId); + 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.closeSavingsAccountApplication(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 @Path("{accountId}") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GSIMContainer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GSIMContainer.java new file mode 100644 index 00000000000..6a8303d7b1b --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GSIMContainer.java @@ -0,0 +1,86 @@ + +/** + * 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.SavingsAccountSummaryData; + +public class GSIMContainer +{ + + private final BigDecimal gsimId; + + private final BigDecimal groupId; + + private final String accountNumber; + + private final List childGSIMAccounts; + + private final BigDecimal parentBalance; + + private final String savingsStatus; + + + public GSIMContainer(final BigDecimal gsimId,final BigDecimal groupId,final String accountNumber,final List 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 getChildGSIMAccounts() { + return childGSIMAccounts; + } + + + public BigDecimal getparentBalance() { + return parentBalance; + } + + + public String getSavingsStatus() { + return savingsStatus; + } + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GroupSavingsIndividualMonitoringAccountData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GroupSavingsIndividualMonitoringAccountData.java new file mode 100644 index 00000000000..5e4ecec63f8 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/GroupSavingsIndividualMonitoringAccountData.java @@ -0,0 +1,128 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.fineract.portfolio.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; + } + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountConstant.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountConstant.java index 73259669919..3f7fff085a7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountConstant.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountConstant.java @@ -32,7 +32,7 @@ public class SavingsAccountConstant extends SavingsApiConstants { * parameters to match those of request parameters. */ protected static final Set 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, submittedOnDateParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GSIMRepositoy.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GSIMRepositoy.java new file mode 100644 index 00000000000..2c263cbdac4 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GSIMRepositoy.java @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.fineract.portfolio.savings.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface GSIMRepositoy extends JpaRepository, JpaSpecificationExecutor +{ + + GroupSavingsIndividualMonitoring findOneByIsAcceptingChild(boolean acceptingChild); + + GroupSavingsIndividualMonitoring findOneByAccountNumber(String accountNumber); +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GroupSavingsIndividualMonitoring.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GroupSavingsIndividualMonitoring.java new file mode 100644 index 00000000000..7efd59084af --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/GroupSavingsIndividualMonitoring.java @@ -0,0 +1,144 @@ +/** + * 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 childSaving; + + @Column(name = "savings_status_id", nullable = false) + private Integer savingsStatus; + + + + private GroupSavingsIndividualMonitoring(String accountNumber,Group group,BigDecimal parentDeposit,Long childAccountsCount, + Boolean isAcceptingChild,Integer savingsStatus) + { + this.accountNumber=accountNumber; + this.group=group; + this.parentDeposit=parentDeposit; + this.childAccountsCount=childAccountsCount; + this.isAcceptingChild=isAcceptingChild; + this.savingsStatus=savingsStatus; + + } + + public static GroupSavingsIndividualMonitoring getInstance(String accountNumber,Group group,BigDecimal parentDeposit,Long childAccountsCount, + Boolean isAcceptingChild,Integer savingsStatus) + { + return new GroupSavingsIndividualMonitoring(accountNumber,group,parentDeposit,childAccountsCount, + isAcceptingChild,savingsStatus); + } + + 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 getChildSaving() { + return childSaving; + } + + public void setChildSaving(Set childSaving) { + this.childSaving = childSaving; + } + + public Integer getSavingsStatus() { + return savingsStatus; + } + + public void setSavingsStatus(Integer savingsStatus) { + this.savingsStatus = savingsStatus; + } + + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java index d7a6298867e..ca1d5ada0ce 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java @@ -89,6 +89,7 @@ import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType; import org.apache.fineract.portfolio.group.domain.Group; +import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount; import org.apache.fineract.portfolio.savings.DepositAccountType; import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType; import org.apache.fineract.portfolio.savings.SavingsApiConstants; @@ -144,6 +145,10 @@ public class SavingsAccount extends AbstractPersistableCustom { @ManyToOne(optional = true) @JoinColumn(name = "group_id", nullable = true) protected Group group; + + @ManyToOne + @JoinColumn(name = "gsim_id", nullable = true) + private GroupSavingsIndividualMonitoring gsim; @ManyToOne @JoinColumn(name = "product_id", nullable = false) @@ -1561,8 +1566,16 @@ public Long groupId() { } return id; } + + public GroupSavingsIndividualMonitoring getGsim() { + return gsim; + } + + public void setGsim(GroupSavingsIndividualMonitoring gsim) { + this.gsim = gsim; + } - public Long hasSavingsOfficerId() { + public Long hasSavingsOfficerId() { Long id = null; if (this.savingsOfficer != null) { id = this.savingsOfficer.getId(); @@ -3037,6 +3050,7 @@ public LocalDate retrieveLastTransactionDate() { return lastransactionDate; } + public BigDecimal getSavingsHoldAmount() { return this.savingsOnHoldAmount == null ? BigDecimal.ZERO : this.savingsOnHoldAmount; } @@ -3049,4 +3063,12 @@ public void releaseAmount(BigDecimal amount) { this.savingsOnHoldAmount = getSavingsHoldAmount().subtract(amount); } + public Integer getAccountType() { + return accountType; + } + + public void setAccountType(Integer accountType) { + this.accountType = accountType; + } + } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java index 97ea3c6a1a4..3f6101796c8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java @@ -127,6 +127,8 @@ public SavingsAccount assembleFrom(final JsonCommand command, final AppUser subm Group group = null; Staff fieldOfficer = null; AccountType accountType = AccountType.INVALID; + + final Long clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element); if (clientId != null) { client = this.clientRepository.findOneWithNotFoundDetection(clientId); @@ -148,6 +150,11 @@ public SavingsAccount assembleFrom(final JsonCommand command, final AppUser subm if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); } accountType = AccountType.JLG; } + + if(((Boolean)command.booleanPrimitiveValueOfParameterNamed("isGSIM"))!=null) + { + accountType = AccountType.GSIM; + } final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element); if (fieldOfficerId != null) { @@ -299,6 +306,7 @@ public SavingsAccount assembleFrom(final Long savingsId) { account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper); return account; } + public void setHelpers(final SavingsAccount account) { account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java index df939f672e1..b06d90a47bb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java @@ -30,6 +30,9 @@ public interface SavingsAccountRepository extends JpaRepository findSavingAccountByClientId(@Param("clientId") Long clientId); + + @Query("select s_acc from SavingsAccount s_acc where s_acc.gsim.id = :gsimId") + List findSavingAccountByGsimId(@Param("gsimId") Long gsimId); @Query("select s_acc from SavingsAccount s_acc where s_acc.status = :status") List findSavingAccountByStatus(@Param("status") Integer status); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepositoryWrapper.java index 97427593b74..1f8a43c0097 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepositoryWrapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepositoryWrapper.java @@ -93,6 +93,10 @@ public boolean doNonClosedSavingAccountsExistForClient(@Param("clientId") Long c public List findByGroupId(@Param("groupId") Long groupId) { return this.repository.findByGroupId(groupId) ; } + + public List findByGsimId(@Param("gsimId") Long gsimId) { + return this.repository.findSavingAccountByGsimId(gsimId); + } //Root Entity is enough public SavingsAccount findNonClosedAccountByAccountNumber(@Param("accountNumber") String accountNumber) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMAccountActivationCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMAccountActivationCommandHandler.java new file mode 100644 index 00000000000..65e39b73ba9 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMAccountActivationCommandHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationApprovalCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationApprovalCommandHandler.java new file mode 100644 index 00000000000..a93816f7cf2 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationApprovalCommandHandler.java @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.fineract.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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationModificationCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationModificationCommandHandler.java new file mode 100644 index 00000000000..550420f52c0 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationModificationCommandHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationRejectionHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationRejectionHandler.java new file mode 100644 index 00000000000..7f9318226c5 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationRejectionHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationSubmittalCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationSubmittalCommandHandler.java new file mode 100644 index 00000000000..bce4ff64938 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMApplicationSubmittalCommandHandler.java @@ -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 = "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); + } + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMUndoApprovalCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMUndoApprovalCommandHandler.java new file mode 100644 index 00000000000..e550a003d9c --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/GSIMUndoApprovalCommandHandler.java @@ -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); + } + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformService.java new file mode 100644 index 00000000000..7b200ded557 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformService.java @@ -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 org.apache.fineract.portfolio.savings.data.GSIMContainer; +import org.apache.fineract.portfolio.savings.data.GroupSavingsIndividualMonitoringAccountData; + +public interface GSIMReadPlatformService { + + Collection findGsimAccountByParentAccountNumber(String parentAccountIds); + + Collection findGSIMAccountsByGSIMId(Long glimId); + + Collection findGSIMAccountsByGroupId(String groupId); + + Collection findGSIMAccountContainerByGroupId(Long groupId); + + Collection findGsimAccountContainerbyGsimAccountNumber(String accountNumber); + + + Collection findGsimAccountByGroupIdandAccountNo(String groupId, + String accountNo); + + GSIMContainer findGsimAccountContainerbyGsimAccountId(Long parentAccountId); + + GroupSavingsIndividualMonitoringAccountData findGSIMAccountByGSIMId(Long gsimId); + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformServiceImpl.java new file mode 100644 index 00000000000..f69c72dd27c --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GSIMReadPlatformServiceImpl.java @@ -0,0 +1,399 @@ + +/** + * 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.SavingsAccountSummaryData; +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 { + 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 { + 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 findGSIMAccountContainerByGroupId(Long groupId) { + this.context.authenticatedUser(); + Collection gsimInfo=findGSIMAccountsByGroupId(groupId+""); + + //List glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId }); + final String savingswhereClauseForGroup = " where sa.group_id = ? and sa.gsim_id is not null order by sa.status_enum ASC, sa.account_no ASC"; + + List gsimAccounts=new ArrayList(); + List childSavings; + for(GroupSavingsIndividualMonitoringAccountData gsimAccount:gsimInfo) + { + + childSavings=retrieveAccountDetails(savingswhereClauseForGroup,new Object[] { groupId}); + + gsimAccounts.add(new GSIMContainer(gsimAccount.getGsimId(),gsimAccount.getGroupId(), gsimAccount.getAccountNumber(), + childSavings, gsimAccount.getParentDeposit(),gsimAccount.getSavingsStatus())); + } + + return gsimAccounts; + } + + + @Override + public Collection findGsimAccountContainerbyGsimAccountNumber(String accountNumber) { + this.context.authenticatedUser(); + Collection gsimInfo=findGsimAccountByParentAccountNumber(accountNumber); + + //List glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId }); + final String savingswhereClauseForGroup = " where gsim.account_number = ? order by sa.status_enum ASC, sa.account_no ASC"; + + List gsimAccounts=new ArrayList(); + for(GroupSavingsIndividualMonitoringAccountData gsimAccount:gsimInfo) + { + + List 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 GSIMContainer findGsimAccountContainerbyGsimAccountId(Long parentAccountId) { + this.context.authenticatedUser(); + GroupSavingsIndividualMonitoringAccountData gsimAccount=findGSIMAccountByGSIMId(parentAccountId); + + //List glimAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroupAndLoanType, new Object[] { groupId }); + final String savingswhereClauseForGroup = " where sa.gsim_id = ? order by sa.status_enum ASC, sa.account_no ASC"; + + List childSavings=retrieveAccountDetails(savingswhereClauseForGroup,new Object[] { parentAccountId }); + + return new GSIMContainer(gsimAccount.getGsimId(),gsimAccount.getGroupId(), gsimAccount.getAccountNumber(), + childSavings, gsimAccount.getParentDeposit(),gsimAccount.getSavingsStatus()); + + } + + + + @Override + public Collection 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() + " and gsim.id=?"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { gsimId }); + } + + + @Override + public Collection 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 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 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 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 { + + final String schemaSql; + + public SavingsAccountSummaryDataMapper() { + final StringBuilder accountsSummary = new StringBuilder(); + accountsSummary.append("sa.id as id, 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 "); + + + this.schemaSql = accountsSummary.toString(); + } + + public String schema() { + return this.schemaSql; + } + + @Override + public SavingsAccountSummaryData 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 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 SavingsAccountSummaryData(id, accountNo, externalId, productId, productName, shortProductName, status, currency, accountBalance, + accountTypeData, timeline, depositTypeData, subStatus, lastActiveTransactionDate); + } + } + + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformService.java new file mode 100644 index 00000000000..0fdaec34aa6 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformService.java @@ -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 addGSIMAccountInfo(String accountNumber,Group group, BigDecimal parentDeposit, Long childAccountsCount, + Boolean isAcceptingChild,Integer savingsAccountStatus); + + void setIsAcceptingChild(GroupSavingsIndividualMonitoring gsimAccount); + + void resetIsAcceptingChild(GroupSavingsIndividualMonitoring gsimAccount); + + void incrementChildAccountCount(GroupSavingsIndividualMonitoring gsimAccount); +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformServiceImpl.java new file mode 100644 index 00000000000..54cdab23f9c --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/GroupSavingsIndividualMonitoringWritePlatformServiceImpl.java @@ -0,0 +1,93 @@ +/** + * 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 void addGSIMAccountInfo(String accountNumber,Group group,BigDecimal parentDeposit,Long childAccountsCount, + Boolean isAcceptingChild,Integer loanStatus) + { + + GroupSavingsIndividualMonitoring glimAccountInfo=GroupSavingsIndividualMonitoring.getInstance(accountNumber,group,parentDeposit,childAccountsCount, + isAcceptingChild,loanStatus); + + 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); + + } + + +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java index d23e09d140c..28eea5fc9f8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java @@ -104,4 +104,6 @@ void processPostActiveActions(SavingsAccount account, DateTimeFormatter fmt, Set CommandProcessingResult unblockDebits(Long savingsId); CommandProcessingResult releaseAmount(Long savingsId, Long transactionId); + + CommandProcessingResult gsimActivate(Long gsimId, JsonCommand command); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java index e143c09b640..3fe383bff55 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java @@ -113,6 +113,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi private final AppUserRepositoryWrapper appuserRepository; private final StandingInstructionRepository standingInstructionRepository; private final BusinessEventNotifierService businessEventNotifierService; + private final GSIMRepositoy gsimRepository; @Autowired public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, @@ -135,7 +136,8 @@ public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurit final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, final AppUserRepositoryWrapper appuserRepository, final StandingInstructionRepository standingInstructionRepository, - final BusinessEventNotifierService businessEventNotifierService) { + final BusinessEventNotifierService businessEventNotifierService, + final GSIMRepositoy gsimRepository) { this.context = context; this.savingAccountRepositoryWrapper = savingAccountRepositoryWrapper; this.savingsAccountTransactionRepository = savingsAccountTransactionRepository; @@ -161,6 +163,40 @@ public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurit this.appuserRepository = appuserRepository; this.standingInstructionRepository = standingInstructionRepository; this.businessEventNotifierService = businessEventNotifierService; + this.gsimRepository=gsimRepository; + } + + + @Transactional + @Override + public CommandProcessingResult gsimActivate(final Long gsimId, final JsonCommand command) { + + Long parentSavingId=gsimId; + GroupSavingsIndividualMonitoring parentSavings=gsimRepository.findOne(parentSavingId); + List 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 @@ -239,6 +275,12 @@ public CommandProcessingResult deposit(final Long savingsId, final JsonCommand c this.context.authenticatedUser(); this.savingsAccountTransactionDataValidator.validate(command); + boolean isGsim=false; + + if( this.savingAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsId).getGsim()!=null) + { + isGsim=true; + } final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); checkClientOrGroupActive(account); @@ -254,6 +296,14 @@ public CommandProcessingResult deposit(final Long savingsId, final JsonCommand c boolean isRegularTransaction = true; final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction); + if(isGsim && (deposit.getId()!=null)) + { + GroupSavingsIndividualMonitoring gsim=gsimRepository.findOne(account.getGsim().getId()); + BigDecimal currentBalance=gsim.getParentDeposit().add(transactionAmount); + gsim.setParentDeposit(currentBalance); + gsimRepository.save(gsim); + + } return new CommandProcessingResultBuilder() // .withEntityId(deposit.getId()) // @@ -276,6 +326,13 @@ private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransact public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command) { this.savingsAccountTransactionDataValidator.validate(command); + + boolean isGsim=false; + + if( this.savingAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsId).getGsim()!=null) + { + isGsim=true; + } final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount"); @@ -297,6 +354,15 @@ public CommandProcessingResult withdrawal(final Long savingsId, final JsonComman isRegularTransaction, isApplyWithdrawFee, isInterestTransfer, isWithdrawBalance); final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate, transactionAmount, paymentDetail, transactionBooleanValues); + + if(isGsim && (withdrawal.getId()!=null)) + { + GroupSavingsIndividualMonitoring gsim=gsimRepository.findOne(account.getGsim().getId()); + BigDecimal currentBalance=gsim.getParentDeposit().subtract(transactionAmount); + gsim.setParentDeposit(currentBalance); + gsimRepository.save(gsim); + + } return new CommandProcessingResultBuilder() // .withEntityId(withdrawal.getId()) // @@ -356,6 +422,7 @@ public CommandProcessingResult calculateInterest(final Long savingsId) { .withSavingsId(savingsId) // .build(); } + @Override public CommandProcessingResult postInterest(final JsonCommand command) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformService.java index fa2dbfac531..fefc2fea721 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformService.java @@ -39,4 +39,14 @@ public interface SavingsApplicationProcessWritePlatformService { CommandProcessingResult applicantWithdrawsFromApplication(Long savingsId, JsonCommand command); 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); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java index 5cabe1ba757..9099f1d47ac 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java @@ -20,7 +20,14 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; -import java.util.*; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import javax.persistence.PersistenceException; @@ -56,15 +63,29 @@ import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService; import org.apache.fineract.portfolio.group.domain.Group; 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.GroupNotActiveException; import org.apache.fineract.portfolio.group.exception.GroupNotFoundException; +import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount; +import org.apache.fineract.portfolio.loanaccount.domain.Loan; +import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus; import org.apache.fineract.portfolio.note.domain.Note; import org.apache.fineract.portfolio.note.domain.NoteRepository; import org.apache.fineract.portfolio.savings.SavingsApiConstants; import org.apache.fineract.portfolio.savings.data.SavingsAccountDataDTO; import org.apache.fineract.portfolio.savings.data.SavingsAccountDataValidator; -import org.apache.fineract.portfolio.savings.domain.*; +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.SavingsAccountAssembler; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountCharge; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountChargeAssembler; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountDomainService; +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.SavingsProductRepository; import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException; import org.apache.fineract.useradministration.domain.AppUser; import org.slf4j.Logger; @@ -74,6 +95,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + @Service public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl implements SavingsApplicationProcessWritePlatformService { @@ -97,6 +122,10 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository; private final BusinessEventNotifierService businessEventNotifierService; private final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService; + private final GSIMRepositoy gsimRepository; + private final GroupRepositoryWrapper groupRepositoryWrapper; + private final GroupSavingsIndividualMonitoringWritePlatformService gsimWritePlatformService; + @Autowired public SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, @@ -111,7 +140,9 @@ public SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl(final Plat final SavingsAccountWritePlatformService savingsAccountWritePlatformService, final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final BusinessEventNotifierService businessEventNotifierService, - final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService) { + final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, + final GSIMRepositoy gsimRepository,final GroupRepositoryWrapper groupRepositoryWrapper, + final GroupSavingsIndividualMonitoringWritePlatformService gsimWritePlatformService) { this.context = context; this.savingAccountRepository = savingAccountRepository; this.savingAccountAssembler = savingAccountAssembler; @@ -130,6 +161,9 @@ public SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl(final Plat this.savingsAccountWritePlatformService = savingsAccountWritePlatformService; this.businessEventNotifierService = businessEventNotifierService ; this.entityDatatableChecksWritePlatformService = entityDatatableChecksWritePlatformService; + this.gsimRepository=gsimRepository; + this.groupRepositoryWrapper=groupRepositoryWrapper; + this.gsimWritePlatformService=gsimWritePlatformService; } /* @@ -158,6 +192,24 @@ private void handleDataIntegrityIssues(final JsonCommand command, final Throwabl logger.error(dve.getMessage(), dve); 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"); + + for(JsonElement gsimApplication:gsimApplications) + { + result=submitApplication(JsonCommand.fromExistingCommand(command, gsimApplication)); + } + + return result; + } + + @Transactional @Override @@ -165,12 +217,125 @@ public CommandProcessingResult submitApplication(final JsonCommand command) { try { this.savingsAccountDataValidator.validateForSubmit(command.json()); final AppUser submittedBy = this.context.authenticatedUser(); + + + final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command, submittedBy); this.savingAccountRepository.save(account); - - generateAccountNumber(account); - + + + + String accountNumber=""; + + GroupSavingsIndividualMonitoring gsimAccount=null; + + // generateAccountNumber(account); + // gsim + if (account.isAccountNumberRequiresAutoGeneration()) { + + final AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(EntityAccountType.SAVINGS); + // if application is of GLIM type + if(account.getAccountType()==5) + { + final Long groupId = command.longValueOfParameterNamed("groupId"); + + Group group= this.groupRepositoryWrapper.findOneWithNotFoundDetection(groupId); + //System.out.println("*************group id:"+groupId); + if(command.booleanObjectValueOfParameterNamed("isParentAccount")!=null) + { + System.out.println("**************isParentAccount********************"); + + //empty table check + if(gsimRepository.count()!=0) + { + System.out.println("**************Parent-Not an empty table********************"); + gsimWritePlatformService.resetIsAcceptingChild(gsimRepository.findOneByIsAcceptingChild(true)); + + accountNumber=this.accountNumberGenerator.generate(account, accountNumberFormat); + account.updateAccountNo(accountNumber+"-1"); + + System.out.println("account number generated:"+account.getAccountNumber()); + + System.out.println("group :"+group.getId()); + gsimWritePlatformService.addGSIMAccountInfo(accountNumber,group,BigDecimal.ZERO ,Long.valueOf(1),true,SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue()); + account.setGsim(gsimRepository.findOneByAccountNumber(accountNumber)); + this.savingAccountRepository.save(account); + + + } + else + { + System.out.println("************** Parent-empty table********************"); + + accountNumber=this.accountNumberGenerator.generate(account, accountNumberFormat); + account.updateAccountNo(accountNumber+"-1"); + + System.out.println("account number generated:"+account.getAccountNumber()); + gsimWritePlatformService.addGSIMAccountInfo(accountNumber,group, BigDecimal.ZERO ,Long.valueOf(1),true, + SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue()); + account.setGsim(gsimRepository.findOneByAccountNumber(accountNumber)); + this.savingAccountRepository.save(account); + + + + } + + + + + + } + else + { + + + + if(gsimRepository.count()!=0) + { + System.out.println("**************Child-Not an empty table********************"); + + gsimAccount=gsimRepository.findOneByIsAcceptingChild(true); + accountNumber=gsimAccount.getAccountNumber()+"-"+(gsimAccount.getChildAccountsCount()+1); + account.updateAccountNo(accountNumber); + this.gsimWritePlatformService.incrementChildAccountCount(gsimAccount); + account.setGsim(gsimRepository.findOneByIsAcceptingChild(true)); + this.savingAccountRepository.save(account); + + } + else + { + System.out.println("**************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()); + account.setGsim(gsimRepository.findOneByAccountNumber(accountNumber)); + this.savingAccountRepository.save(account); + + + + + } + + + + + } + } + else // for applications other than GSIM + { + generateAccountNumber(account); + } + + + + + } + + + // end of gsim final Long savingsId = account.getId(); if(command.parameterExists(SavingsApiConstants.datatables)){ this.entityDatatableChecksWritePlatformService.saveDatatables(StatusEnum.CREATE.getCode().longValue(), @@ -210,6 +375,37 @@ private void generateAccountNumber(final SavingsAccount account) { this.savingAccountRepository.save(account); } } + + + @Transactional + @Override + public CommandProcessingResult modifyGSIMApplication(final Long gsimId, final JsonCommand command) { + + final Long parentSavingId=gsimId; + GroupSavingsIndividualMonitoring parentSavings=gsimRepository.findOne(parentSavingId); + List childSavings=this.savingAccountRepository.findByGsimId(parentSavingId); + + CommandProcessingResult result=null; + int count=0; + for(SavingsAccount account:childSavings) + { + result=modifyApplication(account.getId(), command); + + /*if(result!=null) + { + count++; + if(count==parentSavings.getChildAccountsCount()) + { + parentSavings.setSavingsStatus(SavingsAccountStatusType.REJECTED.getValue()); + gsimRepository.save(parentSavings); + } + }*/ + + + } + + return result; + } @Transactional @Override @@ -335,6 +531,45 @@ public CommandProcessingResult deleteApplication(final Long savingsId) { .withGroupId(account.groupId()) // .withSavingsId(savingsId) // .build(); + } + + @Transactional + @Override + public CommandProcessingResult approveGSIMApplication(final Long gsimId, final JsonCommand command) { + + + + //GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId); + Long parentSavingId=gsimId; + GroupSavingsIndividualMonitoring parentSavings=gsimRepository.findOne(parentSavingId); + List 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 @@ -378,6 +613,36 @@ public CommandProcessingResult approveApplication(final Long savingsId, final Js .with(changes) // .build(); } + + @Transactional + @Override + public CommandProcessingResult undoGSIMApplicationApproval(final Long gsimId, final JsonCommand command) + { + final Long parentSavingId=gsimId; + GroupSavingsIndividualMonitoring parentSavings=gsimRepository.findOne(parentSavingId); + List 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 @Override @@ -412,6 +677,36 @@ public CommandProcessingResult undoApplicationApproval(final Long savingsId, fin .with(changes) // .build(); } + + @Transactional + @Override + public CommandProcessingResult rejectGSIMApplication(final Long gsimId, final JsonCommand command) { + + final Long parentSavingId=gsimId; + GroupSavingsIndividualMonitoring parentSavings=gsimRepository.findOne(parentSavingId); + List 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 @Override diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V7001__GLIM_migration_script.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V7001__GLIM_migration_script.sql new file mode 100644 index 00000000000..06b59f07170 --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V7001__GLIM_migration_script.sql @@ -0,0 +1,56 @@ +-- +-- 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); + + -- 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` bigint(20) NOT NULL DEFAULT '0', + `child_accounts_count` int(11) NOT NULL, + `accepting_child` tinyint(4) NOT NULL DEFAULT '0', + `loan_status_id` smallint(5) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `glim_account_no_UNIQUE` (`account_number`), + KEY `FK_group_id` (`group_id`), + CONSTRAINT `FK_group_id` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; + + -- 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`); + + + + + + \ No newline at end of file diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V7002__GSIM_migration_script.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V7002__GSIM_migration_script.sql new file mode 100644 index 00000000000..9081d3fec89 --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V7002__GSIM_migration_script.sql @@ -0,0 +1,56 @@ +-- +-- 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); + + +-- 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` bigint(20) NOT NULL DEFAULT '0', + `child_accounts_count` int(11) NOT NULL, + `accepting_child` tinyint(4) NOT NULL DEFAULT '0', + `savings_status_id` smallint(5) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `gsim_account_no_UNIQUE` (`account_number`), + KEY `FK_gsim_group_id` (`group_id`), + CONSTRAINT `FK_gsim_group_id` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + + -- 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`); +