FINERACT-2080: Extract DTO mappers from loan entity
This commit is contained in:
committed by
Adam Saghy
parent
b01dca3ecc
commit
2ba7e28108
+56
-59
@@ -29,8 +29,8 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.accounting.closure.domain.GLClosure;
|
||||
import org.apache.fineract.accounting.closure.domain.GLClosureRepository;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForSavings;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForSavings;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForShares;
|
||||
@@ -68,12 +68,11 @@ import org.apache.fineract.portfolio.PortfolioProductType;
|
||||
import org.apache.fineract.portfolio.account.PortfolioAccountType;
|
||||
import org.apache.fineract.portfolio.account.service.AccountTransfersReadPlatformService;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientTransactionRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeLoanTransactionDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidByDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
||||
import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionEnumData;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
@@ -92,55 +91,53 @@ public class AccountingProcessorHelper {
|
||||
private final GLClosureRepository closureRepository;
|
||||
private final GLAccountRepository glAccountRepository;
|
||||
private final OfficeRepository officeRepository;
|
||||
private final LoanTransactionRepository loanTransactionRepository;
|
||||
private final ClientTransactionRepository clientTransactionRepository;
|
||||
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
|
||||
private final AccountTransfersReadPlatformService accountTransfersReadPlatformService;
|
||||
private final ChargeRepositoryWrapper chargeRepositoryWrapper;
|
||||
private final BusinessEventNotifierService businessEventNotifierService;
|
||||
|
||||
public LoanDTO populateLoanDtoFromMap(final Map<String, Object> accountingBridgeData, final boolean cashBasedAccountingEnabled,
|
||||
final boolean upfrontAccrualBasedAccountingEnabled, final boolean periodicAccrualBasedAccountingEnabled) {
|
||||
final Long loanId = (Long) accountingBridgeData.get("loanId");
|
||||
final Long loanProductId = (Long) accountingBridgeData.get("loanProductId");
|
||||
final Long officeId = (Long) accountingBridgeData.get("officeId");
|
||||
final String currencyCode = (String) accountingBridgeData.get("currencyCode");
|
||||
public LoanDTO populateLoanDtoFromDTO(
|
||||
final org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO accountingBridgeData) {
|
||||
final Long loanId = accountingBridgeData.getLoanId();
|
||||
final Long loanProductId = accountingBridgeData.getLoanProductId();
|
||||
final Long officeId = accountingBridgeData.getOfficeId();
|
||||
final String currencyCode = accountingBridgeData.getCurrencyCode();
|
||||
final List<LoanTransactionDTO> newLoanTransactions = new ArrayList<>();
|
||||
boolean isAccountTransfer = (Boolean) accountingBridgeData.get("isAccountTransfer");
|
||||
boolean isLoanMarkedAsChargeOff = (Boolean) accountingBridgeData.get("isChargeOff");
|
||||
boolean isLoanMarkedAsFraud = (Boolean) accountingBridgeData.get("isFraud");
|
||||
final Long chargeOffReasonCodeValue = (Long) accountingBridgeData.get("chargeOffReasonCodeValue");
|
||||
boolean isAccountTransfer = accountingBridgeData.isAccountTransfer();
|
||||
boolean isLoanMarkedAsChargeOff = accountingBridgeData.isChargeOff();
|
||||
boolean isLoanMarkedAsFraud = accountingBridgeData.isFraud();
|
||||
final Long chargeOffReasonCodeValue = accountingBridgeData.getChargeOffReasonCodeValue();
|
||||
final boolean cashBasedAccountingEnabled = accountingBridgeData.isCashBasedAccountingEnabled();
|
||||
final boolean upfrontAccrualBasedAccountingEnabled = accountingBridgeData.isUpfrontAccrualBasedAccountingEnabled();
|
||||
final boolean periodicAccrualBasedAccountingEnabled = accountingBridgeData.isPeriodicAccrualBasedAccountingEnabled();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<Map<String, Object>> newTransactionsMap = (List<Map<String, Object>>) accountingBridgeData.get("newLoanTransactions");
|
||||
final List<AccountingBridgeLoanTransactionDTO> loanTransactionDTOs = accountingBridgeData.getNewLoanTransactions();
|
||||
|
||||
for (final Map<String, Object> map : newTransactionsMap) {
|
||||
final Long transactionOfficeId = (Long) map.get("officeId");
|
||||
final String transactionId = ((Long) map.get("id")).toString();
|
||||
final LocalDate transactionDate = ((LocalDate) map.get("date"));
|
||||
final LoanTransactionEnumData transactionType = (LoanTransactionEnumData) map.get("type");
|
||||
final BigDecimal amount = (BigDecimal) map.get("amount");
|
||||
final BigDecimal principal = (BigDecimal) map.get("principalPortion");
|
||||
final BigDecimal interest = (BigDecimal) map.get("interestPortion");
|
||||
final BigDecimal fees = (BigDecimal) map.get("feeChargesPortion");
|
||||
final BigDecimal penalties = (BigDecimal) map.get("penaltyChargesPortion");
|
||||
final BigDecimal overPayments = (BigDecimal) map.get("overPaymentPortion");
|
||||
final boolean reversed = (Boolean) map.get("reversed");
|
||||
final Long paymentTypeId = (Long) map.get("paymentTypeId");
|
||||
final String chargeRefundChargeType = (String) map.get("chargeRefundChargeType");
|
||||
final LoanChargeData loanChargeData = (LoanChargeData) map.get("loanChargeData");
|
||||
for (final AccountingBridgeLoanTransactionDTO loanTxnDto : loanTransactionDTOs) {
|
||||
final Long transactionOfficeId = loanTxnDto.getOfficeId();
|
||||
final String transactionId = loanTxnDto.getId().toString();
|
||||
final LocalDate transactionDate = loanTxnDto.getDate();
|
||||
final LoanTransactionEnumData transactionType = loanTxnDto.getType();
|
||||
final BigDecimal amount = loanTxnDto.getAmount();
|
||||
final BigDecimal principal = loanTxnDto.getPrincipalPortion();
|
||||
final BigDecimal interest = loanTxnDto.getInterestPortion();
|
||||
final BigDecimal fees = loanTxnDto.getFeeChargesPortion();
|
||||
final BigDecimal penalties = loanTxnDto.getPenaltyChargesPortion();
|
||||
final BigDecimal overPayments = loanTxnDto.getOverPaymentPortion();
|
||||
final boolean reversed = loanTxnDto.isReversed();
|
||||
final Long paymentTypeId = loanTxnDto.getPaymentTypeId();
|
||||
final String chargeRefundChargeType = loanTxnDto.getChargeRefundChargeType();
|
||||
final LoanChargeData loanChargeData = loanTxnDto.getLoanChargeData();
|
||||
|
||||
final List<ChargePaymentDTO> feePaymentDetails = new ArrayList<>();
|
||||
final List<ChargePaymentDTO> penaltyPaymentDetails = new ArrayList<>();
|
||||
// extract charge payment details (if exists)
|
||||
if (map.containsKey("loanChargesPaid")) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<Map<String, Object>> loanChargesPaidData = (List<Map<String, Object>>) map.get("loanChargesPaid");
|
||||
for (final Map<String, Object> loanChargePaid : loanChargesPaidData) {
|
||||
final Long chargeId = (Long) loanChargePaid.get("chargeId");
|
||||
final Long loanChargeId = (Long) loanChargePaid.get("loanChargeId");
|
||||
final boolean isPenalty = (Boolean) loanChargePaid.get("isPenalty");
|
||||
final BigDecimal chargeAmountPaid = (BigDecimal) loanChargePaid.get("amount");
|
||||
if (loanTxnDto.getLoanChargesPaid() != null) {
|
||||
List<LoanChargePaidByDTO> loanChargesPaidData = loanTxnDto.getLoanChargesPaid();
|
||||
for (final LoanChargePaidByDTO loanChargePaid : loanChargesPaidData) {
|
||||
final Long chargeId = loanChargePaid.getChargeId();
|
||||
final Long loanChargeId = loanChargePaid.getLoanChargeId();
|
||||
final boolean isPenalty = loanChargePaid.getIsPenalty();
|
||||
final BigDecimal chargeAmountPaid = loanChargePaid.getAmount();
|
||||
final ChargePaymentDTO chargePaymentDTO = new ChargePaymentDTO(chargeId, chargeAmountPaid, loanChargeId);
|
||||
if (isPenalty) {
|
||||
penaltyPaymentDetails.add(chargePaymentDTO);
|
||||
@@ -150,23 +147,23 @@ public class AccountingProcessorHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAccountTransfer) {
|
||||
isAccountTransfer = this.accountTransfersReadPlatformService.isAccountTransfer(Long.parseLong(transactionId),
|
||||
boolean localIsAccountTransfer = isAccountTransfer;
|
||||
if (!localIsAccountTransfer) {
|
||||
localIsAccountTransfer = this.accountTransfersReadPlatformService.isAccountTransfer(Long.parseLong(transactionId),
|
||||
PortfolioAccountType.LOAN);
|
||||
}
|
||||
|
||||
BigDecimal principalPaid = (BigDecimal) map.get("principalPaid");
|
||||
BigDecimal feePaid = (BigDecimal) map.get("feePaid");
|
||||
BigDecimal penaltyPaid = (BigDecimal) map.get("penaltyPaid");
|
||||
BigDecimal principalPaid = loanTxnDto.getPrincipalPaid();
|
||||
BigDecimal feePaid = loanTxnDto.getFeePaid();
|
||||
BigDecimal penaltyPaid = loanTxnDto.getPenaltyPaid();
|
||||
|
||||
final LoanTransactionDTO transaction = new LoanTransactionDTO(transactionOfficeId, paymentTypeId, transactionId,
|
||||
transactionDate, transactionType, amount, principal, interest, fees, penalties, overPayments, reversed,
|
||||
penaltyPaymentDetails, feePaymentDetails, isAccountTransfer, chargeRefundChargeType, loanChargeData, principalPaid,
|
||||
penaltyPaymentDetails, feePaymentDetails, localIsAccountTransfer, chargeRefundChargeType, loanChargeData, principalPaid,
|
||||
feePaid, penaltyPaid);
|
||||
Boolean isLoanToLoanTransfer = (Boolean) accountingBridgeData.get("isLoanToLoanTransfer");
|
||||
transaction.setLoanToLoanTransfer(isLoanToLoanTransfer != null && isLoanToLoanTransfer);
|
||||
newLoanTransactions.add(transaction);
|
||||
|
||||
transaction.setLoanToLoanTransfer(loanTxnDto.isLoanToLoanTransfer());
|
||||
newLoanTransactions.add(transaction);
|
||||
}
|
||||
|
||||
return new LoanDTO(loanId, loanProductId, officeId, currencyCode, cashBasedAccountingEnabled, upfrontAccrualBasedAccountingEnabled,
|
||||
@@ -559,10 +556,10 @@ public class AccountingProcessorHelper {
|
||||
}
|
||||
|
||||
public void createAccrualBasedJournalEntriesAndReversalsForSavingsTax(final Office office, final String currencyCode,
|
||||
final AccrualAccountsForSavings accountTypeToBeDebited, final AccrualAccountsForSavings accountTypeToBeCredited,
|
||||
final Long savingsProductId, final Long paymentTypeId, final Long savingsId, final String transactionId,
|
||||
final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversal, final List<TaxPaymentDTO> taxDetails) {
|
||||
|
||||
final AccountingConstants.AccrualAccountsForSavings accountTypeToBeDebited,
|
||||
final AccountingConstants.AccrualAccountsForSavings accountTypeToBeCredited, final Long savingsProductId,
|
||||
final Long paymentTypeId, final Long savingsId, final String transactionId, final LocalDate transactionDate,
|
||||
final BigDecimal amount, final Boolean isReversal, final List<TaxPaymentDTO> taxDetails) {
|
||||
for (TaxPaymentDTO taxPaymentDTO : taxDetails) {
|
||||
if (taxPaymentDTO.getAmount() != null) {
|
||||
if (taxPaymentDTO.getCreditAccountId() == null) {
|
||||
@@ -769,10 +766,10 @@ public class AccountingProcessorHelper {
|
||||
}
|
||||
|
||||
public void createAccrualBasedJournalEntriesAndReversalsForSavingsCharges(final Office office, final String currencyCode,
|
||||
final AccrualAccountsForSavings accountTypeToBeDebited, AccrualAccountsForSavings accountTypeToBeCredited,
|
||||
final Long savingsProductId, final Long paymentTypeId, final Long loanId, final String transactionId,
|
||||
final LocalDate transactionDate, final BigDecimal totalAmount, final Boolean isReversal,
|
||||
final List<ChargePaymentDTO> chargePaymentDTOs) {
|
||||
final AccountingConstants.AccrualAccountsForSavings accountTypeToBeDebited,
|
||||
final AccountingConstants.AccrualAccountsForSavings accountTypeToBeCredited, final Long savingsProductId,
|
||||
final Long paymentTypeId, final Long loanId, final String transactionId, final LocalDate transactionDate,
|
||||
final BigDecimal totalAmount, final Boolean isReversal, final List<ChargePaymentDTO> chargePaymentDTOs) {
|
||||
// TODO Vishwas: Remove this validation, as and when appropriate Junit
|
||||
// tests are written for accounting
|
||||
/**
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import java.util.Map;
|
||||
import org.apache.fineract.accounting.provisioning.domain.ProvisioningEntry;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
|
||||
public interface JournalEntryWritePlatformService {
|
||||
|
||||
@@ -31,7 +32,7 @@ public interface JournalEntryWritePlatformService {
|
||||
|
||||
CommandProcessingResult revertJournalEntry(JsonCommand command);
|
||||
|
||||
void createJournalEntriesForLoan(Map<String, Object> accountingBridgeData);
|
||||
void createJournalEntriesForLoan(AccountingBridgeDataDTO accountingBridgeData);
|
||||
|
||||
void createJournalEntriesForSavings(Map<String, Object> accountingBridgeData);
|
||||
|
||||
|
||||
+6
-7
@@ -75,6 +75,7 @@ import org.apache.fineract.organisation.monetary.domain.OrganisationCurrencyRepo
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.PortfolioProductType;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
@@ -480,15 +481,13 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void createJournalEntriesForLoan(final Map<String, Object> accountingBridgeData) {
|
||||
|
||||
final boolean cashBasedAccountingEnabled = (Boolean) accountingBridgeData.get("cashBasedAccountingEnabled");
|
||||
final boolean upfrontAccrualBasedAccountingEnabled = (Boolean) accountingBridgeData.get("upfrontAccrualBasedAccountingEnabled");
|
||||
final boolean periodicAccrualBasedAccountingEnabled = (Boolean) accountingBridgeData.get("periodicAccrualBasedAccountingEnabled");
|
||||
public void createJournalEntriesForLoan(final AccountingBridgeDataDTO accountingBridgeData) {
|
||||
final boolean cashBasedAccountingEnabled = accountingBridgeData.isCashBasedAccountingEnabled();
|
||||
final boolean upfrontAccrualBasedAccountingEnabled = accountingBridgeData.isUpfrontAccrualBasedAccountingEnabled();
|
||||
final boolean periodicAccrualBasedAccountingEnabled = accountingBridgeData.isPeriodicAccrualBasedAccountingEnabled();
|
||||
|
||||
if (cashBasedAccountingEnabled || upfrontAccrualBasedAccountingEnabled || periodicAccrualBasedAccountingEnabled) {
|
||||
final LoanDTO loanDTO = this.helper.populateLoanDtoFromMap(accountingBridgeData, cashBasedAccountingEnabled,
|
||||
upfrontAccrualBasedAccountingEnabled, periodicAccrualBasedAccountingEnabled);
|
||||
final LoanDTO loanDTO = this.helper.populateLoanDtoFromDTO(accountingBridgeData);
|
||||
final AccountingProcessorForLoan accountingProcessorForLoan = this.accountingProcessorForLoanFactory
|
||||
.determineProcessor(loanDTO);
|
||||
accountingProcessorForLoan.createJournalEntriesForLoan(loanDTO);
|
||||
|
||||
+2
-8
@@ -46,10 +46,7 @@ import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
|
||||
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.apache.fineract.portfolio.account.service.AccountTransfersReadPlatformService;
|
||||
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientTransactionRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||
import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -63,14 +60,11 @@ public class AccountingJournalEntryConfiguration {
|
||||
public AccountingProcessorHelper accountingProcessorHelper(JournalEntryRepository glJournalEntryRepository,
|
||||
ProductToGLAccountMappingRepository accountMappingRepository,
|
||||
FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository, GLClosureRepository closureRepository,
|
||||
GLAccountRepository glAccountRepository, OfficeRepository officeRepository, LoanTransactionRepository loanTransactionRepository,
|
||||
ClientTransactionRepository clientTransactionRepository,
|
||||
SavingsAccountTransactionRepository savingsAccountTransactionRepository,
|
||||
GLAccountRepository glAccountRepository, OfficeRepository officeRepository,
|
||||
AccountTransfersReadPlatformService accountTransfersReadPlatformService, ChargeRepositoryWrapper chargeRepositoryWrapper,
|
||||
BusinessEventNotifierService businessEventNotifierService) {
|
||||
return new AccountingProcessorHelper(glJournalEntryRepository, accountMappingRepository, financialActivityAccountRepository,
|
||||
closureRepository, glAccountRepository, officeRepository, loanTransactionRepository, clientTransactionRepository,
|
||||
savingsAccountTransactionRepository, accountTransfersReadPlatformService, chargeRepositoryWrapper,
|
||||
closureRepository, glAccountRepository, officeRepository, accountTransfersReadPlatformService, chargeRepositoryWrapper,
|
||||
businessEventNotifierService);
|
||||
}
|
||||
|
||||
|
||||
+22
-12
@@ -87,6 +87,7 @@ import org.apache.fineract.portfolio.delinquency.service.DelinquencyWritePlatfor
|
||||
import org.apache.fineract.portfolio.delinquency.validator.LoanDelinquencyActionData;
|
||||
import org.apache.fineract.portfolio.group.domain.Group;
|
||||
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanRefundRequestData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanScheduleDelinquencyData;
|
||||
@@ -94,6 +95,7 @@ import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.MoneyHolder;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.TransactionCtx;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanAccountingBridgeMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanDownPaymentTransactionValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanForeclosureValidator;
|
||||
@@ -157,6 +159,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
private final LoanRefundService loanRefundService;
|
||||
private final LoanAccountService loanAccountService;
|
||||
private final ReprocessLoanTransactionsService reprocessLoanTransactionsService;
|
||||
private final LoanAccountingBridgeMapper loanAccountingBridgeMapper;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
@@ -449,19 +452,26 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
|
||||
final MonetaryCurrency currency = loanAccount.getCurrency();
|
||||
|
||||
List<Map<String, Object>> accountingBridgeData = new ArrayList<>();
|
||||
if (loanAccount.isChargedOff()) {
|
||||
accountingBridgeData = loanAccount.deriveAccountingBridgeDataForChargeOff(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
} else {
|
||||
accountingBridgeData.add(loanAccount.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer));
|
||||
}
|
||||
for (Map<String, Object> accountingData : accountingBridgeData) {
|
||||
accountingData.put("isLoanToLoanTransfer", isLoanToLoanTransfer);
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingData);
|
||||
}
|
||||
final List<AccountingBridgeDataDTO> accountingBridgeDataList = loanAccountingBridgeMapper
|
||||
.deriveAccountingBridgeDataForChargeOff(currency.getCode(), existingTransactionIds, existingReversedTransactionIds,
|
||||
isAccountTransfer, loanAccount);
|
||||
if (isLoanToLoanTransfer) {
|
||||
accountingBridgeDataList.forEach(dto -> dto.getNewLoanTransactions().forEach(tx -> tx.setLoanToLoanTransfer(true)));
|
||||
}
|
||||
|
||||
for (AccountingBridgeDataDTO accountingBridgeData : accountingBridgeDataList) {
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
} else {
|
||||
final AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(currency.getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loanAccount);
|
||||
if (isLoanToLoanTransfer) {
|
||||
accountingBridgeData.getNewLoanTransactions().forEach(tx -> tx.setLoanToLoanTransfer(true));
|
||||
}
|
||||
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkClientOrGroupActive(final Loan loan) {
|
||||
@@ -985,7 +995,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final List<LoanRepaymentScheduleInstallment> newInstallments = new ArrayList<>(loan.getRepaymentScheduleInstallments());
|
||||
final MonetaryCurrency currency = loan.getCurrency();
|
||||
Money totalPrincipal = Money.zero(currency);
|
||||
final Money[] balances = loan.retriveIncomeForOverlappingPeriod(transactionDate);
|
||||
final Money[] balances = loan.retrieveIncomeForOverlappingPeriod(transactionDate);
|
||||
boolean isInterestComponent = true;
|
||||
for (final LoanRepaymentScheduleInstallment installment : loan.getRepaymentScheduleInstallments()) {
|
||||
if (!DateUtils.isAfter(transactionDate, installment.getDueDate())) {
|
||||
|
||||
+6
-2
@@ -42,6 +42,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.DefaultScheduledDateGenerator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanTermVariationsMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
||||
import org.springframework.batch.core.StepContribution;
|
||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
||||
@@ -59,6 +60,7 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
|
||||
private final LoanRepositoryWrapper loanRepositoryWrapper;
|
||||
private final LoanUtilService loanUtilService;
|
||||
private final BusinessEventNotifierService businessEventNotifierService;
|
||||
private final LoanTermVariationsMapper loanTermVariationsMapper;
|
||||
|
||||
@Override
|
||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
||||
@@ -120,7 +122,8 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
|
||||
private void adjustRepaymentSchedules(Loan loan, Holiday holiday, LocalDate adjustedRescheduleToDate) {
|
||||
final DefaultScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
|
||||
ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, holiday.getFromDate());
|
||||
final LoanApplicationTerms loanApplicationTerms = loan.constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||
final LoanApplicationTerms loanApplicationTerms = loanTermVariationsMapper.constructLoanApplicationTerms(scheduleGeneratorDTO,
|
||||
loan);
|
||||
|
||||
// first repayment's from date is same as disbursement date.
|
||||
LocalDate tmpFromDate = loan.getDisbursementDate();
|
||||
@@ -152,7 +155,8 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
|
||||
private void adjustAllRepaymentSchedules(Loan loan, Holiday holiday, LocalDate adjustedRescheduleToDate) {
|
||||
final DefaultScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
|
||||
ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, holiday.getFromDate());
|
||||
final LoanApplicationTerms loanApplicationTerms = loan.constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||
final LoanApplicationTerms loanApplicationTerms = loanTermVariationsMapper.constructLoanApplicationTerms(scheduleGeneratorDTO,
|
||||
loan);
|
||||
|
||||
// first repayment's from date is same as disbursement date.
|
||||
LocalDate tmpFromDate = loan.getDisbursementDate();
|
||||
|
||||
+3
-1
@@ -44,6 +44,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleD
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanTermVariationsMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanScheduleValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
||||
@@ -63,6 +64,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
||||
private final LoanUtilService loanUtilService;
|
||||
private final LoanRepositoryWrapper loanRepository;
|
||||
private final LoanLifecycleStateMachine defaultLoanLifecycleStateMachine;
|
||||
private final LoanTermVariationsMapper loanTermVariationsMapper;
|
||||
|
||||
@Override
|
||||
public LoanScheduleModel calculateLoanSchedule(final JsonQuery query, Boolean validateParams) {
|
||||
@@ -204,7 +206,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
||||
private LoanApplicationTerms constructLoanApplicationTerms(final Loan loan) {
|
||||
final LocalDate recalculateFrom = null;
|
||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||
return loan.constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||
return loanTermVariationsMapper.constructLoanApplicationTerms(scheduleGeneratorDTO, loan);
|
||||
}
|
||||
|
||||
private Loan fetchLoan(final Long accountId) {
|
||||
|
||||
+7
-14
@@ -23,6 +23,7 @@ import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
@@ -38,32 +39,23 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplica
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanTermVariationsMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.exception.LoanRescheduleRequestNotFoundException;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanReschedulePreviewPlatformServiceImpl implements LoanReschedulePreviewPlatformService {
|
||||
|
||||
private static final DefaultScheduledDateGenerator DEFAULT_SCHEDULED_DATE_GENERATOR = new DefaultScheduledDateGenerator();
|
||||
private final LoanRescheduleRequestRepositoryWrapper loanRescheduleRequestRepository;
|
||||
private final LoanUtilService loanUtilService;
|
||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
||||
private static final DefaultScheduledDateGenerator DEFAULT_SCHEDULED_DATE_GENERATOR = new DefaultScheduledDateGenerator();
|
||||
|
||||
@Autowired
|
||||
public LoanReschedulePreviewPlatformServiceImpl(final LoanRescheduleRequestRepositoryWrapper loanRescheduleRequestRepository,
|
||||
final LoanUtilService loanUtilService,
|
||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
final LoanScheduleGeneratorFactory loanScheduleFactory) {
|
||||
this.loanRescheduleRequestRepository = loanRescheduleRequestRepository;
|
||||
this.loanUtilService = loanUtilService;
|
||||
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
||||
this.loanScheduleFactory = loanScheduleFactory;
|
||||
}
|
||||
private final LoanTermVariationsMapper loanTermVariationsMapper;
|
||||
|
||||
@Override
|
||||
public LoanScheduleModel previewLoanReschedule(Long requestId) {
|
||||
@@ -80,7 +72,8 @@ public class LoanReschedulePreviewPlatformServiceImpl implements LoanRescheduleP
|
||||
loanRescheduleRequest.getRescheduleFromDate());
|
||||
LocalDate rescheduleFromDate = null;
|
||||
List<LoanTermVariationsData> removeLoanTermVariationsData = new ArrayList<>();
|
||||
final LoanApplicationTerms loanApplicationTerms = loan.constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||
final LoanApplicationTerms loanApplicationTerms = loanTermVariationsMapper.constructLoanApplicationTerms(scheduleGeneratorDTO,
|
||||
loan);
|
||||
LoanTermVariations dueDateVariationInCurrentRequest = loanRescheduleRequest.getDueDateTermVariationIfExists();
|
||||
if (dueDateVariationInCurrentRequest != null) {
|
||||
for (LoanTermVariationsData loanTermVariation : loanApplicationTerms.getLoanTermVariations().getDueDateVariation()) {
|
||||
|
||||
+11
-4
@@ -47,6 +47,7 @@ import org.apache.fineract.infrastructure.event.business.service.BusinessEventNo
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
@@ -68,6 +69,8 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanRepayme
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryWritePlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanAccountingBridgeMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanTermVariationsMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.RescheduleLoansApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestDataValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
|
||||
@@ -116,6 +119,8 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
||||
private final LoanAccrualsProcessingService loanAccrualsProcessingService;
|
||||
private final LoanChargeService loanChargeService;
|
||||
private final ReprocessLoanTransactionsService reprocessLoanTransactionsService;
|
||||
private final LoanTermVariationsMapper loanTermVariationsMapper;
|
||||
private final LoanAccountingBridgeMapper loanAccountingBridgeMapper;
|
||||
private final LoanScheduleComponent loanSchedule;
|
||||
|
||||
/**
|
||||
@@ -363,7 +368,8 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
||||
Collection<LoanRepaymentScheduleHistory> loanRepaymentScheduleHistoryList = this.loanScheduleHistoryWritePlatformService
|
||||
.createLoanScheduleArchive(loan.getRepaymentScheduleInstallments(), loan, loanRescheduleRequest);
|
||||
|
||||
final LoanApplicationTerms loanApplicationTerms = loan.constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||
final LoanApplicationTerms loanApplicationTerms = loanTermVariationsMapper.constructLoanApplicationTerms(scheduleGeneratorDTO,
|
||||
loan);
|
||||
|
||||
LocalDate rescheduleFromDate = null;
|
||||
List<LoanTermVariations> activeLoanTermVariations = loan.getActiveLoanTermVariations();
|
||||
@@ -403,7 +409,8 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
||||
}
|
||||
BigDecimal annualNominalInterestRate = null;
|
||||
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
|
||||
loan.constructLoanTermVariations(scheduleGeneratorDTO.getFloatingRateDTO(), annualNominalInterestRate, loanTermVariations);
|
||||
loanTermVariationsMapper.constructLoanTermVariations(scheduleGeneratorDTO.getFloatingRateDTO(), annualNominalInterestRate,
|
||||
loanTermVariations, loan);
|
||||
loanApplicationTerms.getLoanTermVariations().setExceptionData(loanTermVariations);
|
||||
|
||||
/*
|
||||
@@ -495,8 +502,8 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
||||
private void postJournalEntries(Loan loan, List<Long> existingTransactionIds, List<Long> existingReversedTransactionIds) {
|
||||
final MonetaryCurrency currency = loan.getCurrency();
|
||||
boolean isAccountTransfer = false;
|
||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
final AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(currency.getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loan);
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
|
||||
|
||||
+27
-9
@@ -28,6 +28,7 @@ import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -90,6 +91,7 @@ import org.apache.fineract.portfolio.group.domain.GroupRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.group.exception.ClientNotInGroupException;
|
||||
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCollateralManagement;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanEvent;
|
||||
@@ -109,6 +111,7 @@ import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementData
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException;
|
||||
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.LoanMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
@@ -200,6 +203,7 @@ public final class LoanApplicationValidator {
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
private final LoanUtilService loanUtilService;
|
||||
private final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService;
|
||||
private final LoanMapper loanMapper;
|
||||
|
||||
public void validateForCreate(final Loan loan) {
|
||||
final LocalDate expectedFirstRepaymentOnDate = loan.getExpectedFirstRepaymentOnDate();
|
||||
@@ -1404,12 +1408,11 @@ public final class LoanApplicationValidator {
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT, loanIdToClose, expectedDisbursementDate)
|
||||
.getAmount();
|
||||
final BigDecimal firstDisbursalAmount = loan.getFirstDisbursalAmount();
|
||||
final BigDecimal firstDisbursalAmount = getFirstDisbursalAmount(loan);
|
||||
if (loanOutstanding.compareTo(firstDisbursalAmount) > 0) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed",
|
||||
"Topup loan amount should be greater than outstanding amount of loan to be closed.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1953,7 +1956,7 @@ public final class LoanApplicationValidator {
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
|
||||
}
|
||||
|
||||
public void validateTopupLoan(Loan loan, LocalDate expectedDisbursementDate) {
|
||||
public BigDecimal validateTopupLoan(final Loan loan, final LocalDate disbursementDate) {
|
||||
final Long loanIdToClose = loan.getTopupLoanDetails().getLoanIdToClose();
|
||||
final Loan loanToClose = loanRepositoryWrapper.findNonClosedLoanThatBelongsToClient(loanIdToClose, loan.getClientId());
|
||||
if (loanToClose == null) {
|
||||
@@ -1969,16 +1972,15 @@ public final class LoanApplicationValidator {
|
||||
+ " should be after last transaction date of loan to be closed " + lastUserTransactionOnLoanToClose);
|
||||
}
|
||||
|
||||
BigDecimal loanOutstanding = loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT, loanIdToClose, expectedDisbursementDate).getAmount();
|
||||
final BigDecimal firstDisbursalAmount = loan.getFirstDisbursalAmount();
|
||||
final BigDecimal loanOutstanding = loanReadPlatformService
|
||||
.retrieveLoanPrePaymentTemplate(LoanTransactionType.REPAYMENT, loanIdToClose, disbursementDate).getAmount();
|
||||
final BigDecimal firstDisbursalAmount = getFirstDisbursalAmount(loan);
|
||||
if (loanOutstanding.compareTo(firstDisbursalAmount) > 0) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed",
|
||||
"Topup loan amount should be greater than outstanding amount of loan to be closed.");
|
||||
}
|
||||
|
||||
BigDecimal netDisbursalAmount = loan.getApprovedPrincipal().subtract(loanOutstanding);
|
||||
loan.adjustNetDisbursalAmount(netDisbursalAmount);
|
||||
return loanOutstanding;
|
||||
}
|
||||
|
||||
public void validateApproval(JsonCommand command, Long loanId) {
|
||||
@@ -2074,7 +2076,9 @@ public final class LoanApplicationValidator {
|
||||
StatusEnum.APPROVE.getValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
|
||||
|
||||
if (loan.isTopup() && loan.getClientId() != null) {
|
||||
validateTopupLoan(loan, expectedDisbursementDate);
|
||||
final BigDecimal loanOutstanding = validateTopupLoan(loan, expectedDisbursementDate);
|
||||
final BigDecimal netDisbursalAmountAdjusted = loan.getApprovedPrincipal().subtract(loanOutstanding);
|
||||
loan.adjustNetDisbursalAmount(netDisbursalAmountAdjusted);
|
||||
}
|
||||
|
||||
if (!loan.getStatus().isSubmittedAndPendingApproval()) {
|
||||
@@ -2202,4 +2206,18 @@ public final class LoanApplicationValidator {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||
dataValidationErrors);
|
||||
}
|
||||
|
||||
private BigDecimal getFirstDisbursalAmount(final Loan loan) {
|
||||
BigDecimal firstDisbursalAmount;
|
||||
|
||||
if (loan.isMultiDisburmentLoan()) {
|
||||
List<DisbursementData> disbursementData = loanMapper.getDisbursementData(loan);
|
||||
Collections.sort(disbursementData);
|
||||
firstDisbursalAmount = disbursementData.get(disbursementData.size() - 1).getPrincipal();
|
||||
} else {
|
||||
firstDisbursalAmount = loan.getLoanRepaymentScheduleDetail().getPrincipal().getAmount();
|
||||
}
|
||||
return firstDisbursalAmount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
-24
@@ -32,7 +32,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -60,6 +59,8 @@ import org.apache.fineract.infrastructure.event.business.service.BusinessEventNo
|
||||
import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeLoanTransactionDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccrualBalances;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccrualChargeData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccrualPeriodData;
|
||||
@@ -79,6 +80,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionToRepayme
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanAccountingBridgeMapper;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@@ -109,6 +111,7 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing
|
||||
@Qualifier(TaskExecutorConstant.CONFIGURABLE_TASK_EXECUTOR_BEAN_NAME)
|
||||
private final ThreadPoolTaskExecutor taskExecutor;
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
private final LoanAccountingBridgeMapper loanAccountingBridgeMapper;
|
||||
|
||||
/**
|
||||
* method adds accrual for batch job "Add Periodic Accrual Transactions" and add accruals api for Loan
|
||||
@@ -413,7 +416,7 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing
|
||||
if (!isFinal || progressiveAccrual) {
|
||||
loan.setAccruedTill(isFinal ? accrualDate : tillDate);
|
||||
}
|
||||
ArrayList<Map<String, Object>> newTransactionMapping = new ArrayList<>();
|
||||
List<AccountingBridgeLoanTransactionDTO> newTransactionDTOs = new ArrayList<>();
|
||||
for (LoanTransaction accrualTransaction : accrualTransactions) {
|
||||
accrualTransaction = loanTransactionRepository.saveAndFlush(accrualTransaction);
|
||||
if (addJournal) {
|
||||
@@ -421,11 +424,17 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing
|
||||
? new LoanAccrualTransactionCreatedBusinessEvent(accrualTransaction)
|
||||
: new LoanAccrualAdjustmentTransactionBusinessEvent(accrualTransaction);
|
||||
businessEventNotifierService.notifyPostBusinessEvent(businessEvent);
|
||||
newTransactionMapping.add(accrualTransaction.toMapData(currency.getCode()));
|
||||
AccountingBridgeLoanTransactionDTO transactionDTO = loanAccountingBridgeMapper.mapToLoanTransactionData(accrualTransaction,
|
||||
currency.getCode());
|
||||
newTransactionDTOs.add(transactionDTO);
|
||||
}
|
||||
}
|
||||
if (addJournal) {
|
||||
Map<String, Object> accountingBridgeData = deriveAccountingBridgeData(loan, newTransactionMapping);
|
||||
AccountingBridgeDataDTO accountingBridgeData = new AccountingBridgeDataDTO(loan.getId(), loan.getLoanProduct().getId(),
|
||||
loan.getOfficeId(), loan.getCurrencyCode(), loan.getSummary().getTotalInterestCharged(),
|
||||
loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct(),
|
||||
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(), false,
|
||||
false, false, null, newTransactionDTOs);
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
}
|
||||
@@ -1110,30 +1119,12 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing
|
||||
}
|
||||
}
|
||||
|
||||
// Utility
|
||||
|
||||
private Map<String, Object> deriveAccountingBridgeData(@NotNull Loan loan, List<Map<String, Object>> newLoanTransactions) {
|
||||
final Map<String, Object> accountingBridgeData = new LinkedHashMap<>();
|
||||
accountingBridgeData.put("loanId", loan.getId());
|
||||
accountingBridgeData.put("loanProductId", loan.getLoanProduct().getId());
|
||||
accountingBridgeData.put("officeId", loan.getOfficeId());
|
||||
accountingBridgeData.put("currencyCode", loan.getCurrencyCode());
|
||||
accountingBridgeData.put("cashBasedAccountingEnabled", loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct());
|
||||
accountingBridgeData.put("upfrontAccrualBasedAccountingEnabled", loan.isUpfrontAccrualAccountingEnabledOnLoanProduct());
|
||||
accountingBridgeData.put("periodicAccrualBasedAccountingEnabled", loan.isPeriodicAccrualAccountingEnabledOnLoanProduct());
|
||||
accountingBridgeData.put("isAccountTransfer", false);
|
||||
accountingBridgeData.put("isChargeOff", false);
|
||||
accountingBridgeData.put("isFraud", false);
|
||||
accountingBridgeData.put("newLoanTransactions", newLoanTransactions);
|
||||
return accountingBridgeData;
|
||||
}
|
||||
|
||||
private void postJournalEntries(final Loan loan, final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds) {
|
||||
final MonetaryCurrency currency = loan.getCurrency();
|
||||
boolean isAccountTransfer = false;
|
||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
final AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(currency.getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loan);
|
||||
journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -90,6 +90,7 @@ import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.group.domain.Group;
|
||||
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidByData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
@@ -128,6 +129,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.OverdueLoanSc
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.DefaultScheduledDateGenerator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.ScheduledDateGenerator;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanAccountingBridgeMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeApiJsonValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanDownPaymentTransactionValidator;
|
||||
@@ -178,6 +180,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
|
||||
private final ReprocessLoanTransactionsService reprocessLoanTransactionsService;
|
||||
private final LoanAccountService loanAccountService;
|
||||
private final LoanAdjustmentService loanAdjustmentService;
|
||||
private final LoanAccountingBridgeMapper loanAccountingBridgeMapper;
|
||||
|
||||
private static boolean isPartOfThisInstallment(LoanCharge loanCharge, LoanRepaymentScheduleInstallment e) {
|
||||
return DateUtils.isAfter(loanCharge.getDueDate(), e.getFromDate()) && !DateUtils.isAfter(loanCharge.getDueDate(), e.getDueDate());
|
||||
@@ -929,8 +932,8 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
|
||||
|
||||
loanAccountService.saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(loan.getCurrency().getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, false);
|
||||
final AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(
|
||||
loan.getCurrency().getCode(), existingTransactionIds, existingReversedTransactionIds, false, loan);
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds);
|
||||
loanAccountDomainService.setLoanDelinquencyTag(loan, transactionDate);
|
||||
@@ -1302,8 +1305,8 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
|
||||
|
||||
final MonetaryCurrency currency = loan.getCurrency();
|
||||
boolean isAccountTransfer = false;
|
||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
final AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(currency.getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loan);
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
|
||||
|
||||
+64
-2
@@ -24,15 +24,18 @@ import com.google.common.base.Splitter;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.configuration.service.TemporaryConfigurationServiceContainer;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
@@ -76,14 +79,14 @@ public class LoanDisbursementService {
|
||||
if (disbursementDataArray != null && !disbursementDataArray.isEmpty()) {
|
||||
String dateFormat;
|
||||
Locale locale = null;
|
||||
final Map<String, String> dateAndLocale = loan.getDateFormatAndLocale(jsonCommand);
|
||||
final Map<String, String> dateAndLocale = getDateFormatAndLocale(jsonCommand);
|
||||
dateFormat = dateAndLocale.get(LoanApiConstants.dateFormatParameterName);
|
||||
if (dateAndLocale.containsKey(LoanApiConstants.localeParameterName)) {
|
||||
locale = JsonParserHelper.localeFromString(dateAndLocale.get(LoanApiConstants.localeParameterName));
|
||||
}
|
||||
for (JsonElement jsonElement : disbursementDataArray) {
|
||||
final JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
final Map<String, Object> parsedDisbursementData = loan.parseDisbursementDetails(jsonObject, dateFormat, locale);
|
||||
final Map<String, Object> parsedDisbursementData = parseDisbursementDetails(jsonObject, dateFormat, locale);
|
||||
final LocalDate expectedDisbursementDate = (LocalDate) parsedDisbursementData
|
||||
.get(LoanApiConstants.expectedDisbursementDateParameterName);
|
||||
final BigDecimal principal = (BigDecimal) parsedDisbursementData
|
||||
@@ -298,4 +301,63 @@ public class LoanDisbursementService {
|
||||
}) //
|
||||
.forEach(loanCharge -> reprocessLoanTransactionsService.removeLoanCharge(loan, loanCharge));
|
||||
}
|
||||
|
||||
// This method returns date format and locale if present in the JsonCommand
|
||||
private Map<String, String> getDateFormatAndLocale(final JsonCommand jsonCommand) {
|
||||
Map<String, String> returnObject = new HashMap<>();
|
||||
JsonElement jsonElement = jsonCommand.parsedJson();
|
||||
if (jsonElement.isJsonObject()) {
|
||||
JsonObject topLevel = jsonElement.getAsJsonObject();
|
||||
if (topLevel.has(LoanApiConstants.dateFormatParameterName)
|
||||
&& topLevel.get(LoanApiConstants.dateFormatParameterName).isJsonPrimitive()) {
|
||||
final JsonPrimitive primitive = topLevel.get(LoanApiConstants.dateFormatParameterName).getAsJsonPrimitive();
|
||||
returnObject.put(LoanApiConstants.dateFormatParameterName, primitive.getAsString());
|
||||
}
|
||||
if (topLevel.has(LoanApiConstants.localeParameterName)
|
||||
&& topLevel.get(LoanApiConstants.localeParameterName).isJsonPrimitive()) {
|
||||
final JsonPrimitive primitive = topLevel.get(LoanApiConstants.localeParameterName).getAsJsonPrimitive();
|
||||
String localeString = primitive.getAsString();
|
||||
returnObject.put(LoanApiConstants.localeParameterName, localeString);
|
||||
}
|
||||
}
|
||||
return returnObject;
|
||||
}
|
||||
|
||||
private Map<String, Object> parseDisbursementDetails(final JsonObject jsonObject, String dateFormat, Locale locale) {
|
||||
Map<String, Object> returnObject = new HashMap<>();
|
||||
if (jsonObject.get(LoanApiConstants.expectedDisbursementDateParameterName) != null
|
||||
&& jsonObject.get(LoanApiConstants.expectedDisbursementDateParameterName).isJsonPrimitive()) {
|
||||
final JsonPrimitive primitive = jsonObject.get(LoanApiConstants.expectedDisbursementDateParameterName).getAsJsonPrimitive();
|
||||
final String valueAsString = primitive.getAsString();
|
||||
if (StringUtils.isNotBlank(valueAsString)) {
|
||||
LocalDate date = JsonParserHelper.convertFrom(valueAsString, LoanApiConstants.expectedDisbursementDateParameterName,
|
||||
dateFormat, locale);
|
||||
if (date != null) {
|
||||
returnObject.put(LoanApiConstants.expectedDisbursementDateParameterName, date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonObject.get(LoanApiConstants.disbursementPrincipalParameterName).isJsonPrimitive()
|
||||
&& StringUtils.isNotBlank(jsonObject.get(LoanApiConstants.disbursementPrincipalParameterName).getAsString())) {
|
||||
BigDecimal principal = jsonObject.getAsJsonPrimitive(LoanApiConstants.disbursementPrincipalParameterName).getAsBigDecimal();
|
||||
returnObject.put(LoanApiConstants.disbursementPrincipalParameterName, principal);
|
||||
}
|
||||
|
||||
if (jsonObject.has(LoanApiConstants.disbursementIdParameterName)
|
||||
&& jsonObject.get(LoanApiConstants.disbursementIdParameterName).isJsonPrimitive()
|
||||
&& StringUtils.isNotBlank(jsonObject.get(LoanApiConstants.disbursementIdParameterName).getAsString())) {
|
||||
Long id = jsonObject.getAsJsonPrimitive(LoanApiConstants.disbursementIdParameterName).getAsLong();
|
||||
returnObject.put(LoanApiConstants.disbursementIdParameterName, id);
|
||||
}
|
||||
|
||||
if (jsonObject.has(LoanApiConstants.loanChargeIdParameterName)
|
||||
&& jsonObject.get(LoanApiConstants.loanChargeIdParameterName).isJsonPrimitive()
|
||||
&& StringUtils.isNotBlank(jsonObject.get(LoanApiConstants.loanChargeIdParameterName).getAsString())) {
|
||||
returnObject.put(LoanApiConstants.loanChargeIdParameterName,
|
||||
jsonObject.getAsJsonPrimitive(LoanApiConstants.loanChargeIdParameterName).getAsString());
|
||||
}
|
||||
return returnObject;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
-14
@@ -18,13 +18,13 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanAccountingBridgeMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@@ -32,23 +32,24 @@ import org.springframework.stereotype.Component;
|
||||
public class LoanJournalEntryPoster {
|
||||
|
||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||
private final LoanAccountingBridgeMapper loanAccountingBridgeMapper;
|
||||
|
||||
public void postJournalEntries(final Loan loan, final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds) {
|
||||
|
||||
final MonetaryCurrency currency = loan.getCurrency();
|
||||
boolean isAccountTransfer = false;
|
||||
List<Map<String, Object>> accountingBridgeData = new ArrayList<>();
|
||||
if (loan.isChargedOff()) {
|
||||
accountingBridgeData = loan.deriveAccountingBridgeDataForChargeOff(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
} else {
|
||||
accountingBridgeData.add(loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer));
|
||||
}
|
||||
for (Map<String, Object> accountingData : accountingBridgeData) {
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingData);
|
||||
}
|
||||
|
||||
if (loan.isChargedOff()) {
|
||||
List<AccountingBridgeDataDTO> accountingBridgeDataList = loanAccountingBridgeMapper.deriveAccountingBridgeDataForChargeOff(
|
||||
currency.getCode(), existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loan);
|
||||
for (AccountingBridgeDataDTO accountingBridgeData : accountingBridgeDataList) {
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
} else {
|
||||
AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(currency.getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loan);
|
||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-5
@@ -38,7 +38,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||
@@ -141,15 +141,13 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, LoanReadPlatformServiceCommon {
|
||||
|
||||
private static final String ACCRUAL_ON_CHARGE_SUBMITTED_ON_DATE = "submitted-date";
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
private final LoanRepositoryWrapper loanRepositoryWrapper;
|
||||
@@ -164,7 +162,6 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
private final CalendarReadPlatformService calendarReadPlatformService;
|
||||
private final StaffReadPlatformService staffReadPlatformService;
|
||||
private final PaginationHelper paginationHelper;
|
||||
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
||||
@@ -179,6 +176,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
private final LoanTransactionRelationReadService loanTransactionRelationReadService;
|
||||
private final LoanForeclosureValidator loanForeclosureValidator;
|
||||
private final LoanTransactionMapper loanTransactionMapper;
|
||||
private final org.apache.fineract.portfolio.loanaccount.mapper.LoanMapper loanMapper;
|
||||
private final LoanTransactionProcessingService loadTransactionProcessingService;
|
||||
|
||||
@Override
|
||||
|
||||
+13
-32
@@ -149,6 +149,7 @@ import org.apache.fineract.portfolio.group.domain.Group;
|
||||
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.command.LoanUpdateCommand;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.AccountingBridgeDataDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepository;
|
||||
@@ -163,7 +164,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachin
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||
@@ -195,6 +195,8 @@ import org.apache.fineract.portfolio.loanaccount.guarantor.service.GuarantorDoma
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryWritePlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanAccountingBridgeMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeValidator;
|
||||
@@ -247,14 +249,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final CalendarRepository calendarRepository;
|
||||
private final LoanScheduleHistoryWritePlatformService loanScheduleHistoryWritePlatformService;
|
||||
private final LoanApplicationValidator loanApplicationCommandFromApiJsonHelper;
|
||||
private final LoanApplicationValidator loanApplicationValidator;
|
||||
private final AccountAssociationsRepository accountAssociationRepository;
|
||||
private final AccountTransferDetailRepository accountTransferDetailRepository;
|
||||
private final BusinessEventNotifierService businessEventNotifierService;
|
||||
private final GuarantorDomainService guarantorDomainService;
|
||||
private final LoanUtilService loanUtilService;
|
||||
private final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService;
|
||||
private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy;
|
||||
private final CodeValueRepositoryWrapper codeValueRepository;
|
||||
private final CashierTransactionDataValidator cashierTransactionDataValidator;
|
||||
private final GLIMAccountInfoRepository glimRepository;
|
||||
@@ -280,6 +281,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
private final LoanAccountService loanAccountService;
|
||||
private final LoanJournalEntryPoster journalEntryPoster;
|
||||
private final LoanAdjustmentService loanAdjustmentService;
|
||||
private final LoanAccountingBridgeMapper loanAccountingBridgeMapper;
|
||||
private final LoanMapper loanMapper;
|
||||
private final LoanTransactionProcessingService loanTransactionProcessingService;
|
||||
|
||||
@Transactional
|
||||
@@ -378,27 +381,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final ExternalId txnExternalId = externalIdFactory.createFromCommand(command, LoanApiConstants.externalIdParameterName);
|
||||
|
||||
if (loan.isTopup() && loan.getClientId() != null) {
|
||||
final Long loanIdToClose = loan.getTopupLoanDetails().getLoanIdToClose();
|
||||
final Loan loanToClose = this.loanRepositoryWrapper.findNonClosedLoanThatBelongsToClient(loanIdToClose, loan.getClientId());
|
||||
if (loanToClose == null) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.to.be.closed.with.topup.is.not.active",
|
||||
"Loan to be closed with this topup is not active.");
|
||||
}
|
||||
final LocalDate lastUserTransactionOnLoanToClose = loanToClose.getLastUserTransactionDate();
|
||||
if (DateUtils.isBefore(loan.getDisbursementDate(), lastUserTransactionOnLoanToClose)) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.loan.disbursal.date.should.be.after.last.transaction.date.of.loan.to.be.closed",
|
||||
"Disbursal date of this loan application " + loan.getDisbursementDate()
|
||||
+ " should be after last transaction date of loan to be closed " + lastUserTransactionOnLoanToClose);
|
||||
}
|
||||
|
||||
BigDecimal loanOutstanding = this.loanReadPlatformService
|
||||
.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",
|
||||
"Topup loan amount should be greater than outstanding amount of loan to be closed.");
|
||||
}
|
||||
final BigDecimal loanOutstanding = loanApplicationValidator.validateTopupLoan(loan, actualDisbursementDate);
|
||||
|
||||
amountToDisburse = disburseAmount.minus(loanOutstanding);
|
||||
disburseLoanToLoan(loan, command, loanOutstanding);
|
||||
@@ -625,7 +608,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
private void createAndSaveLoanScheduleArchive(final Loan loan, ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
LoanRescheduleRequest loanRescheduleRequest = null;
|
||||
LoanScheduleModel loanScheduleModel = loan.regenerateScheduleModel(scheduleGeneratorDTO);
|
||||
LoanScheduleModel loanScheduleModel = loanMapper.regenerateScheduleModel(scheduleGeneratorDTO, loan);
|
||||
List<LoanRepaymentScheduleInstallment> installments = retrieveRepaymentScheduleFromModel(loanScheduleModel);
|
||||
this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(installments, loan, loanRescheduleRequest);
|
||||
}
|
||||
@@ -922,11 +905,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
this.accountTransfersWritePlatformService.reverseAllTransactions(loanId, PortfolioAccountType.LOAN);
|
||||
String noteText;
|
||||
createNote(loan, command, changes);
|
||||
boolean isAccountTransfer = false;
|
||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
final AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(currency.getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loan);
|
||||
journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds);
|
||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanUndoDisbursalBusinessEvent(loan));
|
||||
@@ -2353,8 +2335,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
final BigDecimal principal = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("approvedLoanAmount", element);
|
||||
|
||||
loanApplicationCommandFromApiJsonHelper.validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate,
|
||||
principal);
|
||||
loanApplicationValidator.validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate, principal);
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
@@ -2791,8 +2772,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
createNote(loan, command, changes);
|
||||
boolean isAccountTransfer = false;
|
||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
final AccountingBridgeDataDTO accountingBridgeData = loanAccountingBridgeMapper.deriveAccountingBridgeData(currency.getCode(),
|
||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, loan);
|
||||
journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds);
|
||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanUndoLastDisbursalBusinessEvent(loan));
|
||||
|
||||
+23
-18
@@ -83,8 +83,10 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanSchedul
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryWritePlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanAccountingBridgeMapper;
|
||||
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.rescheduleloan.domain.LoanTermVariationsRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionValidator;
|
||||
@@ -162,7 +164,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
|
||||
@Configuration
|
||||
public class LoanAccountConfiguration {
|
||||
@@ -302,7 +303,8 @@ public class LoanAccountConfiguration {
|
||||
LoanAccrualsProcessingService loanAccrualsProcessingService,
|
||||
LoanDownPaymentTransactionValidator loanDownPaymentTransactionValidator, LoanChargeValidator loanChargeValidator,
|
||||
LoanScheduleService loanScheduleService, ReprocessLoanTransactionsService reprocessLoanTransactionsService,
|
||||
LoanAccountService loanAccountService, LoanAdjustmentService loanAdjustmentService) {
|
||||
LoanAccountService loanAccountService, LoanAdjustmentService loanAdjustmentService,
|
||||
LoanAccountingBridgeMapper loanAccountingBridgeMapper) {
|
||||
return new LoanChargeWritePlatformServiceImpl(loanChargeApiJsonValidator, loanAssembler, chargeRepository,
|
||||
businessEventNotifierService, loanTransactionRepository, accountTransfersWritePlatformService, loanRepositoryWrapper,
|
||||
journalEntryWritePlatformService, loanAccountDomainService, loanChargeRepository, loanWritePlatformService, loanUtilService,
|
||||
@@ -310,7 +312,8 @@ public class LoanAccountConfiguration {
|
||||
configurationDomainService, loanRepaymentScheduleTransactionProcessorFactory, externalIdFactory,
|
||||
accountTransferDetailRepository, loanChargeAssembler, paymentDetailWritePlatformService, noteRepository,
|
||||
loanAccrualTransactionBusinessEventService, loanAccrualsProcessingService, loanDownPaymentTransactionValidator,
|
||||
loanChargeValidator, loanScheduleService, reprocessLoanTransactionsService, loanAccountService, loanAdjustmentService);
|
||||
loanChargeValidator, loanScheduleService, reprocessLoanTransactionsService, loanAccountService, loanAdjustmentService,
|
||||
loanAccountingBridgeMapper);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -322,23 +325,23 @@ public class LoanAccountConfiguration {
|
||||
FundReadPlatformService fundReadPlatformService, ChargeReadPlatformService chargeReadPlatformService,
|
||||
CodeValueReadPlatformService codeValueReadPlatformService, CalendarReadPlatformService calendarReadPlatformService,
|
||||
StaffReadPlatformService staffReadPlatformService, PaginationHelper paginationHelper,
|
||||
NamedParameterJdbcTemplate namedParameterJdbcTemplate, PaymentTypeReadPlatformService paymentTypeReadPlatformService,
|
||||
PaymentTypeReadPlatformService paymentTypeReadPlatformService,
|
||||
LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
FloatingRatesReadPlatformService floatingRatesReadPlatformService, LoanUtilService loanUtilService,
|
||||
ConfigurationDomainService configurationDomainService, AccountDetailsReadPlatformService accountDetailsReadPlatformService,
|
||||
ColumnValidator columnValidator, DatabaseSpecificSQLGenerator sqlGenerator,
|
||||
DelinquencyReadPlatformService delinquencyReadPlatformService, LoanTransactionRepository loanTransactionRepository,
|
||||
LoanChargePaidByReadService loanChargePaidByReadService, LoanTransactionRelationReadService loanTransactionRelationReadService,
|
||||
LoanForeclosureValidator loanForeclosureValidator, LoanTransactionMapper loanTransactionMapper,
|
||||
LoanForeclosureValidator loanForeclosureValidator, LoanTransactionMapper loanTransactionMapper, LoanMapper loanMapper,
|
||||
LoanTransactionProcessingService loanTransactionProcessingService) {
|
||||
return new LoanReadPlatformServiceImpl(jdbcTemplate, context, loanRepositoryWrapper, applicationCurrencyRepository,
|
||||
loanProductReadPlatformService, clientReadPlatformService, groupReadPlatformService, loanDropdownReadPlatformService,
|
||||
fundReadPlatformService, chargeReadPlatformService, codeValueReadPlatformService, calendarReadPlatformService,
|
||||
staffReadPlatformService, paginationHelper, namedParameterJdbcTemplate, paymentTypeReadPlatformService,
|
||||
staffReadPlatformService, paginationHelper, paymentTypeReadPlatformService,
|
||||
loanRepaymentScheduleTransactionProcessorFactory, floatingRatesReadPlatformService, loanUtilService,
|
||||
configurationDomainService, accountDetailsReadPlatformService, columnValidator, sqlGenerator,
|
||||
delinquencyReadPlatformService, loanTransactionRepository, loanChargePaidByReadService, loanTransactionRelationReadService,
|
||||
loanForeclosureValidator, loanTransactionMapper, loanTransactionProcessingService);
|
||||
loanForeclosureValidator, loanTransactionMapper, loanMapper, loanTransactionProcessingService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -387,9 +390,9 @@ public class LoanAccountConfiguration {
|
||||
AccountTransferDetailRepository accountTransferDetailRepository, BusinessEventNotifierService businessEventNotifierService,
|
||||
GuarantorDomainService guarantorDomainService, LoanUtilService loanUtilService,
|
||||
EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService,
|
||||
LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy, CodeValueRepositoryWrapper codeValueRepository,
|
||||
CashierTransactionDataValidator cashierTransactionDataValidator, GLIMAccountInfoRepository glimRepository,
|
||||
LoanRepository loanRepository, RepaymentWithPostDatedChecksAssembler repaymentWithPostDatedChecksAssembler,
|
||||
CodeValueRepositoryWrapper codeValueRepository, CashierTransactionDataValidator cashierTransactionDataValidator,
|
||||
GLIMAccountInfoRepository glimRepository, LoanRepository loanRepository,
|
||||
RepaymentWithPostDatedChecksAssembler repaymentWithPostDatedChecksAssembler,
|
||||
PostDatedChecksRepository postDatedChecksRepository,
|
||||
LoanRepaymentScheduleInstallmentRepository loanRepaymentScheduleInstallmentRepository,
|
||||
LoanLifecycleStateMachine defaultLoanLifecycleStateMachine, LoanAccountLockService loanAccountLockService,
|
||||
@@ -401,6 +404,7 @@ public class LoanAccountConfiguration {
|
||||
LoanChargeValidator loanChargeValidator, LoanOfficerService loanOfficerService,
|
||||
ReprocessLoanTransactionsService reprocessLoanTransactionsService, LoanAccountService loanAccountService,
|
||||
LoanJournalEntryPoster journalEntryPoster, LoanAdjustmentService loanAdjustmentService,
|
||||
LoanAccountingBridgeMapper loanAccountingBridgeMapper, LoanMapper loanMapper,
|
||||
LoanTransactionProcessingService loanTransactionProcessingService) {
|
||||
return new LoanWritePlatformServiceJpaRepositoryImpl(context, loanTransactionValidator, loanUpdateCommandFromApiJsonDeserializer,
|
||||
loanRepositoryWrapper, loanAccountDomainService, noteRepository, loanTransactionRepository,
|
||||
@@ -409,14 +413,14 @@ public class LoanAccountConfiguration {
|
||||
accountTransfersWritePlatformService, accountTransfersReadPlatformService, accountAssociationsReadPlatformService,
|
||||
loanReadPlatformService, fromApiJsonHelper, calendarRepository, loanScheduleHistoryWritePlatformService,
|
||||
loanApplicationValidator, accountAssociationRepository, accountTransferDetailRepository, businessEventNotifierService,
|
||||
guarantorDomainService, loanUtilService, entityDatatableChecksWritePlatformService, transactionProcessingStrategy,
|
||||
codeValueRepository, cashierTransactionDataValidator, glimRepository, loanRepository, repaymentWithPostDatedChecksAssembler,
|
||||
guarantorDomainService, loanUtilService, entityDatatableChecksWritePlatformService, codeValueRepository,
|
||||
cashierTransactionDataValidator, glimRepository, loanRepository, repaymentWithPostDatedChecksAssembler,
|
||||
postDatedChecksRepository, loanRepaymentScheduleInstallmentRepository, defaultLoanLifecycleStateMachine,
|
||||
loanAccountLockService, externalIdFactory, loanAccrualTransactionBusinessEventService, errorHandler,
|
||||
loanDownPaymentHandlerService, loanTransactionAssembler, loanAccrualsProcessingService, loanOfficerValidator,
|
||||
loanDownPaymentTransactionValidator, loanDisbursementService, loanScheduleService, loanChargeValidator, loanOfficerService,
|
||||
reprocessLoanTransactionsService, loanAccountService, journalEntryPoster, loanAdjustmentService,
|
||||
loanTransactionProcessingService);
|
||||
reprocessLoanTransactionsService, loanAccountService, journalEntryPoster, loanAdjustmentService, loanAccountingBridgeMapper,
|
||||
loanMapper, loanTransactionProcessingService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -461,10 +465,11 @@ public class LoanAccountConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(LoanScheduleService.class)
|
||||
public LoanScheduleService loanScheduleService(LoanChargeService loanChargeService,
|
||||
ReprocessLoanTransactionsService reprocessLoanTransactionsService,
|
||||
LoanTransactionProcessingService loanTransactionProcessingService, LoanScheduleComponent loanSchedule) {
|
||||
return new LoanScheduleService(loanChargeService, reprocessLoanTransactionsService, loanTransactionProcessingService, loanSchedule);
|
||||
public LoanScheduleService loanScheduleService(final LoanChargeService loanChargeService,
|
||||
final ReprocessLoanTransactionsService reprocessLoanTransactionsService, final LoanMapper loanMapper,
|
||||
final LoanTransactionProcessingService loanTransactionProcessingService, LoanScheduleComponent loanSchedule) {
|
||||
return new LoanScheduleService(loanChargeService, reprocessLoanTransactionsService, loanMapper, loanTransactionProcessingService,
|
||||
loanSchedule);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user