diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java index 1dcc7971e..3474c6a3c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java @@ -5,6 +5,7 @@ */ package org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -142,15 +143,18 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen installmentIndex++; } + Set loanFees = extractFeeCharges(charges); + Set loanPenalties = extractPenaltyCharges(charges); + if (loanTransaction.isNotWaiver()) { Money feeCharges = loanTransaction.getFeeChargesPortion(currency); if (feeCharges.isGreaterThanZero()) { - updateFeeChargesPaidAmountBy(loanTransaction, feeCharges, charges); + updateFeeChargesPaidAmountBy(loanTransaction, feeCharges, loanFees); } Money penaltyCharges = loanTransaction.getPenaltyChargesPortion(currency); if (penaltyCharges.isGreaterThanZero()) { - updatePenaltyChargesPaidAmountBy(loanTransaction, penaltyCharges, charges); + updatePenaltyChargesPaidAmountBy(loanTransaction, penaltyCharges, loanPenalties); } } @@ -159,6 +163,26 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen } } + private Set extractFeeCharges(Set loanCharges) { + final Set feeCharges = new HashSet(); + for (LoanCharge loanCharge : loanCharges) { + if (loanCharge.isFeeCharge()) { + feeCharges.add(loanCharge); + } + } + return feeCharges; + } + + private Set extractPenaltyCharges(Set loanCharges) { + final Set penaltyCharges = new HashSet(); + for (LoanCharge loanCharge : loanCharges) { + if (loanCharge.isPenaltyCharge()) { + penaltyCharges.add(loanCharge); + } + } + return penaltyCharges; + } + private void updateFeeChargesPaidAmountBy(final LoanTransaction loanTransaction, final Money feeCharges, final Set charges) { Money amountRemaining = feeCharges; @@ -185,7 +209,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen for (LoanCharge loanCharge : charges) { if (!loanCharge.isDueAtDisbursement()) { - if (loanCharge.isPenaltyCharge() && amountRemaining.isGreaterThanZero()) { + if (loanCharge.isPenaltyCharge() && loanCharge.isNotFullyPaid() && amountRemaining.isGreaterThanZero()) { final LoanCharge unpaidCharge = findEarliestUnpaidChargeFromUnOrderedSet(charges); Money amountPaidTowardsCharge = unpaidCharge.updatePaidAmountBy(amountRemaining); if (!amountPaidTowardsCharge.isZero()) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/api/LoanProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/api/LoanProductsApiResource.java index 971624337..fcdf05d18 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/api/LoanProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/api/LoanProductsApiResource.java @@ -171,7 +171,7 @@ public class LoanProductsApiResource { paymentChannelToFundSourceMappings = accountMappingReadPlatformService .fetchPaymentTypeToFundSourceMappingsForLoanProduct(productId); feeToGLAccountMappings = accountMappingReadPlatformService.fetchFeeToIncomeAccountMappingsForLoanProduct(productId); - penaltyToGLAccountMappings = accountMappingReadPlatformService.fetchFeeToIncomeAccountMappingsForLoanProduct(productId); + penaltyToGLAccountMappings = accountMappingReadPlatformService.fetchPenaltyToIncomeAccountMappingsForLoanProduct(productId); loanProduct = LoanProductData.withAccountingDetails(loanProduct, accountingMappings, paymentChannelToFundSourceMappings, feeToGLAccountMappings, penaltyToGLAccountMappings); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java index c1e1b18df..b62914bb2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java @@ -516,14 +516,16 @@ public final class LoanProductDataValidator { int i = 0; do { final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject(); - final Long paymentTypeId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).getAsLong(); - final Long paymentSpecificFundAccountId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue()) - .getAsLong(); + final Long paymentTypeId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue(), + jsonObject); + final Long paymentSpecificFundAccountId = fromApiJsonHelper.extractLongNamed( + LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), jsonObject); + baseDataValidator .reset() .parameter( LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]." - + LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.toString()).value(paymentTypeId).notNull() + + LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_TYPE.getValue()).value(paymentTypeId).notNull() .integerGreaterThanZero(); baseDataValidator .reset() @@ -558,10 +560,12 @@ public final class LoanProductDataValidator { int i = 0; do { final JsonObject jsonObject = chargeToIncomeAccountMappingArray.get(i).getAsJsonObject(); - final Long chargeId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.CHARGE_ID.getValue()).getAsLong(); - final Long incomeAccountId = jsonObject.get(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_ACCOUNT_ID.getValue()).getAsLong(); + final Long chargeId = fromApiJsonHelper.extractLongNamed(LOAN_PRODUCT_ACCOUNTING_PARAMS.CHARGE_ID.getValue(), + jsonObject); + final Long incomeAccountId = fromApiJsonHelper.extractLongNamed( + LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_ACCOUNT_ID.getValue(), jsonObject); baseDataValidator.reset() - .parameter(parameterName + "[" + i + "]." + LOAN_PRODUCT_ACCOUNTING_PARAMS.CHARGE_ID.toString()) + .parameter(parameterName + "[" + i + "]." + LOAN_PRODUCT_ACCOUNTING_PARAMS.CHARGE_ID.getValue()) .value(chargeId).notNull().integerGreaterThanZero(); baseDataValidator.reset() .parameter(parameterName + "[" + i + "]." + LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_ACCOUNT_ID.getValue())