FINERACT-2107: Loan transaction Interest Refund GL Entries

This commit is contained in:
Jose Alberto Hernandez
2024-08-22 11:04:26 +02:00
committed by Adam Saghy
parent 7304af57bc
commit 5ebd3429c6
10 changed files with 359 additions and 5 deletions
@@ -111,13 +111,15 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
createJournalEntriesForChargeOff(loanDTO, loanTransactionDTO, office);
}
// Logic for Interest Payment Waiver
else if (loanTransactionDTO.getTransactionType().isInterestPaymentWaiver()) {
createJournalEntriesForInterestPaymentWaiver(loanDTO, loanTransactionDTO, office);
else if (loanTransactionDTO.getTransactionType().isInterestPaymentWaiver()
|| loanTransactionDTO.getTransactionType().isInterestRefund()) {
createJournalEntriesForInterestPaymentWaiverOrInterestRefund(loanDTO, loanTransactionDTO, office);
}
}
}
private void createJournalEntriesForInterestPaymentWaiver(LoanDTO loanDTO, LoanTransactionDTO loanTransactionDTO, Office office) {
private void createJournalEntriesForInterestPaymentWaiverOrInterestRefund(LoanDTO loanDTO, LoanTransactionDTO loanTransactionDTO,
Office office) {
final Long loanProductId = loanDTO.getLoanProductId();
final Long loanId = loanDTO.getLoanId();
final String currencyCode = loanDTO.getCurrencyCode();
@@ -23,9 +23,11 @@ import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsCons
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_BY;
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_DATE;
import com.google.gson.Gson;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
@@ -41,7 +43,9 @@ import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.boot.FineractProfiles;
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
import org.apache.fineract.portfolio.loanaccount.data.LoanRefundRequestData;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
@@ -64,6 +68,8 @@ public class InternalLoanInformationApiResource implements InitializingBean {
private final ToApiJsonSerializer<List> toApiJsonSerializerForList;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final AdvancedPaymentDataMapper advancedPaymentDataMapper;
private final LoanAccountDomainService loanAccountDomainService;
private final Gson gson = new Gson();
@Override
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
@@ -152,4 +158,23 @@ public class InternalLoanInformationApiResource implements InitializingBean {
final Loan loan = loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
return advancedPaymentDataMapper.mapLoanPaymentAllocationRule(loan.getPaymentAllocationRules());
}
@POST
@Path("{loanId}/apply-interest-refund")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
public Long applyInterestRefundToLoan(@Context final UriInfo uriInfo, @PathParam("loanId") Long loanId,
final String apiRequestBodyAsJson) {
log.warn("------------------------------------------------------------");
log.warn(" ");
log.warn(" Apply Loan Transaction to Interest Refund loanId {} ", loanId);
log.warn(" ");
log.warn("------------------------------------------------------------");
LoanRefundRequestData loanRefundRequestData = gson.fromJson(apiRequestBodyAsJson, LoanRefundRequestData.class);
final Loan loan = loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
final LoanTransaction loanTransaction = loanAccountDomainService.applyInterestRefund(loan, loanRefundRequestData);
return loanTransaction.getId();
}
}
@@ -67,7 +67,6 @@ import org.apache.fineract.infrastructure.event.business.service.BusinessEventNo
import org.apache.fineract.organisation.holiday.domain.Holiday;
import org.apache.fineract.organisation.holiday.domain.HolidayRepository;
import org.apache.fineract.organisation.holiday.domain.HolidayStatusType;
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.organisation.workingdays.domain.WorkingDays;
@@ -87,6 +86,7 @@ import org.apache.fineract.portfolio.delinquency.validator.LoanDelinquencyAction
import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
import org.apache.fineract.portfolio.loanaccount.data.LoanRefundRequestData;
import org.apache.fineract.portfolio.loanaccount.data.LoanScheduleDelinquencyData;
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.service.LoanAccrualTransactionBusinessEventService;
@@ -120,7 +120,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
private final NoteRepository noteRepository;
private final AccountTransferRepository accountTransferRepository;
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
private final BusinessEventNotifierService businessEventNotifierService;
private final LoanUtilService loanUtilService;
private final StandingInstructionRepository standingInstructionRepository;
@@ -801,4 +800,26 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
}
}
@Override
public LoanTransaction applyInterestRefund(final Loan loan, final LoanRefundRequestData loanRefundRequest) {
final PaymentDetail paymentDetail = null;
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
final BigDecimal refundAmount = loanRefundRequest.getTotalAmount();
final List<Long> existingTransactionIds = new ArrayList<>();
final List<Long> existingReversedTransactionIds = new ArrayList<>();
existingTransactionIds.addAll(loan.findExistingTransactionIds());
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
final LoanTransaction interestRefundTransaction = LoanTransaction.interestRefund(loan, loan.getOffice(), refundAmount,
loanRefundRequest.getPrincipal(), loanRefundRequest.getInterest(), loanRefundRequest.getFeeCharges(),
loanRefundRequest.getPenaltyCharges(), paymentDetail, transactionDate, externalIdFactory.create());
interestRefundTransaction.updateLoan(loan);
saveLoanTransactionWithDataIntegrityViolationChecks(interestRefundTransaction);
loan.addLoanTransaction(interestRefundTransaction);
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false);
return interestRefundTransaction;
}
}