FINERACT-2232: Capitalized Incomce Adjustment template
This commit is contained in:
committed by
Adam Saghy
parent
f6e24d420a
commit
544607a05a
+3
-1
@@ -35,7 +35,9 @@ public enum TransactionType {
|
||||
INTEREST_PAYMENT_WAIVER("interestPaymentWaiver"), //
|
||||
REPAYMENT_AT_DISBURSEMENT("repaymentAtDisbursement"), //
|
||||
CAPITALIZED_INCOME("capitalizedIncome"), //
|
||||
CAPITALIZED_INCOME_AMORTIZATION("capitalizedIncomeAmortization"); //
|
||||
CAPITALIZED_INCOME_AMORTIZATION("capitalizedIncomeAmortization"), //
|
||||
CAPITALIZED_INCOME_ADJUSTMENT("capitalizedIncomeAdjustment"), //
|
||||
;
|
||||
|
||||
public final String value;
|
||||
|
||||
|
||||
+1
-1
@@ -579,7 +579,7 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId1 = loanResponse.body().getLoanId();
|
||||
Response<GetLoansLoanIdTransactionsTemplateResponse> response = loanTransactionsApi
|
||||
.retrieveTransactionTemplate(loanId1, "prepayLoan", DATE_FORMAT, transactionDate, DEFAULT_LOCALE).execute();
|
||||
.retrieveTransactionTemplate(loanId1, "prepayLoan", DATE_FORMAT, transactionDate, DEFAULT_LOCALE, null).execute();
|
||||
Double transactionAmount = response.body().getAmount();
|
||||
|
||||
log.debug("%n--- Loan Pay-off with amount: {} ---", transactionAmount);
|
||||
|
||||
+1
@@ -175,6 +175,7 @@ public interface LoanApiConstants {
|
||||
String CHARGEBACK_TRANSACTION_COMMAND = "chargeback";
|
||||
String MARK_AS_FRAUD_COMMAND = "markAsFraud";
|
||||
String CAPITALIZED_INCOME_TRANSACTION_COMMAND = "capitalizedIncome";
|
||||
String CAPITALIZED_INCOME_ADJUSTMENT_TRANSACTION_COMMAND = "capitalizedIncomeAdjustment";
|
||||
|
||||
// Data Validator names
|
||||
String LOAN_FRAUD_DATAVALIDATOR_PREFIX = "loans.fraud";
|
||||
|
||||
+1
@@ -54,5 +54,6 @@ public interface LoanTransactionApiConstants {
|
||||
accrualAdjustment, //
|
||||
capitalizedIncome, //
|
||||
capitalizedIncomeAmortization, //
|
||||
capitalizedIncomeAdjustment, //
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -313,6 +313,36 @@ public class LoanTransactionData implements Serializable {
|
||||
null, null, outstandingLoanBalance, null, manuallyReversed, ExternalId.empty(), null, loanId);
|
||||
}
|
||||
|
||||
public static LoanTransactionData loanTransactionDataForCreditTemplate(final LoanTransactionEnumData transactionType,
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final Collection<PaymentTypeData> paymentOptions,
|
||||
final CurrencyData currency) {
|
||||
final Long id = null;
|
||||
final Long loanId = null;
|
||||
final ExternalId externalLoanId = ExternalId.empty();
|
||||
final ExternalId externalId = ExternalId.empty();
|
||||
final Long officeId = null;
|
||||
final String officeName = null;
|
||||
final PaymentDetailData paymentDetailData = null;
|
||||
final BigDecimal unrecognizedIncomePortion = null;
|
||||
final BigDecimal principalPortion = null;
|
||||
final BigDecimal interestPortion = null;
|
||||
final BigDecimal feeChargesPortion = null;
|
||||
final BigDecimal penaltyChargesPortion = null;
|
||||
final BigDecimal overpaymentPortion = null;
|
||||
final BigDecimal netDisbursalAmount = null;
|
||||
final BigDecimal fixedEmiAmount = null;
|
||||
final BigDecimal outstandingLoanBalance = null;
|
||||
final AccountTransferData transfer = null;
|
||||
final LocalDate submittedOnDate = null;
|
||||
final LocalDate possibleNextRepaymentDate = null;
|
||||
final boolean manuallyReversed = false;
|
||||
return new LoanTransactionData(id, officeId, officeName, transactionType, paymentDetailData, currency, transactionDate,
|
||||
transactionAmount, netDisbursalAmount, principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion,
|
||||
overpaymentPortion, unrecognizedIncomePortion, paymentOptions, transfer, externalId, fixedEmiAmount, outstandingLoanBalance,
|
||||
submittedOnDate, manuallyReversed, possibleNextRepaymentDate, loanId, externalLoanId);
|
||||
|
||||
}
|
||||
|
||||
public static LoanTransactionData loanTransactionDataForDisbursalTemplate(final LoanTransactionEnumData transactionType,
|
||||
final LocalDate expectedDisbursedOnLocalDateForTemplate, final BigDecimal disburseAmountForTemplate,
|
||||
final BigDecimal netDisbursalAmount, final Collection<PaymentTypeData> paymentOptions, final BigDecimal retriveLastEmiAmount,
|
||||
|
||||
+4
@@ -650,6 +650,10 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom<Long
|
||||
return LoanTransactionType.CAPITALIZED_INCOME_AMORTIZATION.equals(getTypeOf()) && isNotReversed();
|
||||
}
|
||||
|
||||
public boolean isCapitalizedIncomeAdjustment() {
|
||||
return LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT.equals(getTypeOf()) && isNotReversed();
|
||||
}
|
||||
|
||||
public boolean isWaiver() {
|
||||
return isInterestWaiver() || isChargesWaiver();
|
||||
}
|
||||
|
||||
+6
@@ -69,6 +69,7 @@ public enum LoanTransactionType {
|
||||
ACCRUAL_ADJUSTMENT(34, "loanTransactionType.accrualAdjustment"), //
|
||||
CAPITALIZED_INCOME(35, "loanTransactionType.capitalizedIncome"), //
|
||||
CAPITALIZED_INCOME_AMORTIZATION(36, "loanTransactionType.capitalizedIncomeAmortization"), //
|
||||
CAPITALIZED_INCOME_ADJUSTMENT(37, "loanTransactionType.capitalizedIncomeAdjustment"), //
|
||||
;
|
||||
|
||||
private final Integer value;
|
||||
@@ -121,6 +122,7 @@ public enum LoanTransactionType {
|
||||
case 34 -> LoanTransactionType.ACCRUAL_ADJUSTMENT;
|
||||
case 35 -> LoanTransactionType.CAPITALIZED_INCOME;
|
||||
case 36 -> LoanTransactionType.CAPITALIZED_INCOME_AMORTIZATION;
|
||||
case 37 -> LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT;
|
||||
default -> LoanTransactionType.INVALID;
|
||||
};
|
||||
}
|
||||
@@ -241,4 +243,8 @@ public enum LoanTransactionType {
|
||||
public boolean isCapitalizedIncome() {
|
||||
return this == LoanTransactionType.CAPITALIZED_INCOME;
|
||||
}
|
||||
|
||||
public boolean isCapitalizedIncomeAdjustment() {
|
||||
return this == LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public interface LoanReadPlatformService {
|
||||
|
||||
LoanTransactionData retrieveLoanTransactionTemplate(Long loanId);
|
||||
|
||||
LoanTransactionData retrieveLoanTransactionTemplate(Long loanId, LoanTransactionType transactionType);
|
||||
LoanTransactionData retrieveLoanTransactionTemplate(Long loanId, LoanTransactionType transactionType, Long transactionId);
|
||||
|
||||
LoanTransactionData retrieveWaiveInterestDetails(Long loanId);
|
||||
|
||||
|
||||
+3
@@ -330,6 +330,9 @@ public final class LoanEnumerations {
|
||||
case CAPITALIZED_INCOME_AMORTIZATION ->
|
||||
new LoanTransactionEnumData(LoanTransactionType.CAPITALIZED_INCOME_AMORTIZATION.getValue().longValue(),
|
||||
LoanTransactionType.CAPITALIZED_INCOME_AMORTIZATION.getCode(), "Capitalized Income Amortization");
|
||||
case CAPITALIZED_INCOME_ADJUSTMENT ->
|
||||
new LoanTransactionEnumData(LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT.getValue().longValue(),
|
||||
LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT.getCode(), "Capitalized Income Adjustment");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -93,7 +93,10 @@ public class CapitalizedIncomeWritePlatformServiceImpl implements CapitalizedInc
|
||||
// Post journal entries
|
||||
journalEntryPoster.postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
return new CommandProcessingResultBuilder().withEntityId(loan.getId()).withEntityExternalId(loan.getExternalId()).build();
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(capitalizedIncomeTransaction.getId()) //
|
||||
.withEntityExternalId(capitalizedIncomeTransaction.getExternalId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-6
@@ -91,6 +91,7 @@ public class LoanTransactionsApiResource {
|
||||
public static final String REAMORTIZE = "reAmortize";
|
||||
public static final String UNDO_REAMORTIZE = "undoReAmortize";
|
||||
public static final String CAPITALIZED_INCOME = "capitalizedIncome";
|
||||
public static final String CAPITALIZED_INCOME_ADJUSTMENT = "capitalizedIncomeAdjustment";
|
||||
private final Set<String> responseDataParameters = new HashSet<>(Arrays.asList("id", "type", "date", "currency", "amount", "externalId",
|
||||
LoanApiConstants.REVERSAL_EXTERNAL_ID_PARAMNAME, LoanApiConstants.REVERSED_ON_DATE_PARAMNAME));
|
||||
|
||||
@@ -126,11 +127,12 @@ public class LoanTransactionsApiResource {
|
||||
@QueryParam("command") @Parameter(description = "command") final String commandParam, @Context final UriInfo uriInfo,
|
||||
@QueryParam("dateFormat") @Parameter(description = "dateFormat") final String rawDateFormat,
|
||||
@QueryParam("transactionDate") @Parameter(description = "transactionDate") final DateParam transactionDateParam,
|
||||
@QueryParam("locale") @Parameter(description = "locale") final String locale) {
|
||||
@QueryParam("locale") @Parameter(description = "locale") final String locale,
|
||||
@QueryParam("transactionId") @Parameter(description = "transactionId") final Long transactionId) {
|
||||
|
||||
final DateFormat dateFormat = StringUtils.isBlank(rawDateFormat) ? null : new DateFormat(rawDateFormat);
|
||||
|
||||
return retrieveTransactionTemplate(loanId, null, commandParam, uriInfo, dateFormat, transactionDateParam, locale);
|
||||
return retrieveTransactionTemplate(loanId, null, commandParam, uriInfo, dateFormat, transactionDateParam, locale, transactionId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -156,11 +158,13 @@ public class LoanTransactionsApiResource {
|
||||
@QueryParam("command") @Parameter(description = "command") final String commandParam, @Context final UriInfo uriInfo,
|
||||
@QueryParam("dateFormat") @Parameter(description = "dateFormat") final String rawDateFormat,
|
||||
@QueryParam("transactionDate") @Parameter(description = "transactionDate") final DateParam transactionDateParam,
|
||||
@QueryParam("locale") @Parameter(description = "locale") final String locale) {
|
||||
@QueryParam("locale") @Parameter(description = "locale") final String locale,
|
||||
@QueryParam("transactionId") @Parameter(description = "transactionId") final Long transactionId) {
|
||||
|
||||
final DateFormat dateFormat = StringUtils.isBlank(rawDateFormat) ? null : new DateFormat(rawDateFormat);
|
||||
|
||||
return retrieveTransactionTemplate(null, loanExternalId, commandParam, uriInfo, dateFormat, transactionDateParam, locale);
|
||||
return retrieveTransactionTemplate(null, loanExternalId, commandParam, uriInfo, dateFormat, transactionDateParam, locale,
|
||||
transactionId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -529,6 +533,7 @@ public class LoanTransactionsApiResource {
|
||||
case accrualAdjustment -> LoanTransactionType.ACCRUAL_ADJUSTMENT;
|
||||
case capitalizedIncome -> LoanTransactionType.CAPITALIZED_INCOME;
|
||||
case capitalizedIncomeAmortization -> LoanTransactionType.CAPITALIZED_INCOME_AMORTIZATION;
|
||||
case capitalizedIncomeAdjustment -> LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT;
|
||||
default ->
|
||||
throw new InvalidLoanTransactionTypeException("transaction", transactionTypeParam.name(), "Unknown transaction type");
|
||||
};
|
||||
@@ -598,7 +603,7 @@ public class LoanTransactionsApiResource {
|
||||
}
|
||||
|
||||
private String retrieveTransactionTemplate(Long loanId, String loanExternalIdStr, String commandParam, UriInfo uriInfo,
|
||||
DateFormat dateFormat, DateParam transactionDateParam, String locale) {
|
||||
DateFormat dateFormat, DateParam transactionDateParam, String locale, Long transactionId) {
|
||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
|
||||
|
||||
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
|
||||
@@ -671,7 +676,10 @@ public class LoanTransactionsApiResource {
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(resolvedLoanId);
|
||||
} else if (CommandParameterUtil.is(commandParam, LoanApiConstants.CAPITALIZED_INCOME_TRANSACTION_COMMAND)) {
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(resolvedLoanId,
|
||||
LoanTransactionType.CAPITALIZED_INCOME);
|
||||
LoanTransactionType.CAPITALIZED_INCOME, transactionId);
|
||||
} else if (CommandParameterUtil.is(commandParam, LoanApiConstants.CAPITALIZED_INCOME_ADJUSTMENT_TRANSACTION_COMMAND)) {
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(resolvedLoanId,
|
||||
LoanTransactionType.CAPITALIZED_INCOME_ADJUSTMENT, transactionId);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
+76
-3
@@ -50,6 +50,7 @@ import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.infrastructure.core.service.Page;
|
||||
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
@@ -107,6 +108,7 @@ import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeBalance;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -126,6 +128,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.OverdueLoanSc
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanTransactionMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.repository.LoanCapitalizedIncomeBalanceRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanForeclosureValidator;
|
||||
import org.apache.fineract.portfolio.loanproduct.data.LoanProductData;
|
||||
import org.apache.fineract.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
||||
@@ -180,6 +183,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
private final LoanTransactionMapper loanTransactionMapper;
|
||||
private final LoanTransactionProcessingService loadTransactionProcessingService;
|
||||
private final LoanBalanceService loanBalanceService;
|
||||
private final LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository;
|
||||
|
||||
@Override
|
||||
public LoanAccountData retrieveOne(final Long loanId) {
|
||||
@@ -451,10 +455,52 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
return loanDetails;
|
||||
}
|
||||
|
||||
private CurrencyData retriveLoanCurrencyData(final Long loanId) {
|
||||
final LoanCurrencyDataMapper loanCurrencyMapper = new LoanCurrencyDataMapper(sqlGenerator);
|
||||
final String sql = "select " + loanCurrencyMapper.schema() + " where l.id = ?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, loanCurrencyMapper, loanId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionData retrieveLoanTransactionTemplate(final Long loanId, LoanTransactionType transactionType) {
|
||||
return LoanTransactionData.templateOnTop(retrieveLoanTransactionTemplate(loanId),
|
||||
LoanEnumerations.transactionType(transactionType));
|
||||
public LoanTransactionData retrieveLoanTransactionTemplate(final Long loanId, final LoanTransactionType transactionType,
|
||||
final Long transactionId) {
|
||||
|
||||
LoanTransactionData loanTransactionData = null;
|
||||
Collection<PaymentTypeData> paymentOptions = null;
|
||||
BigDecimal transactionAmount = BigDecimal.ZERO;
|
||||
switch (transactionType) {
|
||||
case CAPITALIZED_INCOME:
|
||||
final Loan loan = loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
|
||||
if (loan.getLoanProduct().getLoanProductRelatedDetail().isEnableIncomeCapitalization()) {
|
||||
final BigDecimal capitalizedIncomeBalance = loanCapitalizedIncomeBalanceRepository.findAllByLoanId(loanId).stream()
|
||||
.map(LoanCapitalizedIncomeBalance::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
transactionAmount = loan.getApprovedPrincipal().subtract(loan.getDisbursedAmount()).subtract(capitalizedIncomeBalance);
|
||||
}
|
||||
paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
|
||||
loanTransactionData = LoanTransactionData.loanTransactionDataForCreditTemplate(
|
||||
LoanEnumerations.transactionType(transactionType), DateUtils.getBusinessLocalDate(), transactionAmount,
|
||||
paymentOptions, retriveLoanCurrencyData(loanId));
|
||||
|
||||
break;
|
||||
case CAPITALIZED_INCOME_ADJUSTMENT:
|
||||
final LoanCapitalizedIncomeBalance loanCapitalizedIncomeBalance = loanCapitalizedIncomeBalanceRepository
|
||||
.findByLoanIdAndLoanTransactionId(loanId, transactionId);
|
||||
|
||||
transactionAmount = (loanCapitalizedIncomeBalance == null) ? BigDecimal.ZERO
|
||||
: loanCapitalizedIncomeBalance.getAmount()
|
||||
.subtract(MathUtil.nullToZero(loanCapitalizedIncomeBalance.getAmountAdjustment()));
|
||||
loanTransactionData = LoanTransactionData.loanTransactionDataForCreditTemplate(
|
||||
LoanEnumerations.transactionType(transactionType), DateUtils.getBusinessLocalDate(), transactionAmount,
|
||||
paymentOptions, retriveLoanCurrencyData(loanId));
|
||||
break;
|
||||
default:
|
||||
loanTransactionData = LoanTransactionData.templateOnTop(retrieveLoanTransactionTemplate(loanId),
|
||||
LoanEnumerations.transactionType(transactionType));
|
||||
break;
|
||||
}
|
||||
|
||||
return loanTransactionData;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -646,6 +692,33 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
return loanId;
|
||||
}
|
||||
|
||||
private static final class LoanCurrencyDataMapper implements RowMapper<CurrencyData> {
|
||||
|
||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
|
||||
LoanCurrencyDataMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
|
||||
this.sqlGenerator = sqlGenerator;
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc."
|
||||
+ sqlGenerator.escape("name")
|
||||
+ " as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode from m_loan l join m_currency rc on rc."
|
||||
+ sqlGenerator.escape("code") + " = l.currency_code ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurrencyData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
|
||||
return new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol, currencyNameCode);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LoanMapper implements RowMapper<LoanAccountData> {
|
||||
|
||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||
|
||||
+5
-2
@@ -88,6 +88,7 @@ import org.apache.fineract.portfolio.loanaccount.mapper.LoanChargeMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanCollateralManagementMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanTransactionMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.repository.LoanCapitalizedIncomeBalanceRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanTermVariationsRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationValidator;
|
||||
@@ -333,14 +334,16 @@ public class LoanAccountConfiguration {
|
||||
DelinquencyReadPlatformService delinquencyReadPlatformService, LoanTransactionRepository loanTransactionRepository,
|
||||
LoanChargePaidByReadService loanChargePaidByReadService, LoanTransactionRelationReadService loanTransactionRelationReadService,
|
||||
LoanForeclosureValidator loanForeclosureValidator, LoanTransactionMapper loanTransactionMapper,
|
||||
LoanTransactionProcessingService loanTransactionProcessingService, LoanBalanceService loanBalanceService) {
|
||||
LoanTransactionProcessingService loanTransactionProcessingService, LoanBalanceService loanBalanceService,
|
||||
LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository) {
|
||||
return new LoanReadPlatformServiceImpl(jdbcTemplate, context, loanRepositoryWrapper, applicationCurrencyRepository,
|
||||
loanProductReadPlatformService, clientReadPlatformService, groupReadPlatformService, loanDropdownReadPlatformService,
|
||||
fundReadPlatformService, chargeReadPlatformService, codeValueReadPlatformService, calendarReadPlatformService,
|
||||
staffReadPlatformService, paginationHelper, paymentTypeReadPlatformService, floatingRatesReadPlatformService,
|
||||
loanUtilService, configurationDomainService, accountDetailsReadPlatformService, columnValidator, sqlGenerator,
|
||||
delinquencyReadPlatformService, loanTransactionRepository, loanChargePaidByReadService, loanTransactionRelationReadService,
|
||||
loanForeclosureValidator, loanTransactionMapper, loanTransactionProcessingService, loanBalanceService);
|
||||
loanForeclosureValidator, loanTransactionMapper, loanTransactionProcessingService, loanBalanceService,
|
||||
loanCapitalizedIncomeBalanceRepository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
+1
-1
@@ -276,7 +276,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
}
|
||||
|
||||
protected GetLoansLoanIdTransactionsTemplateResponse getPrepayAmount(Long loanId, String date) {
|
||||
return ok(fineractClient().loanTransactions.retrieveTransactionTemplate(loanId, "prepayLoan", DATETIME_PATTERN, date, "en"));
|
||||
return ok(fineractClient().loanTransactions.retrieveTransactionTemplate(loanId, "prepayLoan", DATETIME_PATTERN, date, "en", null));
|
||||
}
|
||||
|
||||
protected Long verifyPrepayAmountByRepayment(Long loanId, String date) {
|
||||
|
||||
+57
-5
@@ -25,17 +25,25 @@ import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTemplateResponse;
|
||||
import org.apache.fineract.client.models.PostClientsResponse;
|
||||
import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||
import org.apache.fineract.client.models.PostLoanProductsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.TransactionType;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Slf4j
|
||||
public class LoanTransactionTest extends BaseLoanIntegrationTest {
|
||||
|
||||
private final String capitalizedIncomeCommand = "capitalizedIncome";
|
||||
private final String capitalizedIncomeAdjustmentCommand = "capitalizedIncomeAdjustment";
|
||||
|
||||
@Test
|
||||
public void testGetLoanTransactionsFiltering() {
|
||||
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||
@@ -94,24 +102,68 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest {
|
||||
public void testGetLoanTransactionTemplateForCapitalizedIncome() {
|
||||
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive());
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
|
||||
.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
|
||||
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
|
||||
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
|
||||
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())
|
||||
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE));
|
||||
|
||||
final String loanExternalIdStr = UUID.randomUUID().toString();
|
||||
|
||||
final String command = "capitalizedIncome";
|
||||
runAt("20 December 2024", () -> {
|
||||
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
|
||||
430.0, 7.0, 6, (request) -> request.externalId(loanExternalIdStr));
|
||||
|
||||
disburseLoan(loanId, BigDecimal.valueOf(430), "20 December 2024");
|
||||
disburseLoan(loanId, BigDecimal.valueOf(230), "20 December 2024");
|
||||
|
||||
final GetLoansLoanIdTransactionsTemplateResponse transactionTemplate = loanTransactionHelper.retrieveTransactionTemplate(loanId,
|
||||
command, null, null, null);
|
||||
capitalizedIncomeCommand, null, null, null);
|
||||
|
||||
assertNotNull(transactionTemplate);
|
||||
assertEquals("loanTransactionType." + command, transactionTemplate.getType().getCode());
|
||||
assertEquals("loanTransactionType." + capitalizedIncomeCommand, transactionTemplate.getType().getCode());
|
||||
assertEquals(transactionTemplate.getAmount(), 200);
|
||||
assertThat(transactionTemplate.getPaymentTypeOptions().size() > 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLoanTransactionTemplateForCapitalizedIncomeAdjustment() {
|
||||
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
|
||||
.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
|
||||
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
|
||||
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
|
||||
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())
|
||||
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE));
|
||||
|
||||
final String loanExternalIdStr = UUID.randomUUID().toString();
|
||||
|
||||
runAt("20 December 2024", () -> {
|
||||
final Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(),
|
||||
"20 December 2024", 430.0, 7.0, 6, (request) -> request.externalId(loanExternalIdStr));
|
||||
|
||||
disburseLoan(loanId, BigDecimal.valueOf(230), "20 December 2024");
|
||||
|
||||
PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.executeLoanTransaction(loanId,
|
||||
new PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN).transactionDate("20 December 2024").locale("en")
|
||||
.transactionAmount(150.0),
|
||||
capitalizedIncomeCommand);
|
||||
assertNotNull(loanTransactionResponse);
|
||||
final Long transactionId = loanTransactionResponse.getResourceId();
|
||||
assertNotNull(transactionId);
|
||||
log.info("Loan Id {} with transaction id {}", loanId, transactionId);
|
||||
|
||||
final GetLoansLoanIdTransactionsTemplateResponse transactionTemplate = loanTransactionHelper.retrieveTransactionTemplate(loanId,
|
||||
capitalizedIncomeAdjustmentCommand, null, null, null, transactionId);
|
||||
|
||||
assertNotNull(transactionTemplate);
|
||||
assertEquals("loanTransactionType." + capitalizedIncomeAdjustmentCommand, transactionTemplate.getType().getCode());
|
||||
assertEquals(transactionTemplate.getAmount(), 150);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-3
@@ -902,6 +902,11 @@ public class LoanTransactionHelper {
|
||||
return postLoanTransaction(createLoanTransactionURL(MAKE_REPAYMENT_COMMAND, loanID), getRepaymentBodyAsJSON(date, amountToBePaid));
|
||||
}
|
||||
|
||||
public PostLoansLoanIdTransactionsResponse executeLoanTransaction(final Long loanId, final PostLoansLoanIdTransactionsRequest request,
|
||||
final String command) {
|
||||
return Calls.ok(FineractClientHelper.getFineractClient().loanTransactions.executeLoanTransaction(loanId, request, command));
|
||||
}
|
||||
|
||||
public PostLoansLoanIdTransactionsResponse makeLoanRepayment(final Long loanId, final PostLoansLoanIdTransactionsRequest request) {
|
||||
return Calls.ok(FineractClientHelper.getFineractClient().loanTransactions.executeLoanTransaction(loanId, request, "repayment"));
|
||||
}
|
||||
@@ -2332,7 +2337,7 @@ public class LoanTransactionHelper {
|
||||
public GetLoansLoanIdTransactionsTemplateResponse getPrepaymentAmount(final Long loanId, final String transactionDate,
|
||||
String dateformat) {
|
||||
return Calls.ok(FineractClientHelper.getFineractClient().loanTransactions.retrieveTransactionTemplate(loanId, "prepayLoan",
|
||||
dateformat, transactionDate, "en"));
|
||||
dateformat, transactionDate, "en", null));
|
||||
}
|
||||
|
||||
// TODO: Rewrite to use fineract-client instead!
|
||||
@@ -2806,16 +2811,22 @@ public class LoanTransactionHelper {
|
||||
return chargebackPayload;
|
||||
}
|
||||
|
||||
public GetLoansLoanIdTransactionsTemplateResponse retrieveTransactionTemplate(Long loanId, String command, String dateFormat,
|
||||
String transactionDate, String locale, Long transactionId) {
|
||||
return Calls.ok(FineractClientHelper.getFineractClient().loanTransactions.retrieveTransactionTemplate(loanId, command, dateFormat,
|
||||
transactionDate, locale, transactionId));
|
||||
}
|
||||
|
||||
public GetLoansLoanIdTransactionsTemplateResponse retrieveTransactionTemplate(Long loanId, String command, String dateFormat,
|
||||
String transactionDate, String locale) {
|
||||
return Calls.ok(FineractClientHelper.getFineractClient().loanTransactions.retrieveTransactionTemplate(loanId, command, dateFormat,
|
||||
transactionDate, locale));
|
||||
transactionDate, locale, null));
|
||||
}
|
||||
|
||||
public GetLoansLoanIdTransactionsTemplateResponse retrieveTransactionTemplate(String loanExternalIdStr, String command,
|
||||
String dateFormat, String transactionDate, String locale) {
|
||||
return Calls.ok(FineractClientHelper.getFineractClient().loanTransactions.retrieveTransactionTemplate1(loanExternalIdStr, command,
|
||||
dateFormat, transactionDate, locale));
|
||||
dateFormat, transactionDate, locale, null));
|
||||
}
|
||||
|
||||
public GetLoansApprovalTemplateResponse getLoanApprovalTemplate(String loanExternalIdStr) {
|
||||
|
||||
Reference in New Issue
Block a user