From 2d7b1d9cf4c4ce54aa1ceb99c40bcd27e896394d Mon Sep 17 00:00:00 2001 From: Madhukar Date: Tue, 24 Jun 2014 18:27:42 +0530 Subject: [PATCH] MIFOSX-1235,MIFOSX-1365,MIFSOX-1204 --- api-docs/apiLive.htm | 55 ++++++++++++++++++- .../ClientSavingsIntegrationTest.java | 30 ++++++++++ .../GroupSavingsIntegrationTest.java | 30 ++++++++++ .../common/charges/ChargesHelper.java | 10 ++++ .../glaccount/domain/GLAccountType.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 2 +- .../savings/domain/SavingsAccount.java | 2 +- .../savings/domain/SavingsAccountCharge.java | 40 +++++++++++--- 8 files changed, 157 insertions(+), 14 deletions(-) diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 428629fa5..ca7b712d0 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -14262,8 +14262,29 @@ Request Body: { "resourceId": 7 } - - + + +POST charges +Content-Type: application/json +Request Body: +{ + "chargeAppliesTo": 2, + "name": "Weekly Fee", + "currencyCode": "USD", + "chargeTimeType": 11, + "chargeCalculationType": 1, + "feeInterval": "1", + "amount": "10", + "active": true, + "locale": "en" +} + + +{ + "resourceId": 8 +} + +   @@ -24295,6 +24316,36 @@ Request Body: "resourceIdentifier": "extra_client_details" } + +POST https://DomainName/api/v1/datatables + +Content-Type: application/json +Request Body: +{ + "datatableName": "client_address", + "apptableName": "m_client", + "multiRow":"true", + "columns": [ + { + "name": "Address1", + "type": "String", + "length": 100, + "mandatory": true + }, + { + "name": "Address2", + "length": 100, + "type": "String" + } + ] +} + + +{ + "resourceIdentifier": "client_address" +} + + diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientSavingsIntegrationTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientSavingsIntegrationTest.java index 8878e607e..02827481c 100755 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientSavingsIntegrationTest.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientSavingsIntegrationTest.java @@ -9,6 +9,7 @@ import java.util.Calendar; import java.util.HashMap; import java.util.List; +import org.joda.time.LocalDate; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -399,6 +400,35 @@ public class ClientSavingsIntegrationTest { BigDecimal totalWaiveAmount = BigDecimal.valueOf(Double.valueOf((Float) savingsChargeForWaive.get("amount"))); totalWaiveAmount = totalWaiveAmount.add(totalWaiveAmount); assertEquals(totalWaiveAmount.floatValue(), waiveCharge.get("amountWaived")); + + final Integer weeklyFeeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec, ChargesHelper.getSavingsWeeklyFeeJSON()); + Assert.assertNotNull(weeklyFeeId); + + this.savingsAccountHelper.addChargesForSavings(savingsId, weeklyFeeId); + charges = this.savingsAccountHelper.getSavingsCharges(savingsId); + Assert.assertEquals(3, charges.size()); + + savingsChargeForPay = charges.get(2); + cal = Calendar.getInstance(); + dates = (List) savingsChargeForPay.get("dueDate"); + cal.set(Calendar.YEAR, (Integer) dates.get(0)); + cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1); + cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2)); + + // Depositing huge amount as scheduler job deducts the fee amount + Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "100000", + SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID); + Assert.assertNotNull(depositTransactionId); + + this.savingsAccountHelper.payCharge((Integer) savingsChargeForPay.get("id"), savingsId, + ((Float) savingsChargeForPay.get("amount")).toString(), sdf.format(cal.getTime())); + paidCharge = this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) savingsChargeForPay.get("id")); + assertEquals(savingsChargeForPay.get("amount"), paidCharge.get("amountPaid")); + List nextDueDates = (List) paidCharge.get("dueDate"); + LocalDate nextDueDate = new LocalDate((Integer) nextDueDates.get(0), (Integer) nextDueDates.get(1), (Integer) nextDueDates.get(2)); + LocalDate expectedNextDueDate = new LocalDate((Integer) dates.get(0), (Integer) dates.get(1), (Integer) dates.get(2)) + .plusWeeks((Integer) paidCharge.get("feeInterval")); + assertEquals(expectedNextDueDate, nextDueDate); } private Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/GroupSavingsIntegrationTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/GroupSavingsIntegrationTest.java index 2f7fe66f2..af1db0bb5 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/GroupSavingsIntegrationTest.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/GroupSavingsIntegrationTest.java @@ -9,6 +9,7 @@ import java.util.Calendar; import java.util.HashMap; import java.util.List; +import org.joda.time.LocalDate; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -438,6 +439,35 @@ public class GroupSavingsIntegrationTest { BigDecimal totalWaiveAmount = BigDecimal.valueOf(Double.valueOf((Float) savingsChargeForWaive.get("amount"))); totalWaiveAmount = totalWaiveAmount.add(totalWaiveAmount); assertEquals(totalWaiveAmount.floatValue(), waiveCharge.get("amountWaived")); + + final Integer weeklyFeeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec, ChargesHelper.getSavingsWeeklyFeeJSON()); + Assert.assertNotNull(weeklyFeeId); + + this.savingsAccountHelper.addChargesForSavings(savingsId, weeklyFeeId); + charges = this.savingsAccountHelper.getSavingsCharges(savingsId); + Assert.assertEquals(3, charges.size()); + + savingsChargeForPay = charges.get(2); + cal = Calendar.getInstance(); + dates = (List) savingsChargeForPay.get("dueDate"); + cal.set(Calendar.YEAR, (Integer) dates.get(0)); + cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1); + cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2)); + + // Depositing huge amount as scheduler job deducts the fee amount + Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "100000", + SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID); + Assert.assertNotNull(depositTransactionId); + + this.savingsAccountHelper.payCharge((Integer) savingsChargeForPay.get("id"), savingsId, + ((Float) savingsChargeForPay.get("amount")).toString(), sdf.format(cal.getTime())); + paidCharge = this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) savingsChargeForPay.get("id")); + assertEquals(savingsChargeForPay.get("amount"), paidCharge.get("amountPaid")); + List nextDueDates = (List) paidCharge.get("dueDate"); + LocalDate nextDueDate = new LocalDate((Integer) nextDueDates.get(0), (Integer) nextDueDates.get(1), (Integer) nextDueDates.get(2)); + LocalDate expectedNextDueDate = new LocalDate((Integer) dates.get(0), (Integer) dates.get(1), (Integer) dates.get(2)) + .plusWeeks((Integer) paidCharge.get("feeInterval")); + assertEquals(expectedNextDueDate, nextDueDate); } public static Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/charges/ChargesHelper.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/charges/ChargesHelper.java index 36be16947..912e4f47d 100755 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/charges/ChargesHelper.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/charges/ChargesHelper.java @@ -28,6 +28,7 @@ public class ChargesHelper { private static final Integer CHARGE_INSTALLMENT_FEE = 8; private static final Integer CHARGE_OVERDUE_INSTALLMENT_FEE = 9; private static final Integer CHARGE_OVERDRAFT_FEE = 10; + private static final Integer WEEKLY_FEE = 11; public static final Integer CHARGE_CALCULATION_TYPE_FLAT = 1; public static final Integer CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT = 2; @@ -92,6 +93,15 @@ public class ChargesHelper { System.out.println(chargesCreateJson); return chargesCreateJson; } + + public static String getSavingsWeeklyFeeJSON() { + final HashMap map = populateDefaultsForSavings(); + map.put("chargeTimeType", WEEKLY_FEE); + map.put("feeInterval", 1); + String chargesCreateJson = new Gson().toJson(map); + System.out.println(chargesCreateJson); + return chargesCreateJson; + } public static String getSavingsOverdraftFeeJSON() { final HashMap map = populateDefaultsForSavings(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java index 62e13fc6c..840dc41a5 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/domain/GLAccountType.java @@ -10,7 +10,7 @@ import java.util.Map; public enum GLAccountType { ASSET(1, "accountType.asset"), LIABILITY(2, "accountType.liability"), EQUITY(3, "accountType.equity"), INCOME(4, "accountType.income"), EXPENSE( - 5, "accountType.expense"), ; + 5, "accountType.expense"); private final Integer value; private final String code; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 535bca1b1..f0201fffb 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -1662,7 +1662,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf // Update client loan counter if loan product includeInBorrowerCycle // is true if (loanToUpdate.loanProduct().isIncludeInBorrowerCycle()) { - Integer currentLoanCounter = loanToUpdate.getCurrentLoanCounter(); + Integer currentLoanCounter = loanToUpdate.getCurrentLoanCounter() == null ? 1 : loanToUpdate.getCurrentLoanCounter(); if (newLoanCounter > currentLoanCounter) { newLoanCounter = currentLoanCounter; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java index 00d4eb7d3..493c30ec3 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java @@ -1872,7 +1872,7 @@ public class SavingsAccount extends AbstractPersistable { } - if (savingsAccountCharge.isAnnualFee() || savingsAccountCharge.isMonthlyFee()) { + if (savingsAccountCharge.isAnnualFee() || savingsAccountCharge.isMonthlyFee() || savingsAccountCharge.isWeeklyFee()) { // update due date if (isActive()) { savingsAccountCharge.updateToNextDueDateFrom(getActivationLocalDate()); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountCharge.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountCharge.java index a279956ae..021a7e476 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountCharge.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountCharge.java @@ -155,14 +155,6 @@ public class SavingsAccountCharge extends AbstractPersistable { } - if (isWeeklyFee()) { - if (dueDate == null) { - final String defaultUserMessage = "Savings Account charge is missing due date."; - throw new SavingsAccountChargeWithoutMandatoryFieldException("savingsaccount.charge", dueAsOfDateParamName, - defaultUserMessage, chargeDefinition.getId(), chargeDefinition.getName()); - } - } - if (isAnnualFee() || isMonthlyFee()) { feeOnMonthDay = (feeOnMonthDay == null) ? chargeDefinition.getFeeOnMonthDay() : feeOnMonthDay; if (feeOnMonthDay == null) { @@ -174,6 +166,17 @@ public class SavingsAccountCharge extends AbstractPersistable { this.feeOnMonth = feeOnMonthDay.getMonthOfYear(); this.feeOnDay = feeOnMonthDay.getDayOfMonth(); + } else if (isWeeklyFee()) { + if (dueDate == null) { + final String defaultUserMessage = "Savings Account charge is missing due date."; + throw new SavingsAccountChargeWithoutMandatoryFieldException("savingsaccount.charge", dueAsOfDateParamName, + defaultUserMessage, chargeDefinition.getId(), chargeDefinition.getName()); + } + /** + * For Weekly fee feeOnDay is ISO standard day of the week. + * Monday=1, Tuesday=2 + */ + this.feeOnDay = dueDate.getDayOfWeek(); } else { this.feeOnDay = null; this.feeOnMonth = null; @@ -355,6 +358,9 @@ public class SavingsAccountCharge extends AbstractPersistable { final BigDecimal transactionAmount = BigDecimal.ZERO; if (dueDate != null) { this.dueDate = dueDate.toDate(); + if (isWeeklyFee()) { + this.feeOnDay = dueDate.getDayOfWeek(); + } } if (feeOnMonthDay != null) { @@ -410,6 +416,9 @@ public class SavingsAccountCharge extends AbstractPersistable { final LocalDate newValue = command.localDateValueOfParameterNamed(dueAsOfDateParamName); this.dueDate = newValue.toDate(); + if (this.isWeeklyFee()) { + this.feeOnDay = newValue.getDayOfWeek(); + } } if (command.hasParameter(feeOnMonthDayParamName)) { @@ -696,6 +705,11 @@ public class SavingsAccountCharge extends AbstractPersistable { while (startingDate.isAfter(nextDueLocalDate)) { nextDueLocalDate = calculateNextDueDate(nextDueLocalDate); } + } else if (isWeeklyFee()) { + nextDueLocalDate = getDueLocalDate(); + while (startingDate.isAfter(nextDueLocalDate)) { + nextDueLocalDate = calculateNextDueDate(nextDueLocalDate); + } } else { nextDueLocalDate = calculateNextDueDate(startingDate); } @@ -714,7 +728,8 @@ public class SavingsAccountCharge extends AbstractPersistable { nextDueLocalDate = date.plusMonths(this.feeInterval); nextDueLocalDate = setDayOfMonth(nextDueLocalDate); } else if (isWeeklyFee()) { - nextDueLocalDate = date.plusDays(7 * this.feeInterval); + nextDueLocalDate = date.plusWeeks(this.feeInterval); + nextDueLocalDate = setDayOfWeek(nextDueLocalDate); } return nextDueLocalDate; } @@ -726,6 +741,13 @@ public class SavingsAccountCharge extends AbstractPersistable { return nextDueLocalDate; } + private LocalDate setDayOfWeek(LocalDate nextDueLocalDate) { + if (this.feeOnDay != nextDueLocalDate.getDayOfWeek()) { + nextDueLocalDate = nextDueLocalDate.withDayOfWeek(this.feeOnDay); + } + return nextDueLocalDate; + } + public void updateNextDueDateForRecurringFees() { if (isAnnualFee() || isMonthlyFee() || isWeeklyFee()) { LocalDate nextDueLocalDate = new LocalDate(dueDate);