/** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mifosplatform.portfolio.loanaccount.domain; import java.util.List; import java.util.Set; import org.joda.time.LocalDate; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.Money; import org.springframework.stereotype.Component; /** * A wrapper for dealing with side-effect free functionality related to a loans * transactions and repayment schedule. */ @Component public final class LoanSummaryWrapper { public Money calculateTotalPrincipalRepaid(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getPrincipalCompleted(currency)); } return total; } public Money calculateTotalPrincipalWrittenOff(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getPrincipalWrittenOff(currency)); } return total; } public Money calculateTotalPrincipalOverdueOn(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency, final LocalDate overdueAsOf) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { if (installment.isOverdueOn(overdueAsOf)) { total = total.plus(installment.getPrincipalOutstanding(currency)); } } return total; } public Money calculateTotalInterestCharged(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getInterestCharged(currency)); } return total; } public Money calculateTotalInterestRepaid(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getInterestPaid(currency)); } return total; } public Money calculateTotalInterestWaived(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getInterestWaived(currency)); } return total; } public Money calculateTotalInterestWrittenOff(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getInterestWrittenOff(currency)); } return total; } public Money calculateTotalInterestOverdueOn(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency, final LocalDate overdueAsOf) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { if (installment.isOverdueOn(overdueAsOf)) { total = total.plus(installment.getInterestOutstanding(currency)); } } return total; } public Money calculateTotalFeeChargesCharged(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getFeeChargesCharged(currency)); } return total; } public Money calculateTotalFeeChargesRepaid(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getFeeChargesPaid(currency)); } return total; } public Money calculateTotalFeeChargesWaived(Set<LoanCharge> charges, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanCharge charge : charges) { if(charge.isActive() && !charge.isPenaltyCharge()){ total = total.plus(charge.getAmountWaived(currency)); } } return total; } public Money calculateTotalFeeChargesWrittenOff(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getFeeChargesWrittenOff(currency)); } return total; } public Money calculateTotalFeeChargesOverdueOn(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency, final LocalDate overdueAsOf) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { if (installment.isOverdueOn(overdueAsOf)) { total = total.plus(installment.getFeeChargesOutstanding(currency)); } } return total; } public Money calculateTotalPenaltyChargesCharged(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getPenaltyChargesCharged(currency)); } return total; } public Money calculateTotalPenaltyChargesRepaid(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getPenaltyChargesPaid(currency)); } return total; } public Money calculateTotalPenaltyChargesWaived(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getPenaltyChargesWaived(currency)); } return total; } public Money calculateTotalPenaltyChargesWrittenOff(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { total = total.plus(installment.getPenaltyChargesWrittenOff(currency)); } return total; } public Money calculateTotalPenaltyChargesOverdueOn(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency, final LocalDate overdueAsOf) { Money total = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { if (installment.isOverdueOn(overdueAsOf)) { total = total.plus(installment.getPenaltyChargesOutstanding(currency)); } } return total; } public Money calculateTotalOverdueOn(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency, final LocalDate overdueAsOf) { final Money principalOverdue = calculateTotalPrincipalOverdueOn(repaymentScheduleInstallments, currency, overdueAsOf); final Money interestOverdue = calculateTotalInterestOverdueOn(repaymentScheduleInstallments, currency, overdueAsOf); final Money feeChargesOverdue = calculateTotalFeeChargesOverdueOn(repaymentScheduleInstallments, currency, overdueAsOf); final Money penaltyChargesOverdue = calculateTotalPenaltyChargesOverdueOn(repaymentScheduleInstallments, currency, overdueAsOf); return principalOverdue.plus(interestOverdue).plus(feeChargesOverdue).plus(penaltyChargesOverdue); } public LocalDate determineOverdueSinceDateFrom(final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final MonetaryCurrency currency, final LocalDate from) { LocalDate overdueSince = null; final Money totalOverdue = calculateTotalOverdueOn(repaymentScheduleInstallments, currency, from); if (totalOverdue.isGreaterThanZero()) { for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { if (installment.isOverdueOn(from)) { if (overdueSince == null || overdueSince.isAfter(installment.getDueDate())) { overdueSince = installment.getDueDate(); } } } } return overdueSince; } public Money calculateTotalChargesRepaidAtDisbursement(Set<LoanCharge> charges, MonetaryCurrency currency) { Money total = Money.zero(currency); if(charges == null) return total ; for (final LoanCharge loanCharge : charges) { if (!loanCharge.isPenaltyCharge() && loanCharge.getAmountPaid(currency).isGreaterThanZero()) { total = total.plus(loanCharge.getAmountPaid(currency)); } } return total; } }