FINERACT-1596 New Merchant Issued and Payout Refunds and Goodwill Credit Transactions
This commit is contained in:
committed by
Aleksandar Vidakovic
parent
40eb547a5c
commit
c2be3d9b4b
+3
-3
@@ -73,9 +73,9 @@ public final class AccountingConstants {
|
||||
***/
|
||||
public enum AccrualAccountsForLoan {
|
||||
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(
|
||||
6), INTEREST_RECEIVABLE(
|
||||
7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9), TRANSFERS_SUSPENSE(10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
|
||||
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), //
|
||||
LOSSES_WRITTEN_OFF(6), INTEREST_RECEIVABLE(7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9), //
|
||||
TRANSFERS_SUSPENSE(10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
|
||||
+13
-5
@@ -61,9 +61,10 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
/***
|
||||
* Handle repayments, repayments at disbursement and reversal of Repayments and Repayments at disbursement
|
||||
* Handle repayments, loan refunds, repayments at disbursement and reversal of Repayments and Repayments at
|
||||
* disbursement
|
||||
***/
|
||||
else if (loanTransactionDTO.getTransactionType().isRepayment()
|
||||
else if (loanTransactionDTO.getTransactionType().isRepaymentType()
|
||||
|| loanTransactionDTO.getTransactionType().isRepaymentAtDisbursement()
|
||||
|| loanTransactionDTO.getTransactionType().isChargePayment()) {
|
||||
createJournalEntriesForRepaymentsAndWriteOffs(loanDTO, loanTransactionDTO, office, false,
|
||||
@@ -293,9 +294,16 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
transactionDate, totalDebitAmount, isReversal);
|
||||
} else {
|
||||
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode,
|
||||
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
transactionDate, totalDebitAmount, isReversal);
|
||||
if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
|
||||
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode,
|
||||
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
transactionDate, totalDebitAmount, isReversal);
|
||||
|
||||
} else {
|
||||
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode,
|
||||
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
transactionDate, totalDebitAmount, isReversal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+27
@@ -797,6 +797,33 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder loanMerchantIssuedRefundTransaction(final Long loanId) {
|
||||
this.actionName = "MERCHANTISSUEDREFUND";
|
||||
this.entityName = "LOAN";
|
||||
this.entityId = null;
|
||||
this.loanId = loanId;
|
||||
this.href = "/loans/" + loanId + "/transactions/template?command=merchantissuedrefund";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder loanPayoutRefundTransaction(final Long loanId) {
|
||||
this.actionName = "PAYOUTREFUND";
|
||||
this.entityName = "LOAN";
|
||||
this.entityId = null;
|
||||
this.loanId = loanId;
|
||||
this.href = "/loans/" + loanId + "/transactions/template?command=payoutrefund";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder loanGoodwillCreditTransaction(final Long loanId) {
|
||||
this.actionName = "GOODWILLCREDIT";
|
||||
this.entityName = "LOAN";
|
||||
this.entityId = null;
|
||||
this.loanId = loanId;
|
||||
this.href = "/loans/" + loanId + "/transactions/template?command=goodwillcredit";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder loanRecoveryPaymentTransaction(final Long loanId) {
|
||||
this.actionName = "RECOVERYPAYMENT";
|
||||
this.entityName = "LOAN";
|
||||
|
||||
+9
-9
@@ -177,8 +177,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
final Boolean isHolidayValidationDone = false;
|
||||
final HolidayDetailDTO holidayDetailDto = null;
|
||||
final boolean isRecoveryRepayment = false;
|
||||
final LoanTransaction loanRepaymentTransaction = this.loanAccountDomainService.makeRepayment(toLoanAccount,
|
||||
new CommandProcessingResultBuilder(), transactionDate, transactionAmount, paymentDetail, null, null,
|
||||
final LoanTransaction loanRepaymentTransaction = this.loanAccountDomainService.makeRepayment(LoanTransactionType.REPAYMENT,
|
||||
toLoanAccount, new CommandProcessingResultBuilder(), transactionDate, transactionAmount, paymentDetail, null, null,
|
||||
isRecoveryRepayment, isAccountTransfer, holidayDetailDto, isHolidayValidationDone);
|
||||
|
||||
final AccountTransferDetails accountTransferDetails = this.accountTransferAssembler.assembleSavingsToLoanTransfer(command,
|
||||
@@ -340,10 +340,10 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
final boolean isRecoveryRepayment = false;
|
||||
final Boolean isHolidayValidationDone = false;
|
||||
final HolidayDetailDTO holidayDetailDto = null;
|
||||
loanTransaction = this.loanAccountDomainService.makeRepayment(toLoanAccount, new CommandProcessingResultBuilder(),
|
||||
accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
||||
accountTransferDTO.getPaymentDetail(), null, null, isRecoveryRepayment, isAccountTransfer, holidayDetailDto,
|
||||
isHolidayValidationDone);
|
||||
loanTransaction = this.loanAccountDomainService.makeRepayment(LoanTransactionType.REPAYMENT, toLoanAccount,
|
||||
new CommandProcessingResultBuilder(), accountTransferDTO.getTransactionDate(),
|
||||
accountTransferDTO.getTransactionAmount(), accountTransferDTO.getPaymentDetail(), null, null, isRecoveryRepayment,
|
||||
isAccountTransfer, holidayDetailDto, isHolidayValidationDone);
|
||||
}
|
||||
|
||||
accountTransferDetails = this.accountTransferAssembler.assembleSavingsToLoanTransfer(accountTransferDTO, fromSavingsAccount,
|
||||
@@ -476,9 +476,9 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getPaymentDetail(),
|
||||
accountTransferDTO.getNoteText(), accountTransferDTO.getTxnExternalId(), true);
|
||||
|
||||
LoanTransaction repayTransaction = this.loanAccountDomainService.makeRepayment(toLoanAccount, new CommandProcessingResultBuilder(),
|
||||
accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getPaymentDetail(),
|
||||
null, null, false, isAccountTransfer, null, false, true);
|
||||
LoanTransaction repayTransaction = this.loanAccountDomainService.makeRepayment(LoanTransactionType.REPAYMENT, toLoanAccount,
|
||||
new CommandProcessingResultBuilder(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
||||
accountTransferDTO.getPaymentDetail(), null, null, false, isAccountTransfer, null, false, true);
|
||||
|
||||
AccountTransferDetails accountTransferDetails = this.accountTransferAssembler.assembleLoanToLoanTransfer(accountTransferDTO,
|
||||
fromLoanAccount, toLoanAccount, disburseTransaction, repayTransaction);
|
||||
|
||||
+4
@@ -33,6 +33,10 @@ public class BusinessEventNotificationConstants {
|
||||
LOAN_UNDO_TRANSACTION("loan_undo_transaction"), //
|
||||
LOAN_ADJUST_TRANSACTION("loan_adjust_transaction"), //
|
||||
LOAN_MAKE_REPAYMENT("loan_repayment_transaction"), //
|
||||
LOAN_MERCHANT_ISSUED_REFUND("loan_merchant_issued_refund"), //
|
||||
LOAN_PAYOUT_REFUND("loan_payout_refund"), //
|
||||
LOAN_GOODWILL_CREDIT("loan_goodwill_credit"), //
|
||||
LOAN_RECOVERY_PAYMENT("loan_recovery_payment"), //
|
||||
LOAN_WRITTEN_OFF("loan_writtenoff"), //
|
||||
LOAN_UNDO_WRITTEN_OFF("loan_undo_writtenoff"), //
|
||||
LOAN_DISBURSAL("loan_disbursal"), //
|
||||
|
||||
+43
-16
@@ -57,6 +57,7 @@ import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanRepaymentScheduleInstallmentData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanChargePaidByReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||
@@ -110,12 +111,14 @@ public class LoanTransactionsApiResource {
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(summary = "Retrieve Loan Transaction Template", description = "This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:\n"
|
||||
+ "\n" + "Field Defaults\n" + "Allowed Value Lists\n\n" + "Example Requests:\n" + "\n"
|
||||
+ "loans/1/transactions/template?command=repayment" + "\n" + "loans/1/transactions/template?command=waiveinterest" + "\n"
|
||||
+ "loans/1/transactions/template?command=writeoff" + "\n" + "loans/1/transactions/template?command=close-rescheduled" + "\n"
|
||||
+ "loans/1/transactions/template?command=close" + "\n" + "loans/1/transactions/template?command=disburse" + "\n"
|
||||
+ "loans/1/transactions/template?command=disburseToSavings" + "\n" + "loans/1/transactions/template?command=recoverypayment"
|
||||
+ "\n" + "loans/1/transactions/template?command=prepayLoan" + "\n" + "loans/1/transactions/template?command=refundbycash" + "\n"
|
||||
+ "loans/1/transactions/template?command=refundbytransfer" + "\n" + "loans/1/transactions/template?command=foreclosure" + "\n"
|
||||
+ "loans/1/transactions/template?command=repayment" + "loans/1/transactions/template?command=merchantIssuedRefund"
|
||||
+ "loans/1/transactions/template?command=payoutRefund" + "loans/1/transactions/template?command=goodwillCredit" + "\n"
|
||||
+ "loans/1/transactions/template?command=waiveinterest" + "\n" + "loans/1/transactions/template?command=writeoff" + "\n"
|
||||
+ "loans/1/transactions/template?command=close-rescheduled" + "\n" + "loans/1/transactions/template?command=close" + "\n"
|
||||
+ "loans/1/transactions/template?command=disburse" + "\n" + "loans/1/transactions/template?command=disburseToSavings" + "\n"
|
||||
+ "loans/1/transactions/template?command=recoverypayment" + "\n" + "loans/1/transactions/template?command=prepayLoan" + "\n"
|
||||
+ "loans/1/transactions/template?command=refundbycash" + "\n" + "loans/1/transactions/template?command=refundbytransfer" + "\n"
|
||||
+ "loans/1/transactions/template?command=foreclosure" + "\n"
|
||||
+ "loans/1/transactions/template?command=creditBalanceRefund (returned 'amount' field will have the overpaid value")
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoanTransactionsApiResourceSwagger.GetLoansLoanIdTransactionsTemplateResponse.class))) })
|
||||
@@ -130,6 +133,18 @@ public class LoanTransactionsApiResource {
|
||||
LoanTransactionData transactionData = null;
|
||||
if (is(commandParam, "repayment")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(loanId);
|
||||
} else if (is(commandParam, "merchantIssuedRefund")) {
|
||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.MERCHANT_ISSUED_REFUND,
|
||||
loanId, transactionDate);
|
||||
} else if (is(commandParam, "payoutRefund")) {
|
||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.PAYOUT_REFUND, loanId,
|
||||
transactionDate);
|
||||
} else if (is(commandParam, "goodwillCredit")) {
|
||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.GOODWILL_CREDIT, loanId,
|
||||
transactionDate);
|
||||
} else if (is(commandParam, "waiveinterest")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveWaiveInterestDetails(loanId);
|
||||
} else if (is(commandParam, "writeoff")) {
|
||||
@@ -156,7 +171,8 @@ public class LoanTransactionsApiResource {
|
||||
transactionDate = LocalDate.ofInstant(transactionDateParam.getDate("transactionDate", dateFormat, locale).toInstant(),
|
||||
DateUtils.getDateTimeZoneOfTenant());
|
||||
}
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(loanId, transactionDate);
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT, loanId,
|
||||
transactionDate);
|
||||
} else if (is(commandParam, "refundbycash")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveRefundByCashTemplate(loanId);
|
||||
} else if (is(commandParam, "refundbytransfer")) {
|
||||
@@ -209,15 +225,17 @@ public class LoanTransactionsApiResource {
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(summary = "Significant Loan Transactions", description = "This API covers the major loan transaction functionality\n\n"
|
||||
+ "Example Requests:\n" + "\n" + "loans/1/transactions/template?command=repayment" + " | Make a Repayment | \n"
|
||||
+ "loans/1/transactions/template?command=waiveinterest" + " | Waive Interest | \n"
|
||||
+ "loans/1/transactions/template?command=writeoff" + " | Write-off Loan | \n"
|
||||
+ "loans/1/transactions/template?command=close-rescheduled" + " | Close Rescheduled Loan | \n"
|
||||
+ "loans/1/transactions/template?command=close" + " | Close Loan | \n" + "loans/1/transactions/template?command=undowriteoff"
|
||||
+ " | Undo Loan Write-off | \n" + "loans/1/transactions/template?command=recoverypayment" + " | Make Recovery Payment | \n"
|
||||
+ "loans/1/transactions/template?command=refundByCash" + " | Make a Refund of an Active Loan by Cash | \n"
|
||||
+ "loans/1/transactions/template?command=foreclosure" + " | Foreclosure of an Active Loan | \n"
|
||||
+ "loans/1/transactions/template?command=creditBalanceRefund" + " | Credit Balance Refund" + " | \n")
|
||||
+ "Example Requests:\n" + "\n" + "loans/1/transactions?command=repayment" + " | Make a Repayment | \n"
|
||||
+ "loans/1/transactions?command=merchantIssuedRefund" + " | Merchant Issued Refund | \n"
|
||||
+ "loans/1/transactions?command=payoutRefund" + " | Payout Refund | \n" + "loans/1/transactions?command=goodwillCredit"
|
||||
+ " | Goodwil Credit | \n" + "loans/1/transactions?command=waiveinterest" + " | Waive Interest | \n"
|
||||
+ "loans/1/transactions?command=writeoff" + " | Write-off Loan | \n" + "loans/1/transactions?command=close-rescheduled"
|
||||
+ " | Close Rescheduled Loan | \n" + "loans/1/transactions?command=close" + " | Close Loan | \n"
|
||||
+ "loans/1/transactions?command=undowriteoff" + " | Undo Loan Write-off | \n" + "loans/1/transactions?command=recoverypayment"
|
||||
+ " | Make Recovery Payment | \n" + "loans/1/transactions?command=refundByCash"
|
||||
+ " | Make a Refund of an Active Loan by Cash | \n" + "loans/1/transactions?command=foreclosure"
|
||||
+ " | Foreclosure of an Active Loan | \n" + "loans/1/transactions?command=creditBalanceRefund" + " | Credit Balance Refund"
|
||||
+ " | \n")
|
||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = LoanTransactionsApiResourceSwagger.PostLoansLoanIdTransactionsRequest.class)))
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoanTransactionsApiResourceSwagger.PostLoansLoanIdTransactionsResponse.class))) })
|
||||
@@ -231,6 +249,15 @@ public class LoanTransactionsApiResource {
|
||||
if (is(commandParam, "repayment")) {
|
||||
final CommandWrapper commandRequest = builder.loanRepaymentTransaction(loanId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "merchantIssuedRefund")) {
|
||||
final CommandWrapper commandRequest = builder.loanMerchantIssuedRefundTransaction(loanId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "payoutRefund")) {
|
||||
final CommandWrapper commandRequest = builder.loanPayoutRefundTransaction(loanId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "goodwillCredit")) {
|
||||
final CommandWrapper commandRequest = builder.loanGoodwillCreditTransaction(loanId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "waiveinterest")) {
|
||||
final CommandWrapper commandRequest = builder.waiveInterestPortionTransaction(loanId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
+26
-1
@@ -31,6 +31,9 @@ public class LoanTransactionEnumData {
|
||||
private final boolean disbursement;
|
||||
private final boolean repaymentAtDisbursement;
|
||||
private final boolean repayment;
|
||||
private final boolean merchantIssuedRefund;
|
||||
private final boolean payoutRefund;
|
||||
private final boolean goodwillCredit;
|
||||
private final boolean contra;
|
||||
private final boolean waiveInterest;
|
||||
private final boolean waiveCharges;
|
||||
@@ -53,6 +56,9 @@ public class LoanTransactionEnumData {
|
||||
this.disbursement = Long.valueOf(1).equals(this.id);
|
||||
this.repaymentAtDisbursement = Long.valueOf(5).equals(this.id);
|
||||
this.repayment = Long.valueOf(2).equals(this.id);
|
||||
this.merchantIssuedRefund = Long.valueOf(21).equals(this.id);
|
||||
this.payoutRefund = Long.valueOf(22).equals(this.id);
|
||||
this.goodwillCredit = Long.valueOf(23).equals(this.id);
|
||||
this.contra = Long.valueOf(3).equals(this.id);
|
||||
this.waiveInterest = Long.valueOf(4).equals(this.id);
|
||||
this.waiveCharges = Long.valueOf(9).equals(this.id);
|
||||
@@ -88,7 +94,14 @@ public class LoanTransactionEnumData {
|
||||
* @return
|
||||
*/
|
||||
public boolean isPaymentOrReceipt() {
|
||||
if (isDisbursement() || isRepayment() || isRepaymentAtDisbursement() || isRecoveryRepayment()) {
|
||||
if (isDisbursement() || isRepaymentType() || isRepaymentAtDisbursement() || isRecoveryRepayment()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isRepaymentType() {
|
||||
if (isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -106,6 +119,18 @@ public class LoanTransactionEnumData {
|
||||
return this.repayment;
|
||||
}
|
||||
|
||||
public boolean isMerchantIssuedRefund() {
|
||||
return this.merchantIssuedRefund;
|
||||
}
|
||||
|
||||
public boolean isPayoutRefund() {
|
||||
return this.payoutRefund;
|
||||
}
|
||||
|
||||
public boolean isGoodwillCredit() {
|
||||
return this.goodwillCredit;
|
||||
}
|
||||
|
||||
public boolean isWaiveInterest() {
|
||||
return this.waiveInterest;
|
||||
}
|
||||
|
||||
+12
-12
@@ -3179,7 +3179,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
addLoanTransaction(loanTransaction);
|
||||
}
|
||||
|
||||
if (loanTransaction.isNotRepayment() && loanTransaction.isNotWaiver() && loanTransaction.isNotRecoveryRepayment()) {
|
||||
if (loanTransaction.isNotRepaymentType() && loanTransaction.isNotWaiver() && loanTransaction.isNotRecoveryRepayment()) {
|
||||
final String errorMessage = "A transaction of type repayment or recovery repayment or waiver was expected but not received.";
|
||||
throw new InvalidLoanTransactionTypeException("transaction", "is.not.a.repayment.or.waiver.or.recovery.transaction",
|
||||
errorMessage);
|
||||
@@ -3502,7 +3502,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
|
||||
final LocalDate currentTransactionDate = loanTransaction.getTransactionDate();
|
||||
for (final LoanTransaction previousTransaction : loanTransactions) {
|
||||
if (previousTransaction.isRepayment() && previousTransaction.isNotReversed()) {
|
||||
if (previousTransaction.isRepaymentType() && previousTransaction.isNotReversed()) {
|
||||
if (currentTransactionDate.isBefore(previousTransaction.getTransactionDate())) {
|
||||
isAfterLatRepayment = false;
|
||||
break;
|
||||
@@ -3543,7 +3543,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
|
||||
LocalDate lastTransactionDate = null;
|
||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||
if (transaction.isRepayment() && transaction.isNonZero()) {
|
||||
if (transaction.isRepaymentType() && transaction.isNonZero()) {
|
||||
lastTransactionDate = transaction.getTransactionDate();
|
||||
}
|
||||
}
|
||||
@@ -3615,7 +3615,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_REPAYMENT_OR_WAIVER,
|
||||
transactionForAdjustment.getTransactionDate());
|
||||
|
||||
if (transactionForAdjustment.isNotRepayment() && transactionForAdjustment.isNotWaiver()
|
||||
if (transactionForAdjustment.isNotRepaymentType() && transactionForAdjustment.isNotWaiver()
|
||||
&& transactionForAdjustment.isNotCreditBalanceRefund()) {
|
||||
final String errorMessage = "Only transactions of type repayment, waiver or credit balance refund can be adjusted.";
|
||||
throw new InvalidLoanTransactionTypeException("transaction",
|
||||
@@ -3635,7 +3635,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
this.loanStatus = LoanStatus.ACTIVE.getValue();
|
||||
}
|
||||
|
||||
if (newTransactionDetail.isRepayment() || newTransactionDetail.isInterestWaiver()) {
|
||||
if (newTransactionDetail.isRepaymentType() || newTransactionDetail.isInterestWaiver()) {
|
||||
changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(newTransactionDetail, loanLifecycleStateMachine,
|
||||
transactionForAdjustment, scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
@@ -4139,7 +4139,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
Money cumulativePaid = Money.zero(loanCurrency());
|
||||
|
||||
for (final LoanTransaction repayment : this.loanTransactions) {
|
||||
if (repayment.isRepayment() && !repayment.isReversed()) {
|
||||
if (repayment.isRepaymentType() && !repayment.isReversed()) {
|
||||
cumulativePaid = cumulativePaid.plus(repayment.getAmount(loanCurrency()));
|
||||
}
|
||||
}
|
||||
@@ -4464,7 +4464,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
&& !transaction.getTransactionDate().isAfter(tillDate)) {
|
||||
if (transaction.isAccrual()) {
|
||||
receivableInterest = receivableInterest.plus(transaction.getInterestPortion(getCurrency()));
|
||||
} else if (transaction.isRepayment() || transaction.isInterestWaiver()) {
|
||||
} else if (transaction.isRepaymentType() || transaction.isInterestWaiver()) {
|
||||
receivableInterest = receivableInterest.minus(transaction.getInterestPortion(getCurrency()));
|
||||
}
|
||||
}
|
||||
@@ -4953,7 +4953,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
public LocalDate getLastRepaymentDate() {
|
||||
LocalDate currentTransactionDate = getDisbursementDate();
|
||||
for (final LoanTransaction previousTransaction : this.loanTransactions) {
|
||||
if (previousTransaction.isRepayment()) {
|
||||
if (previousTransaction.isRepaymentType()) {
|
||||
if (currentTransactionDate.isBefore(previousTransaction.getTransactionDate())) {
|
||||
currentTransactionDate = previousTransaction.getTransactionDate();
|
||||
}
|
||||
@@ -5063,7 +5063,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
break;
|
||||
case LOAN_REPAYMENT_OR_WAIVER:
|
||||
if (!isOpen()) {
|
||||
final String defaultUserMessage = "Loan Repayment or Waiver is not allowed. Loan Account is not active.";
|
||||
final String defaultUserMessage = "Loan Repayment (or its types) or Waiver is not allowed. Loan Account is not active.";
|
||||
final ApiParameterError error = ApiParameterError
|
||||
.generalError("error.msg.loan.repayment.or.waiver.account.is.not.active", defaultUserMessage);
|
||||
dataValidationErrors.add(error);
|
||||
@@ -6223,7 +6223,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
|
||||
LocalDate lastTransactionDate = null;
|
||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||
if ((transaction.isRepayment() || transaction.isRefundForActiveLoan() || transaction.isCreditBalanceRefund())
|
||||
if ((transaction.isRepaymentType() || transaction.isRefundForActiveLoan() || transaction.isCreditBalanceRefund())
|
||||
&& transaction.isNonZero() && transaction.isNotReversed()) {
|
||||
lastTransactionDate = transaction.getTransactionDate();
|
||||
}
|
||||
@@ -6268,7 +6268,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
Collections.reverse(loanTransactions);
|
||||
for (final LoanTransaction previousTransaction : loanTransactions) {
|
||||
if (lastTransactionDate.isBefore(previousTransaction.getTransactionDate())) {
|
||||
if (previousTransaction.isRepayment() || previousTransaction.isWaiver() || previousTransaction.isChargePayment()) {
|
||||
if (previousTransaction.isRepaymentType() || previousTransaction.isWaiver() || previousTransaction.isChargePayment()) {
|
||||
throw new UndoLastTrancheDisbursementException(previousTransaction.getId());
|
||||
}
|
||||
}
|
||||
@@ -6602,7 +6602,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
receivableInterest = receivableInterest.plus(transaction.getInterestPortion(currency));
|
||||
receivableFee = receivableFee.plus(transaction.getFeeChargesPortion(currency));
|
||||
receivablePenalty = receivablePenalty.plus(transaction.getPenaltyChargesPortion(currency));
|
||||
} else if (transaction.isRepayment() || transaction.isChargePayment()) {
|
||||
} else if (transaction.isRepaymentType() || transaction.isChargePayment()) {
|
||||
receivableInterest = receivableInterest.minus(transaction.getInterestPortion(currency));
|
||||
receivableFee = receivableFee.minus(transaction.getFeeChargesPortion(currency));
|
||||
receivablePenalty = receivablePenalty.minus(transaction.getPenaltyChargesPortion(currency));
|
||||
|
||||
+7
-6
@@ -28,9 +28,9 @@ import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
|
||||
public interface LoanAccountDomainService {
|
||||
|
||||
LoanTransaction makeRepayment(Loan loan, CommandProcessingResultBuilder builderResult, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId, boolean isRecoveryRepayment,
|
||||
boolean isAccountTransfer, HolidayDetailDTO holidatDetailDto, Boolean isHolidayValidationDone);
|
||||
LoanTransaction makeRepayment(LoanTransactionType repaymentTransactionType, Loan loan, CommandProcessingResultBuilder builderResult,
|
||||
LocalDate transactionDate, BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId,
|
||||
boolean isRecoveryRepayment, boolean isAccountTransfer, HolidayDetailDTO holidatDetailDto, Boolean isHolidayValidationDone);
|
||||
|
||||
LoanTransaction makeRefund(Long accountId, CommandProcessingResultBuilder builderResult, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
||||
@@ -61,9 +61,10 @@ public interface LoanAccountDomainService {
|
||||
*/
|
||||
void recalculateAccruals(Loan loan);
|
||||
|
||||
LoanTransaction makeRepayment(Loan loan, CommandProcessingResultBuilder builderResult, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId, boolean isRecoveryRepayment,
|
||||
boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto, Boolean isHolidayValidationDone, boolean isLoanToLoanTransfer);
|
||||
LoanTransaction makeRepayment(LoanTransactionType repaymentTransactionType, Loan loan, CommandProcessingResultBuilder builderResult,
|
||||
LocalDate transactionDate, BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId,
|
||||
boolean isRecoveryRepayment, boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto, Boolean isHolidayValidationDone,
|
||||
boolean isLoanToLoanTransfer);
|
||||
|
||||
void saveLoanWithDataIntegrityViolationChecks(Loan loan);
|
||||
|
||||
|
||||
+33
-14
@@ -146,12 +146,12 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction makeRepayment(final Loan loan, final CommandProcessingResultBuilder builderResult,
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
||||
final String txnExternalId, final boolean isRecoveryRepayment, boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto,
|
||||
Boolean isHolidayValidationDone) {
|
||||
return makeRepayment(loan, builderResult, transactionDate, transactionAmount, paymentDetail, noteText, txnExternalId,
|
||||
isRecoveryRepayment, isAccountTransfer, holidayDetailDto, isHolidayValidationDone, false);
|
||||
public LoanTransaction makeRepayment(final LoanTransactionType repaymentTransactionType, final Loan loan,
|
||||
final CommandProcessingResultBuilder builderResult, final LocalDate transactionDate, final BigDecimal transactionAmount,
|
||||
final PaymentDetail paymentDetail, final String noteText, final String txnExternalId, final boolean isRecoveryRepayment,
|
||||
boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto, Boolean isHolidayValidationDone) {
|
||||
return makeRepayment(repaymentTransactionType, loan, builderResult, transactionDate, transactionAmount, paymentDetail, noteText,
|
||||
txnExternalId, isRecoveryRepayment, isAccountTransfer, holidayDetailDto, isHolidayValidationDone, false);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -171,13 +171,16 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction makeRepayment(final Loan loan, final CommandProcessingResultBuilder builderResult,
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
||||
final String txnExternalId, final boolean isRecoveryRepayment, boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto,
|
||||
Boolean isHolidayValidationDone, final boolean isLoanToLoanTransfer) {
|
||||
public LoanTransaction makeRepayment(final LoanTransactionType repaymentTransactionType, final Loan loan,
|
||||
final CommandProcessingResultBuilder builderResult, final LocalDate transactionDate, final BigDecimal transactionAmount,
|
||||
final PaymentDetail paymentDetail, final String noteText, final String txnExternalId, final boolean isRecoveryRepayment,
|
||||
boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto, Boolean isHolidayValidationDone,
|
||||
final boolean isLoanToLoanTransfer) {
|
||||
AppUser currentUser = getAppUserIfPresent();
|
||||
checkClientOrGroupActive(loan);
|
||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BusinessEvents.LOAN_MAKE_REPAYMENT,
|
||||
|
||||
BusinessEvents repaymentTypeEvent = getRepaymentTypeBusinessEvent(repaymentTransactionType, isRecoveryRepayment);
|
||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(repaymentTypeEvent,
|
||||
constructEntityMap(BusinessEntity.LOAN, loan));
|
||||
|
||||
// TODO: Is it required to validate transaction date with meeting dates
|
||||
@@ -199,8 +202,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
newRepaymentTransaction = LoanTransaction.recoveryRepayment(loan.getOffice(), repaymentAmount, paymentDetail, transactionDate,
|
||||
txnExternalId, currentDateTime, currentUser);
|
||||
} else {
|
||||
newRepaymentTransaction = LoanTransaction.repayment(loan.getOffice(), repaymentAmount, paymentDetail, transactionDate,
|
||||
txnExternalId, currentDateTime, currentUser);
|
||||
newRepaymentTransaction = LoanTransaction.repaymentType(repaymentTransactionType, loan.getOffice(), repaymentAmount,
|
||||
paymentDetail, transactionDate, txnExternalId, currentDateTime, currentUser);
|
||||
}
|
||||
|
||||
LocalDate recalculateFrom = null;
|
||||
@@ -242,7 +245,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
|
||||
recalculateAccruals(loan);
|
||||
|
||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BusinessEvents.LOAN_MAKE_REPAYMENT,
|
||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(repaymentTypeEvent,
|
||||
constructEntityMap(BusinessEntity.LOAN_TRANSACTION, newRepaymentTransaction));
|
||||
|
||||
// disable all active standing orders linked to this loan if status
|
||||
@@ -284,6 +287,22 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
return newRepaymentTransaction;
|
||||
}
|
||||
|
||||
private BusinessEvents getRepaymentTypeBusinessEvent(LoanTransactionType repaymentTransactionType, boolean isRecoveryRepayment) {
|
||||
BusinessEvents repaymentTypeEvent = null;
|
||||
if (repaymentTransactionType.isRepayment()) {
|
||||
repaymentTypeEvent = BusinessEvents.LOAN_MAKE_REPAYMENT;
|
||||
} else if (repaymentTransactionType.isMerchantIssuedRefund()) {
|
||||
repaymentTypeEvent = BusinessEvents.LOAN_MERCHANT_ISSUED_REFUND;
|
||||
} else if (repaymentTransactionType.isPayoutRefund()) {
|
||||
repaymentTypeEvent = BusinessEvents.LOAN_PAYOUT_REFUND;
|
||||
} else if (repaymentTransactionType.isGoodwillCredit()) {
|
||||
repaymentTypeEvent = BusinessEvents.LOAN_GOODWILL_CREDIT;
|
||||
} else if (isRecoveryRepayment) {
|
||||
repaymentTypeEvent = BusinessEvents.LOAN_RECOVERY_PAYMENT;
|
||||
}
|
||||
return repaymentTypeEvent;
|
||||
}
|
||||
|
||||
private void saveLoanTransactionWithDataIntegrityViolationChecks(LoanTransaction newRepaymentTransaction) {
|
||||
try {
|
||||
this.loanTransactionRepository.saveAndFlush(newRepaymentTransaction);
|
||||
|
||||
+23
-4
@@ -169,6 +169,13 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
||||
createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction repaymentType(final LoanTransactionType repaymentType, final Office office, final Money amount,
|
||||
final PaymentDetail paymentDetail, final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate,
|
||||
final AppUser appUser) {
|
||||
return new LoanTransaction(null, office, repaymentType, paymentDetail, amount.getAmount(), paymentDate, externalId, createdDate,
|
||||
appUser);
|
||||
}
|
||||
|
||||
public void setLoanTransactionToRepaymentScheduleMappings(final Integer installmentId, final BigDecimal chargePerInstallment) {
|
||||
for (LoanTransactionToRepaymentScheduleMapping loanTransactionToRepaymentScheduleMapping : this.loanTransactionToRepaymentScheduleMappings) {
|
||||
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loanTransactionToRepaymentScheduleMapping
|
||||
@@ -524,16 +531,28 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
||||
this.manuallyAdjustedOrReversed = true;
|
||||
}
|
||||
|
||||
public boolean isAnyTypeOfRepayment() {
|
||||
return isRepayment() || isRepaymentAtDisbursement() || isRecoveryRepayment();
|
||||
public boolean isRepaymentType() {
|
||||
return isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit();
|
||||
}
|
||||
|
||||
public boolean isRepayment() {
|
||||
return LoanTransactionType.REPAYMENT.equals(getTypeOf()) && isNotReversed();
|
||||
}
|
||||
|
||||
public boolean isNotRepayment() {
|
||||
return !isRepayment();
|
||||
public boolean isMerchantIssuedRefund() {
|
||||
return LoanTransactionType.MERCHANT_ISSUED_REFUND.equals(getTypeOf()) && isNotReversed();
|
||||
}
|
||||
|
||||
public boolean isPayoutRefund() {
|
||||
return LoanTransactionType.PAYOUT_REFUND.equals(getTypeOf()) && isNotReversed();
|
||||
}
|
||||
|
||||
public boolean isGoodwillCredit() {
|
||||
return LoanTransactionType.GOODWILL_CREDIT.equals(getTypeOf()) && isNotReversed();
|
||||
}
|
||||
|
||||
public boolean isNotRepaymentType() {
|
||||
return !isRepaymentType();
|
||||
}
|
||||
|
||||
public boolean isIncomePosting() {
|
||||
|
||||
+29
-1
@@ -52,7 +52,10 @@ public enum LoanTransactionType {
|
||||
CHARGE_PAYMENT(17, "loanTransactionType.chargePayment"), //
|
||||
REFUND_FOR_ACTIVE_LOAN(18, "loanTransactionType.refund"), //
|
||||
INCOME_POSTING(19, "loanTransactionType.incomePosting"), //
|
||||
CREDIT_BALANCE_REFUND(20, "loanTransactionType.creditBalanceRefund");
|
||||
CREDIT_BALANCE_REFUND(20, "loanTransactionType.creditBalanceRefund"), //
|
||||
MERCHANT_ISSUED_REFUND(21, "loanTransactionType.merchantIssuedRefund"), //
|
||||
PAYOUT_REFUND(22, "loanTransactionType.payoutRefund"), //
|
||||
GOODWILL_CREDIT(23, "loanTransactionType.goodwillCredit");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
@@ -135,6 +138,15 @@ public enum LoanTransactionType {
|
||||
case 20:
|
||||
loanTransactionType = LoanTransactionType.CREDIT_BALANCE_REFUND;
|
||||
break;
|
||||
case 21:
|
||||
loanTransactionType = LoanTransactionType.MERCHANT_ISSUED_REFUND;
|
||||
break;
|
||||
case 22:
|
||||
loanTransactionType = LoanTransactionType.PAYOUT_REFUND;
|
||||
break;
|
||||
case 23:
|
||||
loanTransactionType = LoanTransactionType.GOODWILL_CREDIT;
|
||||
break;
|
||||
default:
|
||||
loanTransactionType = LoanTransactionType.INVALID;
|
||||
break;
|
||||
@@ -154,6 +166,22 @@ public enum LoanTransactionType {
|
||||
return this.value.equals(LoanTransactionType.REPAYMENT.getValue());
|
||||
}
|
||||
|
||||
public boolean isMerchantIssuedRefund() {
|
||||
return this.value.equals(LoanTransactionType.MERCHANT_ISSUED_REFUND.getValue());
|
||||
}
|
||||
|
||||
public boolean isPayoutRefund() {
|
||||
return this.value.equals(LoanTransactionType.PAYOUT_REFUND.getValue());
|
||||
}
|
||||
|
||||
public boolean isGoodwillCredit() {
|
||||
return this.value.equals(LoanTransactionType.GOODWILL_CREDIT.getValue());
|
||||
}
|
||||
|
||||
public boolean isRepaymentType() {
|
||||
return (isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit());
|
||||
}
|
||||
|
||||
public boolean isRecoveryRepayment() {
|
||||
return this.value.equals(LoanTransactionType.RECOVERY_REPAYMENT.getValue());
|
||||
}
|
||||
|
||||
+3
-3
@@ -152,7 +152,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
Collections.sort(installments, byDate);
|
||||
}
|
||||
|
||||
if (loanTransaction.isRepayment() || loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
|
||||
if (loanTransaction.isRepaymentType() || loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
|
||||
// pass through for new transactions
|
||||
if (loanTransaction.getId() == null) {
|
||||
handleTransaction(loanTransaction, currency, installments, charges);
|
||||
@@ -230,7 +230,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
final List<LoanRepaymentScheduleInstallment> installments, final Set<LoanCharge> charges, final Money chargeAmountToProcess,
|
||||
final boolean isFeeCharge) {
|
||||
// to.
|
||||
if (loanTransaction.isRepayment() || loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
|
||||
if (loanTransaction.isRepaymentType() || loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
|
||||
loanTransaction.resetDerivedComponents();
|
||||
}
|
||||
Money transactionAmountUnprocessed = processTransaction(loanTransaction, currency, installments, chargeAmountToProcess);
|
||||
@@ -488,7 +488,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
Money unProcessed = Money.zero(currency);
|
||||
for (final LoanTransaction loanTransaction : transactionsPostDisbursement) {
|
||||
Money amountToProcess = null;
|
||||
if (loanTransaction.isRepayment() || loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
|
||||
if (loanTransaction.isRepaymentType() || loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
|
||||
loanTransaction.resetDerivedComponents();
|
||||
}
|
||||
if (loanTransaction.isInterestWaiver()) {
|
||||
|
||||
+2
-6
@@ -18,24 +18,20 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AddAndDeleteLoanDisburseDetailsCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public AddAndDeleteLoanDisburseDetailsCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
+5
-11
@@ -18,33 +18,27 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@CommandType(entity = "LOANCHARGE", action = "CREATE")
|
||||
public class AddLoanChargeCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AddLoanChargeCommandHandler.class);
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public AddLoanChargeCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
@@ -71,7 +65,7 @@ public class AddLoanChargeCommandHandler implements NewCommandSourceHandler {
|
||||
}
|
||||
|
||||
private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) {
|
||||
LOG.error("Error occured.", dve);
|
||||
log.error("Error occured.", dve);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-6
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "BULKREASSIGN")
|
||||
public class BulkUpdateLoanOfficerCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public BulkUpdateLoanOfficerCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
+2
-6
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "CLOSEASRESCHEDULED")
|
||||
public class CloseLoanAsRescheduledCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CloseLoanAsRescheduledCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
+2
-6
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "CLOSE")
|
||||
public class CloseLoanCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CloseLoanCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
+2
-2
@@ -31,9 +31,9 @@ import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@CommandType(entity = "LOAN", action = "CREDITBALANCEREFUND")
|
||||
public class CreditBalanceRefundCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
|
||||
+2
-6
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOANCHARGE", action = "DELETE")
|
||||
public class DeleteLoanChargeCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteLoanChargeCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
+2
-6
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "DISBURSE")
|
||||
public class DisburseLoanCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DisburseLoanCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
+2
-6
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "DISBURSETOSAVINGS")
|
||||
public class DisburseLoanToSavingsCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DisburseLoanToSavingsCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
|
||||
+2
-6
@@ -18,25 +18,21 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "FORECLOSURE")
|
||||
public class ForeClosureCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ForeClosureCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return writePlatformService.forecloseLoan(command.getLoanId(), command);
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "GOODWILLCREDIT")
|
||||
public class LoanGoodwilCreditCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
boolean isRecoveryRepayment = false;
|
||||
return this.writePlatformService.makeLoanRepayment(LoanTransactionType.GOODWILL_CREDIT, command.getLoanId(), command,
|
||||
isRecoveryRepayment);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "MERCHANTISSUEDREFUND")
|
||||
public class LoanMerchantIssuedRefundCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
boolean isRecoveryRepayment = false;
|
||||
return this.writePlatformService.makeLoanRepayment(LoanTransactionType.MERCHANT_ISSUED_REFUND, command.getLoanId(), command,
|
||||
isRecoveryRepayment);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "PAYOUTREFUND")
|
||||
public class LoanPayoutRefundCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
boolean isRecoveryRepayment = false;
|
||||
return this.writePlatformService.makeLoanRepayment(LoanTransactionType.PAYOUT_REFUND, command.getLoanId(), command,
|
||||
isRecoveryRepayment);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -22,6 +22,7 @@ import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -40,6 +41,6 @@ public class LoanRecoveryPaymentCommandHandler implements NewCommandSourceHandle
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
final boolean isRecoveryRepayment = true;
|
||||
return writePlatformService.makeLoanRepayment(command.getLoanId(), command, isRecoveryRepayment);
|
||||
return writePlatformService.makeLoanRepayment(LoanTransactionType.REPAYMENT, command.getLoanId(), command, isRecoveryRepayment);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-7
@@ -18,30 +18,28 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@CommandType(entity = "LOAN", action = "REPAYMENT")
|
||||
public class LoanRepaymentCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanRepaymentCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
boolean isRecoveryRepayment = false;
|
||||
return this.writePlatformService.makeLoanRepayment(command.getLoanId(), command, isRecoveryRepayment);
|
||||
return this.writePlatformService.makeLoanRepayment(LoanTransactionType.REPAYMENT, command.getLoanId(), command,
|
||||
isRecoveryRepayment);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -112,6 +112,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummaryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTopupDetails;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationDateException;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified;
|
||||
@@ -378,8 +379,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
+ " should be after last transaction date of loan to be closed "
|
||||
+ lastUserTransactionOnLoanToClose);
|
||||
}
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(loanIdToClose, newLoanApplication.getDisbursementDate()).getAmount();
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT,
|
||||
loanIdToClose, newLoanApplication.getDisbursementDate()).getAmount();
|
||||
final BigDecimal firstDisbursalAmount = newLoanApplication.getFirstDisbursalAmount();
|
||||
if (loanOutstanding.compareTo(firstDisbursalAmount) > 0) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed",
|
||||
@@ -956,8 +957,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
+ " should be after last transaction date of loan to be closed "
|
||||
+ lastUserTransactionOnLoanToClose);
|
||||
}
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(loanIdToClose, existingLoanApplication.getDisbursementDate()).getAmount();
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(
|
||||
LoanTransactionType.REPAYMENT, loanIdToClose, existingLoanApplication.getDisbursementDate()).getAmount();
|
||||
final BigDecimal firstDisbursalAmount = existingLoanApplication.getFirstDisbursalAmount();
|
||||
if (loanOutstanding.compareTo(firstDisbursalAmount) > 0) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed",
|
||||
@@ -1456,7 +1457,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
+ " should be after last transaction date of loan to be closed " + lastUserTransactionOnLoanToClose);
|
||||
}
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(loanIdToClose, expectedDisbursementDate).getAmount();
|
||||
.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT, loanIdToClose, expectedDisbursementDate).getAmount();
|
||||
final BigDecimal firstDisbursalAmount = loan.getFirstDisbursalAmount();
|
||||
if (loanOutstanding.compareTo(firstDisbursalAmount) > 0) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed",
|
||||
|
||||
+2
-1
@@ -38,6 +38,7 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
||||
@@ -114,7 +115,7 @@ public interface LoanReadPlatformService {
|
||||
|
||||
List<Long> fetchLoansForInterestRecalculation(Integer pageSize, Long maxLoanIdInList, String officeHierarchy);
|
||||
|
||||
LoanTransactionData retrieveLoanPrePaymentTemplate(Long loanId, LocalDate onDate);
|
||||
LoanTransactionData retrieveLoanPrePaymentTemplate(LoanTransactionType repaymentTransactionType, Long loanId, LocalDate onDate);
|
||||
|
||||
Collection<LoanTransactionData> retrieveWaiverLoanTransactions(Long loanId);
|
||||
|
||||
|
||||
+4
-2
@@ -445,9 +445,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionData retrieveLoanPrePaymentTemplate(final Long loanId, LocalDate onDate) {
|
||||
public LoanTransactionData retrieveLoanPrePaymentTemplate(final LoanTransactionType repaymentTransactionType, final Long loanId,
|
||||
LocalDate onDate) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
this.loanUtilService.validateRepaymentTransactionType(repaymentTransactionType);
|
||||
|
||||
final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
|
||||
loan.setHelpers(null, null, loanRepaymentScheduleTransactionProcessorFactory);
|
||||
@@ -461,7 +463,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final LocalDate recalculateFrom = null;
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loan.fetchPrepaymentDetail(scheduleGeneratorDTO, onDate);
|
||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT);
|
||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(repaymentTransactionType);
|
||||
final Collection<PaymentTypeData> paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
|
||||
final BigDecimal outstandingLoanBalance = loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount();
|
||||
final BigDecimal unrecognizedIncomePortion = null;
|
||||
|
||||
+10
@@ -30,6 +30,7 @@ import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformServiceUnavailableException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||
import org.apache.fineract.organisation.holiday.domain.HolidayRepository;
|
||||
@@ -57,6 +58,7 @@ import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -351,4 +353,12 @@ public class LoanUtilService {
|
||||
return disbursementDatas;
|
||||
}
|
||||
|
||||
public void validateRepaymentTransactionType(LoanTransactionType repaymentTransactionType) {
|
||||
if (!repaymentTransactionType.isRepaymentType()) {
|
||||
throw new PlatformServiceUnavailableException("error.msg.repaymentTransactionType.provided.not.a.repayment.type",
|
||||
"Loan :" + repaymentTransactionType.getCode() + " Repayment Transaction Type provided is not a Repayment Type",
|
||||
repaymentTransactionType.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -32,6 +32,7 @@ import org.apache.fineract.portfolio.collectionsheet.command.CollectionSheetBulk
|
||||
import org.apache.fineract.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
||||
|
||||
public interface LoanWritePlatformService {
|
||||
@@ -43,7 +44,8 @@ public interface LoanWritePlatformService {
|
||||
|
||||
CommandProcessingResult undoLoanDisbursal(Long loanId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult makeLoanRepayment(Long loanId, JsonCommand command, boolean isRecoveryRepayment);
|
||||
CommandProcessingResult makeLoanRepayment(LoanTransactionType repaymentTransactionType, Long loanId, JsonCommand command,
|
||||
boolean isRecoveryRepayment);
|
||||
|
||||
Map<String, Object> makeLoanBulkRepayment(CollectionSheetBulkRepaymentCommand bulkRepaymentCommand);
|
||||
|
||||
|
||||
+14
-12
@@ -488,7 +488,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(loanIdToClose, actualDisbursementDate).getAmount();
|
||||
.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT, loanIdToClose, actualDisbursementDate).getAmount();
|
||||
final BigDecimal firstDisbursalAmount = loan.getFirstDisbursalAmount();
|
||||
if (loanOutstanding.compareTo(firstDisbursalAmount) > 0) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed",
|
||||
@@ -886,7 +886,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final LocalDate expectedDisbursementDate = command
|
||||
.localDateValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName);
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(loanIdToClose, expectedDisbursementDate).getAmount();
|
||||
.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT, loanIdToClose, expectedDisbursementDate).getAmount();
|
||||
BigDecimal netDisbursalAmount = loan.getApprovedPrincipal().subtract(loanOutstanding);
|
||||
loan.adjustNetDisbursalAmount(netDisbursalAmount);
|
||||
}
|
||||
@@ -941,15 +941,17 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
int j = 0;
|
||||
for (JsonElement element : repayments) {
|
||||
childCommand = JsonCommand.fromExistingCommand(command, element);
|
||||
result = makeLoanRepayment(childLoanId[j++], childCommand, false);
|
||||
result = makeLoanRepayment(LoanTransactionType.REPAYMENT, childLoanId[j++], childCommand, false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult makeLoanRepayment(final Long loanId, final JsonCommand command, final boolean isRecoveryRepayment) {
|
||||
public CommandProcessingResult makeLoanRepayment(final LoanTransactionType repaymentTransactionType, final Long loanId,
|
||||
final JsonCommand command, final boolean isRecoveryRepayment) {
|
||||
|
||||
this.loanUtilService.validateRepaymentTransactionType(repaymentTransactionType);
|
||||
this.loanEventApiJsonValidator.validateNewRepaymentTransaction(command.json());
|
||||
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
@@ -973,9 +975,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final HolidayDetailDTO holidayDetailDto = null;
|
||||
boolean isAccountTransfer = false;
|
||||
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
||||
LoanTransaction loanTransaction = this.loanAccountDomainService.makeRepayment(loan, commandProcessingResultBuilder, transactionDate,
|
||||
transactionAmount, paymentDetail, noteText, txnExternalId, isRecoveryRepayment, isAccountTransfer, holidayDetailDto,
|
||||
isHolidayValidationDone);
|
||||
LoanTransaction loanTransaction = this.loanAccountDomainService.makeRepayment(repaymentTransactionType, loan,
|
||||
commandProcessingResultBuilder, transactionDate, transactionAmount, paymentDetail, noteText, txnExternalId,
|
||||
isRecoveryRepayment, isAccountTransfer, holidayDetailDto, isHolidayValidationDone);
|
||||
|
||||
// Update loan transaction on repayment.
|
||||
if (AccountType.fromInt(loan.getLoanType()).isIndividualAccount()) {
|
||||
@@ -1044,10 +1046,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
|
||||
}
|
||||
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
||||
LoanTransaction loanTransaction = this.loanAccountDomainService.makeRepayment(loan, commandProcessingResultBuilder,
|
||||
bulkRepaymentCommand.getTransactionDate(), singleLoanRepaymentCommand.getTransactionAmount(), paymentDetail,
|
||||
bulkRepaymentCommand.getNote(), null, isRecoveryRepayment, isAccountTransfer, holidayDetailDTO,
|
||||
isHolidayValidationDone);
|
||||
LoanTransaction loanTransaction = this.loanAccountDomainService.makeRepayment(LoanTransactionType.REPAYMENT, loan,
|
||||
commandProcessingResultBuilder, bulkRepaymentCommand.getTransactionDate(),
|
||||
singleLoanRepaymentCommand.getTransactionAmount(), paymentDetail, bulkRepaymentCommand.getNote(), null,
|
||||
isRecoveryRepayment, isAccountTransfer, holidayDetailDTO, isHolidayValidationDone);
|
||||
transactionIds.add(loanTransaction.getId());
|
||||
}
|
||||
}
|
||||
@@ -1183,7 +1185,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||
Map<BusinessEntity, Object> entityMap = constructEntityMap(BusinessEntity.LOAN_ADJUSTED_TRANSACTION, transactionToAdjust);
|
||||
if (newTransactionDetail.isRepayment() && newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
|
||||
if (newTransactionDetail.isRepaymentType() && newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
|
||||
entityMap.put(BusinessEntity.LOAN_TRANSACTION, newTransactionDetail);
|
||||
}
|
||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BusinessEvents.LOAN_ADJUST_TRANSACTION, entityMap);
|
||||
|
||||
+12
@@ -415,6 +415,18 @@ public final class LoanEnumerations {
|
||||
optionData = new LoanTransactionEnumData(LoanTransactionType.CREDIT_BALANCE_REFUND.getValue().longValue(),
|
||||
LoanTransactionType.CREDIT_BALANCE_REFUND.getCode(), "Credit Balance Refund");
|
||||
break;
|
||||
case MERCHANT_ISSUED_REFUND:
|
||||
optionData = new LoanTransactionEnumData(LoanTransactionType.MERCHANT_ISSUED_REFUND.getValue().longValue(),
|
||||
LoanTransactionType.MERCHANT_ISSUED_REFUND.getCode(), "Merchant Issued Refund");
|
||||
break;
|
||||
case PAYOUT_REFUND:
|
||||
optionData = new LoanTransactionEnumData(LoanTransactionType.PAYOUT_REFUND.getValue().longValue(),
|
||||
LoanTransactionType.PAYOUT_REFUND.getCode(), "Payout Refund");
|
||||
break;
|
||||
case GOODWILL_CREDIT:
|
||||
optionData = new LoanTransactionEnumData(LoanTransactionType.GOODWILL_CREDIT.getValue().longValue(),
|
||||
LoanTransactionType.GOODWILL_CREDIT.getCode(), "Goodwill Credit");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
|
||||
@@ -31,4 +31,5 @@
|
||||
<include file="parts/0009_hold_reason_savings_account.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0010_lien_allowed_on_savings_account_products.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0011_add_credit_balance_refund_permission.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0012_add_merchantissuedrefund_payoutrefund_goodwillcredit_permissions.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
<changeSet author="fineract" id="1">
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="transaction_loan" />
|
||||
<column name="code" value="MERCHANTISSUEDREFUND_LOAN" />
|
||||
<column name="entity_name" value="LOAN" />
|
||||
<column name="action_name" value="MERCHANTISSUEDREFUND" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="transaction_loan" />
|
||||
<column name="code" value="PAYOUTREFUND_LOAN" />
|
||||
<column name="entity_name" value="LOAN" />
|
||||
<column name="action_name" value="PAYOUTREFUND" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="transaction_loan" />
|
||||
<column name="code" value="GOODWILLCREDIT_LOAN" />
|
||||
<column name="entity_name" value="LOAN" />
|
||||
<column name="action_name" value="GOODWILLCREDIT" />
|
||||
<column name="can_maker_checker" valueBoolean="false" />
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+56
-7
@@ -45,9 +45,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ClientLoanCreditBalanceRefundIntegrationTest.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.class);
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
private RequestSpecification requestSpec;
|
||||
@@ -56,11 +56,15 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
private JournalEntryHelper journalEntryHelper;
|
||||
private AccountHelper accountHelper;
|
||||
private Integer disbursedLoanID;
|
||||
private static final String CASH_BASED = "2";
|
||||
private static final String ACCRUAL_PERIODIC = "3";
|
||||
private Account assetAccount;
|
||||
private Account incomeAccount;
|
||||
private Account expenseAccount;
|
||||
private Account overpaymentAccount;
|
||||
private static final String MERCHANT_ISSUED_REFUND = "merchantIssuedRefund";
|
||||
private static final String PAYOUT_REFUND = "payoutRefund";
|
||||
private static final String GOODWILL_CREDIT = "goodwillCredit";
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
@@ -76,12 +80,13 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
this.expenseAccount = this.accountHelper.createExpenseAccount();
|
||||
this.overpaymentAccount = this.accountHelper.createLiabilityAccount();
|
||||
this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec);
|
||||
}
|
||||
|
||||
private void disburseLoanOfAccountingRule(final String accountingType) {
|
||||
final String principal = "12000.00";
|
||||
final String submitApproveDisburseDate = "01 January 2022";
|
||||
this.disbursedLoanID = fromStartToDisburseLoan(submitApproveDisburseDate, principal, ACCRUAL_PERIODIC, assetAccount, incomeAccount,
|
||||
expenseAccount, overpaymentAccount);
|
||||
|
||||
}
|
||||
|
||||
private Integer createLoanProduct(final String principal, final boolean multiDisburseLoan, final String accountingRule,
|
||||
@@ -162,6 +167,7 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void creditBalanceRefundCanOnlyBeAppliedWhereLoanStatusIsOverpaidTest() {
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 2000.00f); // not full payment
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
|
||||
@@ -174,14 +180,11 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
assertEquals("error.msg.loan.credit.balance.refund.account.is.not.overpaid",
|
||||
cbrErrors.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
|
||||
|
||||
// ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec,
|
||||
// this.responseSpec, loanID);
|
||||
// final int loanScheduleLineCount = loanSchedule.size();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cantRefundMoreThanOverpaidTest() {
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
@@ -204,6 +207,7 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void fullRefundChangesStatusToClosedObligationMetTest() {
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
@@ -229,6 +233,7 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void partialRefundKeepsOverpaidStatusTest() {
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
@@ -246,6 +251,7 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
@Test
|
||||
public void newCreditBalanceRefundSavesExternalIdTest() {
|
||||
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
@@ -265,6 +271,7 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
@Test
|
||||
public void newCreditBalanceRefundFindsDuplicateExternalIdTest() {
|
||||
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
@@ -287,6 +294,7 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
@Test
|
||||
public void newCreditBalanceRefundCreatesCorrectJournalEntriesForPeriodicAccrualsTest() {
|
||||
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
@@ -304,4 +312,45 @@ public class ClientLoanCreditBalanceRefundIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newCreditBalanceRefundCreatesCorrectJournalEntriesForCashAccrualsTest() {
|
||||
|
||||
disburseLoanOfAccountingRule(CASH_BASED);
|
||||
HashMap loanStatusHashMap = makeRepayment("08 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
final Float refund = 1000.00f; // partial refund
|
||||
final String creditBalanceRefundDate = "09 January 2022";
|
||||
final String externalId = null;
|
||||
final Integer resourceId = (Integer) loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, refund, externalId,
|
||||
disbursedLoanID, "resourceId");
|
||||
Assertions.assertNotNull(resourceId);
|
||||
|
||||
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, creditBalanceRefundDate,
|
||||
new JournalEntry(refund, JournalEntry.TransactionType.DEBIT));
|
||||
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount, creditBalanceRefundDate,
|
||||
new JournalEntry(refund, JournalEntry.TransactionType.CREDIT));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void repaymentTransactionTypeMatchesTest() {
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC);
|
||||
verifyRepaymentTransactionTypeMatches(MERCHANT_ISSUED_REFUND);
|
||||
verifyRepaymentTransactionTypeMatches(PAYOUT_REFUND);
|
||||
verifyRepaymentTransactionTypeMatches(GOODWILL_CREDIT);
|
||||
|
||||
}
|
||||
|
||||
private void verifyRepaymentTransactionTypeMatches(final String repaymentTransactionType) {
|
||||
HashMap loanStatusHashMap = this.loanTransactionHelper.makeRepaymentTypePayment(repaymentTransactionType, "06 January 2022",
|
||||
200.00f, this.disbursedLoanID);
|
||||
Integer newTransactionId = (Integer) loanStatusHashMap.get("resourceId");
|
||||
loanStatusHashMap = this.loanTransactionHelper.getLoanTransactionDetails(this.disbursedLoanID, newTransactionId);
|
||||
|
||||
HashMap typeMap = (HashMap) loanStatusHashMap.get("type");
|
||||
Boolean isTypeCorrect = (Boolean) typeMap.get(repaymentTransactionType);
|
||||
Assertions.assertTrue(Boolean.TRUE.equals(isTypeCorrect), "Not " + repaymentTransactionType);
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -339,6 +339,12 @@ public class LoanTransactionHelper {
|
||||
getCreditBalanceRefundBodyAsJSON(date, amountToBePaid, externalId), jsonAttributeToGetback);
|
||||
}
|
||||
|
||||
public HashMap makeRepaymentTypePayment(final String repaymentTypeCommand, final String date, final Float amountToBePaid,
|
||||
final Integer loanID) {
|
||||
return (HashMap) performLoanTransaction(createLoanTransactionURL(repaymentTypeCommand, loanID),
|
||||
getRepaymentBodyAsJSON(date, amountToBePaid), "");
|
||||
}
|
||||
|
||||
public HashMap makeRepayment(final String date, final Float amountToBePaid, final Integer loanID) {
|
||||
return (HashMap) performLoanTransaction(createLoanTransactionURL(MAKE_REPAYMENT_COMMAND, loanID),
|
||||
getRepaymentBodyAsJSON(date, amountToBePaid), "");
|
||||
|
||||
Reference in New Issue
Block a user