From 6646ab57db30223dcca4472ee5cae205e5533093 Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Mon, 24 Nov 2014 12:13:04 +0530 Subject: [PATCH 1/2] MIFOSX-1675 : Added support to capture guarantor funding details for loan account --- .../service/CommandWrapperBuilder.java | 3 +- .../core/api/ApiParameterHelper.java | 10 + .../account/data/PortfolioAccountDTO.java | 65 ++++++ .../account/domain/AccountAssociations.java | 15 +- ...ntAssociationsReadPlatformServiceImpl.java | 43 ++-- ...countTransfersReadPlatformServiceImpl.java | 11 +- .../PortfolioAccountReadPlatformService.java | 5 +- ...rtfolioAccountReadPlatformServiceImpl.java | 34 ++- ...ingInstructionReadPlatformServiceImpl.java | 11 +- .../loanaccount/api/LoansApiResource.java | 12 +- .../guarantor/GuarantorConstants.java | 2 +- .../guarantor/api/GuarantorsApiResource.java | 47 ++++- .../guarantor/command/GuarantorCommand.java | 27 ++- .../guarantor/data/GuarantorData.java | 34 ++- .../guarantor/data/GuarantorFundingData.java | 47 +++++ .../data/GuarantorTransactionData.java | 31 +++ .../guarantor/domain/Guarantor.java | 130 +++++++----- .../domain/GuarantorFundStatusType.java | 78 +++++++ .../domain/GuarantorFundingDetails.java | 76 +++++++ .../domain/GuarantorFundingTransaction.java | 32 +++ .../exception/GuarantorNotFoundException.java | 11 +- .../exception/InvalidGuarantorException.java | 5 + .../DeleteGuarantorCommandHandler.java | 2 +- ...arantorCommandFromApiJsonDeserializer.java | 17 +- .../service/GuarantorEnumerations.java | 11 + .../GuarantorReadPlatformServiceImpl.java | 197 +++++++++++++++--- .../GuarantorWritePlatformService.java | 2 +- ...ritePlatformServiceJpaRepositoryIImpl.java | 145 +++++++++---- ...WritePlatformServiceJpaRepositoryImpl.java | 6 +- .../service/LoanReadPlatformService.java | 2 + .../service/LoanReadPlatformServiceImpl.java | 6 + .../DepositAccountOnHoldTransactionType.java | 61 ++++++ .../DepositAccountOnHoldTransactionData.java | 34 +++ .../DepositAccountOnHoldTransaction.java | 38 ++++ ...WritePlatformServiceJpaRepositoryImpl.java | 9 +- .../savings/service/SavingsEnumerations.java | 25 +++ ...antor_on_hold_fund_changes_for_account.sql | 47 +++++ 37 files changed, 1132 insertions(+), 199 deletions(-) create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundStatusType.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositAccountOnHoldTransactionType.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java create mode 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java create mode 100755 mifosng-provider/src/main/resources/sql/migrations/core_db/V219__guarantor_on_hold_fund_changes_for_account.sql diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index 9f15a214e..a9c83213b 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -198,10 +198,11 @@ public class CommandWrapperBuilder { return this; } - public CommandWrapperBuilder deleteGuarantor(final Long loanId, final Long guarantorId) { + public CommandWrapperBuilder deleteGuarantor(final Long loanId, final Long guarantorId, final Long guarantorFundingId) { this.actionName = "DELETE"; this.entityName = "GUARANTOR"; this.entityId = guarantorId; + this.subentityId = guarantorFundingId; this.loanId = loanId; this.href = "/loans/" + loanId + "/guarantors/" + guarantorId; return this; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java index b64e6fa81..8118b87ec 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java @@ -55,6 +55,16 @@ public class ApiParameterHelper { return fields; } + public static void excludeAssociationsForResponseIfProvided(final MultivaluedMap queryParams, Set fields) { + String commaSerperatedParameters = ""; + if (queryParams.getFirst("exclude") != null) { + commaSerperatedParameters = queryParams.getFirst("exclude"); + if (StringUtils.isNotBlank(commaSerperatedParameters)) { + fields.removeAll(new HashSet<>(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*")))); + } + } + } + public static boolean prettyPrint(final MultivaluedMap queryParams) { boolean prettyPrint = false; if (queryParams.getFirst("pretty") != null) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java new file mode 100755 index 000000000..2e453d950 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java @@ -0,0 +1,65 @@ +package org.mifosplatform.portfolio.account.data; + +public class PortfolioAccountDTO { + + private final Integer accountTypeId; + private final Long clientId; + private final String currencyCode; + private final long[] accountStatus; + private final Integer depositType; + private final boolean excludeOverDraftAccounts; + + public PortfolioAccountDTO(final Integer accountTypeId, final Long clientId, final String currencyCode, final long[] accountStatus, + final Integer depositType, final boolean excludeOverDraftAccounts) { + this.accountTypeId = accountTypeId; + this.clientId = clientId; + this.currencyCode = currencyCode; + this.accountStatus = accountStatus; + this.depositType = depositType; + this.excludeOverDraftAccounts = excludeOverDraftAccounts; + } + + public PortfolioAccountDTO(final Integer accountTypeId, final Long clientId, final long[] accountStatus) { + this.accountTypeId = accountTypeId; + this.clientId = clientId; + this.currencyCode = null; + this.accountStatus = accountStatus; + this.depositType = null; + this.excludeOverDraftAccounts = false; + } + + public PortfolioAccountDTO(final Integer accountTypeId, final Long clientId, final String currencyCode, final long[] accountStatus, + final Integer depositType) { + this.accountTypeId = accountTypeId; + this.clientId = clientId; + this.currencyCode = currencyCode; + this.accountStatus = accountStatus; + this.depositType = depositType; + this.excludeOverDraftAccounts = false; + } + + public Integer getAccountTypeId() { + return this.accountTypeId; + } + + public Long getClientId() { + return this.clientId; + } + + public String getCurrencyCode() { + return this.currencyCode; + } + + public long[] getAccountStatus() { + return this.accountStatus; + } + + public Integer getDepositType() { + return this.depositType; + } + + public boolean isExcludeOverDraftAccounts() { + return this.excludeOverDraftAccounts; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountAssociations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountAssociations.java index 0adb1e575..045b0c9d9 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountAssociations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/domain/AccountAssociations.java @@ -42,25 +42,30 @@ public class AccountAssociations extends AbstractPersistable { @Column(name = "association_type_enum", nullable = false) private Integer associationType; + @SuppressWarnings("unused") + @Column(name = "is_active", nullable = false) + private boolean active = true; + protected AccountAssociations() {} private AccountAssociations(final Loan loanAccount, final SavingsAccount savingsAccount, final Loan linkedLoanAccount, - final SavingsAccount linkedSavingsAccount, final Integer associationType) { + final SavingsAccount linkedSavingsAccount, final Integer associationType, boolean active) { this.loanAccount = loanAccount; this.savingsAccount = savingsAccount; this.linkedLoanAccount = linkedLoanAccount; this.linkedSavingsAccount = linkedSavingsAccount; this.associationType = associationType; + this.active = active; } public static AccountAssociations associateSavingsAccount(final Loan loan, final SavingsAccount savingsAccount, - final Integer associationType) { - return new AccountAssociations(loan, null, null, savingsAccount, associationType); + final Integer associationType, boolean isActive) { + return new AccountAssociations(loan, null, null, savingsAccount, associationType, isActive); } public static AccountAssociations associateSavingsAccount(final SavingsAccount savingsAccount, - final SavingsAccount linkedSavingsAccount, final Integer associationType) { - return new AccountAssociations(null, savingsAccount, null, linkedSavingsAccount, associationType); + final SavingsAccount linkedSavingsAccount, final Integer associationType, boolean isActive) { + return new AccountAssociations(null, savingsAccount, null, linkedSavingsAccount, associationType, isActive); } public SavingsAccount linkedSavingsAccount() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java index e205be363..3107ec413 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountAssociationsReadPlatformServiceImpl.java @@ -9,6 +9,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.util.List; +import java.util.Map; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.service.RoutingDataSource; @@ -85,28 +86,38 @@ public class AccountAssociationsReadPlatformServiceImpl implements AccountAssoci @Override public boolean isLinkedWithAnyActiveAccount(final Long savingsId) { boolean hasActiveAccount = false; - final String sql = "select loanAccount.loan_status_id as status from m_portfolio_account_associations aa " - + "left join m_loan loanAccount on loanAccount.id = aa.loan_account_id " + "where aa.linked_savings_account_id = ?"; - final List statusList = this.jdbcTemplate.queryForList(sql, Integer.class, savingsId); - for (final Integer status : statusList) { - if (status != null) { - final LoanStatus loanStatus = LoanStatus.fromInt(status); - if (loanStatus.isActiveOrAwaitingApprovalOrDisbursal() || loanStatus.isUnderTransfer()) { return true; } - } - } - - final String savsql = "select savingAccount.status_enum as status from m_portfolio_account_associations aa " + final String sql1 = "select aa.is_active as active,aa.association_type_enum as type, loanAccount.loan_status_id as loanStatus," + + "savingAccount.status_enum as savingsStatus from m_portfolio_account_associations aa " + + "left join m_loan loanAccount on loanAccount.id = aa.loan_account_id " + "left join m_savings_account savingAccount on savingAccount.id = aa.savings_account_id " + "where aa.linked_savings_account_id = ?"; - final List savstatusList = this.jdbcTemplate.queryForList(savsql, Integer.class, savingsId); - for (final Integer status : savstatusList) { - if (status != null) { - final SavingsAccountStatusType saveStatus = SavingsAccountStatusType.fromInt(status); - if (saveStatus.isActiveOrAwaitingApprovalOrDisbursal() || saveStatus.isUnderTransfer()) { return true; } + final List> statusList = this.jdbcTemplate.queryForList(sql1, savingsId); + for (final Map statusMap : statusList) { + AccountAssociationType associationType = AccountAssociationType.fromInt((Integer) statusMap.get("type")); + if (!associationType.isLinkedAccountAssociation() && (Boolean) statusMap.get("active")) { + hasActiveAccount = true; + break; + } + + if (statusMap.get("loanStatus") != null) { + final LoanStatus loanStatus = LoanStatus.fromInt((Integer) statusMap.get("loanStatus")); + if (loanStatus.isActiveOrAwaitingApprovalOrDisbursal() || loanStatus.isUnderTransfer()) { + hasActiveAccount = true; + break; + } + } + + if (statusMap.get("savingsStatus") != null) { + final SavingsAccountStatusType saveStatus = SavingsAccountStatusType.fromInt((Integer) statusMap.get("savingsStatus")); + if (saveStatus.isActiveOrAwaitingApprovalOrDisbursal() || saveStatus.isUnderTransfer()) { + hasActiveAccount = true; + break; + } } } + return hasActiveAccount; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java index c617d6530..445ae4180 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java @@ -25,6 +25,7 @@ import org.mifosplatform.organisation.office.data.OfficeData; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.portfolio.account.PortfolioAccountType; import org.mifosplatform.portfolio.account.data.AccountTransferData; +import org.mifosplatform.portfolio.account.data.PortfolioAccountDTO; import org.mifosplatform.portfolio.account.data.PortfolioAccountData; import org.mifosplatform.portfolio.account.domain.AccountTransferType; import org.mifosplatform.portfolio.account.exception.AccountTransferNotFoundException; @@ -124,8 +125,9 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers if (mostRelevantFromAccountType == 1) { loanStatus = new long[] { 300, 700 }; } - fromAccountOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(mostRelevantFromAccountType, - mostRelevantFromClientId, loanStatus); + PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(mostRelevantFromAccountType, mostRelevantFromClientId, + loanStatus); + fromAccountOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO); } Collection fromOfficeOptions = null; @@ -178,8 +180,9 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers final String currencyCode = excludeThisAccountFromOptions != null ? excludeThisAccountFromOptions.currencyCode() : null; - Collection accountOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(toAccountType, - toClientId, currencyCode, null, null); + PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(toAccountType, toClientId, currencyCode, null, null); + Collection accountOptions = this.portfolioAccountReadPlatformService + .retrieveAllForLookup(portfolioAccountDTO); if (!CollectionUtils.isEmpty(accountOptions)) { accountOptions.remove(excludeThisAccountFromOptions); } else { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformService.java index 9c370b443..a89259ea1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformService.java @@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.account.service; import java.util.Collection; +import org.mifosplatform.portfolio.account.data.PortfolioAccountDTO; import org.mifosplatform.portfolio.account.data.PortfolioAccountData; public interface PortfolioAccountReadPlatformService { @@ -15,7 +16,5 @@ public interface PortfolioAccountReadPlatformService { PortfolioAccountData retrieveOne(Long accountId, Integer accountTypeId, String currencyCode); - Collection retrieveAllForLookup(Integer toAccountType, Long toClientId, long[] accountStatus); - - Collection retrieveAllForLookup(Integer toAccountType, Long toClientId, String currencyCode, long[] accountStatus, Integer depositType); + Collection retrieveAllForLookup(final PortfolioAccountDTO portfolioAccountDTO); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java index b60f2a513..af99ac8b2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java @@ -16,6 +16,7 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.portfolio.account.PortfolioAccountType; +import org.mifosplatform.portfolio.account.data.PortfolioAccountDTO; import org.mifosplatform.portfolio.account.data.PortfolioAccountData; import org.mifosplatform.portfolio.account.exception.AccountTransferNotFoundException; import org.springframework.beans.factory.annotation.Autowired; @@ -86,36 +87,29 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount } @Override - public Collection retrieveAllForLookup(final Integer accountTypeId, final Long clientId, - final long[] accountStatus) { - return retrieveAllForLookup(accountTypeId, clientId, null, accountStatus, null); - } - - @Override - public Collection retrieveAllForLookup(final Integer accountTypeId, final Long clientId, - final String currencyCode, final long[] accountStatus, final Integer depositType) { + public Collection retrieveAllForLookup(final PortfolioAccountDTO portfolioAccountDTO) { List sqlParams = new ArrayList<>(); - sqlParams.add(clientId); + sqlParams.add(portfolioAccountDTO.getClientId()); Collection accounts = null; String sql = null; String defaultAccountStatus = "300"; - if (accountStatus != null) { - for (final long status : accountStatus) { + if (portfolioAccountDTO.getAccountStatus() != null) { + for (final long status : portfolioAccountDTO.getAccountStatus()) { defaultAccountStatus += ", " + status; } defaultAccountStatus = defaultAccountStatus.substring(defaultAccountStatus.indexOf(",") + 1); } - final PortfolioAccountType accountType = PortfolioAccountType.fromInt(accountTypeId); + final PortfolioAccountType accountType = PortfolioAccountType.fromInt(portfolioAccountDTO.getAccountTypeId()); switch (accountType) { case INVALID: break; case LOAN: sql = "select " + this.loanAccountMapper.schema() + " where la.client_id = ? and la.loan_status_id in (" + defaultAccountStatus.toString() + ")"; - if (currencyCode != null) { + if (portfolioAccountDTO.getCurrencyCode() != null) { sql += " and la.currency_code = ?"; - sqlParams.add(currencyCode); + sqlParams.add(portfolioAccountDTO.getCurrencyCode()); } accounts = this.jdbcTemplate.query(sql, this.loanAccountMapper, sqlParams.toArray()); @@ -123,14 +117,18 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount case SAVINGS: sql = "select " + this.savingsAccountMapper.schema() + " where sa.client_id = ? and sa.status_enum in (" + defaultAccountStatus.toString() + ")"; - if (currencyCode != null) { + if (portfolioAccountDTO.getCurrencyCode() != null) { sql += " and sa.currency_code = ?"; - sqlParams.add(currencyCode); + sqlParams.add(portfolioAccountDTO.getCurrencyCode()); } - if (depositType != null) { + if (portfolioAccountDTO.getDepositType() != null) { sql += " and sa.deposit_type_enum = ?"; - sqlParams.add(depositType); + sqlParams.add(portfolioAccountDTO.getDepositType()); + } + + if(portfolioAccountDTO.isExcludeOverDraftAccounts()){ + sql += " and sa.allow_overdraft = 0"; } accounts = this.jdbcTemplate.query(sql, this.savingsAccountMapper, sqlParams.toArray()); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java index 91fddefc7..5bb0d6dc2 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java @@ -31,6 +31,7 @@ import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.organisation.office.data.OfficeData; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.portfolio.account.PortfolioAccountType; +import org.mifosplatform.portfolio.account.data.PortfolioAccountDTO; import org.mifosplatform.portfolio.account.data.PortfolioAccountData; import org.mifosplatform.portfolio.account.data.StandingInstructionDTO; import org.mifosplatform.portfolio.account.data.StandingInstructionData; @@ -152,8 +153,9 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr if (mostRelevantFromAccountType == 1) { loanStatus = new long[] { 300, 700 }; } - fromAccountOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(mostRelevantFromAccountType, - mostRelevantFromClientId, loanStatus); + PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(mostRelevantFromAccountType, mostRelevantFromClientId, + loanStatus); + fromAccountOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO); } Collection fromOfficeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown(); @@ -228,8 +230,9 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr final String currencyCode = excludeThisAccountFromOptions != null ? excludeThisAccountFromOptions.currencyCode() : null; - Collection accountOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(toAccountType, - toClientId, currencyCode, null, null); + PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(toAccountType, toClientId, currencyCode, null, null); + Collection accountOptions = this.portfolioAccountReadPlatformService + .retrieveAllForLookup(portfolioAccountDTO); if (!CollectionUtils.isEmpty(accountOptions)) { accountOptions.remove(excludeThisAccountFromOptions); } else { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java index b1c44fecd..3fdf7e176 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java @@ -46,6 +46,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.portfolio.account.PortfolioAccountType; +import org.mifosplatform.portfolio.account.data.PortfolioAccountDTO; import org.mifosplatform.portfolio.account.data.PortfolioAccountData; import org.mifosplatform.portfolio.account.service.AccountAssociationsReadPlatformService; import org.mifosplatform.portfolio.account.service.PortfolioAccountReadPlatformService; @@ -306,9 +307,9 @@ public class LoansApiResource { currencyCode = currencyData.code(); } final long[] accountStatus = { SavingsAccountStatusType.ACTIVE.getValue() }; - accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup( - PortfolioAccountType.SAVINGS.getValue(), clientId, currencyCode, accountStatus, - DepositAccountType.SAVINGS_DEPOSIT.getValue()); + PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(PortfolioAccountType.SAVINGS.getValue(), clientId, + currencyCode, accountStatus, DepositAccountType.SAVINGS_DEPOSIT.getValue()); + accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO); } @@ -362,6 +363,8 @@ public class LoansApiResource { "charges", "guarantors", "collateral", "notes", "linkedAccount", "multiDisburseDetails")); } + ApiParameterHelper.excludeAssociationsForResponseIfProvided(uriInfo.getQueryParameters(), associationParameters); + if (associationParameters.contains("guarantors")) { mandatoryResponseParameters.add("guarantors"); guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId); @@ -491,8 +494,9 @@ public class LoansApiResource { currencyCode = currencyData.code(); } final long[] accountStatus = { SavingsAccountStatusType.ACTIVE.getValue() }; - accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(PortfolioAccountType.SAVINGS.getValue(), + PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(PortfolioAccountType.SAVINGS.getValue(), loanBasicDetails.clientId(), currencyCode, accountStatus, DepositAccountType.SAVINGS_DEPOSIT.getValue()); + accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO); if (!associationParameters.contains("linkedAccount")) { mandatoryResponseParameters.add("linkedAccount"); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/GuarantorConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/GuarantorConstants.java index acc73e2d1..dfed1e137 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/GuarantorConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/GuarantorConstants.java @@ -19,7 +19,7 @@ public class GuarantorConstants { LOAN_ID("loanId"), CLIENT_RELATIONSHIP_TYPE_ID("clientRelationshipTypeId"), GUARANTOR_TYPE_ID("guarantorTypeId"), ENTITY_ID( "entityId"), FIRSTNAME("firstname"), LASTNAME("lastname"), ADDRESS_LINE_1("addressLine1"), ADDRESS_LINE_2("addressLine2"), CITY( "city"), STATE("state"), ZIP("zip"), COUNTRY("country"), MOBILE_NUMBER("mobileNumber"), PHONE_NUMBER("housePhoneNumber"), COMMENT( - "comment"), DATE_OF_BIRTH("dob"); + "comment"), DATE_OF_BIRTH("dob"), AMOUNT("amount"), SAVINGS_ID("savingsId"); private final String value; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/api/GuarantorsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/api/GuarantorsApiResource.java index 8678365df..b586291af 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/api/GuarantorsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/api/GuarantorsApiResource.java @@ -19,6 +19,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; @@ -34,11 +35,17 @@ import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.account.PortfolioAccountType; +import org.mifosplatform.portfolio.account.api.AccountTransfersApiConstants; +import org.mifosplatform.portfolio.account.data.PortfolioAccountDTO; +import org.mifosplatform.portfolio.account.data.PortfolioAccountData; +import org.mifosplatform.portfolio.account.service.PortfolioAccountReadPlatformService; import org.mifosplatform.portfolio.loanaccount.guarantor.GuarantorConstants; import org.mifosplatform.portfolio.loanaccount.guarantor.data.GuarantorData; import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorType; import org.mifosplatform.portfolio.loanaccount.guarantor.service.GuarantorEnumerations; import org.mifosplatform.portfolio.loanaccount.guarantor.service.GuarantorReadPlatformService; +import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -61,18 +68,24 @@ public class GuarantorsApiResource { private final ApiRequestParameterHelper apiRequestParameterHelper; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PlatformSecurityContext context; + private final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService; + private final LoanReadPlatformService loanReadPlatformService; @Autowired public GuarantorsApiResource(final PlatformSecurityContext context, final GuarantorReadPlatformService guarantorReadPlatformService, final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, - final CodeValueReadPlatformService codeValueReadPlatformService) { + final CodeValueReadPlatformService codeValueReadPlatformService, + final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService, + final LoanReadPlatformService loanReadPlatformService) { this.context = context; this.apiRequestParameterHelper = apiRequestParameterHelper; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; this.apiJsonSerializerService = toApiJsonSerializer; this.guarantorReadPlatformService = guarantorReadPlatformService; this.codeValueReadPlatformService = codeValueReadPlatformService; + this.portfolioAccountReadPlatformService = portfolioAccountReadPlatformService; + this.loanReadPlatformService = loanReadPlatformService; } @GET @@ -85,7 +98,9 @@ public class GuarantorsApiResource { final List guarantorTypeOptions = GuarantorEnumerations.guarantorType(GuarantorType.values()); final Collection allowedClientRelationshipTypes = this.codeValueReadPlatformService .retrieveCodeValuesByCode(GuarantorConstants.GUARANTOR_RELATIONSHIP_CODE_NAME); - final GuarantorData guarantorData = GuarantorData.template(guarantorTypeOptions, allowedClientRelationshipTypes); + final Collection accountLinkingOptions = null; + final GuarantorData guarantorData = GuarantorData.template(guarantorTypeOptions, allowedClientRelationshipTypes, + accountLinkingOptions); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.apiJsonSerializerService.serialize(settings, guarantorData, RESPONSE_DATA_PARAMETERS); @@ -119,7 +134,9 @@ public class GuarantorsApiResource { final Collection allowedClientRelationshipTypes = this.codeValueReadPlatformService .retrieveCodeValuesByCode(GuarantorConstants.GUARANTOR_RELATIONSHIP_CODE_NAME); final List guarantorTypeOptions = GuarantorEnumerations.guarantorType(GuarantorType.values()); - guarantorData = GuarantorData.templateOnTop(guarantorData, guarantorTypeOptions, allowedClientRelationshipTypes); + final Collection accountLinkingOptions = null; + guarantorData = GuarantorData.templateOnTop(guarantorData, guarantorTypeOptions, allowedClientRelationshipTypes, + accountLinkingOptions); } return this.apiJsonSerializerService.serialize(settings, guarantorData, RESPONSE_DATA_PARAMETERS); @@ -155,11 +172,31 @@ public class GuarantorsApiResource { @Path("{guarantorId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String deleteGuarantor(@PathParam("loanId") final Long loanId, @PathParam("guarantorId") final Long guarantorId) { - final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGuarantor(loanId, guarantorId).build(); + public String deleteGuarantor(@PathParam("loanId") final Long loanId, @PathParam("guarantorId") final Long guarantorId, + @QueryParam("guarantorFundingId") final Long guarantorFundingId) { + final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGuarantor(loanId, guarantorId, guarantorFundingId).build(); final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.apiJsonSerializerService.serialize(result); } + + @GET + @Path("accounts/template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String accountsTemplate(@QueryParam("clientId") final Long clientId, @PathParam("loanId") final Long loanId, + @Context final UriInfo uriInfo) { + + this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission); + + PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(PortfolioAccountType.SAVINGS.getValue(), clientId, null); + Collection accountLinkingOptions = null; + if (this.loanReadPlatformService.isGuaranteeRequired(loanId)) { + accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO); + } + final GuarantorData guarantorData = GuarantorData.template(null, null, accountLinkingOptions); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.apiJsonSerializerService.serialize(settings, guarantorData, AccountTransfersApiConstants.RESPONSE_DATA_PARAMETERS); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/command/GuarantorCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/command/GuarantorCommand.java index 768b617af..466e0819b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/command/GuarantorCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/command/GuarantorCommand.java @@ -5,6 +5,7 @@ */ package org.mifosplatform.portfolio.loanaccount.guarantor.command; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -41,11 +42,13 @@ public class GuarantorCommand { private final String housePhoneNumber; private final String comment; private final LocalDate dob; + private final Long savingsId; + private final BigDecimal amount; public GuarantorCommand(final Long clientRelationshipTypeId, final Integer guarantorTypeId, final Long entityId, final String firstname, final String lastname, final String addressLine1, final String addressLine2, final String city, final String state, final String zip, final String country, final String mobileNumber, final String housePhoneNumber, - final String comment, final LocalDate dob) { + final String comment, final LocalDate dob, final Long savingsId, final BigDecimal amount) { this.clientRelationshipTypeId = clientRelationshipTypeId; @@ -66,6 +69,8 @@ public class GuarantorCommand { this.housePhoneNumber = housePhoneNumber; this.comment = comment; this.dob = dob; + this.savingsId = savingsId; + this.amount = amount; } public boolean isExternalGuarantor() { @@ -92,6 +97,12 @@ public class GuarantorCommand { if (!isExternalGuarantor()) { baseDataValidator.reset().parameter(GUARANTOR_JSON_INPUT_PARAMS.ENTITY_ID.getValue()).value(this.entityId).notNull() .integerGreaterThanZero(); + baseDataValidator.reset().parameter(GUARANTOR_JSON_INPUT_PARAMS.SAVINGS_ID.getValue()).value(this.savingsId) + .longGreaterThanZero(); + if (this.savingsId != null) { + baseDataValidator.reset().parameter(GUARANTOR_JSON_INPUT_PARAMS.AMOUNT.getValue()).value(this.amount).notNull() + .positiveAmount(); + } } else { // validate for an external guarantor baseDataValidator.reset().parameter(GUARANTOR_JSON_INPUT_PARAMS.FIRSTNAME.getValue()).value(this.firstname).notBlank() @@ -120,6 +131,12 @@ public class GuarantorCommand { if (!isExternalGuarantor()) { baseDataValidator.reset().parameter(GUARANTOR_JSON_INPUT_PARAMS.ENTITY_ID.getValue()).value(this.entityId).ignoreIfNull() .integerGreaterThanZero(); + baseDataValidator.reset().parameter(GUARANTOR_JSON_INPUT_PARAMS.SAVINGS_ID.getValue()).value(this.savingsId) + .longGreaterThanZero(); + if (this.savingsId != null) { + baseDataValidator.reset().parameter(GUARANTOR_JSON_INPUT_PARAMS.AMOUNT.getValue()).value(this.amount).notNull() + .positiveAmount(); + } } else { // TODO: Vishwas this validation is buggy (it is compulsory to // update @@ -185,4 +202,12 @@ public class GuarantorCommand { public Integer getGuarantorTypeId() { return this.guarantorTypeId; } + + public Long getSavingsId() { + return this.savingsId; + } + + public BigDecimal getAmount() { + return this.amount; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorData.java index 432b7cf0f..e2d0a26c8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorData.java @@ -12,6 +12,7 @@ import org.joda.time.LocalDate; import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.organisation.staff.data.StaffData; +import org.mifosplatform.portfolio.account.data.PortfolioAccountData; import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorType; import org.mifosplatform.portfolio.loanaccount.guarantor.service.GuarantorEnumerations; @@ -44,48 +45,56 @@ public class GuarantorData { private final String housePhoneNumber; private final String comment; private final LocalDate dob; + private final Collection guarantorFundingDetails; + private final boolean status; // template @SuppressWarnings("unused") private final List guarantorTypeOptions; private final Collection allowedClientRelationshipTypes; + private final Collection accountLinkingOptions; public static GuarantorData template(final List guarantorTypeOptions, - final Collection allowedClientRelationshipTypes) { + final Collection allowedClientRelationshipTypes, Collection accountLinkingOptions) { + final Collection guarantorFundingDetails = null; + final boolean status = false; return new GuarantorData(null, null, null, null, GuarantorEnumerations.guarantorType(GuarantorType.CUSTOMER), null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, guarantorTypeOptions, - allowedClientRelationshipTypes); + null, null, null, null, null, null, null, null, null, null, null, null, status, guarantorFundingDetails, + guarantorTypeOptions, allowedClientRelationshipTypes, accountLinkingOptions); } public static GuarantorData templateOnTop(final GuarantorData guarantorData, final List guarantorTypeOptions, - final Collection allowedClientRelationshipTypes) { + final Collection allowedClientRelationshipTypes, Collection accountLinkingOptions) { return new GuarantorData(guarantorData.id, guarantorData.loanId, guarantorData.clientRelationshipType, guarantorData.entityId, guarantorData.guarantorType, guarantorData.firstname, guarantorData.lastname, guarantorData.dob, guarantorData.addressLine1, guarantorData.addressLine2, guarantorData.city, guarantorData.state, guarantorData.zip, guarantorData.country, guarantorData.mobileNumber, guarantorData.housePhoneNumber, guarantorData.comment, - guarantorData.officeName, guarantorData.joinedDate, guarantorData.externalId, guarantorTypeOptions, - allowedClientRelationshipTypes); + guarantorData.officeName, guarantorData.joinedDate, guarantorData.externalId, guarantorData.status, + guarantorData.guarantorFundingDetails, guarantorTypeOptions, allowedClientRelationshipTypes, accountLinkingOptions); } public static GuarantorData mergeClientData(final ClientData clientData, final GuarantorData guarantorData) { return new GuarantorData(guarantorData.id, guarantorData.loanId, guarantorData.clientRelationshipType, guarantorData.entityId, guarantorData.guarantorType, clientData.getFirstname(), clientData.getLastname(), null, null, null, null, null, null, null, - null, null, null, clientData.officeName(), clientData.getActivationDate(), clientData.getExternalId(), null, - guarantorData.allowedClientRelationshipTypes); + null, null, null, clientData.officeName(), clientData.getActivationDate(), clientData.getExternalId(), + guarantorData.status, guarantorData.guarantorFundingDetails, null, guarantorData.allowedClientRelationshipTypes, + guarantorData.accountLinkingOptions); } public static GuarantorData mergeStaffData(final StaffData staffData, final GuarantorData guarantorData) { return new GuarantorData(guarantorData.id, guarantorData.loanId, guarantorData.clientRelationshipType, guarantorData.entityId, guarantorData.guarantorType, staffData.getFirstname(), staffData.getLastname(), null, null, null, null, null, null, null, - null, null, null, staffData.getOfficeName(), null, null, null, guarantorData.allowedClientRelationshipTypes); + null, null, null, staffData.getOfficeName(), null, null, guarantorData.status, guarantorData.guarantorFundingDetails, null, + guarantorData.allowedClientRelationshipTypes, guarantorData.accountLinkingOptions); } public GuarantorData(final Long id, final Long loanId, final CodeValueData clientRelationshipType, final Long entityId, final EnumOptionData guarantorType, final String firstname, final String lastname, final LocalDate dob, final String addressLine1, final String addressLine2, final String city, final String state, final String zip, final String country, final String mobileNumber, final String housePhoneNumber, final String comment, final String officeName, - final LocalDate joinedDate, final String externalId, final List guarantorTypeOptions, - final Collection allowedClientRelationshipTypes) { + final LocalDate joinedDate, final String externalId, final boolean status, + Collection guarantorFundingDetails, final List guarantorTypeOptions, + final Collection allowedClientRelationshipTypes, final Collection accountLinkingOptions) { this.id = id; this.loanId = loanId; this.clientRelationshipType = clientRelationshipType; @@ -106,8 +115,11 @@ public class GuarantorData { this.officeName = officeName; this.joinedDate = joinedDate; this.externalId = externalId; + this.status = status; + this.guarantorFundingDetails = guarantorFundingDetails; this.guarantorTypeOptions = guarantorTypeOptions; this.allowedClientRelationshipTypes = allowedClientRelationshipTypes; + this.accountLinkingOptions = accountLinkingOptions; } public boolean isExternalGuarantor() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java new file mode 100755 index 000000000..7e19b58cf --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java @@ -0,0 +1,47 @@ +package org.mifosplatform.portfolio.loanaccount.guarantor.data; + +import java.math.BigDecimal; +import java.util.Collection; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.account.data.PortfolioAccountData; + +public class GuarantorFundingData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final EnumOptionData status; + @SuppressWarnings("unused") + private final PortfolioAccountData savingsAccount; + @SuppressWarnings("unused") + private final BigDecimal amount; + @SuppressWarnings("unused") + private final BigDecimal amountReleased; + @SuppressWarnings("unused") + private final BigDecimal amountRemaining; + @SuppressWarnings("unused") + private final BigDecimal amountTransfered; + @SuppressWarnings("unused") + private final Collection guarantorTransactions; + + private GuarantorFundingData(final Long id, final EnumOptionData status, final PortfolioAccountData savingsAccount, final BigDecimal amount, + final BigDecimal amountReleased, final BigDecimal amountRemaining, final BigDecimal amountTransfered, + final Collection guarantorTransactions) { + this.id = id; + this.status = status; + this.savingsAccount = savingsAccount; + this.amount = amount; + this.amountReleased = amountReleased; + this.amountRemaining = amountRemaining; + this.amountTransfered = amountTransfered; + this.guarantorTransactions = guarantorTransactions; + } + + public static GuarantorFundingData instance(final Long id, final EnumOptionData status, final PortfolioAccountData savingsAccount, final BigDecimal amount, + final BigDecimal amountReleased, final BigDecimal amountRemaining, final BigDecimal amountTransfered, + final Collection guarantorTransactions) { + return new GuarantorFundingData(id, status, savingsAccount, amount, amountReleased, amountRemaining, amountTransfered, + guarantorTransactions); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java new file mode 100755 index 000000000..78d7f2596 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java @@ -0,0 +1,31 @@ +package org.mifosplatform.portfolio.loanaccount.guarantor.data; + +import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData; +import org.mifosplatform.portfolio.savings.data.DepositAccountOnHoldTransactionData; + +public class GuarantorTransactionData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final DepositAccountOnHoldTransactionData onHoldTransactionData; + @SuppressWarnings("unused") + private final LoanTransactionData loanTransactionData; + @SuppressWarnings("unused") + private final boolean reversed; + + private GuarantorTransactionData(final Long id, final DepositAccountOnHoldTransactionData onHoldTransactionData, + final LoanTransactionData loanTransactionData, final boolean reversed) { + + this.id = id; + this.onHoldTransactionData = onHoldTransactionData; + this.loanTransactionData = loanTransactionData; + this.reversed = reversed; + } + + public static GuarantorTransactionData instance(final Long id, final DepositAccountOnHoldTransactionData onHoldTransactionData, + final LoanTransactionData loanTransactionData, final boolean reversed) { + return new GuarantorTransactionData(id, onHoldTransactionData, loanTransactionData, reversed); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/Guarantor.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/Guarantor.java index b49adbfb6..a5a46a00b 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/Guarantor.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/Guarantor.java @@ -5,19 +5,25 @@ */ package org.mifosplatform.portfolio.loanaccount.guarantor.domain; +import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import javax.persistence.CascadeType; 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.Temporal; import javax.persistence.TemporalType; import org.apache.commons.lang.StringUtils; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.portfolio.loanaccount.domain.Loan; @@ -79,22 +85,22 @@ public class Guarantor extends AbstractPersistable { @Column(name = "comment", length = 500) private String comment; + @Column(name = "is_active", nullable = false) + private boolean active; + + @LazyCollection(LazyCollectionOption.FALSE) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantor", orphanRemoval = true) + private final List guarantorFundDetails = new ArrayList<>(); + protected Guarantor() { } - public static Guarantor createNew(final Loan loan, final CodeValue clientRelationshipType, final Integer gurantorType, - final Long entityId, final String firstname, final String lastname, final Date dateOfBirth, final String addressLine1, - final String addressLine2, final String city, final String state, final String country, final String zip, - final String housePhoneNumber, final String mobilePhoneNumber, final String comment) { - return new Guarantor(loan, clientRelationshipType, gurantorType, entityId, firstname, lastname, dateOfBirth, addressLine1, - addressLine2, city, state, country, zip, housePhoneNumber, mobilePhoneNumber, comment); - } - - public Guarantor(final Loan loan, final CodeValue clientRelationshipType, final Integer gurantorType, final Long entityId, + private Guarantor(final Loan loan, final CodeValue clientRelationshipType, final Integer gurantorType, final Long entityId, final String firstname, final String lastname, final Date dateOfBirth, final String addressLine1, final String addressLine2, final String city, final String state, final String country, final String zip, final String housePhoneNumber, - final String mobilePhoneNumber, final String comment) { + final String mobilePhoneNumber, final String comment, final boolean active, + final List guarantorFundDetails) { this.loan = loan; this.clientRelationshipType = clientRelationshipType; this.gurantorType = gurantorType; @@ -111,13 +117,16 @@ public class Guarantor extends AbstractPersistable { this.housePhoneNumber = StringUtils.defaultIfEmpty(housePhoneNumber, null); this.mobilePhoneNumber = StringUtils.defaultIfEmpty(mobilePhoneNumber, null); this.comment = StringUtils.defaultIfEmpty(comment, null); + this.active = active; + this.guarantorFundDetails.addAll(guarantorFundDetails); } - public static Guarantor fromJson(final Loan loan, final CodeValue clientRelationshipType, final JsonCommand command) { + public static Guarantor fromJson(final Loan loan, final CodeValue clientRelationshipType, final JsonCommand command, + final List fundingDetails) { final Integer gurantorType = command.integerValueSansLocaleOfParameterNamed(GUARANTOR_JSON_INPUT_PARAMS.GUARANTOR_TYPE_ID .getValue()); final Long entityId = command.longValueOfParameterNamed(GUARANTOR_JSON_INPUT_PARAMS.ENTITY_ID.getValue()); - + final boolean active = true; if (GuarantorType.EXTERNAL.getValue().equals(gurantorType)) { final String firstname = command.stringValueOfParameterNamed(GUARANTOR_JSON_INPUT_PARAMS.FIRSTNAME.getValue()); final String lastname = command.stringValueOfParameterNamed(GUARANTOR_JSON_INPUT_PARAMS.LASTNAME.getValue()); @@ -133,11 +142,11 @@ public class Guarantor extends AbstractPersistable { final String comment = command.stringValueOfParameterNamed(GUARANTOR_JSON_INPUT_PARAMS.COMMENT.getValue()); return new Guarantor(loan, clientRelationshipType, gurantorType, entityId, firstname, lastname, dateOfBirth, addressLine1, - addressLine2, city, state, country, zip, housePhoneNumber, mobilePhoneNumber, comment); + addressLine2, city, state, country, zip, housePhoneNumber, mobilePhoneNumber, comment, active, fundingDetails); } return new Guarantor(loan, clientRelationshipType, gurantorType, entityId, null, null, null, null, null, null, null, null, null, - null, null, null); + null, null, null, active, fundingDetails); } @@ -145,7 +154,6 @@ public class Guarantor extends AbstractPersistable { final Map actualChanges = new LinkedHashMap<>(); - handlePropertyUpdate(command, actualChanges, GUARANTOR_JSON_INPUT_PARAMS.GUARANTOR_TYPE_ID.getValue(), this.gurantorType, true); handlePropertyUpdate(command, actualChanges, GUARANTOR_JSON_INPUT_PARAMS.CLIENT_RELATIONSHIP_TYPE_ID.getValue(), 0, true); if (isExternalGuarantor()) { @@ -162,9 +170,6 @@ public class Guarantor extends AbstractPersistable { handlePropertyUpdate(command, actualChanges, GUARANTOR_JSON_INPUT_PARAMS.MOBILE_NUMBER.getValue(), this.mobilePhoneNumber); handlePropertyUpdate(command, actualChanges, GUARANTOR_JSON_INPUT_PARAMS.COMMENT.getValue(), this.comment); updateExistingEntityToNull(); - } else { - handlePropertyUpdate(command, actualChanges, GUARANTOR_JSON_INPUT_PARAMS.ENTITY_ID.getValue(), this.entityId); - updateExternalGuarantorFieldsToNull(); } return actualChanges; @@ -235,20 +240,6 @@ public class Guarantor extends AbstractPersistable { } } - private void handlePropertyUpdate(final JsonCommand command, final Map actualChanges, final String paramName, - Long propertyToBeUpdated) { - if (command.isChangeInLongParameterNamed(paramName, propertyToBeUpdated)) { - final Long newValue = command.longValueOfParameterNamed(paramName); - actualChanges.put(paramName, newValue); - propertyToBeUpdated = newValue; - - // now update actual property - if (paramName.equals(GUARANTOR_JSON_INPUT_PARAMS.ENTITY_ID.getValue())) { - this.entityId = newValue; - } - } - } - private void handlePropertyUpdate(final JsonCommand command, final Map actualChanges, final String paramName, Date propertyToBeUpdated) { if (command.isChangeInDateParameterNamed(paramName, propertyToBeUpdated)) { @@ -287,21 +278,6 @@ public class Guarantor extends AbstractPersistable { this.clientRelationshipType = clientRelationshipType; } - private void updateExternalGuarantorFieldsToNull() { - this.firstname = null; - this.lastname = null; - this.dateOfBirth = null; - this.addressLine1 = null; - this.addressLine2 = null; - this.city = null; - this.state = null; - this.country = null; - this.zip = null; - this.housePhoneNumber = null; - this.mobilePhoneNumber = null; - this.comment = null; - } - private void updateExistingEntityToNull() { this.entityId = null; } @@ -309,4 +285,64 @@ public class Guarantor extends AbstractPersistable { public Integer getGurantorType() { return this.gurantorType; } + + public boolean isActive() { + return this.active; + } + + public void updateStatus(final boolean status) { + this.active = status; + } + + public void addFundingDetails(final List fundingDetails) { + this.guarantorFundDetails.addAll(fundingDetails); + } + + public void updateStatus(final GuarantorFundingDetails guarantorFundingDetails, final GuarantorFundStatusType fundStatusType) { + guarantorFundingDetails.updateStatus(fundStatusType); + updateStatus(); + } + + public GuarantorFundingDetails getGuarantorFundingDetail(final Long fundingDetailId) { + GuarantorFundingDetails guarantorFundingDetails = null; + for (GuarantorFundingDetails fundingDetails : this.guarantorFundDetails) { + if (fundingDetails.getId().equals(fundingDetailId)) { + guarantorFundingDetails = fundingDetails; + break; + } + } + return guarantorFundingDetails; + } + + private void updateStatus() { + boolean isActive = false; + for (GuarantorFundingDetails guarantorFundingDetails : this.guarantorFundDetails) { + if (guarantorFundingDetails.getStatus().isActive()) { + isActive = true; + break; + } + } + this.active = isActive; + } + + public Loan getLoan() { + return this.loan; + } + + public List getGuarantorFundDetails() { + return this.guarantorFundDetails; + } + + public boolean hasGuarantor(Long savingsId) { + if (savingsId == null) { return false; } + boolean hasGuarantee = false; + for (GuarantorFundingDetails guarantorFundingDetails : this.guarantorFundDetails) { + if (guarantorFundingDetails.getStatus().isActive() + && savingsId.equals(guarantorFundingDetails.getLinkedSavingsAccount().getId())) { + hasGuarantee = true; + break; + } + } + return hasGuarantee; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundStatusType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundStatusType.java new file mode 100755 index 000000000..3fff83130 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundStatusType.java @@ -0,0 +1,78 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.loanaccount.guarantor.domain; + +/** + * Enum representation of {@link Guarantor} status states. + */ +public enum GuarantorFundStatusType { + + INVALID(0, "guarantorFundStatusType.invalid"), // + ACTIVE(100, "guarantorFundStatusType.active"), // + COMPLETED(200, "guarantorFundStatusType.completed"), // + WITHDRAWN(300, "guarantorFundStatusType.withdrawn"), // + DELETED(400, "guarantorFundStatusType.deleted"); + + private final Integer value; + private final String code; + + public static GuarantorFundStatusType fromInt(final Integer type) { + + GuarantorFundStatusType enumeration = GuarantorFundStatusType.INVALID; + switch (type) { + case 100: + enumeration = GuarantorFundStatusType.ACTIVE; + break; + case 200: + enumeration = GuarantorFundStatusType.COMPLETED; + break; + case 300: + enumeration = GuarantorFundStatusType.WITHDRAWN; + break; + case 400: + enumeration = GuarantorFundStatusType.DELETED; + break; + } + return enumeration; + } + + private GuarantorFundStatusType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + public boolean hasStateOf(final GuarantorFundStatusType state) { + return this.value.equals(state.getValue()); + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + public boolean isActive() { + return this.value.equals(GuarantorFundStatusType.ACTIVE.getValue()); + } + + public boolean isClosed() { + return isWithdrawn() || isCompleted() || isDeleted(); + } + + public boolean isWithdrawn() { + return this.value.equals(GuarantorFundStatusType.WITHDRAWN.getValue()); + } + + public boolean isCompleted() { + return this.value.equals(GuarantorFundStatusType.COMPLETED.getValue()); + } + + public boolean isDeleted() { + return this.value.equals(GuarantorFundStatusType.DELETED.getValue()); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java new file mode 100755 index 000000000..f87b93ca9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java @@ -0,0 +1,76 @@ +package org.mifosplatform.portfolio.loanaccount.guarantor.domain; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +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 org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; +import org.mifosplatform.portfolio.account.domain.AccountAssociations; +import org.mifosplatform.portfolio.savings.domain.SavingsAccount; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_guarantor_funding_details") +public class GuarantorFundingDetails extends AbstractPersistable { + + @ManyToOne + @JoinColumn(name = "guarantor_id", nullable = false) + private Guarantor guarantor; + + @ManyToOne + @JoinColumn(name = "account_associations_id", nullable = false) + private AccountAssociations accountAssociations; + + @Column(name = "status_enum", nullable = false) + private Integer status; + + @Column(name = "amount", scale = 6, precision = 19, nullable = false) + private BigDecimal amount; + + @Column(name = "amount_released_derived", scale = 6, precision = 19, nullable = true) + private BigDecimal amountReleased; + + @Column(name = "amount_remaining_derived", scale = 6, precision = 19, nullable = true) + private BigDecimal amountRemaining; + + @Column(name = "amount_transfered_derived", scale = 6, precision = 19, nullable = true) + private BigDecimal amountTransfered; + + @LazyCollection(LazyCollectionOption.FALSE) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantorFundingDetails", orphanRemoval = true) + private final List guarantorFundingTransactions = new ArrayList<>(); + + protected GuarantorFundingDetails() {} + + public GuarantorFundingDetails(final AccountAssociations accountAssociations, final Integer status, final BigDecimal amount) { + this.accountAssociations = accountAssociations; + this.status = status; + this.amount = amount; + this.amountRemaining = amount; + } + + public void updateGuarantor(final Guarantor guarantor) { + this.guarantor = guarantor; + } + + public void updateStatus(final GuarantorFundStatusType guarantorFundStatusType) { + this.status = guarantorFundStatusType.getValue(); + } + + public GuarantorFundStatusType getStatus(){ + return GuarantorFundStatusType.fromInt(this.status); + } + + public SavingsAccount getLinkedSavingsAccount(){ + return accountAssociations.linkedSavingsAccount(); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java new file mode 100755 index 000000000..0a687fce5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java @@ -0,0 +1,32 @@ +package org.mifosplatform.portfolio.loanaccount.guarantor.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction; +import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransaction; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_guarantor_transaction") +public class GuarantorFundingTransaction extends AbstractPersistable { + + @ManyToOne + @JoinColumn(name = "guarantor_fund_detail_id", nullable = false) + private GuarantorFundingDetails guarantorFundingDetails; + + @ManyToOne + @JoinColumn(name = "loan_transaction_id", nullable = false) + private LoanTransaction loanTransaction; + + @ManyToOne + @JoinColumn(name = "deposit_on_hold_transaction_id", nullable = false) + private DepositAccountOnHoldTransaction depositAccountOnHoldTransaction; + + @Column(name = "is_reversed", nullable = false) + private boolean reversed; + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/GuarantorNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/GuarantorNotFoundException.java index e1052dfbd..55f64e152 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/GuarantorNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/GuarantorNotFoundException.java @@ -13,11 +13,16 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN public class GuarantorNotFoundException extends AbstractPlatformResourceNotFoundException { public GuarantorNotFoundException(final Long id) { - super("error.msg.loan.guarantor.", "Guarantor with identifier " + id + " does not exist", id); + super("error.msg.loan.guarantor.not.found", "Guarantor with identifier " + id + " does not exist", id); } public GuarantorNotFoundException(final Long loanId, final Long guarantorId) { - super("error.msg.loan.guarantor.", "Guarantor with identifier " + guarantorId + " does not exist for loan with Identifier " - + loanId, loanId, guarantorId); + super("error.msg.loan.guarantor.not.found", "Guarantor with identifier " + guarantorId + + " does not exist for loan with Identifier " + loanId, loanId, guarantorId); + } + + public GuarantorNotFoundException(final Long loanId, final Long guarantorId, final Long guarantorFundingId) { + super("error.msg.loan.guarantor.not.found", "Guarantor with identifier " + guarantorId + "and with funding detail " + + guarantorFundingId + " does not exist for loan with Identifier " + loanId, loanId, guarantorId, guarantorFundingId); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/InvalidGuarantorException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/InvalidGuarantorException.java index 2bb47ab2b..c0657da58 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/InvalidGuarantorException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/exception/InvalidGuarantorException.java @@ -17,5 +17,10 @@ public class InvalidGuarantorException extends AbstractPlatformDomainRuleExcepti super("error.msg.invalid.guarantor", "Tried to set Client with id " + clientId + " as a guarantor to his/her own loan with loan identifier =" + loanId, clientId, loanId); } + + public InvalidGuarantorException(final Long clientId, final Long loanId,final String errorcode) { + super("error.msg."+errorcode, "Tried to set Client with id " + clientId + + " as a guarantor to his/her own loan with loan identifier =" + loanId, clientId, loanId); + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/handler/DeleteGuarantorCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/handler/DeleteGuarantorCommandHandler.java index 461cdf8c9..610112f92 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/handler/DeleteGuarantorCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/handler/DeleteGuarantorCommandHandler.java @@ -26,6 +26,6 @@ public class DeleteGuarantorCommandHandler implements NewCommandSourceHandler { @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - return this.guarantorWritePlatformService.removeGuarantor(command.getLoanId(), command.entityId()); + return this.guarantorWritePlatformService.removeGuarantor(command.getLoanId(), command.entityId(), command.subentityId()); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/serialization/GuarantorCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/serialization/GuarantorCommandFromApiJsonDeserializer.java index f377ca777..a716e5f14 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/serialization/GuarantorCommandFromApiJsonDeserializer.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/serialization/GuarantorCommandFromApiJsonDeserializer.java @@ -6,6 +6,8 @@ package org.mifosplatform.portfolio.loanaccount.guarantor.serialization; import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -48,7 +50,13 @@ public final class GuarantorCommandFromApiJsonDeserializer extends AbstractFromA this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); final JsonElement element = this.fromApiJsonHelper.parse(json); + final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject()); + final String dateFormat = this.fromApiJsonHelper.extractDateFormatParameter(element.getAsJsonObject()); + return extractGuarantorCommand(element, locale, dateFormat); + } + + private GuarantorCommand extractGuarantorCommand(final JsonElement element, final Locale locale, final String dateFormat) { final Long clientRelationshipTypeId = this.fromApiJsonHelper.extractLongNamed( GUARANTOR_JSON_INPUT_PARAMS.CLIENT_RELATIONSHIP_TYPE_ID.getValue(), element); final Integer guarantorTypeId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( @@ -69,9 +77,14 @@ public final class GuarantorCommandFromApiJsonDeserializer extends AbstractFromA final String housePhoneNumber = this.fromApiJsonHelper.extractStringNamed(GUARANTOR_JSON_INPUT_PARAMS.PHONE_NUMBER.getValue(), element); final String comment = this.fromApiJsonHelper.extractStringNamed(GUARANTOR_JSON_INPUT_PARAMS.COMMENT.getValue(), element); - final LocalDate dob = this.fromApiJsonHelper.extractLocalDateNamed(GUARANTOR_JSON_INPUT_PARAMS.DATE_OF_BIRTH.getValue(), element); + final LocalDate dob = this.fromApiJsonHelper.extractLocalDateNamed(GUARANTOR_JSON_INPUT_PARAMS.DATE_OF_BIRTH.getValue(), element, + dateFormat, locale); + final Long savingsId = this.fromApiJsonHelper.extractLongNamed(GUARANTOR_JSON_INPUT_PARAMS.SAVINGS_ID.getValue(), element); + final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(GUARANTOR_JSON_INPUT_PARAMS.AMOUNT.getValue(), element, + locale); return new GuarantorCommand(clientRelationshipTypeId, guarantorTypeId, entityId, firstname, lastname, addressLine1, addressLine2, - city, state, zip, country, mobileNumber, housePhoneNumber, comment, dob); + city, state, zip, country, mobileNumber, housePhoneNumber, comment, dob, savingsId, amount); } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorEnumerations.java index 3fa074591..95116dcac 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorEnumerations.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.List; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorFundStatusType; import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorType; public class GuarantorEnumerations { @@ -31,4 +32,14 @@ public class GuarantorEnumerations { return optionDatas; } + public static EnumOptionData guarantorFundStatusType(final int id) { + return guarantorFundStatusType(GuarantorFundStatusType.fromInt(id)); + } + + public static EnumOptionData guarantorFundStatusType(final GuarantorFundStatusType guarantorFundType) { + final EnumOptionData optionData = new EnumOptionData(guarantorFundType.getValue().longValue(), guarantorFundType.getCode(), + guarantorFundType.toString()); + return optionData; + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java index 2eb37e87c..68d115289 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java @@ -5,9 +5,11 @@ */ package org.mifosplatform.portfolio.loanaccount.guarantor.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.joda.time.LocalDate; @@ -17,12 +19,18 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; +import org.mifosplatform.portfolio.account.data.PortfolioAccountData; +import org.mifosplatform.portfolio.account.domain.AccountAssociationType; import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository; import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException; import org.mifosplatform.portfolio.loanaccount.guarantor.data.GuarantorData; +import org.mifosplatform.portfolio.loanaccount.guarantor.data.GuarantorFundingData; +import org.mifosplatform.portfolio.loanaccount.guarantor.data.GuarantorTransactionData; +import org.mifosplatform.portfolio.savings.data.DepositAccountOnHoldTransactionData; +import org.mifosplatform.portfolio.savings.service.SavingsEnumerations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @@ -45,20 +53,69 @@ public class GuarantorReadPlatformServiceImpl implements GuarantorReadPlatformSe this.loanRepository = loanRepository; } + @Override + public List retrieveGuarantorsForValidLoan(final Long loanId) { + final Loan loan = this.loanRepository.findOne(loanId); + if (loan == null) { throw new LoanNotFoundException(loanId); } + return retrieveGuarantorsForLoan(loanId); + } + + @Override + public List retrieveGuarantorsForLoan(final Long loanId) { + final GuarantorMapper rm = new GuarantorMapper(); + String sql = "select " + rm.schema(); + sql += " where loan_id = ? group by g.id,gfd.id"; + final List guarantorDatas = this.jdbcTemplate.query(sql, rm, + new Object[] { AccountAssociationType.GUARANTOR_ACCOUNT_ASSOCIATION.getValue(), + loanId }); + + final List mergedGuarantorDatas = new ArrayList<>(); + + for (final GuarantorData guarantorData : guarantorDatas) { + mergedGuarantorDatas.add(mergeDetailsForClientOrStaffGuarantor(guarantorData)); + } + return mergedGuarantorDatas; + } + + @Override + public GuarantorData retrieveGuarantor(final Long loanId, final Long guarantorId) { + final GuarantorMapper rm = new GuarantorMapper(); + String sql = "select " + rm.schema(); + sql += " where g.loan_id = ? and g.id = ? group by g.id,gfd.id"; + final GuarantorData guarantorData = this.jdbcTemplate.queryForObject(sql, rm, + new Object[] { AccountAssociationType.GUARANTOR_ACCOUNT_ASSOCIATION.getValue(), + loanId, guarantorId }); + + return mergeDetailsForClientOrStaffGuarantor(guarantorData); + } + private static final class GuarantorMapper implements RowMapper { + private GuarantorTransactionMapper guarantorTransactionMapper = new GuarantorTransactionMapper(); + private GuarantorFundingMapper guarantorFundingMapper = new GuarantorFundingMapper(guarantorTransactionMapper); + private final StringBuilder sqlBuilder = new StringBuilder( " g.id as id, g.loan_id as loanId, g.client_reln_cv_id clientRelationshipTypeId, g.entity_id as entityId, g.type_enum guarantorType ,g.firstname as firstname, g.lastname as lastname, g.dob as dateOfBirth, g.address_line_1 as addressLine1, g.address_line_2 as addressLine2, g.city as city, g.state as state, g.country as country, g.zip as zip, g.house_phone_number as housePhoneNumber, g.mobile_number as mobilePhoneNumber, g.comment as comment, ") - .append(" cv.code_value as typeName")// + .append(" g.is_active as guarantorStatus,")// + .append(" cv.code_value as typeName, ")// + .append("gfd.amount,")// + .append(this.guarantorFundingMapper.schema())// + .append(",")// + .append(this.guarantorTransactionMapper.schema())// .append(" FROM m_guarantor g") // - .append(" left JOIN m_code_value cv on g.client_reln_cv_id = cv.id"); + .append(" left JOIN m_code_value cv on g.client_reln_cv_id = cv.id")// + .append(" left JOIN m_guarantor_funding_details gfd on g.id = gfd.guarantor_id")// + .append(" left JOIN m_portfolio_account_associations aa on gfd.account_associations_id = aa.id and aa.is_active = 1 and aa.association_type_enum = ?")// + .append(" left JOIN m_savings_account sa on sa.id = aa.linked_savings_account_id ")// + .append(" left join m_guarantor_transaction gt on gt.guarantor_fund_detail_id = gfd.id") // + .append(" left join m_deposit_account_on_hold_transaction oht on oht.id = gt.deposit_on_hold_transaction_id"); public String schema() { return this.sqlBuilder.toString(); } @Override - public GuarantorData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + public GuarantorData mapRow(final ResultSet rs, final int rowNum) throws SQLException { final Long id = rs.getLong("id"); final Long loanId = rs.getLong("loanId"); final Long clientRelationshipTypeId = JdbcSupport.getLong(rs, "clientRelationshipTypeId"); @@ -84,41 +141,127 @@ public class GuarantorReadPlatformServiceImpl implements GuarantorReadPlatformSe final String mobileNumber = rs.getString("mobilePhoneNumber"); final String housePhoneNumber = rs.getString("housePhoneNumber"); final String comment = rs.getString("comment"); + final boolean status = rs.getBoolean("guarantorStatus"); + final Collection accountLinkingOptions = null; + List guarantorFundingDetails = null; + GuarantorFundingData guarantorFundingData = this.guarantorFundingMapper.mapRow(rs, rowNum); + if (guarantorFundingData != null) { + guarantorFundingDetails = new ArrayList<>(); + guarantorFundingDetails.add(guarantorFundingData); + while (rs.next()) { + Long tempId = rs.getLong("id"); + if (tempId.equals(id)) { + guarantorFundingData = this.guarantorFundingMapper.mapRow(rs, rowNum); + guarantorFundingDetails.add(guarantorFundingData); + } else { + rs.previous(); + break; + } + + } + } + + + return new GuarantorData(id, loanId, clientRelationshipType, entityId, guarantorType, firstname, lastname, dob, addressLine1, - addressLine2, city, state, zip, country, mobileNumber, housePhoneNumber, comment, null, null, null, null, null); + addressLine2, city, state, zip, country, mobileNumber, housePhoneNumber, comment, null, null, null, status, + guarantorFundingDetails, null, null, accountLinkingOptions); } } - @Override - public List retrieveGuarantorsForValidLoan(final Long loanId) { - final Loan loan = this.loanRepository.findOne(loanId); - if (loan == null) { throw new LoanNotFoundException(loanId); } - return retrieveGuarantorsForLoan(loanId); - } + private static final class GuarantorFundingMapper implements RowMapper { - @Override - public List retrieveGuarantorsForLoan(final Long loanId) { - final GuarantorMapper rm = new GuarantorMapper(); - String sql = "select " + rm.schema(); - sql += " where loan_id = ?"; - final List guarantorDatas = this.jdbcTemplate.query(sql, rm, new Object[] { loanId }); + private final String sql; + private final GuarantorTransactionMapper guarantorTransactionMapper; - final List mergedGuarantorDatas = new ArrayList<>(); + public GuarantorFundingMapper(final GuarantorTransactionMapper guarantorTransactionMapper) { + this.guarantorTransactionMapper = guarantorTransactionMapper; + StringBuilder sb = new StringBuilder(" gfd.id as gfdId,"); + sb.append(" gfd.amount as amount, gfd.amount_released_derived as amountReleased, "); + sb.append(" gfd.amount_remaining_derived as amountRemaining, "); + sb.append(" gfd.amount_transfered_derived as amountTransfered, gfd.status_enum as statusEnum, "); + sb.append(" sa.id as savingsId, sa.account_no as accountNumber "); + sql = sb.toString(); + } - for (final GuarantorData guarantorData : guarantorDatas) { - mergedGuarantorDatas.add(mergeDetailsForClientOrStaffGuarantor(guarantorData)); + public String schema() { + return this.sql; + } + + @Override + public GuarantorFundingData mapRow(final ResultSet rs, final int rowNum) throws SQLException { + GuarantorFundingData guarantorFundingData = null; + final Long id = rs.getLong("gfdId"); + if (id != null && id > 0) { + final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amount"); + final BigDecimal amountReleased = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountReleased"); + final BigDecimal amountRemaining = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountRemaining"); + final BigDecimal amountTransfered = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountTransfered"); + final int statusEnum = rs.getInt("statusEnum"); + final EnumOptionData status = GuarantorEnumerations.guarantorFundStatusType(statusEnum); + final Long savingsId = rs.getLong("savingsId"); + final String savingsAccountNumber = rs.getString("accountNumber"); + final PortfolioAccountData portfolioAccountData = PortfolioAccountData.lookup(savingsId, savingsAccountNumber); + List guarantorTransactions = new ArrayList<>(); + if (this.guarantorTransactionMapper != null) { + GuarantorTransactionData guarantorTransactionData = this.guarantorTransactionMapper.mapRow(rs, rowNum); + if (guarantorTransactionData != null) { + guarantorTransactions.add(guarantorTransactionData); + while (rs.next()) { + final Long tempFundId = rs.getLong("gfdId"); + if (tempFundId != null && tempFundId.equals(id)) { + guarantorTransactionData = this.guarantorTransactionMapper.mapRow(rs, rowNum); + guarantorTransactions.add(guarantorTransactionData); + } else { + rs.previous(); + break; + } + } + } + } + guarantorFundingData = GuarantorFundingData.instance(id, status, portfolioAccountData, amount, amountReleased, + amountRemaining, amountTransfered, guarantorTransactions); + } + return guarantorFundingData; } - return mergedGuarantorDatas; } - @Override - public GuarantorData retrieveGuarantor(final Long loanId, final Long guarantorId) { - final GuarantorMapper rm = new GuarantorMapper(); - String sql = "select " + rm.schema(); - sql += " where g.loan_id = ? and g.id = ?"; - final GuarantorData guarantorData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId, guarantorId }); + private static final class GuarantorTransactionMapper implements RowMapper { + + private final String sql; + + public GuarantorTransactionMapper() { + StringBuilder sb = new StringBuilder(" gt.id as gtId,"); + sb.append("gt.is_reversed as reversed,"); + sb.append(" oht.id as ohtId, oht.amount as transactionAmount, "); + sb.append(" oht.transaction_type_enum as transactionType, "); + sb.append(" oht.transaction_date as transactionDate, oht.is_reversed as transactionReversed "); + sql = sb.toString(); + } + + public String schema() { + return this.sql; + } + + @Override + public GuarantorTransactionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + GuarantorTransactionData guarantorTransactionData = null; + final Long id = rs.getLong("gtId"); + final Long transactionId = rs.getLong("ohtId"); + final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount"); + final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate"); + final int transactionTypeEnum = rs.getInt("transactionType"); + EnumOptionData transactionType = SavingsEnumerations.onHoldTransactionType(transactionTypeEnum); + final boolean reversed = rs.getBoolean("reversed"); + final boolean transactionReversed = rs.getBoolean("transactionReversed"); + if (id != null) { + DepositAccountOnHoldTransactionData onHoldTransactionData = DepositAccountOnHoldTransactionData.instance(transactionId, + amount, transactionType, date, transactionReversed); + guarantorTransactionData = GuarantorTransactionData.instance(id, onHoldTransactionData, null, reversed); + } + return guarantorTransactionData; + } - return mergeDetailsForClientOrStaffGuarantor(guarantorData); } /** diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformService.java index f62165739..8a3070ab6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformService.java @@ -14,6 +14,6 @@ public interface GuarantorWritePlatformService { CommandProcessingResult updateGuarantor(final Long loanId, final Long guarantorId, final JsonCommand command); - CommandProcessingResult removeGuarantor(final Long loanId, final Long guarantorId); + CommandProcessingResult removeGuarantor(final Long loanId, final Long guarantorId, Long guarantorFundingId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java index 7bd50ff31..c73aa974d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java @@ -5,6 +5,8 @@ */ package org.mifosplatform.portfolio.loanaccount.guarantor.service; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -15,6 +17,9 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper; +import org.mifosplatform.portfolio.account.domain.AccountAssociationType; +import org.mifosplatform.portfolio.account.domain.AccountAssociations; +import org.mifosplatform.portfolio.account.domain.AccountAssociationsRepository; import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanRepositoryWrapper; @@ -22,12 +27,16 @@ import org.mifosplatform.portfolio.loanaccount.guarantor.GuarantorConstants; import org.mifosplatform.portfolio.loanaccount.guarantor.GuarantorConstants.GUARANTOR_JSON_INPUT_PARAMS; import org.mifosplatform.portfolio.loanaccount.guarantor.command.GuarantorCommand; import org.mifosplatform.portfolio.loanaccount.guarantor.domain.Guarantor; +import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorFundStatusType; +import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorFundingDetails; import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorRepository; import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorType; import org.mifosplatform.portfolio.loanaccount.guarantor.exception.DuplicateGuarantorException; import org.mifosplatform.portfolio.loanaccount.guarantor.exception.GuarantorNotFoundException; import org.mifosplatform.portfolio.loanaccount.guarantor.exception.InvalidGuarantorException; import org.mifosplatform.portfolio.loanaccount.guarantor.serialization.GuarantorCommandFromApiJsonDeserializer; +import org.mifosplatform.portfolio.savings.domain.SavingsAccount; +import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -46,28 +55,49 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto private final GuarantorRepository guarantorRepository; private final GuarantorCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final CodeValueRepositoryWrapper codeValueRepositoryWrapper; + private final SavingsAccountAssembler savingsAccountAssembler; + private final AccountAssociationsRepository accountAssociationsRepository; @Autowired public GuarantorWritePlatformServiceJpaRepositoryIImpl(final LoanRepositoryWrapper loanRepositoryWrapper, final GuarantorRepository guarantorRepository, final ClientRepositoryWrapper clientRepositoryWrapper, final StaffRepositoryWrapper staffRepositoryWrapper, final GuarantorCommandFromApiJsonDeserializer fromApiJsonDeserializer, - final CodeValueRepositoryWrapper codeValueRepositoryWrapper) { + final CodeValueRepositoryWrapper codeValueRepositoryWrapper, final SavingsAccountAssembler savingsAccountAssembler, + final AccountAssociationsRepository accountAssociationsRepository) { this.loanRepositoryWrapper = loanRepositoryWrapper; this.clientRepositoryWrapper = clientRepositoryWrapper; this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.guarantorRepository = guarantorRepository; this.staffRepositoryWrapper = staffRepositoryWrapper; this.codeValueRepositoryWrapper = codeValueRepositoryWrapper; + this.savingsAccountAssembler = savingsAccountAssembler; + this.accountAssociationsRepository = accountAssociationsRepository; } @Override @Transactional public CommandProcessingResult createGuarantor(final Long loanId, final JsonCommand command) { - try { - final GuarantorCommand guarantorCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json()); - guarantorCommand.validateForCreate(); + final GuarantorCommand guarantorCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json()); + final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId); + final List existGuarantorList = this.guarantorRepository.findByLoan(loan); + return createGuarantor(loan, command, guarantorCommand, existGuarantorList); + } - final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId); + private CommandProcessingResult createGuarantor(final Loan loan, final JsonCommand command, final GuarantorCommand guarantorCommand, + final Collection existGuarantorList) { + try { + guarantorCommand.validateForCreate(); + final List guarantorFundingDetails = new ArrayList<>(); + AccountAssociations accountAssociations = null; + if (guarantorCommand.getSavingsId() != null) { + final SavingsAccount savingsAccount = this.savingsAccountAssembler.assembleFrom(guarantorCommand.getSavingsId()); + accountAssociations = AccountAssociations.associateSavingsAccount(loan, savingsAccount, + AccountAssociationType.GUARANTOR_ACCOUNT_ASSOCIATION.getValue(), true); + + GuarantorFundingDetails fundingDetails = new GuarantorFundingDetails(accountAssociations, + GuarantorFundStatusType.ACTIVE.getValue(), guarantorCommand.getAmount()); + guarantorFundingDetails.add(fundingDetails); + } final Long clientRelationshipId = guarantorCommand.getClientRelationshipTypeId(); CodeValue clientRelationshipType = null; @@ -77,36 +107,47 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto GuarantorConstants.GUARANTOR_RELATIONSHIP_CODE_NAME, clientRelationshipId); } - final List existGuarantorList = this.guarantorRepository.findByLoan(loan); final Long entityId = guarantorCommand.getEntityId(); final Integer guarantorTypeId = guarantorCommand.getGuarantorTypeId(); + Guarantor guarantor = null; + for (final Guarantor avilableGuarantor : existGuarantorList) { + if (entityId != null && avilableGuarantor.getEntityId() == entityId + && avilableGuarantor.getGurantorType() == guarantorTypeId && avilableGuarantor.isActive()) { + if (guarantorCommand.getSavingsId() == null || avilableGuarantor.hasGuarantor(guarantorCommand.getSavingsId())) { + /** Get the right guarantor based on guarantorType **/ + String defaultUserMessage = null; + if (guarantorTypeId == GuarantorType.STAFF.getValue()) { + defaultUserMessage = this.staffRepositoryWrapper.findOneWithNotFoundDetection(entityId).displayName(); + } else { + defaultUserMessage = this.clientRepositoryWrapper.findOneWithNotFoundDetection(entityId).getDisplayName(); + } - for (final Guarantor guarantor : existGuarantorList) { - if (guarantor.getLoanId() == loanId && entityId != null && guarantor.getEntityId() == entityId - && guarantor.getGurantorType() == guarantorTypeId) { - /** Get the right guarantor based on guarantorType **/ - String defaultUserMessage = null; - if (guarantorTypeId == GuarantorType.STAFF.getValue()) { - defaultUserMessage = this.staffRepositoryWrapper.findOneWithNotFoundDetection(entityId).displayName(); - } else { - defaultUserMessage = this.clientRepositoryWrapper.findOneWithNotFoundDetection(entityId).getDisplayName(); + defaultUserMessage = defaultUserMessage + " is already exist as a guarantor for this loan"; + final String action = loan.client() != null ? "client.guarantor" : "group.guarantor"; + throw new DuplicateGuarantorException(action, "is.already.exist.same.loan", defaultUserMessage, entityId, + loan.getId()); } - - defaultUserMessage = defaultUserMessage + " is already exist as a guarantor for this loan"; - final String action = loan.client() != null ? "client.guarantor" : "group.guarantor"; - throw new DuplicateGuarantorException(action, "is.already.exist.same.loan", defaultUserMessage, entityId, loanId); + guarantor = avilableGuarantor; + break; } } - Guarantor guarantor = null; - guarantor = Guarantor.fromJson(loan, clientRelationshipType, command); - + if (guarantor == null) { + guarantor = Guarantor.fromJson(loan, clientRelationshipType, command, guarantorFundingDetails); + } else { + guarantor.addFundingDetails(guarantorFundingDetails); + } validateGuarantorBusinessRules(guarantor); + for (GuarantorFundingDetails fundingDetails : guarantorFundingDetails) { + fundingDetails.updateGuarantor(guarantor); + } - this.guarantorRepository.saveAndFlush(guarantor); - + if (accountAssociations != null) { + this.accountAssociationsRepository.save(accountAssociations); + } + this.guarantorRepository.save(guarantor); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(guarantor.getOfficeId()) - .withEntityId(guarantor.getId()).withLoanId(loanId).build(); + .withEntityId(guarantor.getId()).withLoanId(loan.getId()).build(); } catch (final DataIntegrityViolationException dve) { handleGuarantorDataIntegrityIssues(dve); return CommandProcessingResult.empty(); @@ -142,8 +183,8 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto if (guarantorType.isCustomer() || guarantorType.isStaff()) { final Long entityId = guarantorCommand.getEntityId(); for (final Guarantor guarantor : existGuarantorList) { - if (guarantor.getLoanId() == loanId && guarantor.getEntityId() == entityId - && guarantor.getGurantorType() == guarantorTypeId && !guarantorForUpdate.getId().equals(guarantor.getId())) { + if (guarantor.getEntityId() == entityId && guarantor.getGurantorType() == guarantorTypeId + && !guarantorForUpdate.getId().equals(guarantor.getId())) { String defaultUserMessage = this.clientRepositoryWrapper.findOneWithNotFoundDetection(entityId).getDisplayName(); defaultUserMessage = defaultUserMessage + " is already exist as a guarantor for this loan"; final String action = loan.client() != null ? "client.guarantor" : "group.guarantor"; @@ -158,7 +199,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto } if (!changesOnly.isEmpty()) { - this.guarantorRepository.saveAndFlush(guarantorForUpdate); + this.guarantorRepository.save(guarantorForUpdate); } return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(guarantorForUpdate.getOfficeId()) @@ -171,29 +212,55 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto @Override @Transactional - public CommandProcessingResult removeGuarantor(final Long loanId, final Long guarantorId) { + public CommandProcessingResult removeGuarantor(final Long loanId, final Long guarantorId, final Long guarantorFundingId) { final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId); final Guarantor guarantorForDelete = this.guarantorRepository.findByLoanAndId(loan, guarantorId); - if (guarantorForDelete == null) { throw new GuarantorNotFoundException(loanId, guarantorId); } - - this.guarantorRepository.delete(guarantorForDelete); - - return new CommandProcessingResultBuilder().withEntityId(guarantorId).withLoanId(guarantorForDelete.getLoanId()) - .withOfficeId(guarantorForDelete.getOfficeId()).build(); + if (guarantorForDelete == null || (guarantorFundingId == null && !guarantorForDelete.getGuarantorFundDetails().isEmpty())) { throw new GuarantorNotFoundException( + loanId, guarantorId, guarantorFundingId); } + return removeGuarantor(guarantorForDelete, loanId, guarantorFundingId); } + private CommandProcessingResult removeGuarantor(final Guarantor guarantorForDelete, final Long loanId, final Long guarantorFundingId) { + if (guarantorFundingId == null) { + guarantorForDelete.updateStatus(false); + } else { + GuarantorFundingDetails guarantorFundingDetails = guarantorForDelete.getGuarantorFundingDetail(guarantorFundingId); + if (guarantorFundingDetails == null) { throw new GuarantorNotFoundException(loanId, guarantorForDelete.getId(), + guarantorFundingId); } + GuarantorFundStatusType fundStatusType = GuarantorFundStatusType.DELETED; + if (guarantorForDelete.getLoan().isDisbursed()) { + fundStatusType = GuarantorFundStatusType.WITHDRAWN; + } + guarantorForDelete.updateStatus(guarantorFundingDetails, fundStatusType); + + } + this.guarantorRepository.save(guarantorForDelete); + CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder() + .withEntityId(guarantorForDelete.getId()).withLoanId(guarantorForDelete.getLoanId()) + .withOfficeId(guarantorForDelete.getOfficeId()); + if (guarantorFundingId != null) { + commandProcessingResultBuilder.withSubEntityId(guarantorFundingId); + } + return commandProcessingResultBuilder.build(); + } + + private void validateGuarantorBusinessRules(final Guarantor guarantor) { // validate guarantor conditions if (guarantor.isExistingCustomer()) { // check client exists this.clientRepositoryWrapper.findOneWithNotFoundDetection(guarantor.getEntityId()); // validate that the client is not set as a self guarantor - if (guarantor.getClientId() != null) { - if (guarantor.getClientId().equals(guarantor.getEntityId())) { - // - throw new InvalidGuarantorException(guarantor.getEntityId(), guarantor.getLoanId()); + if (guarantor.getClientId() != null && guarantor.getClientId().equals(guarantor.getEntityId())) { + String errorCode = null; + if (guarantor.getGuarantorFundDetails().isEmpty()) { + errorCode = "guarantor.can.not.be.own"; + } else if (guarantor.getClientRelationshipType() != null) { + errorCode = "guarantor.relation.should.be.empty.for.own"; } + if (errorCode != null) { throw new InvalidGuarantorException(guarantor.getEntityId(), guarantor.getLoanId(), errorCode); } } + } else if (guarantor.isExistingEmployee()) { this.staffRepositoryWrapper.findOneWithNotFoundDetection(guarantor.getEntityId()); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 360bdd3c4..9ab87a564 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -260,8 +260,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa 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()); + savingsAccount, AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive); this.accountAssociationsRepository.save(accountAssociations); } @@ -598,8 +599,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final SavingsAccount savingsAccount = this.savingsAccountAssembler.assembleFrom(savingsAccountId); this.fromApiJsonDeserializer.validatelinkedSavingsAccount(savingsAccount, existingLoanApplication); if (accountAssociations == null) { + boolean isActive = true; accountAssociations = AccountAssociations.associateSavingsAccount(existingLoanApplication, savingsAccount, - AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue()); + AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive); } else { accountAssociations.updateLinkedSavingsAccount(savingsAccount); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java index 92d0cefe7..095a63bcb 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java @@ -99,4 +99,6 @@ public interface LoanReadPlatformService { Collection retrieveWaiverLoanTransactions(Long loanId); Collection fetchWaiverInterestRepaymentData(Long loanId); + + boolean isGuaranteeRequired(Long loanId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 715bcaa04..97dc92d9b 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -1664,6 +1664,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { } } + @Override + public boolean isGuaranteeRequired(final Long loanId) { + final String sql = "select pl.hold_guarantee_funds from m_loan ml inner join m_product_loan pl on pl.id = ml.product_id where ml.id=?"; + return this.jdbcTemplate.queryForObject(sql, Boolean.class, loanId); + } + private static final class LoanTransactionDerivedComponentMapper implements RowMapper { public String schema() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositAccountOnHoldTransactionType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositAccountOnHoldTransactionType.java new file mode 100755 index 000000000..56c1f059f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/DepositAccountOnHoldTransactionType.java @@ -0,0 +1,61 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.savings; + +import org.mifosplatform.portfolio.savings.domain.SavingsAccount; + +/** + * An enumeration of on hold transactions that can occur on a + * {@link SavingsAccount}. + */ +public enum DepositAccountOnHoldTransactionType { + + INVALID(0, "deposutAccountOnHoldTransactionType.invalid"), // + HOLD(1, "deposutAccountOnHoldTransactionType.hold"), // + RELEASE(2, "deposutAccountOnHoldTransactionType.release"); + + private final Integer value; + private final String code; + + private DepositAccountOnHoldTransactionType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + public static DepositAccountOnHoldTransactionType fromInt(final Integer transactionType) { + + if (transactionType == null) { return DepositAccountOnHoldTransactionType.INVALID; } + + DepositAccountOnHoldTransactionType savingsAccountTransactionType = DepositAccountOnHoldTransactionType.INVALID; + switch (transactionType) { + case 1: + savingsAccountTransactionType = DepositAccountOnHoldTransactionType.HOLD; + break; + case 2: + savingsAccountTransactionType = DepositAccountOnHoldTransactionType.RELEASE; + break; + + } + return savingsAccountTransactionType; + } + + public boolean isHold() { + return this.value.equals(DepositAccountOnHoldTransactionType.HOLD.getValue()); + } + + public boolean isRelease() { + return this.value.equals(DepositAccountOnHoldTransactionType.RELEASE.getValue()); + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java new file mode 100755 index 000000000..aff3b1a02 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java @@ -0,0 +1,34 @@ +package org.mifosplatform.portfolio.savings.data; + +import java.math.BigDecimal; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; + +public class DepositAccountOnHoldTransactionData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final BigDecimal amount; + @SuppressWarnings("unused") + private EnumOptionData transactionType; + @SuppressWarnings("unused") + private final LocalDate transactionDate; + @SuppressWarnings("unused") + private final boolean reversed; + + private DepositAccountOnHoldTransactionData(final Long id, final BigDecimal amount, final EnumOptionData transactionType, + final LocalDate transactionDate, final boolean reversed) { + this.id = id; + this.amount = amount; + this.transactionType = transactionType; + this.transactionDate = transactionDate; + this.reversed = reversed; + } + + public static DepositAccountOnHoldTransactionData instance(final Long id, final BigDecimal amount, + final EnumOptionData transactionType, final LocalDate transactionDate, final boolean reversed) { + return new DepositAccountOnHoldTransactionData(id, amount, transactionType, transactionDate, reversed); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java new file mode 100755 index 000000000..6b79b65f2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java @@ -0,0 +1,38 @@ +package org.mifosplatform.portfolio.savings.domain; + +import java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_deposit_account_on_hold_transaction") +public class DepositAccountOnHoldTransaction extends AbstractPersistable { + + @SuppressWarnings("unused") + @ManyToOne + @JoinColumn(name = "savings_account_id", nullable = true) + private SavingsAccount savingsAccount; + + @Column(name = "amount", scale = 6, precision = 19, nullable = false) + private BigDecimal amount; + + @Column(name = "transaction_type_enum", nullable = false) + private Integer transactionType; + + @Temporal(TemporalType.DATE) + @Column(name = "transaction_date", nullable = false) + private Date transactionDate; + + @Column(name = "is_reversed", nullable = false) + private boolean reversed; + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java index c2727ad9e..f2f06ac0c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java @@ -200,8 +200,9 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(savingsAccountId, DepositAccountType.SAVINGS_DEPOSIT); this.depositAccountDataValidator.validatelinkedSavingsAccount(savingsAccount, account); + boolean isActive = true; final AccountAssociations accountAssociations = AccountAssociations.associateSavingsAccount(account, savingsAccount, - AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue()); + AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive); this.accountAssociationsRepository.save(accountAssociations); } @@ -354,7 +355,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); this.savingAccountRepository.save(account); } - + boolean isLinkedAccRequired = command.booleanPrimitiveValueOfParameterNamed(transferInterestToSavingsParamName); // Save linked account information @@ -387,8 +388,9 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl DepositAccountType.SAVINGS_DEPOSIT); this.depositAccountDataValidator.validatelinkedSavingsAccount(savingsAccount, account); if (accountAssociations == null) { + boolean isActive = true; accountAssociations = AccountAssociations.associateSavingsAccount(account, savingsAccount, - AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue()); + AccountAssociationType.LINKED_ACCOUNT_ASSOCIATION.getValue(), isActive); } else { accountAssociations.updateLinkedSavingsAccount(savingsAccount); } @@ -464,7 +466,6 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl this.calendarInstanceRepository.save(calendarInstance); } - return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(accountId) // diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsEnumerations.java index 83b12ea34..069b2dbfd 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsEnumerations.java @@ -11,6 +11,7 @@ import java.util.List; import org.mifosplatform.accounting.common.AccountingEnumerations; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.portfolio.savings.DepositAccountOnClosureType; +import org.mifosplatform.portfolio.savings.DepositAccountOnHoldTransactionType; import org.mifosplatform.portfolio.savings.DepositAccountType; import org.mifosplatform.portfolio.savings.PreClosurePenalInterestOnType; import org.mifosplatform.portfolio.savings.RecurringDepositType; @@ -728,4 +729,28 @@ public class SavingsEnumerations { } return optionDatas; } + + public static EnumOptionData onHoldTransactionType(final int id) { + return onHoldTransactionType(DepositAccountOnHoldTransactionType.fromInt(id)); + } + + public static EnumOptionData onHoldTransactionType(final DepositAccountOnHoldTransactionType type) { + EnumOptionData optionData = new EnumOptionData(DepositAccountOnHoldTransactionType.INVALID.getValue().longValue(), + DepositAccountType.INVALID.getCode(), "Invalid"); + switch (type) { + case INVALID: + break; + case HOLD: + optionData = new EnumOptionData(DepositAccountOnHoldTransactionType.HOLD.getValue().longValue(), + DepositAccountOnHoldTransactionType.HOLD.getCode(), "hold"); + break; + case RELEASE: + optionData = new EnumOptionData(DepositAccountOnHoldTransactionType.RELEASE.getValue().longValue(), + DepositAccountOnHoldTransactionType.RELEASE.getCode(), "release"); + break; + + } + return optionData; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/resources/sql/migrations/core_db/V219__guarantor_on_hold_fund_changes_for_account.sql b/mifosng-provider/src/main/resources/sql/migrations/core_db/V219__guarantor_on_hold_fund_changes_for_account.sql new file mode 100755 index 000000000..2cf75600c --- /dev/null +++ b/mifosng-provider/src/main/resources/sql/migrations/core_db/V219__guarantor_on_hold_fund_changes_for_account.sql @@ -0,0 +1,47 @@ +ALTER TABLE `m_portfolio_account_associations` + ADD COLUMN `is_active` TINYINT(1) NOT NULL DEFAULT '1'; + +ALTER TABLE `m_guarantor` + ADD COLUMN `is_active` TINYINT(1) NOT NULL DEFAULT '1'; + +CREATE TABLE `m_guarantor_funding_details` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `guarantor_id` BIGINT(20) NOT NULL, + `account_associations_id` BIGINT(20) NOT NULL, + `amount` DECIMAL(19,6) NOT NULL, + `amount_released_derived` DECIMAL(19,6) NULL, + `amount_remaining_derived` DECIMAL(19,6) NULL, + `amount_transfered_derived` DECIMAL(19,6) NULL, + `status_enum` SMALLINT(3) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `FK_m_guarantor_fund_details_m_guarantor` FOREIGN KEY (`guarantor_id`) REFERENCES `m_guarantor` (`id`), + CONSTRAINT `FK_m_guarantor_fund_details_account_associations_id` FOREIGN KEY (`account_associations_id`) REFERENCES `m_portfolio_account_associations` (`id`) +); + +CREATE TABLE `m_deposit_account_on_hold_transaction` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `savings_account_id` BIGINT(20) NOT NULL, + `amount` DECIMAL(19,6) NOT NULL, + `transaction_type_enum` SMALLINT(1) NOT NULL, + `transaction_date` DATE NOT NULL, + `is_reversed` TINYINT(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + CONSTRAINT `FK_deposit_on_hold_transaction_m_savings_account` FOREIGN KEY (`savings_account_id`) REFERENCES `m_savings_account` (`id`) +); + +CREATE TABLE `m_guarantor_transaction` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `guarantor_fund_detail_id` BIGINT(20) NOT NULL, + `loan_transaction_id` BIGINT(20) NOT NULL, + `deposit_on_hold_transaction_id` BIGINT(20) NOT NULL, + `is_reversed` TINYINT(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + CONSTRAINT `FK_guarantor_transaction_m_deposit_account_on_hold_transaction` FOREIGN KEY (`deposit_on_hold_transaction_id`) REFERENCES `m_deposit_account_on_hold_transaction` (`id`), + CONSTRAINT `FK_guarantor_transaction_guarantor_fund_detail` FOREIGN KEY (`guarantor_fund_detail_id`) REFERENCES `m_guarantor_funding_details` (`id`), + CONSTRAINT `FK_guarantor_transaction_m_loan_transaction` FOREIGN KEY (`loan_transaction_id`) REFERENCES `m_loan_transaction` (`id`) +); + +ALTER TABLE `m_loan` + ADD COLUMN `guarantee_amount_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `interest_recalculation_enabled`, + ADD COLUMN `guarantee_outstanding_amount_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `guarantee_amount_derived`; + From 958fb33db212eae00e91fa2a3e8ffe649286fbd7 Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Mon, 24 Nov 2014 13:17:07 +0530 Subject: [PATCH 2/2] added licences --- .../portfolio/account/data/PortfolioAccountDTO.java | 5 +++++ .../loanaccount/guarantor/data/GuarantorFundingData.java | 5 +++++ .../loanaccount/guarantor/data/GuarantorTransactionData.java | 5 +++++ .../guarantor/domain/GuarantorFundingDetails.java | 5 +++++ .../guarantor/domain/GuarantorFundingTransaction.java | 5 +++++ .../savings/data/DepositAccountOnHoldTransactionData.java | 5 +++++ .../savings/domain/DepositAccountOnHoldTransaction.java | 5 +++++ 7 files changed, 35 insertions(+) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java index 2e453d950..f7330affb 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/account/data/PortfolioAccountDTO.java @@ -1,3 +1,8 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ package org.mifosplatform.portfolio.account.data; public class PortfolioAccountDTO { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java index 7e19b58cf..586236324 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorFundingData.java @@ -1,3 +1,8 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ package org.mifosplatform.portfolio.loanaccount.guarantor.data; import java.math.BigDecimal; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java index 78d7f2596..a6cabd409 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/data/GuarantorTransactionData.java @@ -1,3 +1,8 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ package org.mifosplatform.portfolio.loanaccount.guarantor.data; import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java index f87b93ca9..6c805b52f 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java @@ -1,3 +1,8 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ package org.mifosplatform.portfolio.loanaccount.guarantor.domain; import java.math.BigDecimal; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java index 0a687fce5..dc9b9c809 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java @@ -1,3 +1,8 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ package org.mifosplatform.portfolio.loanaccount.guarantor.domain; import javax.persistence.Column; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java index aff3b1a02..405393ed1 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/data/DepositAccountOnHoldTransactionData.java @@ -1,3 +1,8 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ package org.mifosplatform.portfolio.savings.data; import java.math.BigDecimal; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java index 6b79b65f2..09142300c 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java @@ -1,3 +1,8 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ package org.mifosplatform.portfolio.savings.domain; import java.math.BigDecimal;