Example usage for org.springframework.dao DataIntegrityViolationException getCause

List of usage examples for org.springframework.dao DataIntegrityViolationException getCause

Introduction

In this page you can find the example usage for org.springframework.dao DataIntegrityViolationException getCause.

Prototype

public synchronized Throwable getCause() 

Source Link

Document

Returns the cause of this throwable or null if the cause is nonexistent or unknown.

Usage

From source file:org.apache.fineract.portfolio.fund.service.FundWritePlatformServiceJpaRepositoryImpl.java

@Transactional
@Override//from   ww  w.  ja  v a 2s.  c  o  m
@CacheEvict(value = "funds", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('fn')")
public CommandProcessingResult updateFund(final Long fundId, final JsonCommand command) {

    try {
        this.context.authenticatedUser();

        this.fromApiJsonDeserializer.validateForUpdate(command.json());

        final Fund fund = this.fundRepository.findOne(fundId);
        if (fund == null) {
            throw new FundNotFoundException(fundId);
        }

        final Map<String, Object> changes = fund.update(command);
        if (!changes.isEmpty()) {
            this.fundRepository.saveAndFlush(fund);
        }

        return new CommandProcessingResultBuilder().withCommandId(command.commandId())
                .withEntityId(fund.getId()).with(changes).build();
    } catch (final DataIntegrityViolationException dve) {
        handleFundDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
        return CommandProcessingResult.empty();
    } catch (final PersistenceException dve) {
        Throwable throwable = ExceptionUtils.getRootCause(dve.getCause());
        handleFundDataIntegrityIssues(command, throwable, dve);
        return CommandProcessingResult.empty();
    }
}

From source file:org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainServiceJpa.java

private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) {
    try {/*from ww  w  .j  av  a 2s . co  m*/
        List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
        for (LoanRepaymentScheduleInstallment installment : installments) {
            if (installment.getId() == null) {
                this.repaymentScheduleInstallmentRepository.save(installment);
            }
        }
        this.loanRepository.saveAndFlush(loan);
    } catch (final DataIntegrityViolationException e) {
        final Throwable realCause = e.getCause();
        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                .resource("loan.transaction");
        if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
            baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
        }
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                    "Validation errors exist.", dataValidationErrors);
        }
    }
}

From source file:org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainServiceJpa.java

@Override
public void saveLoanWithDataIntegrityViolationChecks(final Loan loan) {
    try {/*from  w  ww  . j  av  a  2  s  .  co m*/
        List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
        for (LoanRepaymentScheduleInstallment installment : installments) {
            if (installment.getId() == null) {
                this.repaymentScheduleInstallmentRepository.save(installment);
            }
        }
        this.loanRepository.save(loan);
    } catch (final DataIntegrityViolationException e) {
        final Throwable realCause = e.getCause();
        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                .resource("loan.transaction");
        if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
            baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
        }
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                    "Validation errors exist.", dataValidationErrors);
        }
    }
}

From source file:org.apache.fineract.portfolio.loanaccount.service.LoanApplicationWritePlatformServiceJpaRepositoryImpl.java

private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) {
    try {/*from   w  ww  .j  a v  a  2s . c o m*/
        List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
        for (LoanRepaymentScheduleInstallment installment : installments) {
            if (installment.getId() == null) {
                this.repaymentScheduleInstallmentRepository.save(installment);
            }
        }
        this.loanRepository.saveAndFlush(loan);
    } catch (final DataIntegrityViolationException e) {
        final Throwable realCause = e.getCause();
        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                .resource("loan.application");
        if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
            baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
        }
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                    "Validation errors exist.", dataValidationErrors);
        }
    }
}

From source file:org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java

private void saveLoanWithDataIntegrityViolationChecks(final Loan loan) {
    try {/*from w  ww  .  j ava2 s .  com*/
        List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
        for (LoanRepaymentScheduleInstallment installment : installments) {
            if (installment.getId() == null) {
                this.repaymentScheduleInstallmentRepository.save(installment);
            }
        }
        this.loanRepository.save(loan);
    } catch (final DataIntegrityViolationException e) {
        final Throwable realCause = e.getCause();
        final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                .resource("loan.transaction");
        if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
            baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
        }
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                    "Validation errors exist.", dataValidationErrors);
        }
    }
}

From source file:org.jspresso.framework.application.frontend.controller.AbstractFrontendController.java

/**
 * Refines the data integrity violation exception to determine the translation
 * key from which the user message will be constructed.
 *
 * @param exception// w w w.j  a v a 2  s. c o m
 *     the DataIntegrityViolationException.
 * @return the translation key to use.
 */
protected String refineIntegrityViolationTranslationKey(DataIntegrityViolationException exception) {
    if (exception.getCause() instanceof ConstraintViolationException) {
        ConstraintViolationException cve = (ConstraintViolationException) exception.getCause();
        if (cve.getSQL() != null && cve.getSQL().toUpperCase().contains("DELETE")) {
            return "error.fk.delete";
        }
        if (cve.getConstraintName() != null) {
            if (cve.getConstraintName().toUpperCase().contains("FK")) {
                return "error.fk.update";
            }
            return "error.unicity";
        }
        return "error.integrity";
    }
    return "error.integrity";
}

From source file:org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainServiceJpa.java

@Transactional
@Override//ww  w.ja  v a2s  .c  o  m
public LoanTransaction makeRepayment(final Loan loan, final CommandProcessingResultBuilder builderResult,
        final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
        final String noteText, final String txnExternalId) {

    checkClientOrGroupActive(loan);

    // TODO: Is it required to validate transaction date with meeting dates
    // if repayments is synced with meeting?
    /*
     * if(loan.isSyncDisbursementWithMeeting()){ // validate actual
     * disbursement date against meeting date CalendarInstance
     * calendarInstance =
     * this.calendarInstanceRepository.findCalendarInstaneByLoanId
     * (loan.getId(), CalendarEntityType.LOANS.getValue());
     * this.loanEventApiJsonValidator
     * .validateRepaymentDateWithMeetingDate(transactionDate,
     * calendarInstance); }
     */

    final List<Long> existingTransactionIds = new ArrayList<Long>();
    final List<Long> existingReversedTransactionIds = new ArrayList<Long>();

    final Money repaymentAmount = Money.of(loan.getCurrency(), transactionAmount);
    final LoanTransaction newRepaymentTransaction = LoanTransaction.repayment(loan.getOffice(), repaymentAmount,
            paymentDetail, transactionDate, txnExternalId);
    final boolean allowTransactionsOnHoliday = this.configurationDomainService
            .allowTransactionsOnHolidayEnabled();
    final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
            transactionDate.toDate(), HolidayStatusType.ACTIVE.getValue());
    final WorkingDays workingDays = this.workingDaysRepository.findOne();
    final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService
            .allowTransactionsOnNonWorkingDayEnabled();

    final ChangedTransactionDetail changedTransactionDetail = loan.makeRepayment(newRepaymentTransaction,
            defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds,
            allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay);

    try {
        this.loanTransactionRepository.save(newRepaymentTransaction);
    } catch (DataIntegrityViolationException e) {
        final Throwable realCause = e.getCause();
        final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                .resource("loan.transaction");
        if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
            baseDataValidator.reset().parameter("externalId").value(newRepaymentTransaction.getExternalId())
                    .failWithCode("value.must.be.unique");
        }
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                    "Validation errors exist.", dataValidationErrors);
        }
    }

    /***
     * TODO Vishwas Batch save is giving me a
     * HibernateOptimisticLockingFailureException, looping and saving for
     * the time being, not a major issue for now as this loop is entered
     * only in edge cases (when a payment is made before the latest payment
     * recorded against the loan)
     ***/

    this.loanRepository.saveAndFlush(loan);

    if (changedTransactionDetail != null) {
        for (Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings()
                .entrySet()) {
            this.loanTransactionRepository.save(mapEntry.getValue());
            updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
        }
    }

    if (StringUtils.isNotBlank(noteText)) {
        final Note note = Note.loanTransactionNote(loan, newRepaymentTransaction, noteText);
        this.noteRepository.save(note);
    }

    postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);

    builderResult.withEntityId(newRepaymentTransaction.getId()) //
            .withOfficeId(loan.getOfficeId()) //
            .withClientId(loan.getClientId()) //
            .withGroupId(loan.getGroupId()); //

    return newRepaymentTransaction;
}

From source file:org.mifosplatform.portfolio.loanaccount.service.LoanApplicationWritePlatformServiceJpaRepositoryImpl.java

private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) {
    try {/*from  w ww  . j  ava  2  s  .c  o m*/
        List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
        for (LoanRepaymentScheduleInstallment installment : installments) {
            if (installment.getId() == null) {
                this.repaymentScheduleInstallmentRepository.save(installment);
            }
        }
        this.loanRepository.saveAndFlush(loan);
    } catch (final DataIntegrityViolationException e) {
        final Throwable realCause = e.getCause();
        final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
        final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                .resource("loan.application");
        if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
            baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
        }
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                    "Validation errors exist.", dataValidationErrors);
        }
    }
}

From source file:org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java

@Transactional
@Override//from   w w  w.j a va  2s  . c o m
public CommandProcessingResult disburseLoan(final Long loanId, final JsonCommand command) {

    final AppUser currentUser = this.context.authenticatedUser();

    this.loanEventApiJsonValidator.validateDisbursement(command.json());

    final Loan loan = this.loanAssembler.assembleFrom(loanId);

    checkClientOrGroupActive(loan);

    // check for product mix validations
    checkForProductMixRestrictions(loan);

    // validate actual disbursement date against meeting date
    final CalendarInstance calendarInstance = this.calendarInstanceRepository
            .findCalendarInstaneByLoanId(loan.getId(), CalendarEntityType.LOANS.getValue());
    if (loan.isSyncDisbursementWithMeeting()) {

        final LocalDate actualDisbursementDate = command
                .localDateValueOfParameterNamed("actualDisbursementDate");
        this.loanEventApiJsonValidator.validateDisbursementDateWithMeetingDate(actualDisbursementDate,
                calendarInstance);
    }

    final MonetaryCurrency currency = loan.getCurrency();
    final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository
            .findOneWithNotFoundDetection(currency);

    final List<Long> existingTransactionIds = new ArrayList<Long>();
    final List<Long> existingReversedTransactionIds = new ArrayList<Long>();

    final Map<String, Object> changes = new LinkedHashMap<String, Object>();

    final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService
            .createAndPersistPaymentDetail(command, changes);

    // Recalculate first repayment date based in actual disbursement date.
    final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
    final LocalDate calculatedRepaymentsStartingFromDate = getCalculatedRepaymentsStartingFromDate(
            actualDisbursementDate, loan, calendarInstance);
    final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
    final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
            actualDisbursementDate.toDate());
    final WorkingDays workingDays = this.workingDaysRepository.findOne();
    final boolean allowTransactionsOnHoliday = this.configurationDomainService
            .allowTransactionsOnHolidayEnabled();
    final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService
            .allowTransactionsOnNonWorkingDayEnabled();
    updateLoanCounters(loan, actualDisbursementDate);

    loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency, existingTransactionIds,
            existingReversedTransactionIds, changes, paymentDetail, calculatedRepaymentsStartingFromDate,
            isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
            allowTransactionsOnNonWorkingDay);

    if (!changes.isEmpty()) {
        try {
            this.loanRepository.saveAndFlush(loan);
        } catch (final DataIntegrityViolationException e) {
            final Throwable realCause = e.getCause();
            final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
            final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                    .resource("loan.transaction");
            if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
                baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
            }
            if (!dataValidationErrors.isEmpty()) {
                throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                        "Validation errors exist.", dataValidationErrors);
            }
        }

        final String noteText = command.stringValueOfParameterNamed("note");
        if (StringUtils.isNotBlank(noteText)) {
            final Note note = Note.loanNote(loan, noteText);
            this.noteRepository.save(note);
        }

        postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
    }

    final Set<LoanCharge> loanCharges = loan.charges();
    final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<Long, BigDecimal>();
    for (final LoanCharge loanCharge : loanCharges) {
        if (loanCharge.isDueAtDisbursement()
                && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
            disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
        } else if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
            final Set<LoanInstallmentCharge> chargePerInstallments = loan
                    .generateInstallmentLoanCharges(loanCharge);
            loanCharge.addLoanInstallmentCharges(chargePerInstallments);
            this.loanChargeRepository.save(loanCharge);
        }
    }
    final Locale locale = command.extractLocale();
    final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
    for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) {
        final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService
                .retriveLoanAssociation(loanId);
        final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate,
                entrySet.getValue(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
                savingAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null,
                LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null);
        this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
    }
    //madhav
    LoanProductRelatedDetail loanProductRelatedDetail = loan.getLoanRepaymentScheduleDetail();
    Money principalAmount = loanProductRelatedDetail.getPrincipal();
    String amount = principalAmount.toString();
    String disbursmentDate = actualDisbursementDate.toString();
    String mailId = loanReadPlatformService.getEmailForClient(loan.getClientId());
    String type = "Lease Disbursment Details<br>";
    if (mailId != null) {
        gmailSendingNotificationToClients.sendToUserAccount(mailId, disbursmentDate, type, amount);
    }

    return new CommandProcessingResultBuilder() //
            .withCommandId(command.commandId()) //
            .withEntityId(loan.getId()) //
            .withOfficeId(loan.getOfficeId()) //
            .withClientId(loan.getClientId()) //
            .withGroupId(loan.getGroupId()) //
            .withLoanId(loanId) //
            .with(changes) //
            .build();
}

From source file:org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java

/****
 * TODO Vishwas: Pair with Ashok and re-factor collection sheet code-base
 *****//*from   www. j  a  va 2 s.c om*/
@Transactional
@Override
public Map<String, Object> bulkLoanDisbursal(final JsonCommand command,
        final CollectionSheetBulkDisbursalCommand bulkDisbursalCommand) {
    final AppUser currentUser = this.context.authenticatedUser();

    final SingleDisbursalCommand[] disbursalCommand = bulkDisbursalCommand.getDisburseTransactions();
    final Map<String, Object> changes = new LinkedHashMap<String, Object>();
    if (disbursalCommand == null) {
        return changes;
    }

    for (int i = 0; i < disbursalCommand.length; i++) {
        final SingleDisbursalCommand singleLoanDisbursalCommand = disbursalCommand[i];

        final Loan loan = this.loanAssembler.assembleFrom(singleLoanDisbursalCommand.getLoanId());
        checkClientOrGroupActive(loan);
        final MonetaryCurrency currency = loan.getCurrency();
        final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository
                .findOneWithNotFoundDetection(currency);

        final List<Long> existingTransactionIds = new ArrayList<Long>();
        final List<Long> existingReversedTransactionIds = new ArrayList<Long>();

        final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService
                .createAndPersistPaymentDetail(command, changes);

        // Bulk disbursement should happen on meeting date (mostly from
        // collection sheet).
        // FIXME: AA - this should be first meeting date based on
        // disbursement date and next available meeting dates
        // assuming repayment schedule won't regenerate because expected
        // disbursement and actual disbursement happens on same date
        final LocalDate firstRepaymentOnDate = null;
        final LocalDate actualDisbursementDate = command
                .localDateValueOfParameterNamed("actualDisbursementDate");
        final boolean isHolidayEnabled = this.configurationDomainService
                .isRescheduleRepaymentsOnHolidaysEnabled();
        final List<Holiday> holidays = this.holidayRepository
                .findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), actualDisbursementDate.toDate());
        final WorkingDays workingDays = this.workingDaysRepository.findOne();
        final boolean allowTransactionsOnHoliday = this.configurationDomainService
                .allowTransactionsOnHolidayEnabled();
        final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService
                .allowTransactionsOnNonWorkingDayEnabled();
        updateLoanCounters(loan, actualDisbursementDate);

        loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency,
                existingTransactionIds, existingReversedTransactionIds, changes, paymentDetail,
                firstRepaymentOnDate, isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
                allowTransactionsOnNonWorkingDay);

        if (!changes.isEmpty()) {
            try {
                this.loanRepository.save(loan);
            } catch (final DataIntegrityViolationException e) {
                final Throwable realCause = e.getCause();
                final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
                final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
                        .resource("loan.transaction");
                if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
                    baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
                }
                if (!dataValidationErrors.isEmpty()) {
                    throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                            "Validation errors exist.", dataValidationErrors);
                }
            }

            final String noteText = command.stringValueOfParameterNamed("note");
            if (StringUtils.isNotBlank(noteText)) {
                final Note note = Note.loanNote(loan, noteText);
                this.noteRepository.save(note);
            }

            postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
        }
        final Set<LoanCharge> loanCharges = loan.charges();
        final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<Long, BigDecimal>();
        for (final LoanCharge loanCharge : loanCharges) {
            if (loanCharge.isDueAtDisbursement()
                    && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
                disBuLoanCharges.put(loanCharge.getId(), loanCharge.amount());
            } else if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
                final Set<LoanInstallmentCharge> chargePerInstallments = loan
                        .generateInstallmentLoanCharges(loanCharge);
                loanCharge.addLoanInstallmentCharges(chargePerInstallments);
                this.loanChargeRepository.save(loanCharge);
            }
        }
        final Locale locale = command.extractLocale();
        final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
        for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) {
            final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService
                    .retriveLoanAssociation(loan.getId());
            final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate,
                    entrySet.getValue(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
                    savingAccountData.accountId(), loan.getId(), "Loan Charge Payment", locale, fmt, null, null,
                    LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null);
            this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
        }
    }
    return changes;
}