Example usage for org.joda.time LocalDate isBefore

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

Introduction

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

Prototype

public boolean isBefore(ReadablePartial partial) 

Source Link

Document

Is this partial earlier than the specified partial.

Usage

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

private BigDecimal constructFloatingInterestRates(final BigDecimal annualNominalInterestRate,
        final FloatingRateDTO floatingRateDTO, final List<LoanTermVariationsData> loanTermVariations) {
    final LocalDate dateValue = null;
    final boolean isSpecificToInstallment = false;
    BigDecimal interestRate = annualNominalInterestRate;
    if (loanProduct.isLinkedToFloatingInterestRate()) {
        floatingRateDTO.resetInterestRateDiff();
        Collection<FloatingRatePeriodData> applicableRates = loanProduct.fetchInterestRates(floatingRateDTO);
        LocalDate interestRateStartDate = DateUtils.getLocalDateOfTenant();
        for (FloatingRatePeriodData periodData : applicableRates) {
            LoanTermVariationsData loanTermVariation = new LoanTermVariationsData(
                    LoanEnumerations.loanvariationType(LoanTermVariationType.INTEREST_RATE),
                    periodData.getFromDateAsLocalDate(), periodData.getInterestRate(), dateValue,
                    isSpecificToInstallment);
            if (!interestRateStartDate.isBefore(periodData.getFromDateAsLocalDate())) {
                interestRateStartDate = periodData.getFromDateAsLocalDate();
                interestRate = periodData.getInterestRate();
            }/*from w w  w.  j ava 2  s  .com*/
            loanTermVariations.add(loanTermVariation);
        }
    }
    return interestRate;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

private void handleDisbursementTransaction(final LocalDate disbursedOn, final LocalDateTime createdDate,
        final AppUser currentUser, final PaymentDetail paymentDetail) {

    // add repayment transaction to track incoming money from client to mfi
    // for (charges due at time of disbursement)

    /***//  w ww.j av a2 s  .  c o m
     * TODO Vishwas: do we need to be able to pass in payment type details
     * for repayments at disbursements too?
     ***/

    final Money totalFeeChargesDueAtDisbursement = this.summary
            .getTotalFeeChargesDueAtDisbursement(loanCurrency());
    /**
     * all Charges repaid at disbursal is marked as repaid and
     * "APPLY Charge" transactions are created for all other fees ( which
     * are created during disbursal but not repaid)
     **/

    Money disbursentMoney = Money.zero(getCurrency());
    final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(getOffice(), disbursentMoney,
            paymentDetail, disbursedOn, null, createdDate, currentUser);
    final Integer installmentNumber = null;
    for (final LoanCharge charge : charges()) {
        Date actualDisbursementDate = getActualDisbursementDate(charge);
        if ((charge.getCharge().getChargeTimeType() == ChargeTimeType.DISBURSEMENT.getValue()
                && disbursedOn.equals(new LocalDate(actualDisbursementDate)) && actualDisbursementDate != null
                && !charge.isWaived() && !charge.isFullyPaid())
                || (charge.getCharge().getChargeTimeType() == ChargeTimeType.TRANCHE_DISBURSEMENT.getValue()
                        && disbursedOn.equals(new LocalDate(actualDisbursementDate))
                        && actualDisbursementDate != null && !charge.isWaived() && !charge.isFullyPaid())) {
            if (totalFeeChargesDueAtDisbursement.isGreaterThanZero()
                    && !charge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
                charge.markAsFullyPaid();
                // Add "Loan Charge Paid By" details to this transaction
                final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(chargesPayment, charge,
                        charge.amount(), installmentNumber);
                chargesPayment.getLoanChargesPaid().add(loanChargePaidBy);
                disbursentMoney = disbursentMoney.plus(charge.amount());
            }
        } else if (disbursedOn.equals(new LocalDate(this.actualDisbursementDate))) {
            /**
             * create a Charge applied transaction if Up front Accrual, None
             * or Cash based accounting is enabled
             **/
            if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
                handleChargeAppliedTransaction(charge, disbursedOn, currentUser);
            }
        }
    }

    if (disbursentMoney.isGreaterThanZero()) {
        final Money zero = Money.zero(getCurrency());
        chargesPayment.updateComponentsAndTotal(zero, zero, disbursentMoney, zero);
        chargesPayment.updateLoan(this);
        addLoanTransaction(chargesPayment);
        updateLoanOutstandingBalaces();
    }

    if (getApprovedOnDate() != null && disbursedOn.isBefore(getApprovedOnDate())) {
        final String errorMessage = "The date on which a loan is disbursed cannot be before its approval date: "
                + getApprovedOnDate().toString();
        throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.before.approval.date",
                errorMessage, disbursedOn, getApprovedOnDate());
    }

    if (getExpectedFirstRepaymentOnDate() != null
            && (disbursedOn.isAfter(this.fetchRepaymentScheduleInstallment(1).getDueDate())
                    || disbursedOn.isAfter(getExpectedFirstRepaymentOnDate()))
            && disbursedOn.toDate().equals(this.actualDisbursementDate)) {
        final String errorMessage = "submittedOnDate cannot be after the loans  expectedFirstRepaymentOnDate: "
                + getExpectedFirstRepaymentOnDate().toString();
        throw new InvalidLoanStateTransitionException("disbursal",
                "cannot.be.after.expected.first.repayment.date", errorMessage, disbursedOn,
                getExpectedFirstRepaymentOnDate());
    }

    validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSED, disbursedOn);

    if (disbursedOn.isAfter(new LocalDate())) {
        final String errorMessage = "The date on which a loan with identifier : " + this.accountNumber
                + " is disbursed cannot be in the future.";
        throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.a.future.date", errorMessage,
                disbursedOn);
    }

}

From source file:com.gst.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.  java  2  s .  c  o 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,
            getLoanTransactions());

    if (loanTransaction.isNotZero(loanCurrency())) {
        addLoanTransaction(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 (!isForeclosure() && isTransactionChronologicallyLatest && adjustedTransaction == null
            && loanTransaction.getTransactionDate().isEqual(DateUtils.getLocalDateOfTenant())
            && currentInstallment != null && currentInstallment.getTotalOutstanding(getCurrency())
                    .isEqualTo(loanTransaction.getAmount(getCurrency()))) {
        reprocess = false;
    }

    if (isTransactionChronologicallyLatest && adjustedTransaction == null
            && (!reprocess || !this.repaymentScheduleDetail().isInterestRecalculationEnabled())
            && !isForeclosure()) {
        loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(),
                getRepaymentScheduleInstallments(), 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(),
                getRepaymentScheduleInstallments(), 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;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

private boolean isChronologicallyLatestRepaymentOrWaiver(final LoanTransaction loanTransaction,
        final List<LoanTransaction> loanTransactions) {

    boolean isChronologicallyLatestRepaymentOrWaiver = true;

    final LocalDate currentTransactionDate = loanTransaction.getTransactionDate();
    for (final LoanTransaction previousTransaction : loanTransactions) {
        if (!previousTransaction.isDisbursement() && previousTransaction.isNotReversed()) {
            if (currentTransactionDate.isBefore(previousTransaction.getTransactionDate())
                    || currentTransactionDate.isEqual(previousTransaction.getTransactionDate())) {
                isChronologicallyLatestRepaymentOrWaiver = false;
                break;
            }//from   w ww. j av a 2s  .  c  o  m
        }
    }

    return isChronologicallyLatestRepaymentOrWaiver;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

private boolean isAfterLatRepayment(final LoanTransaction loanTransaction,
        final List<LoanTransaction> loanTransactions) {

    boolean isAfterLatRepayment = true;

    final LocalDate currentTransactionDate = loanTransaction.getTransactionDate();
    for (final LoanTransaction previousTransaction : loanTransactions) {
        if (previousTransaction.isRepayment() && previousTransaction.isNotReversed()) {
            if (currentTransactionDate.isBefore(previousTransaction.getTransactionDate())) {
                isAfterLatRepayment = false;
                break;
            }/* w  ww . j a  va 2 s . co m*/
        }
    }
    return isAfterLatRepayment;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

private boolean isChronologicallyLatestTransaction(final LoanTransaction loanTransaction,
        final List<LoanTransaction> loanTransactions) {

    boolean isChronologicallyLatestRepaymentOrWaiver = true;

    final LocalDate currentTransactionDate = loanTransaction.getTransactionDate();
    for (final LoanTransaction previousTransaction : loanTransactions) {
        if (previousTransaction.isNotReversed()) {
            if (currentTransactionDate.isBefore(previousTransaction.getTransactionDate())
                    || currentTransactionDate.isEqual(previousTransaction.getTransactionDate())) {
                isChronologicallyLatestRepaymentOrWaiver = false;
                break;
            }/* w  ww . java  2  s.  co m*/
        }
    }

    return isChronologicallyLatestRepaymentOrWaiver;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

public ChangedTransactionDetail closeAsWrittenOff(final JsonCommand command,
        final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes,
        final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
        final AppUser currentUser, final ScheduleGeneratorDTO scheduleGeneratorDTO) {

    final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
            .determineProcessor(this.transactionProcessingStrategy);
    ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
            loanRepaymentScheduleTransactionProcessor, currentUser);

    validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING);

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

    LoanTransaction loanTransaction = null;
    if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
        this.loanStatus = statusEnum.getValue();
        changes.put("status", LoanEnumerations.status(this.loanStatus));

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

        final LocalDate writtenOffOnLocalDate = command.localDateValueOfParameterNamed("transactionDate");
        final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId");

        this.closedOnDate = writtenOffOnLocalDate.toDate();
        this.writtenOffOnDate = writtenOffOnLocalDate.toDate();
        this.closedBy = currentUser;
        changes.put("closedOnDate", command.stringValueOfParameterNamed("transactionDate"));
        changes.put("writtenOffOnDate", command.stringValueOfParameterNamed("transactionDate"));

        if (writtenOffOnLocalDate.isBefore(getDisbursementDate())) {
            final String errorMessage = "The date on which a loan is written off cannot be before the loan disbursement date: "
                    + getDisbursementDate().toString();
            throw new InvalidLoanStateTransitionException("writeoff", "cannot.be.before.submittal.date",
                    errorMessage, writtenOffOnLocalDate, getDisbursementDate());
        }//from   ww w .jav  a2s.c o m

        validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.WRITE_OFF_OUTSTANDING,
                writtenOffOnLocalDate);

        if (writtenOffOnLocalDate.isAfter(DateUtils.getLocalDateOfTenant())) {
            final String errorMessage = "The date on which a loan is written off cannot be in the future.";
            throw new InvalidLoanStateTransitionException("writeoff", "cannot.be.a.future.date", errorMessage,
                    writtenOffOnLocalDate);
        }

        LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
        loanTransaction = LoanTransaction.writeoff(this, getOffice(), writtenOffOnLocalDate, txnExternalId,
                createdDate, currentUser);
        LocalDate lastTransactionDate = getLastUserTransactionDate();
        if (lastTransactionDate.isAfter(writtenOffOnLocalDate)) {
            final String errorMessage = "The date of the writeoff transaction must occur on or before previous transactions.";
            throw new InvalidLoanStateTransitionException("writeoff",
                    "must.occur.on.or.after.other.transaction.dates", errorMessage, writtenOffOnLocalDate);
        }

        addLoanTransaction(loanTransaction);
        loanRepaymentScheduleTransactionProcessor.handleWriteOff(loanTransaction, loanCurrency(),
                getRepaymentScheduleInstallments());

        updateLoanSummaryDerivedFields();
    }
    if (changedTransactionDetail == null) {
        changedTransactionDetail = new ChangedTransactionDetail();
    }
    changedTransactionDetail.getNewTransactionMappings().put(0L, loanTransaction);
    return changedTransactionDetail;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

public ChangedTransactionDetail close(final JsonCommand command,
        final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes,
        final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
        final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {

    validateAccountStatus(LoanEvent.LOAN_CLOSED);

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

    final LocalDate closureDate = command.localDateValueOfParameterNamed("transactionDate");
    final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId");

    this.closedOnDate = closureDate.toDate();
    changes.put("closedOnDate", command.stringValueOfParameterNamed("transactionDate"));

    validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.REPAID_IN_FULL, closureDate);
    if (closureDate.isBefore(getDisbursementDate())) {
        final String errorMessage = "The date on which a loan is closed cannot be before the loan disbursement date: "
                + getDisbursementDate().toString();
        throw new InvalidLoanStateTransitionException("close", "cannot.be.before.submittal.date", errorMessage,
                closureDate, getDisbursementDate());
    }// w  ww .  j  a v a 2 s. c  om

    if (closureDate.isAfter(DateUtils.getLocalDateOfTenant())) {
        final String errorMessage = "The date on which a loan is closed cannot be in the future.";
        throw new InvalidLoanStateTransitionException("close", "cannot.be.a.future.date", errorMessage,
                closureDate);
    }
    final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
            .determineProcessor(this.transactionProcessingStrategy);
    ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
            loanRepaymentScheduleTransactionProcessor, currentUser);

    LoanTransaction loanTransaction = null;
    if (isOpen()) {
        final Money totalOutstanding = this.summary.getTotalOutstanding(loanCurrency());
        if (totalOutstanding.isGreaterThanZero()
                && getInArrearsTolerance().isGreaterThanOrEqualTo(totalOutstanding)) {

            final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL,
                    LoanStatus.fromInt(this.loanStatus));
            if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
                this.loanStatus = statusEnum.getValue();
                changes.put("status", LoanEnumerations.status(this.loanStatus));
            }
            this.closedOnDate = closureDate.toDate();
            loanTransaction = LoanTransaction.writeoff(this, getOffice(), closureDate, txnExternalId,
                    DateUtils.getLocalDateTimeOfTenant(), currentUser);
            final boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction,
                    getLoanTransactions());
            if (!isLastTransaction) {
                final String errorMessage = "The closing date of the loan must be on or after latest transaction date.";
                throw new InvalidLoanStateTransitionException("close.loan",
                        "must.occur.on.or.after.latest.transaction.date", errorMessage, closureDate);
            }

            addLoanTransaction(loanTransaction);
            loanRepaymentScheduleTransactionProcessor.handleWriteOff(loanTransaction, loanCurrency(),
                    getRepaymentScheduleInstallments());

            updateLoanSummaryDerivedFields();
        } else if (totalOutstanding.isGreaterThanZero()) {
            final String errorMessage = "A loan with money outstanding cannot be closed";
            throw new InvalidLoanStateTransitionException("close", "loan.has.money.outstanding", errorMessage,
                    totalOutstanding.toString());
        }
    }

    if (isOverPaid()) {
        final Money totalLoanOverpayment = calculateTotalOverpayment();
        if (totalLoanOverpayment.isGreaterThanZero()
                && getInArrearsTolerance().isGreaterThanOrEqualTo(totalLoanOverpayment)) {
            // TODO - KW - technically should set somewhere that this loan
            // has
            // 'overpaid' amount
            final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL,
                    LoanStatus.fromInt(this.loanStatus));
            if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
                this.loanStatus = statusEnum.getValue();
                changes.put("status", LoanEnumerations.status(this.loanStatus));
            }
            this.closedOnDate = closureDate.toDate();
        } else if (totalLoanOverpayment.isGreaterThanZero()) {
            final String errorMessage = "The loan is marked as 'Overpaid' and cannot be moved to 'Closed (obligations met).";
            throw new InvalidLoanStateTransitionException("close", "loan.is.overpaid", errorMessage,
                    totalLoanOverpayment.toString());
        }
    }

    if (changedTransactionDetail == null) {
        changedTransactionDetail = new ChangedTransactionDetail();
    }
    changedTransactionDetail.getNewTransactionMappings().put(0L, loanTransaction);
    return changedTransactionDetail;
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

/**
 * Behaviour added to comply with capability of previous mifos product to
 * support easier transition to fineract platform.
 *///from  w w w .  j a  va  2  s  .  c  om
public void closeAsMarkedForReschedule(final JsonCommand command,
        final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes) {

    final LocalDate rescheduledOn = command.localDateValueOfParameterNamed("transactionDate");

    final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_RESCHEDULE,
            LoanStatus.fromInt(this.loanStatus));
    if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
        this.loanStatus = statusEnum.getValue();
        changes.put("status", LoanEnumerations.status(this.loanStatus));
    }

    this.closedOnDate = rescheduledOn.toDate();
    this.rescheduledOnDate = rescheduledOn.toDate();
    changes.put("closedOnDate", command.stringValueOfParameterNamed("transactionDate"));
    changes.put("rescheduledOnDate", command.stringValueOfParameterNamed("transactionDate"));

    final LocalDate rescheduledOnLocalDate = new LocalDate(this.rescheduledOnDate);
    if (rescheduledOnLocalDate.isBefore(getDisbursementDate())) {
        final String errorMessage = "The date on which a loan is rescheduled cannot be before the loan disbursement date: "
                + getDisbursementDate().toString();
        throw new InvalidLoanStateTransitionException("close.reschedule", "cannot.be.before.submittal.date",
                errorMessage, rescheduledOnLocalDate, getDisbursementDate());
    }

    if (rescheduledOnLocalDate.isAfter(new LocalDate())) {
        final String errorMessage = "The date on which a loan is rescheduled cannot be in the future.";
        throw new InvalidLoanStateTransitionException("close.reschedule", "cannot.be.a.future.date",
                errorMessage, rescheduledOnLocalDate);
    }
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
        final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays,
        final Boolean reschedulebasedOnMeetingDates, final LocalDate presentMeetingDate,
        final LocalDate newMeetingDate, final boolean isSkipRepaymentonfirstdayofmonth,
        final Integer numberofDays) {

    // first repayment's from date is same as disbursement date.
    /*/*from  w w  w .j a  v  a2s. co  m*/
     * meetingStartDate is used as seedDate Capture the seedDate from user
     * and use the seedDate as meetingStart date
     */

    LocalDate tmpFromDate = getDisbursementDate();
    final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail
            .getRepaymentPeriodFrequencyType();
    final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery();
    final String frequency = CalendarUtils
            .getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType);

    LocalDate newRepaymentDate = null;
    Boolean isFirstTime = true;
    LocalDate latestRepaymentDate = null;
    List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
    for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) {

        LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();

        if (oldDueDate.isEqual(presentMeetingDate) || oldDueDate.isAfter(presentMeetingDate)) {

            if (isFirstTime) {

                isFirstTime = false;
                newRepaymentDate = newMeetingDate;

            } else {
                // tmpFromDate.plusDays(1) is done to make sure
                // getNewRepaymentMeetingDate method returns next meeting
                // date and not the same as tmpFromDate
                newRepaymentDate = CalendarUtils.getNewRepaymentMeetingDate(recuringRule, tmpFromDate,
                        tmpFromDate.plusDays(1), loanRepaymentInterval, frequency, workingDays,
                        isSkipRepaymentonfirstdayofmonth, numberofDays);
            }

            if (isHolidayEnabled) {
                newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate,
                        holidays);
            }
            if (latestRepaymentDate == null || latestRepaymentDate.isBefore(newRepaymentDate)) {
                latestRepaymentDate = newRepaymentDate;
            }
            loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
            // reset from date to get actual daysInPeriod

            if (!isFirstTime) {
                loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
            }

            tmpFromDate = newRepaymentDate;// update with new repayment
            // date
        } else {
            tmpFromDate = oldDueDate;
        }
    }
    if (latestRepaymentDate != null) {
        this.expectedMaturityDate = latestRepaymentDate.toDate();
    }
}