diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferData.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferData.java index 7d019de8361..23b7267d3ff 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferData.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferData.java @@ -27,6 +27,7 @@ import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.office.data.OfficeData; import org.apache.fineract.portfolio.client.data.ClientData; +import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData; /** * Immutable data object representing a savings account. @@ -48,6 +49,7 @@ public final class AccountTransferData implements Serializable { private final ClientData toClient; private final EnumOptionData toAccountType; private final PortfolioAccountData toAccount; + private final PaymentDetailData paymentDetailData; // template private final Collection fromOfficeOptions; @@ -78,7 +80,7 @@ public static AccountTransferData template(final OfficeData fromOffice, final Cl final String transferDescription = null; final Boolean reversed = null; return new AccountTransferData(id, reversed, fromOffice, fromClient, fromAccountType, fromAccount, currency, transferAmount, - transferDate, transferDescription, toOffice, toClient, toAccountType, toAccount, fromOfficeOptions, fromClientOptions, + transferDate, transferDescription, toOffice, toClient, toAccountType, toAccount, null, fromOfficeOptions, fromClientOptions, fromAccountTypeOptions, fromAccountOptions, toOfficeOptions, toClientOptions, toAccountTypeOptions, toAccountOptions); } @@ -89,7 +91,18 @@ public static AccountTransferData instance(final Long id, final Boolean reversed return new AccountTransferData(id, reversed, fromOffice, fromClient, fromAccountType, fromAccount, currency, transferAmount, transferDate, transferDescription, toOffice, toClient, toAccountType, toAccount, null, null, null, null, null, null, null, - null); + null, null); + } + + public static AccountTransferData instance(final Long id, final Boolean reversed, final LocalDate transferDate, + final CurrencyData currency, final BigDecimal transferAmount, final String transferDescription, final OfficeData fromOffice, + final OfficeData toOffice, final ClientData fromClient, final ClientData toClient, final EnumOptionData fromAccountType, + final PortfolioAccountData fromAccount, final EnumOptionData toAccountType, final PortfolioAccountData toAccount, + final PaymentDetailData paymentDetailData) { + + return new AccountTransferData(id, reversed, fromOffice, fromClient, fromAccountType, fromAccount, currency, transferAmount, + transferDate, transferDescription, toOffice, toClient, toAccountType, toAccount, paymentDetailData, null, null, null, null, + null, null, null, null); } public static AccountTransferData transferBasicDetails(final Long id, final CurrencyData currency, final BigDecimal transferAmount, @@ -99,17 +112,18 @@ public static AccountTransferData transferBasicDetails(final Long id, final Curr final EnumOptionData toAccountType = null; return new AccountTransferData(id, reversed, null, null, fromAccountType, null, currency, transferAmount, transferDate, description, - null, null, toAccountType, null, null, null, null, null, null, null, null, null); + null, null, toAccountType, null, null, null, null, null, null, null, null, null, null); } private AccountTransferData(final Long id, final Boolean reversed, final OfficeData fromOffice, final ClientData fromClient, final EnumOptionData fromAccountType, final PortfolioAccountData fromAccount, final CurrencyData currency, final BigDecimal transferAmount, final LocalDate transferDate, final String transferDescription, final OfficeData toOffice, final ClientData toClient, final EnumOptionData toAccountType, final PortfolioAccountData toAccount, - final Collection fromOfficeOptions, final Collection fromClientOptions, - final Collection fromAccountTypeOptions, final Collection fromAccountOptions, - final Collection toOfficeOptions, final Collection toClientOptions, - final Collection toAccountTypeOptions, final Collection toAccountOptions) { + final PaymentDetailData paymentDetailData, final Collection fromOfficeOptions, + final Collection fromClientOptions, final Collection fromAccountTypeOptions, + final Collection fromAccountOptions, final Collection toOfficeOptions, + final Collection toClientOptions, final Collection toAccountTypeOptions, + final Collection toAccountOptions) { this.id = id; this.reversed = reversed; this.fromOffice = fromOffice; @@ -125,6 +139,7 @@ private AccountTransferData(final Long id, final Boolean reversed, final OfficeD this.transferAmount = transferAmount; this.transferDate = transferDate; this.transferDescription = transferDescription; + this.paymentDetailData = paymentDetailData; this.fromOfficeOptions = fromOfficeOptions; this.fromClientOptions = fromClientOptions; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/api/AccountTransfersApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/api/AccountTransfersApiResourceSwagger.java index 8e34eff52a9..c19739f6b20 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/api/AccountTransfersApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/api/AccountTransfersApiResourceSwagger.java @@ -170,6 +170,18 @@ private PostAccountTransfersRequest() {} public Float transferAmount; @Schema(example = "A description of the transfer") public String transferDescription; + @Schema(example = "1") + public Long paymentTypeId; + @Schema(example = "ACC-123") + public String accountNumber; + @Schema(example = "CHK-123") + public String checkNumber; + @Schema(example = "RT-123") + public String routingCode; + @Schema(example = "RC-123") + public String receiptNumber; + @Schema(example = "BNK-123") + public String bankNumber; } @Schema(description = "PostAccountTransfersResponse") @@ -242,6 +254,35 @@ private GetAccountTransfersPageItemsToAccountType() {} public String description; } + static final class GetAccountTransfersPageItemsPaymentDetailData { + + private GetAccountTransfersPageItemsPaymentDetailData() {} + + static final class GetAccountTransfersPageItemsPaymentType { + + private GetAccountTransfersPageItemsPaymentType() {} + + @Schema(example = "1") + public Long id; + @Schema(example = "Cash") + public String name; + } + + @Schema(example = "1") + public Long id; + public GetAccountTransfersPageItemsPaymentType paymentType; + @Schema(example = "ACC-123") + public String accountNumber; + @Schema(example = "CHK-123") + public String checkNumber; + @Schema(example = "RT-123") + public String routingCode; + @Schema(example = "RC-123") + public String receiptNumber; + @Schema(example = "BNK-123") + public String bankNumber; + } + @Schema(example = "1") public Long id; @Schema(example = "false") @@ -261,6 +302,7 @@ private GetAccountTransfersPageItemsToAccountType() {} public GetAccountTransfersTemplateResponse.GetAccountTransfersFromClientOptions toClient; public GetAccountTransfersPageItemsToAccountType toAccountType; public GetAccountTransfersPageItemsFromAccount toAccount; + public GetAccountTransfersPageItemsPaymentDetailData paymentDetailData; } @Schema(example = "4") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferDTO.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferDTO.java index 2d46ba2be1e..8c2882b5add 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferDTO.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransferDTO.java @@ -96,6 +96,15 @@ public AccountTransferDTO(final LocalDate transactionDate, final BigDecimal tran final Long toAccountId, final String description, final Locale locale, final DateTimeFormatter fmt, final Integer fromTransferType, final Integer toTransferType, final ExternalId txnExternalId, final Loan fromLoan, final Loan toLoan) { + this(transactionDate, transactionAmount, fromAccountType, toAccountType, fromAccountId, toAccountId, description, locale, fmt, null, + fromTransferType, toTransferType, txnExternalId, fromLoan, toLoan); + } + + public AccountTransferDTO(final LocalDate transactionDate, final BigDecimal transactionAmount, + final PortfolioAccountType fromAccountType, final PortfolioAccountType toAccountType, final Long fromAccountId, + final Long toAccountId, final String description, final Locale locale, final DateTimeFormatter fmt, + final PaymentDetail paymentDetail, final Integer fromTransferType, final Integer toTransferType, final ExternalId txnExternalId, + final Loan fromLoan, final Loan toLoan) { this.transactionDate = transactionDate; this.transactionAmount = transactionAmount; this.fromAccountType = fromAccountType; @@ -105,7 +114,7 @@ public AccountTransferDTO(final LocalDate transactionDate, final BigDecimal tran this.description = description; this.locale = locale; this.fmt = fmt; - this.paymentDetail = null; + this.paymentDetail = paymentDetail; this.fromTransferType = fromTransferType; this.toTransferType = toTransferType; this.chargeId = null; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransfersDataValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransfersDataValidator.java index 61ab78ad4bf..edd7b885cfa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransfersDataValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/AccountTransfersDataValidator.java @@ -38,6 +38,7 @@ import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; import org.apache.fineract.portfolio.account.AccountDetailConstants; import org.apache.fineract.portfolio.account.api.AccountTransfersApiConstants; +import org.apache.fineract.portfolio.paymentdetail.PaymentDetailConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -52,7 +53,10 @@ public class AccountTransfersDataValidator { AccountDetailConstants.fromAccountIdParamName, AccountDetailConstants.toOfficeIdParamName, AccountDetailConstants.toClientIdParamName, AccountDetailConstants.toAccountTypeParamName, AccountDetailConstants.toAccountIdParamName, AccountTransfersApiConstants.transferDateParamName, - AccountTransfersApiConstants.transferAmountParamName, AccountTransfersApiConstants.transferDescriptionParamName)); + AccountTransfersApiConstants.transferAmountParamName, AccountTransfersApiConstants.transferDescriptionParamName, + PaymentDetailConstants.paymentTypeParamName, PaymentDetailConstants.accountNumberParamName, + PaymentDetailConstants.checkNumberParamName, PaymentDetailConstants.routingCodeParamName, + PaymentDetailConstants.receiptNumberParamName, PaymentDetailConstants.bankNumberParamName)); @Autowired public AccountTransfersDataValidator(final FromJsonHelper fromApiJsonHelper, @@ -94,9 +98,34 @@ public void validate(final JsonCommand command) { baseDataValidator.reset().parameter(AccountTransfersApiConstants.transferDescriptionParamName).value(transactionDescription) .notBlank().notExceedingLengthOf(200); + validatePaymentTypeDetails(baseDataValidator, element); + throwExceptionIfValidationWarningsExist(dataValidationErrors); } + private void validatePaymentTypeDetails(final DataValidatorBuilder baseDataValidator, final JsonElement element) { + boolean checkPaymentTypeDetails = false; + final Integer paymentTypeId = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(PaymentDetailConstants.paymentTypeParamName, + element); + baseDataValidator.reset().parameter(PaymentDetailConstants.paymentTypeParamName).value(paymentTypeId).ignoreIfNull() + .integerGreaterThanZero(); + final Set paymentDetailParameters = new HashSet<>(Arrays.asList(PaymentDetailConstants.accountNumberParamName, + PaymentDetailConstants.checkNumberParamName, PaymentDetailConstants.routingCodeParamName, + PaymentDetailConstants.receiptNumberParamName, PaymentDetailConstants.bankNumberParamName)); + for (final String paymentDetailParameterName : paymentDetailParameters) { + final String paymentDetailParameterValue = this.fromApiJsonHelper.extractStringNamed(paymentDetailParameterName, element); + baseDataValidator.reset().parameter(paymentDetailParameterName).value(paymentDetailParameterValue).ignoreIfNull() + .notExceedingLengthOf(50); + if (paymentDetailParameterValue != null && !paymentDetailParameterValue.equals("")) { + checkPaymentTypeDetails = true; + } + } + if (checkPaymentTypeDetails) { + baseDataValidator.reset().parameter(PaymentDetailConstants.paymentTypeParamName).value(paymentTypeId).notBlank() + .integerGreaterThanZero(); + } + } + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/request/AccountTransferRequest.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/request/AccountTransferRequest.java index 39f1b5f0141..95b61ce2ba3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/request/AccountTransferRequest.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/data/request/AccountTransferRequest.java @@ -43,4 +43,10 @@ public class AccountTransferRequest implements Serializable { private String toClientId; private String fromAccountId; private String fromOfficeId; + private Long paymentTypeId; + private String accountNumber; + private String checkNumber; + private String routingCode; + private String receiptNumber; + private String bankNumber; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferAssembler.java index 48445373e8e..091a7dc40eb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferAssembler.java @@ -56,7 +56,7 @@ public AccountTransferDetails assembleSavingsToSavingsTransfer(final JsonCommand final String description = command.stringValueOfParameterNamed(transferDescriptionParamName); AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToSavingsTransfer(accountTransferDetails, - withdrawal, deposit, transactionDate, transactionMonetaryAmount, description); + withdrawal, deposit, transactionDate, transactionMonetaryAmount, description, withdrawal.getPaymentDetail()); accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction); return accountTransferDetails; } @@ -73,7 +73,8 @@ public AccountTransferDetails assembleSavingsToLoanTransfer(final JsonCommand co final String description = command.stringValueOfParameterNamed(transferDescriptionParamName); AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToLoanTransfer(accountTransferDetails, - withdrawal, loanRepaymentTransaction, transactionDate, transactionMonetaryAmount, description); + withdrawal, loanRepaymentTransaction, transactionDate, transactionMonetaryAmount, description, + withdrawal.getPaymentDetail()); accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction); return accountTransferDetails; } @@ -91,7 +92,7 @@ public AccountTransferDetails assembleLoanToSavingsTransfer(final JsonCommand co final String description = command.stringValueOfParameterNamed(transferDescriptionParamName); AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.loanTosavingsTransfer(accountTransferDetails, - deposit, loanRefundTransaction, transactionDate, transactionMonetaryAmount, description); + deposit, loanRefundTransaction, transactionDate, transactionMonetaryAmount, description, deposit.getPaymentDetail()); accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction); return accountTransferDetails; } @@ -107,7 +108,7 @@ public AccountTransferDetails assembleSavingsToLoanTransfer(final AccountTransfe } AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToLoanTransfer(accountTransferDetails, savingsAccountTransaction, loanTransaction, accountTransferDTO.getTransactionDate(), transactionMonetaryAmount, - accountTransferDTO.getDescription()); + accountTransferDTO.getDescription(), accountTransferDTO.getPaymentDetail()); accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction); return accountTransferDetails; } @@ -124,7 +125,7 @@ public AccountTransferDetails assembleSavingsToSavingsTransfer(final AccountTran AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.savingsToSavingsTransfer(accountTransferDetails, withdrawal, deposit, accountTransferDTO.getTransactionDate(), transactionMonetaryAmount, - accountTransferDTO.getDescription()); + accountTransferDTO.getDescription(), accountTransferDTO.getPaymentDetail()); accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction); return accountTransferDetails; } @@ -139,7 +140,7 @@ public AccountTransferDetails assembleLoanToSavingsTransfer(final AccountTransfe } AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.loanTosavingsTransfer(accountTransferDetails, deposit, loanRefundTransaction, accountTransferDTO.getTransactionDate(), transactionMonetaryAmount, - accountTransferDTO.getDescription()); + accountTransferDTO.getDescription(), accountTransferDTO.getPaymentDetail()); accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction); return accountTransferDetails; } @@ -154,7 +155,7 @@ public AccountTransferDetails assembleLoanToLoanTransfer(final AccountTransferDT } AccountTransferTransaction accountTransferTransaction = AccountTransferTransaction.loanToLoanTransfer(accountTransferDetails, disburseTransaction, repaymentTransaction, accountTransferDTO.getTransactionDate(), transactionMonetaryAmount, - accountTransferDTO.getDescription()); + accountTransferDTO.getDescription(), accountTransferDTO.getPaymentDetail()); accountTransferDetails.addAccountTransferTransaction(accountTransferTransaction); return accountTransferDetails; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java index d3755bc2b55..1965c3e9198 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java @@ -31,6 +31,7 @@ import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; +import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction; @Entity @@ -58,6 +59,10 @@ public class AccountTransferTransaction extends AbstractPersistableCustom @JoinColumn(name = "from_loan_transaction_id", nullable = true) private LoanTransaction fromLoanTransaction; + @ManyToOne + @JoinColumn(name = "payment_detail_id", nullable = true) + private PaymentDetail paymentDetail; + @Column(name = "is_reversed", nullable = false) private boolean reversed = false; @@ -77,22 +82,43 @@ public static AccountTransferTransaction savingsToSavingsTransfer(final AccountT final SavingsAccountTransaction withdrawal, final SavingsAccountTransaction deposit, final LocalDate transactionDate, final Money transactionAmount, final String description) { + return savingsToSavingsTransfer(accountTransferDetails, withdrawal, deposit, transactionDate, transactionAmount, description, null); + } + + public static AccountTransferTransaction savingsToSavingsTransfer(final AccountTransferDetails accountTransferDetails, + final SavingsAccountTransaction withdrawal, final SavingsAccountTransaction deposit, final LocalDate transactionDate, + final Money transactionAmount, final String description, final PaymentDetail paymentDetail) { + return new AccountTransferTransaction(accountTransferDetails, withdrawal, deposit, null, null, transactionDate, transactionAmount, - description); + description, paymentDetail); } public static AccountTransferTransaction savingsToLoanTransfer(final AccountTransferDetails accountTransferDetails, final SavingsAccountTransaction withdrawal, final LoanTransaction loanRepaymentTransaction, final LocalDate transactionDate, final Money transactionAmount, final String description) { + return savingsToLoanTransfer(accountTransferDetails, withdrawal, loanRepaymentTransaction, transactionDate, transactionAmount, + description, null); + } + + public static AccountTransferTransaction savingsToLoanTransfer(final AccountTransferDetails accountTransferDetails, + final SavingsAccountTransaction withdrawal, final LoanTransaction loanRepaymentTransaction, final LocalDate transactionDate, + final Money transactionAmount, final String description, final PaymentDetail paymentDetail) { return new AccountTransferTransaction(accountTransferDetails, withdrawal, null, loanRepaymentTransaction, null, transactionDate, - transactionAmount, description); + transactionAmount, description, paymentDetail); } public static AccountTransferTransaction loanTosavingsTransfer(final AccountTransferDetails accountTransferDetails, final SavingsAccountTransaction deposit, final LoanTransaction loanRefundTransaction, final LocalDate transactionDate, final Money transactionAmount, final String description) { + return loanTosavingsTransfer(accountTransferDetails, deposit, loanRefundTransaction, transactionDate, transactionAmount, + description, null); + } + + public static AccountTransferTransaction loanTosavingsTransfer(final AccountTransferDetails accountTransferDetails, + final SavingsAccountTransaction deposit, final LoanTransaction loanRefundTransaction, final LocalDate transactionDate, + final Money transactionAmount, final String description, final PaymentDetail paymentDetail) { return new AccountTransferTransaction(accountTransferDetails, null, deposit, null, loanRefundTransaction, transactionDate, - transactionAmount, description); + transactionAmount, description, paymentDetail); } protected AccountTransferTransaction() { @@ -102,12 +128,13 @@ protected AccountTransferTransaction() { private AccountTransferTransaction(final AccountTransferDetails accountTransferDetails, final SavingsAccountTransaction withdrawal, final SavingsAccountTransaction deposit, final LoanTransaction loanRepaymentTransaction, final LoanTransaction loanRefundTransaction, final LocalDate transactionDate, final Money transactionAmount, - final String description) { + final String description, final PaymentDetail paymentDetail) { this.accountTransferDetails = accountTransferDetails; this.fromLoanTransaction = loanRefundTransaction; this.fromSavingsTransaction = withdrawal; this.toSavingsTransaction = deposit; this.toLoanTransaction = loanRepaymentTransaction; + this.paymentDetail = paymentDetail; this.date = transactionDate; this.currency = transactionAmount.getCurrency(); this.amount = transactionAmount.getAmountDefaultedToNullIfZero(); @@ -153,7 +180,14 @@ public AccountTransferDetails accountTransferDetails() { public static AccountTransferTransaction loanToLoanTransfer(AccountTransferDetails accountTransferDetails, LoanTransaction disburseTransaction, LoanTransaction repaymentTransaction, LocalDate transactionDate, Money transactionMonetaryAmount, String description) { + return loanToLoanTransfer(accountTransferDetails, disburseTransaction, repaymentTransaction, transactionDate, + transactionMonetaryAmount, description, null); + } + + public static AccountTransferTransaction loanToLoanTransfer(AccountTransferDetails accountTransferDetails, + LoanTransaction disburseTransaction, LoanTransaction repaymentTransaction, LocalDate transactionDate, + Money transactionMonetaryAmount, String description, PaymentDetail paymentDetail) { return new AccountTransferTransaction(accountTransferDetails, null, null, repaymentTransaction, disburseTransaction, - transactionDate, transactionMonetaryAmount, description); + transactionDate, transactionMonetaryAmount, description, paymentDetail); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/mapper/AccountTransfersMapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/mapper/AccountTransfersMapper.java index 2f241819d46..41687f88b1e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/mapper/AccountTransfersMapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/mapper/AccountTransfersMapper.java @@ -31,6 +31,8 @@ import org.apache.fineract.portfolio.account.data.PortfolioAccountData; import org.apache.fineract.portfolio.account.service.AccountTransferEnumerations; import org.apache.fineract.portfolio.client.data.ClientData; +import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData; +import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Component; @@ -56,9 +58,15 @@ public final class AccountTransfersMapper implements RowMapper changes = new HashMap<>(); + final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); Long fromSavingsAccountId = null; Long transferDetailId = null; boolean isInterestTransfer = false; @@ -211,7 +215,7 @@ public CommandProcessingResult create(final JsonCommand command) { builder.withLoanId(fromLoanAccountId); } - return builder.build(); + return builder.with(changes).build(); } @Override @@ -575,7 +579,8 @@ public CommandProcessingResult refundByTransfer(JsonCommand command) { final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale); - final PaymentDetail paymentDetail = null; + final Map changes = new HashMap<>(); + final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); Long transferTransactionId = null; final Long fromLoanAccountId = command.longValueOfParameterNamed(fromAccountIdParamName); @@ -615,6 +620,6 @@ public CommandProcessingResult refundByTransfer(JsonCommand command) { builder.withSavingsId(toSavingsAccountId); // } - return builder.build(); + return builder.with(changes).build(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/starter/AccountConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/starter/AccountConfiguration.java index c538968909d..6a7ff45cd01 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/starter/AccountConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/starter/AccountConfiguration.java @@ -54,6 +54,7 @@ import org.apache.fineract.portfolio.loanaccount.service.LoanAssembler; import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService; import org.apache.fineract.portfolio.loanaccount.service.adjustment.LoanAdjustmentService; +import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService; import org.apache.fineract.portfolio.savings.domain.GSIMRepositoy; import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler; import org.apache.fineract.portfolio.savings.service.SavingsAccountDomainService; @@ -92,11 +93,13 @@ public AccountTransfersWritePlatformService accountTransfersWritePlatformService LoanAccountDomainService loanAccountDomainService, SavingsAccountWritePlatformService savingsAccountWritePlatformService, AccountTransferDetailRepository accountTransferDetailRepository, LoanReadPlatformService loanReadPlatformService, GSIMRepositoy gsimRepository, ConfigurationDomainService configurationDomainService, ExternalIdFactory externalIdFactory, - FineractProperties fineractProperties, LoanAdjustmentService loanAdjustmentService) { + FineractProperties fineractProperties, LoanAdjustmentService loanAdjustmentService, + PaymentDetailWritePlatformService paymentDetailWritePlatformService) { return new AccountTransfersWritePlatformServiceImpl(accountTransfersDataValidator, accountTransferAssembler, accountTransferRepository, savingsAccountAssembler, savingsAccountDomainService, loanAccountAssembler, loanAccountDomainService, savingsAccountWritePlatformService, accountTransferDetailRepository, loanReadPlatformService, - gsimRepository, configurationDomainService, externalIdFactory, fineractProperties, loanAdjustmentService); + gsimRepository, configurationDomainService, externalIdFactory, fineractProperties, loanAdjustmentService, + paymentDetailWritePlatformService); } @Bean diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index a5997753af8..ee023063839 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -262,4 +262,5 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0244_add_payment_detail_to_account_transfer_transaction.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0244_add_payment_detail_to_account_transfer_transaction.xml new file mode 100644 index 00000000000..d74e5e8ea50 --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0244_add_payment_detail_to_account_transfer_transaction.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/data/AccountTransfersDataValidatorTest.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/data/AccountTransfersDataValidatorTest.java new file mode 100644 index 00000000000..402b1029db5 --- /dev/null +++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/data/AccountTransfersDataValidatorTest.java @@ -0,0 +1,113 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.account.data; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; +import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; +import org.apache.fineract.portfolio.paymentdetail.PaymentDetailConstants; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class AccountTransfersDataValidatorTest { + + private final FromJsonHelper fromJsonHelper = new FromJsonHelper(); + private AccountTransfersDataValidator validator; + + @BeforeEach + void setUp() { + validator = new AccountTransfersDataValidator(fromJsonHelper, new AccountTransfersDetailDataValidator(fromJsonHelper)); + } + + @Test + void validateWithoutPaymentDetailsStillSucceeds() { + assertDoesNotThrow(() -> validator.validate(command(baseTransferJson()))); + } + + @Test + void validateWithPaymentDetailsSucceeds() { + assertDoesNotThrow(() -> validator.validate(command(baseTransferJson(""" + , + "paymentTypeId": 1, + "accountNumber": "ACC-123", + "checkNumber": "CHK-123", + "routingCode": "RT-123", + "receiptNumber": "RC-123", + "bankNumber": "BNK-123" + """)))); + } + + @Test + void validateRejectsPaymentDetailFieldsWithoutPaymentType() { + PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class, + () -> validator.validate(command(baseTransferJson(""" + , + "accountNumber": "ACC-123" + """)))); + + assertTrue(exception.getErrors().stream() + .anyMatch(error -> PaymentDetailConstants.paymentTypeParamName.equals(error.getParameterName()))); + } + + @Test + void validateRejectsPaymentDetailFieldsExceedingLength() { + PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class, + () -> validator.validate(command(baseTransferJson(""" + , + "paymentTypeId": 1, + "accountNumber": "123456789012345678901234567890123456789012345678901" + """)))); + + assertTrue(exception.getErrors().stream() + .anyMatch(error -> PaymentDetailConstants.accountNumberParamName.equals(error.getParameterName()))); + } + + private JsonCommand command(final String json) { + return new JsonCommand(1L, fromJsonHelper.parse(json), fromJsonHelper); + } + + private String baseTransferJson() { + return baseTransferJson(""); + } + + private String baseTransferJson(final String additionalProperties) { + return """ + { + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "fromOfficeId": 1, + "fromClientId": 1, + "fromAccountType": 2, + "fromAccountId": 1, + "toOfficeId": 1, + "toClientId": 1, + "toAccountType": 2, + "toAccountId": 2, + "transferDate": "01 March 2026", + "transferAmount": "100.0", + "transferDescription": "Transfer" + %s + } + """.formatted(additionalProperties); + } +} diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransactionTest.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransactionTest.java new file mode 100644 index 00000000000..7c124862aee --- /dev/null +++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransactionTest.java @@ -0,0 +1,81 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.account.domain; + +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.math.BigDecimal; +import java.time.LocalDate; +import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; +import org.apache.fineract.organisation.monetary.domain.Money; +import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; +import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction; +import org.junit.jupiter.api.Test; + +class AccountTransferTransactionTest { + + private static final LocalDate TRANSACTION_DATE = LocalDate.of(2026, 3, 1); + + @Test + void transferFactoriesAcceptPaymentDetailsForEveryDirection() { + PaymentDetail paymentDetail = mock(PaymentDetail.class); + AccountTransferDetails transferDetails = mock(AccountTransferDetails.class); + SavingsAccountTransaction savingsTransaction = mock(SavingsAccountTransaction.class); + LoanTransaction loanTransaction = mock(LoanTransaction.class); + Money transactionAmount = transactionAmount(); + + assertSame(paymentDetail, AccountTransferTransaction.savingsToSavingsTransfer(transferDetails, savingsTransaction, + savingsTransaction, TRANSACTION_DATE, transactionAmount, "savings to savings", paymentDetail).getPaymentDetail()); + assertSame(paymentDetail, AccountTransferTransaction.savingsToLoanTransfer(transferDetails, savingsTransaction, loanTransaction, + TRANSACTION_DATE, transactionAmount, "savings to loan", paymentDetail).getPaymentDetail()); + assertSame(paymentDetail, AccountTransferTransaction.loanTosavingsTransfer(transferDetails, savingsTransaction, loanTransaction, + TRANSACTION_DATE, transactionAmount, "loan to savings", paymentDetail).getPaymentDetail()); + assertSame(paymentDetail, AccountTransferTransaction.loanToLoanTransfer(transferDetails, loanTransaction, loanTransaction, + TRANSACTION_DATE, transactionAmount, "loan to loan", paymentDetail).getPaymentDetail()); + } + + @Test + void existingTransferFactoriesRemainPaymentDetailOptional() { + AccountTransferDetails transferDetails = mock(AccountTransferDetails.class); + SavingsAccountTransaction savingsTransaction = mock(SavingsAccountTransaction.class); + LoanTransaction loanTransaction = mock(LoanTransaction.class); + Money transactionAmount = transactionAmount(); + + assertNull(AccountTransferTransaction.savingsToSavingsTransfer(transferDetails, savingsTransaction, savingsTransaction, + TRANSACTION_DATE, transactionAmount, "savings to savings").getPaymentDetail()); + assertNull(AccountTransferTransaction.savingsToLoanTransfer(transferDetails, savingsTransaction, loanTransaction, TRANSACTION_DATE, + transactionAmount, "savings to loan").getPaymentDetail()); + assertNull(AccountTransferTransaction.loanTosavingsTransfer(transferDetails, savingsTransaction, loanTransaction, TRANSACTION_DATE, + transactionAmount, "loan to savings").getPaymentDetail()); + assertNull(AccountTransferTransaction + .loanToLoanTransfer(transferDetails, loanTransaction, loanTransaction, TRANSACTION_DATE, transactionAmount, "loan to loan") + .getPaymentDetail()); + } + + private Money transactionAmount() { + Money transactionAmount = mock(Money.class); + when(transactionAmount.getCurrency()).thenReturn(new MonetaryCurrency("USD", 2, null)); + when(transactionAmount.getAmountDefaultedToNullIfZero()).thenReturn(BigDecimal.TEN); + return transactionAmount; + } +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java index 8f252c7977e..6ec22fe4808 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java @@ -31,10 +31,13 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.apache.fineract.client.models.PaymentTypeCreateRequest; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.CollateralManagementHelper; import org.apache.fineract.integrationtests.common.CommonConstants; import org.apache.fineract.integrationtests.common.OfficeHelper; +import org.apache.fineract.integrationtests.common.PaymentTypeHelper; import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.accounting.Account; import org.apache.fineract.integrationtests.common.accounting.Account.AccountType; @@ -242,6 +245,55 @@ public void testFromSavingsToSavingsAccountTransfer() { } + @Test + public void testFromSavingsToSavingsAccountTransferWithoutPaymentDetailsReadResponseRemainsCompatible() { + this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec); + this.accountTransferHelper = new AccountTransferHelper(this.requestSpec, this.responseSpec); + + SavingsTransferFixture fixture = createSavingsTransferFixture(); + Long accountTransferDetailId = this.accountTransferHelper.accountTransferReturningResourceId(fixture.fromClientId, + fixture.fromSavingsId, fixture.toClientId, fixture.toSavingsId, FROM_SAVINGS_ACCOUNT_TYPE, TO_SAVINGS_ACCOUNT_TYPE, + ACCOUNT_TRANSFER_AMOUNT, null); + + ArrayList transfers = this.accountTransferHelper.retrieveTransfersByAccountDetailId(accountTransferDetailId); + Assertions.assertEquals(1, transfers.size()); + Assertions.assertTrue(!transfers.get(0).containsKey("paymentDetailData") || transfers.get(0).get("paymentDetailData") == null); + } + + @Test + public void testFromSavingsToSavingsAccountTransferWithPaymentDetailsPersistsAndReadsPaymentDetails() { + this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec); + this.accountTransferHelper = new AccountTransferHelper(this.requestSpec, this.responseSpec); + + SavingsTransferFixture fixture = createSavingsTransferFixture(); + Long paymentTypeId = createPaymentType(); + Map paymentDetails = Map.of("paymentTypeId", paymentTypeId, "accountNumber", "ACC-2733", "checkNumber", "CHK-2733", + "routingCode", "RT-2733", "receiptNumber", "RC-2733", "bankNumber", "BNK-2733"); + + Long accountTransferDetailId = this.accountTransferHelper.accountTransferReturningResourceId(fixture.fromClientId, + fixture.fromSavingsId, fixture.toClientId, fixture.toSavingsId, FROM_SAVINGS_ACCOUNT_TYPE, TO_SAVINGS_ACCOUNT_TYPE, + ACCOUNT_TRANSFER_AMOUNT, paymentDetails); + + ArrayList transfers = this.accountTransferHelper.retrieveTransfersByAccountDetailId(accountTransferDetailId); + Assertions.assertEquals(1, transfers.size()); + HashMap paymentDetailData = (HashMap) transfers.get(0).get("paymentDetailData"); + Assertions.assertNotNull(paymentDetailData); + HashMap paymentType = (HashMap) paymentDetailData.get("paymentType"); + Assertions.assertEquals(paymentTypeId, ((Number) paymentType.get("id")).longValue()); + Assertions.assertEquals("ACC-2733", paymentDetailData.get("accountNumber")); + Assertions.assertEquals("CHK-2733", paymentDetailData.get("checkNumber")); + Assertions.assertEquals("RT-2733", paymentDetailData.get("routingCode")); + Assertions.assertEquals("RC-2733", paymentDetailData.get("receiptNumber")); + Assertions.assertEquals("BNK-2733", paymentDetailData.get("bankNumber")); + } + + @Test + public void testAccountTransferRejectsPaymentDetailsWithoutPaymentType() { + this.accountTransferHelper = new AccountTransferHelper(this.requestSpec, this.responseSpec); + + this.accountTransferHelper.invalidAccountTransferWithPaymentDetails(Map.of("accountNumber", "ACC-2733")); + } + @Test public void testFromSavingsToLoanAccountTransfer() { final Account assetAccount = this.accountHelper.createAssetAccount(); @@ -919,6 +971,50 @@ private Integer createSavingsProduct(final RequestSpecification requestSpec, fin return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec); } + private SavingsTransferFixture createSavingsTransferFixture() { + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account liabilityAccount = this.accountHelper.createLiabilityAccount(); + + OfficeHelper officeHelper = new OfficeHelper(); + Integer fromOfficeId = officeHelper.createOffice(LocalDate.of(2011, 1, 1)).getResourceId().intValue(); + Integer toOfficeId = officeHelper.createOffice(LocalDate.of(2011, 1, 1)).getResourceId().intValue(); + + final Integer savingsProductId = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE, assetAccount, + incomeAccount, expenseAccount, liabilityAccount); + + final Integer fromClientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2011", + String.valueOf(fromOfficeId)); + final Integer fromSavingsId = createActiveSavingsAccount(fromClientId, savingsProductId); + + final Integer toClientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2011", + String.valueOf(toOfficeId)); + final Integer toSavingsId = createActiveSavingsAccount(toClientId, savingsProductId); + + return new SavingsTransferFixture(fromClientId, fromSavingsId, toClientId, toSavingsId); + } + + private Integer createActiveSavingsAccount(final Integer clientId, final Integer savingsProductId) { + final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientId, savingsProductId, ACCOUNT_TYPE_INDIVIDUAL); + HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId); + SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap); + savingsStatusHashMap = this.savingsAccountHelper.approveSavings(savingsId); + SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap); + savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId); + SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap); + return savingsId; + } + + private Long createPaymentType() { + String paymentTypeName = PaymentTypeHelper.randomNameGenerator("P_T", 5); + String description = PaymentTypeHelper.randomNameGenerator("PT_Desc", 15); + return PaymentTypeHelper + .createPaymentType( + new PaymentTypeCreateRequest().name(paymentTypeName).description(description).isCashPayment(false).position(1L)) + .getResourceId(); + } + private Integer createLoanProduct(final Account... accounts) { LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------"); final String loanProductJSON = new LoanProductTestBuilder() // @@ -973,4 +1069,7 @@ private HashMap collaterals(Integer collateralId, BigDecimal qua collateral.put("quantity", quantity.toString()); return collateral; } + + private record SavingsTransferFixture(Integer fromClientId, Integer fromSavingsId, Integer toClientId, Integer toSavingsId) { + } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/AccountTransferHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/AccountTransferHelper.java index 1ca77933075..a2ef09a7e4d 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/AccountTransferHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/AccountTransferHelper.java @@ -22,7 +22,9 @@ import io.restassured.builder.ResponseSpecBuilder; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; import org.apache.fineract.integrationtests.common.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,7 +63,15 @@ public AccountTransferHelper(final RequestSpecification requestSpec, final Respo public String build(final String fromAccountId, final String fromClientId, final String toAccountId, final String toClientId, final String fromAccountType, final String toAccountType, final String transferAmount) { - final HashMap map = new HashMap<>(); + return build(fromAccountId, fromClientId, toAccountId, toClientId, fromAccountType, toAccountType, transferAmount, null); + } + + @Deprecated(forRemoval = true) + public String build(final String fromAccountId, final String fromClientId, final String toAccountId, final String toClientId, + final String fromAccountType, final String toAccountType, final String transferAmount, + final Map paymentDetails) { + + final HashMap map = new HashMap<>(); map.put("dateFormat", "dd MMMM yyyy"); map.put("locale", LOCALE); map.put("fromClientId", fromClientId); @@ -75,6 +85,9 @@ public String build(final String fromAccountId, final String fromClientId, final map.put("transferDate", this.transferDate); map.put("transferAmount", transferAmount); map.put("transferDescription", this.transferDescription); + if (paymentDetails != null) { + map.putAll(paymentDetails); + } String savingsApplicationJSON = new Gson().toJson(map); LOG.info("{}", savingsApplicationJSON); return savingsApplicationJSON; @@ -100,6 +113,37 @@ public Integer accountTransfer(final Integer fromClientId, final Integer fromAcc accountTransferJSON, "savingsId"); } + @Deprecated(forRemoval = true) + public Long accountTransferReturningResourceId(final Integer fromClientId, final Integer fromAccountId, final Integer toClientId, + final Integer toAccountId, final String fromAccountType, final String toAccountType, final String transferAmount, + final Map paymentDetails) { + LOG.debug("--------------------------------ACCOUNT TRANSFER--------------------------------"); + final String accountTransferJSON = new AccountTransferHelper(this.requestSpec, this.responseSpec) // + .withTransferOnDate(ACCOUNT_TRANSFER_DATE) // + .build(fromAccountId.toString(), fromClientId.toString(), toAccountId.toString(), toClientId.toString(), fromAccountType, + toAccountType, transferAmount, paymentDetails); + final Integer resourceId = Utils.performServerPost(this.requestSpec, this.responseSpec, + ACCOUNT_TRANSFER_URL + "?" + Utils.TENANT_IDENTIFIER, accountTransferJSON, "resourceId"); + return resourceId.longValue(); + } + + @Deprecated(forRemoval = true) + public Object invalidAccountTransferWithPaymentDetails(final Map paymentDetails) { + LOG.debug("--------------------------------ACCOUNT TRANSFER--------------------------------"); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(400).build(); + final String accountTransferJSON = new AccountTransferHelper(this.requestSpec, this.responseSpec) // + .withTransferOnDate(ACCOUNT_TRANSFER_DATE) // + .build("1", "1", "2", "1", "2", "2", "100.0", paymentDetails); + return Utils.performServerPost(this.requestSpec, this.responseSpec, ACCOUNT_TRANSFER_URL + "?" + Utils.TENANT_IDENTIFIER, + accountTransferJSON, ""); + } + + @Deprecated(forRemoval = true) + public ArrayList retrieveTransfersByAccountDetailId(final Long accountDetailId) { + return Utils.performServerGet(this.requestSpec, this.responseSpec, + ACCOUNT_TRANSFER_URL + "?" + Utils.TENANT_IDENTIFIER + "&accountDetailId=" + accountDetailId, "pageItems"); + } + // TODO: Rewrite to use fineract-client instead! // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, // org.apache.fineract.client.models.PostLoansLoanIdRequest)