Example usage for org.joda.time LocalDate now

List of usage examples for org.joda.time LocalDate now

Introduction

In this page you can find the example usage for org.joda.time LocalDate now.

Prototype

public static LocalDate now() 

Source Link

Document

Obtains a LocalDate set to the current system millisecond time using ISOChronology in the default time zone.

Usage

From source file:net.jrkatz.minero.data.BudgetPeriodProvider.java

License:Open Source License

@NonNull
public BudgetPeriod getCurrentBudgetPeriod(@NonNull final ProviderContext context, final long budgetId)
        throws ProviderException {
    BudgetPeriod budgetPeriod = getLatestBudgetPeriod(context, budgetId);
    //if this budgetPeriod is too old it may be necessary to create a new one or _several_
    //new ones.//from w w  w  .  jav a 2s  .  c o  m
    final LocalDate now = LocalDate.now();
    if (budgetPeriod == null) {
        final Budget budget = context.getBudgetProvider().getBudget(context, budgetId);
        final PeriodDefinition periodDefinition = budget.getPeriodDefinition();
        final Period period = periodDefinition.periodForDate(now);
        budgetPeriod = createBudgetPeriod(context, budgetId, budget.getDistribution(), period);
    } else if (!now.isBefore(budgetPeriod.getPeriod().getEnd())) {
        final BudgetProvider bp = context.getBudgetProvider();
        final Budget budget = bp.getBudget(context, budgetId);
        final PeriodDefinition periodDefinition = budget.getPeriodDefinition();
        do {
            //add savings from previous period
            bp.setBudgetRunningTotal(context, budgetId, budgetPeriod.getRemaining());
            //make subsequent period
            final Period nextPeriod = periodDefinition.periodForDate(budgetPeriod.getPeriod().getEnd());
            budgetPeriod = createBudgetPeriod(context, budgetId, budget.getDistribution(), nextPeriod);
        } while (!now.isBefore(budgetPeriod.getPeriod().getEnd()));
    }
    return budgetPeriod;
}

From source file:org.alfresco.repo.web.scripts.solr.StatsGet.java

License:Open Source License

/**
 * Parses ISO8601 formatted Date Strings.
 * @param start If start is null then defaults to 1 month
 * @param end If end is null then it defaults to now();
 *//*from  w w w.  ja  va2 s .  co  m*/
public static Pair<LocalDate, LocalDate> getStartAndEndDates(String start, String end) {
    if (start == null)
        return null;
    LocalDate startDate = LocalDate.parse(start);
    LocalDate endDate = end != null ? LocalDate.parse(end) : LocalDate.now();
    return new Pair<LocalDate, LocalDate>(startDate, endDate);
}

From source file:org.apache.fineract.accounting.closure.bookoffincomeandexpense.service.CalculateIncomeAndExpenseBookingImpl.java

License:Apache License

private IncomeAndExpenseBookingData bookOffIncomeAndExpense(
        final List<IncomeAndExpenseJournalEntryData> incomeAndExpenseJournalEntryDataList,
        final GLClosureCommand closureData, final boolean preview, final GLAccount glAccount,
        final Office office) {
    /* All running balances has to be calculated before booking off income and expense account */
    boolean isRunningBalanceCalculated = true;
    for (final IncomeAndExpenseJournalEntryData incomeAndExpenseData : incomeAndExpenseJournalEntryDataList) {
        if (!incomeAndExpenseData.isRunningBalanceCalculated()) {
            throw new RunningBalanceNotCalculatedException(incomeAndExpenseData.getOfficeId());
        }/*from  w  w  w  . j a  v  a2s . com*/
    }
    BigDecimal debits = BigDecimal.ZERO;
    BigDecimal credits = BigDecimal.ZERO;

    final List<SingleDebitOrCreditEntry> debitsJournalEntry = new ArrayList<>();
    final List<SingleDebitOrCreditEntry> creditsJournalEntry = new ArrayList<>();

    for (final IncomeAndExpenseJournalEntryData incomeAndExpense : incomeAndExpenseJournalEntryDataList) {
        if (incomeAndExpense.isIncomeAccountType()) {
            if (incomeAndExpense.getOfficeRunningBalance().signum() == 1) {
                debits = debits.add(incomeAndExpense.getOfficeRunningBalance());
                debitsJournalEntry.add(new SingleDebitOrCreditEntry(incomeAndExpense.getAccountId(),
                        incomeAndExpense.getGlAccountName(), incomeAndExpense.getOfficeRunningBalance(), null));
            } else {
                credits = credits.add(incomeAndExpense.getOfficeRunningBalance().abs());
                creditsJournalEntry.add(new SingleDebitOrCreditEntry(incomeAndExpense.getAccountId(),
                        incomeAndExpense.getGlAccountName(), incomeAndExpense.getOfficeRunningBalance().abs(),
                        null));
                ;
            }
        }
        if (incomeAndExpense.isExpenseAccountType()) {
            if (incomeAndExpense.getOfficeRunningBalance().signum() == 1) {
                credits = credits.add(incomeAndExpense.getOfficeRunningBalance());
                creditsJournalEntry.add(new SingleDebitOrCreditEntry(incomeAndExpense.getAccountId(),
                        incomeAndExpense.getGlAccountName(), incomeAndExpense.getOfficeRunningBalance().abs(),
                        null));
                ;
            } else {
                debits = debits.add(incomeAndExpense.getOfficeRunningBalance().abs());
                debitsJournalEntry.add(new SingleDebitOrCreditEntry(incomeAndExpense.getAccountId(),
                        incomeAndExpense.getGlAccountName(), incomeAndExpense.getOfficeRunningBalance().abs(),
                        null));
            }
        }
    }
    final LocalDate today = DateUtils.getLocalDateOfTenant();
    final int compare = debits.compareTo(credits);
    BigDecimal difference = BigDecimal.ZERO;
    JournalEntry journalEntry = null;
    if (compare == 1) {
        /* book with target gl id on the credit side */
        difference = debits.subtract(credits);
        SingleDebitOrCreditEntry targetBooking = new SingleDebitOrCreditEntry(
                closureData.getEquityGlAccountId(), glAccount.getName(), difference, null);
        creditsJournalEntry.add(targetBooking);
        journalEntry = new JournalEntry(office.getId(), today.toString(), closureData.getComments(),
                creditsJournalEntry, debitsJournalEntry, null, false, closureData.getCurrencyCode(),
                office.getName());
    } else if (compare == -1) {
        /* book with target gl id on the debit side*/
        difference = credits.subtract(debits);
        SingleDebitOrCreditEntry targetBooking = new SingleDebitOrCreditEntry(
                closureData.getEquityGlAccountId(), glAccount.getName(), difference, null);
        debitsJournalEntry.add(targetBooking);
        journalEntry = new JournalEntry(office.getId(), today.toString(), closureData.getComments(),
                creditsJournalEntry, debitsJournalEntry, null, false, closureData.getCurrencyCode(),
                office.getName());
    } else if (compare == 0) {
        //throw new RunningBalanceZeroException(office.getName());
    }
    final LocalDate localDate = LocalDate.now();
    final List<JournalEntry> journalEntries = new ArrayList<>();
    if (journalEntry != null) {
        journalEntries.add(journalEntry);
    }

    return new IncomeAndExpenseBookingData(localDate, closureData.getComments(), journalEntries);
}

From source file:org.apache.fineract.infrastructure.scheduledemail.domain.EmailMessage.java

License:Apache License

private EmailMessage(final Group group, final Client client, final Staff staff,
        final EmailCampaign emailCampaign, final EmailMessageStatusType statusType, final String emailSubject,
        final String message, final String emailAddress, final String campaignName) {
    this.group = group;
    this.client = client;
    this.staff = staff;
    this.emailCampaign = emailCampaign;
    this.statusType = statusType.getValue();
    this.emailAddress = emailAddress;
    this.emailSubject = emailSubject;
    this.message = message;
    this.campaignName = campaignName;
    this.submittedOnDate = LocalDate.now().toDate();
}

From source file:org.apache.fineract.portfolio.client.command.ClientIdentifierCommand.java

License:Apache License

public void validateForCreate() {
    final List<ApiParameterError> dataValidationErrors = new ArrayList<>();

    final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
            .resource("clientIdentifier");

    baseDataValidator.reset().parameter("documentTypeId").value(this.documentTypeId).notNull()
            .integerGreaterThanZero();//from ww w  .ja  v a  2s  . c o m
    baseDataValidator.reset().parameter("documentKey").value(this.documentKey).notBlank();

    baseDataValidator.reset().parameter("validity").value(this.validity)
            .validateDateAfter(LocalDate.now().plusMonths(1)).ignoreIfNull();
    baseDataValidator.reset().parameter("isLifeTime").value(this.isLifeTime).ignoreIfNull();

    if (!dataValidationErrors.isEmpty()) {
        throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
                "Validation errors exist.", dataValidationErrors);
    }
}

From source file:org.apache.fineract.portfolio.group.service.GroupingTypesWritePlatformServiceJpaRepositoryImpl.java

License:Apache License

@Override
public CommandProcessingResult assignGroupOrCenterStaff(final Long groupId, final JsonCommand command) {

    this.context.authenticatedUser();

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

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

    final Group groupForUpdate = this.groupRepository.findOneWithNotFoundDetection(groupId);

    Staff staff = null;//from www  . j a  v  a  2s  . co  m
    final Long staffId = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName);
    final boolean inheritStaffForClientAccounts = command
            .booleanPrimitiveValueOfParameterNamed(GroupingTypesApiConstants.inheritStaffForClientAccounts);
    staff = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(staffId,
            groupForUpdate.getOffice().getHierarchy());
    groupForUpdate.updateStaff(staff);

    if (inheritStaffForClientAccounts) {
        LocalDate loanOfficerReassignmentDate = LocalDate.now();
        /*
         * update loan officer for client and update loan officer for
         * clients loans and savings
         */
        Set<Client> clients = groupForUpdate.getClientMembers();
        if (clients != null) {
            for (Client client : clients) {
                client.updateStaff(staff);
                if (this.loanRepository.doNonClosedLoanAccountsExistForClient(client.getId())) {
                    for (final Loan loan : this.loanRepository.findLoanByClientId(client.getId())) {
                        if (loan.isDisbursed() && !loan.isClosed()) {
                            loan.reassignLoanOfficer(staff, loanOfficerReassignmentDate);
                        }
                    }
                }
                if (this.savingsAccountRepository.doNonClosedSavingAccountsExistForClient(client.getId())) {
                    for (final SavingsAccount savingsAccount : this.savingsAccountRepository
                            .findSavingAccountByClientId(client.getId())) {
                        if (!savingsAccount.isClosed()) {
                            savingsAccount.reassignSavingsOfficer(staff, loanOfficerReassignmentDate);
                        }
                    }
                }
            }
        }
    }
    this.groupRepository.saveAndFlush(groupForUpdate);

    actualChanges.put(GroupingTypesApiConstants.staffIdParamName, staffId);

    return new CommandProcessingResultBuilder() //
            .withOfficeId(groupForUpdate.officeId()) //
            .withEntityId(groupForUpdate.getId()) //
            .withGroupId(groupId) //
            .with(actualChanges) //
            .build();
}

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

License:Apache License

public LoanTransaction waiveLoanCharge(final LoanCharge loanCharge,
        final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes,
        final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
        final Integer loanInstallmentNumber, final ScheduleGeneratorDTO scheduleGeneratorDTO,
        final Money accruedCharge, final AppUser currentUser) {

    validateLoanIsNotClosed(loanCharge);

    final Money amountWaived = loanCharge.waive(loanCurrency(), loanInstallmentNumber);

    changes.put("amount", amountWaived.getAmount());

    Money unrecognizedIncome = amountWaived.zero();
    Money chargeComponent = amountWaived;
    if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
        Money receivableCharge = Money.zero(getCurrency());
        if (loanInstallmentNumber != null) {
            receivableCharge = accruedCharge.minus(
                    loanCharge.getInstallmentLoanCharge(loanInstallmentNumber).getAmountPaid(getCurrency()));
        } else {// w  w  w. j av  a2 s.c o m
            receivableCharge = accruedCharge.minus(loanCharge.getAmountPaid(getCurrency()));
        }
        if (receivableCharge.isLessThanZero()) {
            receivableCharge = amountWaived.zero();
        }
        if (amountWaived.isGreaterThan(receivableCharge)) {
            chargeComponent = receivableCharge;
            unrecognizedIncome = amountWaived.minus(receivableCharge);
        }
    }
    Money feeChargesWaived = chargeComponent;
    Money penaltyChargesWaived = Money.zero(loanCurrency());
    if (loanCharge.isPenaltyCharge()) {
        penaltyChargesWaived = chargeComponent;
        feeChargesWaived = Money.zero(loanCurrency());
    }

    LocalDate transactionDate = getDisbursementDate();
    if (loanCharge.isSpecifiedDueDate()) {
        transactionDate = loanCharge.getDueLocalDate();
    }
    scheduleGeneratorDTO.setRecalculateFrom(transactionDate);

    updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());

    existingTransactionIds.addAll(findExistingTransactionIds());
    existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());

    final LoanTransaction waiveLoanChargeTransaction = LoanTransaction.waiveLoanCharge(this, getOffice(),
            amountWaived, transactionDate, feeChargesWaived, penaltyChargesWaived, unrecognizedIncome,
            DateUtils.getLocalDateTimeOfTenant(), currentUser);
    final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(waiveLoanChargeTransaction, loanCharge,
            waiveLoanChargeTransaction.getAmount(getCurrency()).getAmount(), loanInstallmentNumber);
    waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy);
    this.loanTransactions.add(waiveLoanChargeTransaction);

    if (this.repaymentScheduleDetail().isInterestRecalculationEnabled() && (loanCharge.getDueLocalDate() == null
            || LocalDate.now().isAfter(loanCharge.getDueLocalDate()))) {
        regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
    }
    // Waive of charges whose due date falls after latest 'repayment'
    // transaction dont require entire loan schedule to be reprocessed.
    final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
            .determineProcessor(this.transactionProcessingStrategy);
    if (!loanCharge.isDueAtDisbursement() && loanCharge.isPaidOrPartiallyPaid(loanCurrency())) {
        /****
         * TODO Vishwas Currently we do not allow waiving fully paid loan
         * charge and waiving partially paid loan charges only waives the
         * remaining amount.
         * 
         * Consider removing this block of code or logically completing it
         * for the future by getting the list of affected Transactions
         ***/
        final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
        loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
                allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments,
                charges());
    } else {
        // reprocess loan schedule based on charge been waived.
        final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
        wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges());
    }

    updateLoanSummaryDerivedFields();

    doPostLoanTransactionChecks(waiveLoanChargeTransaction.getTransactionDate(), loanLifecycleStateMachine);

    return waiveLoanChargeTransaction;
}

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

License:Apache License

private BigDecimal calculateOverdueAmountPercentageAppliedTo(final LoanCharge loanCharge,
        final int penaltyWaitPeriod) {
    LoanRepaymentScheduleInstallment installment = loanCharge.getOverdueInstallmentCharge().getInstallment();
    LocalDate graceDate = LocalDate.now().minusDays(penaltyWaitPeriod);
    Money amount = Money.zero(getCurrency());
    if (graceDate.isAfter(installment.getDueDate())) {
        amount = calculateOverdueAmountPercentageAppliedTo(installment, loanCharge.getChargeCalculation());
        if (!amount.isGreaterThanZero()) {
            loanCharge.setActive(false);
        }/*from w ww . ja va 2  s.  c  o  m*/
    } else {
        loanCharge.setActive(false);
    }
    return amount.getAmount();
}

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

License:Apache License

public ChangedTransactionDetail disburse(final AppUser currentUser, final JsonCommand command,
        final Map<String, Object> actualChanges, final ScheduleGeneratorDTO scheduleGeneratorDTO) {

    final LoanStatus statusEnum = this.loanLifecycleStateMachine.transition(LoanEvent.LOAN_DISBURSED,
            LoanStatus.fromInt(this.loanStatus));

    final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");

    this.loanStatus = statusEnum.getValue();
    actualChanges.put("status", LoanEnumerations.status(this.loanStatus));

    this.disbursedBy = currentUser;
    updateLoanScheduleDependentDerivedFields();

    actualChanges.put("locale", command.locale());
    actualChanges.put("dateFormat", command.dateFormat());
    actualChanges.put("actualDisbursementDate", command.stringValueOfParameterNamed("actualDisbursementDate"));

    HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO();

    // validate if disbursement date is a holiday or a non-working day
    validateDisbursementDateIsOnNonWorkingDay(holidayDetailDTO.getWorkingDays(),
            holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
    validateDisbursementDateIsOnHoliday(holidayDetailDTO.isAllowTransactionsOnHoliday(),
            holidayDetailDTO.getHolidays());

    if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()
            && (fetchRepaymentScheduleInstallment(1).getDueDate().isBefore(LocalDate.now())
                    || isDisbursementMissed())) {
        regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
    }/*w  w w .  ja  va 2s.com*/

    updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
    updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
    LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
    handleDisbursementTransaction(actualDisbursementDate, createdDate, currentUser);
    updateLoanSummaryDerivedFields();
    final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());

    /**
     * Add an interest applied transaction of the interest is accrued
     * upfront (Up front accrual), no accounting or cash based accounting is
     * selected
     **/

    if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
        final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this,
                interestApplied, actualDisbursementDate, createdDate, currentUser);
        this.loanTransactions.add(interestAppliedTransaction);
    }

    return reprocessTransactionForDisbursement();

}

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

License:Apache License

private ChangedTransactionDetail handleRepaymentOrRecoveryOrWaiverTransaction(
        final LoanTransaction loanTransaction, final LoanLifecycleStateMachine loanLifecycleStateMachine,
        final LoanTransaction adjustedTransaction, final ScheduleGeneratorDTO scheduleGeneratorDTO,
        final AppUser currentUser) {

    ChangedTransactionDetail changedTransactionDetail = null;

    LoanStatus statusEnum = null;/*  w  w  w  . jav  a2s  .co m*/

    LocalDate recalculateFrom = loanTransaction.getTransactionDate();
    if (adjustedTransaction != null && adjustedTransaction.getTransactionDate().isBefore(recalculateFrom)) {
        recalculateFrom = adjustedTransaction.getTransactionDate();
    }

    if (loanTransaction.isRecoveryRepayment()) {
        statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_RECOVERY_PAYMENT,
                LoanStatus.fromInt(this.loanStatus));
    } else {
        statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT_OR_WAIVER,
                LoanStatus.fromInt(this.loanStatus));
    }

    this.loanStatus = statusEnum.getValue();

    loanTransaction.updateLoan(this);

    final boolean isTransactionChronologicallyLatest = isChronologicallyLatestRepaymentOrWaiver(loanTransaction,
            this.loanTransactions);

    if (loanTransaction.isNotZero(loanCurrency())) {
        this.loanTransactions.add(loanTransaction);
    }

    if (loanTransaction.isNotRepayment() && loanTransaction.isNotWaiver()
            && loanTransaction.isNotRecoveryRepayment()) {
        final String errorMessage = "A transaction of type repayment or recovery repayment or waiver was expected but not received.";
        throw new InvalidLoanTransactionTypeException("transaction",
                "is.not.a.repayment.or.waiver.or.recovery.transaction", errorMessage);
    }

    final LocalDate loanTransactionDate = loanTransaction.getTransactionDate();
    if (loanTransactionDate.isBefore(getDisbursementDate())) {
        final String errorMessage = "The transaction date cannot be before the loan disbursement date: "
                + getApprovedOnDate().toString();
        throw new InvalidLoanStateTransitionException("transaction", "cannot.be.before.disbursement.date",
                errorMessage, loanTransactionDate, getDisbursementDate());
    }

    if (loanTransactionDate.isAfter(DateUtils.getLocalDateOfTenant())) {
        final String errorMessage = "The transaction date cannot be in the future.";
        throw new InvalidLoanStateTransitionException("transaction", "cannot.be.a.future.date", errorMessage,
                loanTransactionDate);
    }

    if (loanTransaction.isInterestWaiver()) {
        Money totalInterestOutstandingOnLoan = getTotalInterestOutstandingOnLoan();
        if (adjustedTransaction != null) {
            totalInterestOutstandingOnLoan = totalInterestOutstandingOnLoan
                    .plus(adjustedTransaction.getAmount(loanCurrency()));
        }
        if (loanTransaction.getAmount(loanCurrency()).isGreaterThan(totalInterestOutstandingOnLoan)) {
            final String errorMessage = "The amount of interest to waive cannot be greater than total interest outstanding on loan.";
            throw new InvalidLoanStateTransitionException("waive.interest",
                    "amount.exceeds.total.outstanding.interest", errorMessage,
                    loanTransaction.getAmount(loanCurrency()), totalInterestOutstandingOnLoan.getAmount());
        }
    }

    if (this.loanProduct.isMultiDisburseLoan() && adjustedTransaction == null) {
        BigDecimal totalDisbursed = getDisbursedAmount();
        if (totalDisbursed.compareTo(this.summary.getTotalPrincipalRepaid()) < 0) {
            final String errorMessage = "The transaction cannot be done before the loan disbursement: "
                    + getApprovedOnDate().toString();
            throw new InvalidLoanStateTransitionException("transaction", "cannot.be.done.before.disbursement",
                    errorMessage);
        }
    }

    final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
            .determineProcessor(this.transactionProcessingStrategy);

    final LoanRepaymentScheduleInstallment currentInstallment = fetchLoanRepaymentScheduleInstallment(
            loanTransaction.getTransactionDate());
    boolean reprocess = true;

    if (isTransactionChronologicallyLatest && adjustedTransaction == null
            && loanTransaction.getTransactionDate().isEqual(LocalDate.now()) && currentInstallment != null
            && currentInstallment.getTotalOutstanding(getCurrency())
                    .isEqualTo(loanTransaction.getAmount(getCurrency()))) {
        reprocess = false;
    }

    if (isTransactionChronologicallyLatest && adjustedTransaction == null
            && (!reprocess || !this.repaymentScheduleDetail().isInterestRecalculationEnabled())) {
        loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(),
                this.repaymentScheduleInstallments, charges());
        reprocess = false;
        if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
            if (currentInstallment == null || currentInstallment.isNotFullyPaidOff()) {
                reprocess = true;
            } else {
                final LoanRepaymentScheduleInstallment nextInstallment = fetchRepaymentScheduleInstallment(
                        currentInstallment.getInstallmentNumber() + 1);
                if (nextInstallment != null
                        && nextInstallment.getTotalPaidInAdvance(getCurrency()).isGreaterThanZero()) {
                    reprocess = true;
                }
            }
        }
    }
    if (reprocess) {
        if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
            regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
        }
        final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
        changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(
                getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(),
                this.repaymentScheduleInstallments, charges());
        for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail
                .getNewTransactionMappings().entrySet()) {
            mapEntry.getValue().updateLoan(this);
        }
        /***
         * Commented since throwing exception if external id present for one
         * of the transactions. for this need to save the reversed
         * transactions first and then new transactions.
         */
        this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values());
    }

    updateLoanSummaryDerivedFields();

    /**
     * FIXME: Vishwas, skipping post loan transaction checks for Loan
     * recoveries
     **/
    if (loanTransaction.isNotRecoveryRepayment()) {
        doPostLoanTransactionChecks(loanTransaction.getTransactionDate(), loanLifecycleStateMachine);
    }

    if (this.loanProduct.isMultiDisburseLoan()) {
        BigDecimal totalDisbursed = getDisbursedAmount();
        if (totalDisbursed.compareTo(this.summary.getTotalPrincipalRepaid()) < 0
                && this.repaymentScheduleDetail().getPrincipal().minus(totalDisbursed).isGreaterThanZero()) {
            final String errorMessage = "The transaction cannot be done before the loan disbursement: "
                    + getApprovedOnDate().toString();
            throw new InvalidLoanStateTransitionException("transaction", "cannot.be.done.before.disbursement",
                    errorMessage);
        }
    }

    if (changedTransactionDetail != null) {
        this.loanTransactions.removeAll(changedTransactionDetail.getNewTransactionMappings().values());
    }
    return changedTransactionDetail;
}