Example usage for org.joda.time LocalDate isAfter

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

Introduction

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

Prototype

public boolean isAfter(ReadablePartial partial) 

Source Link

Document

Is this partial later than the specified partial.

Usage

From source file:com.gst.portfolio.loanaccount.service.LoanArrearsAgingServiceImpl.java

License:Apache License

private void createInsertStatements(List<String> insertStatement,
        Map<Long, List<LoanSchedulePeriodData>> scheduleDate, boolean isInsertStatement) {
    for (Map.Entry<Long, List<LoanSchedulePeriodData>> entry : scheduleDate.entrySet()) {
        final Long loanId = entry.getKey();
        BigDecimal principalOverdue = BigDecimal.ZERO;
        BigDecimal interestOverdue = BigDecimal.ZERO;
        BigDecimal feeOverdue = BigDecimal.ZERO;
        BigDecimal penaltyOverdue = BigDecimal.ZERO;
        LocalDate overDueSince = LocalDate.now();

        for (LoanSchedulePeriodData loanSchedulePeriodData : entry.getValue()) {
            if (!loanSchedulePeriodData.getComplete()) {
                principalOverdue = principalOverdue.add(
                        loanSchedulePeriodData.principalDue().subtract(loanSchedulePeriodData.principalPaid()));
                interestOverdue = interestOverdue.add(
                        loanSchedulePeriodData.interestDue().subtract(loanSchedulePeriodData.interestPaid()));
                feeOverdue = feeOverdue.add(loanSchedulePeriodData.feeChargesDue()
                        .subtract(loanSchedulePeriodData.feeChargesPaid()));
                penaltyOverdue = penaltyOverdue.add(loanSchedulePeriodData.penaltyChargesDue()
                        .subtract(loanSchedulePeriodData.penaltyChargesPaid()));
                if (overDueSince.isAfter(loanSchedulePeriodData.periodDueDate()) && loanSchedulePeriodData
                        .principalDue().subtract(loanSchedulePeriodData.principalPaid())
                        .compareTo(BigDecimal.ZERO) == 1) {
                    overDueSince = loanSchedulePeriodData.periodDueDate();
                }/*from  ww w.  j a  va 2 s.c  om*/
            }
        }
        if (principalOverdue.compareTo(BigDecimal.ZERO) == 1) {
            String sqlStatement = null;
            if (isInsertStatement) {
                sqlStatement = constructInsertStatement(loanId, principalOverdue, interestOverdue, feeOverdue,
                        penaltyOverdue, overDueSince);
            } else {
                sqlStatement = constructUpdateStatement(loanId, principalOverdue, interestOverdue, feeOverdue,
                        penaltyOverdue, overDueSince);
            }
            insertStatement.add(sqlStatement);
        }

    }
}

From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java

License:Apache License

@Transactional
@Override//from  w w w . j a v a2s .  co  m
public CommandProcessingResult addLoanCharge(final Long loanId, final JsonCommand command) {

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

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

    List<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails();
    final Long chargeDefinitionId = command.longValueOfParameterNamed("chargeId");
    final Charge chargeDefinition = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);

    if (loan.isDisbursed() && chargeDefinition.isDisbursementCharge()) {
        validateAddingNewChargeAllowed(loanDisburseDetails); // validates
                                                             // whether any
                                                             // pending
                                                             // disbursements
                                                             // are
                                                             // available to
                                                             // apply this
                                                             // charge
    }
    final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
    final List<Long> existingReversedTransactionIds = new ArrayList<>(
            loan.findExistingReversedTransactionIds());

    boolean isAppliedOnBackDate = false;
    LoanCharge loanCharge = null;
    LocalDate recalculateFrom = loan.fetchInterestRecalculateFromDate();
    if (chargeDefinition.isPercentageOfDisbursementAmount()) {
        LoanTrancheDisbursementCharge loanTrancheDisbursementCharge = null;
        for (LoanDisbursementDetails disbursementDetail : loanDisburseDetails) {
            if (disbursementDetail.actualDisbursementDate() == null) {
                loanCharge = LoanCharge.createNewWithoutLoan(chargeDefinition, disbursementDetail.principal(),
                        null, null, null, disbursementDetail.expectedDisbursementDateAsLocalDate(), null, null);
                loanTrancheDisbursementCharge = new LoanTrancheDisbursementCharge(loanCharge,
                        disbursementDetail);
                loanCharge.updateLoanTrancheDisbursementCharge(loanTrancheDisbursementCharge);
                this.businessEventNotifierService.notifyBusinessEventToBeExecuted(
                        BUSINESS_EVENTS.LOAN_ADD_CHARGE,
                        constructEntityMap(BUSINESS_ENTITY.LOAN_CHARGE, loanCharge));
                validateAddLoanCharge(loan, chargeDefinition, loanCharge);
                addCharge(loan, chargeDefinition, loanCharge);
                isAppliedOnBackDate = true;
                if (recalculateFrom.isAfter(disbursementDetail.expectedDisbursementDateAsLocalDate())) {
                    recalculateFrom = disbursementDetail.expectedDisbursementDateAsLocalDate();
                }
            }
        }
        loan.addTrancheLoanCharge(chargeDefinition);
    } else {
        loanCharge = LoanCharge.createNewFromJson(loan, chargeDefinition, command);
        this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_ADD_CHARGE,
                constructEntityMap(BUSINESS_ENTITY.LOAN_CHARGE, loanCharge));

        validateAddLoanCharge(loan, chargeDefinition, loanCharge);
        isAppliedOnBackDate = addCharge(loan, chargeDefinition, loanCharge);
        if (loanCharge.getDueLocalDate() == null || recalculateFrom.isAfter(loanCharge.getDueLocalDate())) {
            isAppliedOnBackDate = true;
            recalculateFrom = loanCharge.getDueLocalDate();
        }
    }

    boolean reprocessRequired = true;
    if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
        if (isAppliedOnBackDate && loan.isFeeCompoundingEnabledForInterestRecalculation()) {

            runScheduleRecalculation(loan, recalculateFrom);
            reprocessRequired = false;
        }
        updateOriginalSchedule(loan);
    }
    if (reprocessRequired) {
        ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions();
        if (changedTransactionDetail != null) {
            for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail
                    .getNewTransactionMappings().entrySet()) {
                this.loanTransactionRepository.save(mapEntry.getValue());
                // update loan with references to the newly created
                // transactions
                loan.addLoanTransaction(mapEntry.getValue());
                this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(),
                        mapEntry.getValue());
            }
        }
        saveLoanWithDataIntegrityViolationChecks(loan);
    }

    postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);

    if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && isAppliedOnBackDate
            && loan.isFeeCompoundingEnabledForInterestRecalculation()) {
        this.loanAccountDomainService.recalculateAccruals(loan);
    }
    this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_ADD_CHARGE,
            constructEntityMap(BUSINESS_ENTITY.LOAN_CHARGE, loanCharge));
    return new CommandProcessingResultBuilder() //
            .withCommandId(command.commandId()) //
            .withEntityId(loanCharge.getId()) //
            .withOfficeId(loan.getOfficeId()) //
            .withClientId(loan.getClientId()) //
            .withGroupId(loan.getGroupId()) //
            .withLoanId(loanId) //
            .build();
}

From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java

License:Apache License

@Override
@Transactional//from  w w  w.  ja va2 s.  com
public void applyOverdueChargesForLoan(final Long loanId,
        Collection<OverdueLoanScheduleData> overdueLoanScheduleDatas) {

    Loan loan = null;
    final List<Long> existingTransactionIds = new ArrayList<>();
    final List<Long> existingReversedTransactionIds = new ArrayList<>();
    boolean runInterestRecalculation = false;
    LocalDate recalculateFrom = DateUtils.getLocalDateOfTenant();
    LocalDate lastChargeDate = null;
    for (final OverdueLoanScheduleData overdueInstallment : overdueLoanScheduleDatas) {

        final JsonElement parsedCommand = this.fromApiJsonHelper.parse(overdueInstallment.toString());
        final JsonCommand command = JsonCommand.from(overdueInstallment.toString(), parsedCommand,
                this.fromApiJsonHelper, null, null, null, null, null, loanId, null, null, null, null);
        LoanOverdueDTO overdueDTO = applyChargeToOverdueLoanInstallment(loanId,
                overdueInstallment.getChargeId(), overdueInstallment.getPeriodNumber(), command, loan,
                existingTransactionIds, existingReversedTransactionIds);
        loan = overdueDTO.getLoan();
        runInterestRecalculation = runInterestRecalculation || overdueDTO.isRunInterestRecalculation();
        if (recalculateFrom.isAfter(overdueDTO.getRecalculateFrom())) {
            recalculateFrom = overdueDTO.getRecalculateFrom();
        }
        if (lastChargeDate == null || overdueDTO.getLastChargeAppliedDate().isAfter(lastChargeDate)) {
            lastChargeDate = overdueDTO.getLastChargeAppliedDate();
        }
    }
    if (loan != null) {
        boolean reprocessRequired = true;
        LocalDate recalculatedTill = loan.fetchInterestRecalculateFromDate();
        if (recalculateFrom.isAfter(recalculatedTill)) {
            recalculateFrom = recalculatedTill;
        }

        if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
            if (runInterestRecalculation && loan.isFeeCompoundingEnabledForInterestRecalculation()) {
                runScheduleRecalculation(loan, recalculateFrom);
                reprocessRequired = false;
            }
            updateOriginalSchedule(loan);
        }

        if (reprocessRequired) {
            addInstallmentIfPenaltyAppliedAfterLastDueDate(loan, lastChargeDate);
            ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions();
            if (changedTransactionDetail != null) {
                for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail
                        .getNewTransactionMappings().entrySet()) {
                    this.loanTransactionRepository.save(mapEntry.getValue());
                    // update loan with references to the newly created
                    // transactions
                    loan.addLoanTransaction(mapEntry.getValue());
                    this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(),
                            mapEntry.getValue());
                }
            }
            saveLoanWithDataIntegrityViolationChecks(loan);
        }

        postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);

        if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && runInterestRecalculation
                && loan.isFeeCompoundingEnabledForInterestRecalculation()) {
            this.loanAccountDomainService.recalculateAccruals(loan);
        }
        this.businessEventNotifierService.notifyBusinessEventWasExecuted(
                BUSINESS_EVENTS.LOAN_APPLY_OVERDUE_CHARGE, constructEntityMap(BUSINESS_ENTITY.LOAN, loan));

    }
}

From source file:com.gst.portfolio.loanaccount.service.LoanWritePlatformServiceJpaRepositoryImpl.java

License:Apache License

private void addInstallmentIfPenaltyAppliedAfterLastDueDate(Loan loan, LocalDate lastChargeDate) {
    if (lastChargeDate != null) {
        List<LoanRepaymentScheduleInstallment> installments = loan.getRepaymentScheduleInstallments();
        LoanRepaymentScheduleInstallment lastInstallment = loan
                .fetchRepaymentScheduleInstallment(installments.size());
        if (lastChargeDate.isAfter(lastInstallment.getDueDate())) {
            if (lastInstallment.isRecalculatedInterestComponent()) {
                installments.remove(lastInstallment);
                lastInstallment = loan.fetchRepaymentScheduleInstallment(installments.size());
            }//from  ww  w.  j  a v a2 s .c o m
            boolean recalculatedInterestComponent = true;
            BigDecimal principal = BigDecimal.ZERO;
            BigDecimal interest = BigDecimal.ZERO;
            BigDecimal feeCharges = BigDecimal.ZERO;
            BigDecimal penaltyCharges = BigDecimal.ONE;
            final Set<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null;
            LoanRepaymentScheduleInstallment newEntry = new LoanRepaymentScheduleInstallment(loan,
                    installments.size() + 1, lastInstallment.getDueDate(), lastChargeDate, principal, interest,
                    feeCharges, penaltyCharges, recalculatedInterestComponent, compoundingDetails);
            installments.add(newEntry);
            loan.addLoanRepaymentScheduleInstallment(newEntry);
        }
    }
}

From source file:com.gst.portfolio.savings.domain.DepositAccountTermAndPreClosure.java

License:Apache License

public boolean isAfterExpectedFirstDepositDate(final LocalDate compareDate) {
    boolean isAfterExpectedFirstDepositDate = false;
    if (this.expectedFirstDepositOnDate != null) {
        isAfterExpectedFirstDepositDate = compareDate.isAfter(getExpectedFirstDepositOnDate());
    }//from   w  w w  . j a v a  2 s.  c o m
    return isAfterExpectedFirstDepositDate;
}

From source file:com.gst.portfolio.savings.domain.FixedDepositAccount.java

License:Apache License

public void prematureClosure(final AppUser currentUser, final JsonCommand command,
        final LocalDate tenantsTodayDate, final Map<String, Object> actualChanges) {

    final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
    final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
            .resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + DepositsApiConstants.preMatureCloseAction);

    final SavingsAccountStatusType currentStatus = SavingsAccountStatusType.fromInt(this.status);
    if (!SavingsAccountStatusType.ACTIVE.hasStateOf(currentStatus)) {
        baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("not.in.active.state");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }/*from  w ww.  j a v a2  s.c om*/
    }

    final Locale locale = command.extractLocale();
    final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
    final LocalDate closedDate = command
            .localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);

    if (closedDate.isBefore(getActivationLocalDate())) {
        baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                .failWithCode("must.be.after.activation.date");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
    }

    if (isAccountLocked(closedDate)) {
        baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                .failWithCode("must.be.after.lockin.period");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
    }

    if (closedDate.isAfter(maturityDate())) {
        baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                .failWithCode("must.be.before.maturity.date");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
    }

    if (closedDate.isAfter(tenantsTodayDate)) {
        baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                .failWithCode("cannot.be.a.future.date");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
    }
    final List<SavingsAccountTransaction> savingsAccountTransactions = retreiveListOfTransactions();
    if (savingsAccountTransactions.size() > 0) {
        final SavingsAccountTransaction accountTransaction = savingsAccountTransactions
                .get(savingsAccountTransactions.size() - 1);
        if (accountTransaction.isAfter(closedDate)) {
            baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                    .failWithCode("must.be.after.last.transaction.date");
            if (!dataValidationErrors.isEmpty()) {
                throw new PlatformApiDataValidationException(dataValidationErrors);
            }
        }
    }

    validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_CLOSE_ACCOUNT, closedDate);
    this.status = SavingsAccountStatusType.PRE_MATURE_CLOSURE.getValue();

    final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
    final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
    this.accountTermAndPreClosure.updateOnAccountClosureStatus(onClosureType);

    /*
     * // withdraw deposit amount before closing the account final Money
     * transactionAmountMoney = Money.of(this.currency,
     * this.getAccountBalance()); final SavingsAccountTransaction withdraw =
     * SavingsAccountTransaction.withdrawal(this, office(), paymentDetail,
     * closedDate, transactionAmountMoney, new Date());
     * this.transactions.add(withdraw);
     */
    actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status));
    actualChanges.put(SavingsApiConstants.localeParamName, command.locale());
    actualChanges.put(SavingsApiConstants.dateFormatParamName, command.dateFormat());
    actualChanges.put(SavingsApiConstants.closedOnDateParamName, closedDate.toString(fmt));

    this.rejectedOnDate = null;
    this.rejectedBy = null;
    this.withdrawnOnDate = null;
    this.withdrawnBy = null;
    this.closedOnDate = closedDate.toDate();
    this.closedBy = currentUser;
    this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
}

From source file:com.gst.portfolio.savings.domain.FixedDepositAccount.java

License:Apache License

public void close(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
        final Map<String, Object> actualChanges) {

    final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
    final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
            .resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.closeAction);

    final SavingsAccountStatusType currentStatus = SavingsAccountStatusType.fromInt(this.status);
    if (!SavingsAccountStatusType.MATURED.hasStateOf(currentStatus)) {
        baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("not.in.matured.state");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }/*  w ww . j a v a 2s  .  c o  m*/
    }

    final Locale locale = command.extractLocale();
    final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
    final LocalDate closedDate = command
            .localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);

    if (closedDate.isBefore(getActivationLocalDate())) {
        baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                .failWithCode("must.be.after.activation.date");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
    }
    if (closedDate.isBefore(maturityDate())) {
        baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                .failWithCode("must.be.after.account.maturity.date");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
    }
    if (closedDate.isAfter(tenantsTodayDate)) {
        baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                .failWithCode("cannot.be.a.future.date");
        if (!dataValidationErrors.isEmpty()) {
            throw new PlatformApiDataValidationException(dataValidationErrors);
        }
    }

    final List<SavingsAccountTransaction> savingsAccountTransactions = retreiveListOfTransactions();
    if (savingsAccountTransactions.size() > 0) {
        final SavingsAccountTransaction accountTransaction = savingsAccountTransactions
                .get(savingsAccountTransactions.size() - 1);
        if (accountTransaction.isAfter(closedDate)) {
            baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
                    .failWithCode("must.be.after.last.transaction.date");
            if (!dataValidationErrors.isEmpty()) {
                throw new PlatformApiDataValidationException(dataValidationErrors);
            }
        }
    }

    validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_CLOSE_ACCOUNT, closedDate);
    this.status = SavingsAccountStatusType.CLOSED.getValue();

    final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
    final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
    this.accountTermAndPreClosure.updateOnAccountClosureStatus(onClosureType);

    // // withdraw deposit amount before closing the account
    // final Money transactionAmountMoney = Money.of(this.currency,
    // this.getAccountBalance());
    // final SavingsAccountTransaction withdraw =
    // SavingsAccountTransaction.withdrawal(this, office(), paymentDetail,
    // closedDate,
    // transactionAmountMoney, new Date());
    // this.transactions.add(withdraw);

    actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status));
    actualChanges.put(SavingsApiConstants.localeParamName, command.locale());
    actualChanges.put(SavingsApiConstants.dateFormatParamName, command.dateFormat());
    actualChanges.put(SavingsApiConstants.closedOnDateParamName, closedDate.toString(fmt));

    this.rejectedOnDate = null;
    this.rejectedBy = null;
    this.withdrawnOnDate = null;
    this.withdrawnBy = null;
    this.closedOnDate = closedDate.toDate();
    this.closedBy = currentUser;
    // this.summary.updateSummary(this.currency,
    // this.savingsAccountTransactionSummaryWrapper, this.transactions);
}

From source file:com.gst.portfolio.savings.domain.FixedDepositAccount.java

License:Apache License

public void postMaturityInterest(final boolean isSavingsInterestPostingAtCurrentPeriodEnd,
        final Integer financialYearBeginningMonth) {
    final LocalDate interestPostingUpToDate = maturityDate();
    final MathContext mc = MathContext.DECIMAL64;
    final boolean isInterestTransfer = false;
    final LocalDate postInterestOnDate = null;
    final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate,
            isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
            postInterestOnDate);/*from  w ww  .j  a  va  2  s . c o m*/

    Money interestPostedToDate = Money.zero(this.currency);

    boolean recalucateDailyBalanceDetails = false;

    for (final PostingPeriod interestPostingPeriod : postingPeriods) {

        LocalDate interestPostingTransactionDate = interestPostingPeriod.dateOfPostingTransaction();

        interestPostingTransactionDate = interestPostingTransactionDate.isAfter(interestPostingUpToDate)
                ? interestPostingUpToDate
                : interestPostingTransactionDate;

        final Money interestEarnedToBePostedForPeriod = interestPostingPeriod.getInterestEarned();

        interestPostedToDate = interestPostedToDate.plus(interestEarnedToBePostedForPeriod);

        final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(
                interestPostingTransactionDate);
        if (postingTransaction == null) {
            final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(
                    this, office(), interestPostingTransactionDate, interestEarnedToBePostedForPeriod,
                    interestPostingPeriod.isUserPosting());
            this.transactions.add(newPostingTransaction);
            recalucateDailyBalanceDetails = true;
        } else {
            final boolean correctionRequired = postingTransaction
                    .hasNotAmount(interestEarnedToBePostedForPeriod);
            if (correctionRequired) {
                postingTransaction.reverse();
                final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction
                        .interestPosting(this, office(), interestPostingTransactionDate,
                                interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
                this.transactions.add(newPostingTransaction);
                recalucateDailyBalanceDetails = true;
            }
        }
    }
    recalucateDailyBalanceDetails = applyWithholdTaxForDepositAccounts(interestPostingUpToDate,
            recalucateDailyBalanceDetails);
    if (recalucateDailyBalanceDetails) {
        // update existing transactions so derived balance fields are
        // correct.
        recalculateDailyBalances(Money.zero(this.currency), interestPostingUpToDate);
    }

    this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
}

From source file:com.gst.portfolio.savings.domain.interest.EndOfDayBalance.java

License:Apache License

/**
 * @param compoundingPeriodInterval//from  w  w w.ja  va 2  s  . c om
 * @param upToInterestCalculationDate
 *            : For calculating maturity details in advance
 *            upToInterestCalculationDate will be maturity date else it will
 *            be DateUtils.getLocalDateOfTenant().
 * @return
 */
public EndOfDayBalance upTo(final LocalDateInterval compoundingPeriodInterval,
        final LocalDate upToInterestCalculationDate) {

    Money startingBalance = this.openingBalance;
    LocalDate balanceStartDate = this.date;

    LocalDate oldBalanceEndDate = this.date.plusDays(this.numberOfDays - 1);

    int daysOfBalance = this.numberOfDays;

    if (this.date.isBefore(compoundingPeriodInterval.startDate())) {
        balanceStartDate = compoundingPeriodInterval.startDate();
        startingBalance = this.endOfDayBalance;
        final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate,
                oldBalanceEndDate);
        daysOfBalance = balancePeriodInterval.daysInPeriodInclusiveOfEndDate();
    }

    LocalDate balanceEndDate = balanceStartDate.plusDays(daysOfBalance - 1);
    if (balanceEndDate.isAfter(compoundingPeriodInterval.endDate())) {
        balanceEndDate = compoundingPeriodInterval.endDate();
        final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate,
                balanceEndDate);
        daysOfBalance = balancePeriodInterval.daysInPeriodInclusiveOfEndDate();
    }
    if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
        balanceEndDate = upToInterestCalculationDate;
        final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate,
                balanceEndDate);
        daysOfBalance = balancePeriodInterval.daysInPeriodInclusiveOfEndDate();
    }

    return new EndOfDayBalance(balanceStartDate, startingBalance, this.endOfDayBalance, daysOfBalance);
}

From source file:com.gst.portfolio.savings.domain.interest.PostingPeriod.java

License:Apache License

public static PostingPeriod createFrom(final LocalDateInterval periodInterval,
        final Money periodStartingBalance, final List<SavingsAccountTransaction> orderedListOfTransactions,
        final MonetaryCurrency currency,
        final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
        final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction,
        final long daysInYear, final LocalDate upToInterestCalculationDate,
        Collection<Long> interestPostTransactions, boolean isInterestTransfer,
        final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,
        final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation,
        boolean isUserPosting) {

    final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<>();
    boolean interestTransfered = false;
    Money openingDayBalance = periodStartingBalance;
    Money closeOfDayBalance = openingDayBalance;
    for (final SavingsAccountTransaction transaction : orderedListOfTransactions) {

        if (transaction.fallsWithin(periodInterval)) {
            // the balance of the transaction falls entirely within this
            // period so no need to do any cropping/bounding
            final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalance(openingDayBalance);
            accountEndOfDayBalances.add(endOfDayBalance);

            openingDayBalance = endOfDayBalance.closingBalance();

        } else if (transaction.spansAnyPortionOf(periodInterval)) {
            final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance,
                    periodInterval);//  w w  w  .  j  a v a2 s.c o m
            accountEndOfDayBalances.add(endOfDayBalance);

            closeOfDayBalance = endOfDayBalance.closingBalance();
            openingDayBalance = closeOfDayBalance;
        }

        // this check is to make sure to add interest if withdrawal is
        // happened for already
        if (transaction.occursOn(periodInterval.endDate().plusDays(1))) {
            if (transaction.getId() == null) {
                interestTransfered = isInterestTransfer;
            } else if (interestPostTransactions.contains(transaction.getId())) {
                interestTransfered = true;
            }
        }

    }

    if (accountEndOfDayBalances.isEmpty()) {
        LocalDate balanceStartDate = periodInterval.startDate();
        LocalDate balanceEndDate = periodInterval.endDate();
        Integer numberOfDaysOfBalance = periodInterval.daysInPeriodInclusiveOfEndDate();

        if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
            balanceEndDate = upToInterestCalculationDate;
            final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
            numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
        }

        final EndOfDayBalance endOfDayBalance = EndOfDayBalance.from(balanceStartDate, openingDayBalance,
                closeOfDayBalance, numberOfDaysOfBalance);

        accountEndOfDayBalances.add(endOfDayBalance);

        closeOfDayBalance = endOfDayBalance.closingBalance();
        openingDayBalance = closeOfDayBalance;
    }

    final List<CompoundingPeriod> compoundingPeriods = compoundingPeriodsInPostingPeriod(periodInterval,
            interestCompoundingPeriodType, accountEndOfDayBalances, upToInterestCalculationDate);

    return new PostingPeriod(periodInterval, currency, periodStartingBalance, openingDayBalance,
            interestCompoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYear,
            compoundingPeriods, interestTransfered, minBalanceForInterestCalculation,
            isSavingsInterestPostingAtCurrentPeriodEnd, overdraftInterestRateAsFraction,
            minOverdraftForInterestCalculation, isUserPosting);
}