From 602f0bdb074ec2b3d2dc1a227f702582630b6a66 Mon Sep 17 00:00:00 2001 From: goutham-M Date: Mon, 16 Jun 2014 19:02:07 +0530 Subject: [PATCH] Weekly saving charges --- .../portfolio/charge/domain/Charge.java | 4 + .../charge/domain/ChargeTimeType.java | 16 +++- ...initionCommandFromApiJsonDeserializer.java | 6 ++ ...ChargeDropdownReadPlatformServiceImpl.java | 3 +- .../charge/service/ChargeEnumerations.java | 4 + .../ChargeReadPlatformServiceImpl.java | 2 +- .../savings/domain/SavingsAccountCharge.java | 96 +++++++++++-------- ...sAccountChargeReadPlatformServiceImpl.java | 2 +- 8 files changed, 88 insertions(+), 45 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/Charge.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/Charge.java index b0f30250a..8d5020209 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/Charge.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/Charge.java @@ -467,6 +467,10 @@ public class Charge extends AbstractPersistable { public Integer getChargePaymentMode() { return this.chargePaymentMode; } + + public Integer getFeeInterval(){ + return this.feeInterval; + } public boolean isMonthlyFee() { return ChargeTimeType.fromInt(this.chargeTime).isMonthlyFee(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeTimeType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeTimeType.java index 166decf5c..d0fefd749 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeTimeType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeTimeType.java @@ -20,7 +20,8 @@ public enum ChargeTimeType { INSTALMENT_FEE(8, "chargeTimeType.instalmentFee"), // only for loan charges OVERDUE_INSTALLMENT(9, "chargeTimeType.overdueInstallment"), // only for // loan charges - OVERDRAFT_FEE(10, "chargeTimeType.overdraftFee");// only for savings + OVERDRAFT_FEE(10, "chargeTimeType.overdraftFee"),// only for savings + WEEKLY_FEE(11, "chargeTimeType.weeklyFee"); // only for savings private final Integer value; private final String code; @@ -51,7 +52,7 @@ public enum ChargeTimeType { public static Object[] validSavingsValues() { return new Integer[] { ChargeTimeType.SPECIFIED_DUE_DATE.getValue(), ChargeTimeType.SAVINGS_ACTIVATION.getValue(), ChargeTimeType.SAVINGS_CLOSURE.getValue(), ChargeTimeType.WITHDRAWAL_FEE.getValue(), ChargeTimeType.ANNUAL_FEE.getValue(), - ChargeTimeType.MONTHLY_FEE.getValue(), ChargeTimeType.OVERDRAFT_FEE.getValue() }; + ChargeTimeType.MONTHLY_FEE.getValue(), ChargeTimeType.OVERDRAFT_FEE.getValue(), ChargeTimeType.WEEKLY_FEE.getValue() }; } public static ChargeTimeType fromInt(final Integer chargeTime) { @@ -88,6 +89,9 @@ public enum ChargeTimeType { case 10: chargeTimeType = OVERDRAFT_FEE; break; + case 11: + chargeTimeType = WEEKLY_FEE; + break; default: chargeTimeType = INVALID; break; @@ -123,7 +127,11 @@ public enum ChargeTimeType { public boolean isMonthlyFee() { return this.value.equals(ChargeTimeType.MONTHLY_FEE.getValue()); } - + + public boolean isWeeklyFee() { + return this.value.equals(ChargeTimeType.WEEKLY_FEE.getValue()); + } + public boolean isInstalmentFee() { return this.value.equals(ChargeTimeType.INSTALMENT_FEE.getValue()); } @@ -138,7 +146,7 @@ public enum ChargeTimeType { public boolean isAllowedSavingsChargeTime() { return isOnSpecifiedDueDate() || isSavingsActivation() || isSavingsClosure() || isWithdrawalFee() || isAnnualFee() - || isMonthlyFee() || isOverdraftFee(); + || isMonthlyFee() || isWeeklyFee() || isOverdraftFee(); } public boolean isOverdraftFee() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java index 663af9893..85555d4fd 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/serialization/ChargeDefinitionCommandFromApiJsonDeserializer.java @@ -113,6 +113,12 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer { } final ChargeTimeType ctt = ChargeTimeType.fromInt(chargeTimeType); + + if (ctt.isWeeklyFee()) { + final String monthDay = this.fromApiJsonHelper.extractStringNamed("feeOnMonthDay", element); + baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).mustBeBlankWhenParameterProvidedIs("chargeTimeType", chargeTimeType); + } + if (ctt.isMonthlyFee()) { final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed("feeOnMonthDay", element); baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).notNull(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java index 3ed1f06e7..91e291ef1 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java @@ -84,6 +84,7 @@ public class ChargeDropdownReadPlatformServiceImpl implements ChargeDropdownRead return Arrays.asList(chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE), chargeTimeType(ChargeTimeType.SAVINGS_ACTIVATION), // chargeTimeType(ChargeTimeType.SAVINGS_CLOSURE), chargeTimeType(ChargeTimeType.WITHDRAWAL_FEE), chargeTimeType(ChargeTimeType.ANNUAL_FEE), - chargeTimeType(ChargeTimeType.MONTHLY_FEE), chargeTimeType(ChargeTimeType.OVERDRAFT_FEE)); + chargeTimeType(ChargeTimeType.MONTHLY_FEE), chargeTimeType(ChargeTimeType.WEEKLY_FEE), + chargeTimeType(ChargeTimeType.OVERDRAFT_FEE)); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeEnumerations.java index 821765285..506c35517 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeEnumerations.java @@ -48,6 +48,10 @@ public class ChargeEnumerations { optionData = new EnumOptionData(ChargeTimeType.MONTHLY_FEE.getValue().longValue(), ChargeTimeType.MONTHLY_FEE.getCode(), "Monthly Fee"); break; + case WEEKLY_FEE: + optionData = new EnumOptionData(ChargeTimeType.WEEKLY_FEE.getValue().longValue(), ChargeTimeType.WEEKLY_FEE.getCode(), + "Weekly Fee"); + break; case INSTALMENT_FEE: optionData = new EnumOptionData(ChargeTimeType.INSTALMENT_FEE.getValue().longValue(), ChargeTimeType.INSTALMENT_FEE.getCode(), "Instalment Fee"); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformServiceImpl.java index c43c762e1..ea4bd9a55 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformServiceImpl.java @@ -241,7 +241,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService MonthDay feeOnMonthDay = null; final Integer feeOnMonth = JdbcSupport.getInteger(rs, "feeOnMonth"); final Integer feeOnDay = JdbcSupport.getInteger(rs, "feeOnDay"); - if (feeOnDay != null) { + if (feeOnDay != null && feeOnMonth != null) { feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay); } final BigDecimal minCap = rs.getBigDecimal("minCap"); 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 b3b0f2650..cb17049c0 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 @@ -108,13 +108,18 @@ public class SavingsAccountCharge extends AbstractPersistable { public static SavingsAccountCharge createNewFromJson(final SavingsAccount savingsAccount, final Charge chargeDefinition, final JsonCommand command) { - final BigDecimal amount = command.bigDecimalValueOfParameterNamed(amountParamName); + BigDecimal amount = command.bigDecimalValueOfParameterNamed(amountParamName); final LocalDate dueDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName); - final MonthDay feeOnMonthDay = command.extractMonthDayNamed(feeOnMonthDayParamName); - final Integer feeInterval = command.integerValueOfParameterNamed(feeIntervalParamName); + MonthDay feeOnMonthDay = command.extractMonthDayNamed(feeOnMonthDayParamName); + Integer feeInterval = command.integerValueOfParameterNamed(feeIntervalParamName); final ChargeTimeType chargeTime = null; final ChargeCalculationType chargeCalculation = null; final boolean status = true; + + // If these values is not sent as parameter, then derive from Charge definition + amount = (amount == null)? chargeDefinition.getAmount():amount; + feeOnMonthDay = (feeOnMonthDay == null)? chargeDefinition.getFeeOnMonthDay() : feeOnMonthDay; + feeInterval = ( feeInterval == null )? chargeDefinition.getFeeInterval():feeInterval; return new SavingsAccountCharge(savingsAccount, chargeDefinition, amount, chargeTime, chargeCalculation, dueDate, status, feeOnMonthDay, feeInterval); @@ -148,6 +153,14 @@ 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; @@ -160,11 +173,10 @@ public class SavingsAccountCharge extends AbstractPersistable { this.feeOnMonth = feeOnMonthDay.getMonthOfYear(); this.feeOnDay = feeOnMonthDay.getDayOfMonth(); - if (isMonthlyFee()) { - this.feeInterval = (feeInterval == null) ? chargeDefinition.feeInterval() : feeInterval; - } - - } else { + } else if(isMonthlyFee() || isWeeklyFee() ){ + this.feeInterval = (feeInterval == null) ? chargeDefinition.feeInterval() : feeInterval; + } + else { this.feeOnDay = null; this.feeOnMonth = null; this.feeInterval = null; @@ -195,7 +207,7 @@ public class SavingsAccountCharge extends AbstractPersistable { } public void recalculateAmountOutstanding() { - if (isMonthlyFee() || isAnnualFee()) { + if (isMonthlyFee() || isAnnualFee() || isWeeklyFee()) { // FIXME: AA: If charge is percentage of x amount then need to // update amount outstanding accordingly. // Right now annual and monthly charges supports charge calculation @@ -628,6 +640,10 @@ public class SavingsAccountCharge extends AbstractPersistable { return ChargeTimeType.fromInt(this.chargeTime).isMonthlyFee(); } + public boolean isWeeklyFee() { + return ChargeTimeType.fromInt(this.chargeTime).isWeeklyFee(); + } + public boolean hasCurrencyCodeOf(final String matchingCurrencyCode) { if (this.currencyCode() == null || matchingCurrencyCode == null) { return false; } return this.currencyCode().equalsIgnoreCase(matchingCurrencyCode); @@ -668,38 +684,40 @@ public class SavingsAccountCharge extends AbstractPersistable { } public void updateToNextDueDateFrom(final LocalDate startingDate) { - if (isAnnualFee() || isMonthlyFee()) { - LocalDate nextDueLocalDate = startingDate.withMonthOfYear(this.feeOnMonth); - int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); - int newDayOfMonth = (this.feeOnDay.intValue() <= maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth; - nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth); - - while (startingDate.isAfter(nextDueLocalDate)) { - if (isAnnualFee()) { - nextDueLocalDate = nextDueLocalDate.plusYears(1); - } else if (isMonthlyFee()) { - nextDueLocalDate = nextDueLocalDate.plusMonths(this.feeInterval); - } - } - - this.dueDate = nextDueLocalDate.toDate(); + if (isAnnualFee() || isMonthlyFee() || isWeeklyFee()) { + LocalDate nextDueLocalDate = null; + if (isAnnualFee()) { + nextDueLocalDate = startingDate.withMonthOfYear(this.feeOnMonth).plusYears(1); + } else if (isMonthlyFee()) { + nextDueLocalDate = startingDate.plusMonths(this.feeInterval); + int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); + int newDayOfMonth = (this.feeOnDay.intValue() < maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth; + nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth); + } else if (isWeeklyFee()){ + nextDueLocalDate = startingDate.plusDays(7 * this.feeInterval); + } + + this.dueDate = nextDueLocalDate.toDate(); } + } public void updateToNextDueDate() { - if (isAnnualFee() || isMonthlyFee()) { - LocalDate nextDueLocalDate = new LocalDate(dueDate); - int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); - int newDayOfMonth = (this.feeOnDay.intValue() < maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth; - nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth); - - if (isAnnualFee()) { - nextDueLocalDate = nextDueLocalDate.withMonthOfYear(this.feeOnMonth).plusYears(1); - } else if (isMonthlyFee()) { - nextDueLocalDate = nextDueLocalDate.plusMonths(this.feeInterval); - } - - this.dueDate = nextDueLocalDate.toDate(); + if (isAnnualFee() || isMonthlyFee() || isWeeklyFee()) { + LocalDate currentDueLocalDate = new LocalDate(dueDate); + LocalDate nextDueLocalDate = null; + if (isAnnualFee()) { + nextDueLocalDate = currentDueLocalDate.withMonthOfYear(this.feeOnMonth).plusYears(1); + } else if (isMonthlyFee()) { + nextDueLocalDate = currentDueLocalDate.plusMonths(this.feeInterval); + int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); + int newDayOfMonth = (this.feeOnDay.intValue() < maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth; + nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth); + } else if (isWeeklyFee()){ + nextDueLocalDate = currentDueLocalDate.plusDays(7 * this.feeInterval); + } + + this.dueDate = nextDueLocalDate.toDate(); } } @@ -710,7 +728,9 @@ public class SavingsAccountCharge extends AbstractPersistable { nextDueLocalDate = nextDueLocalDate.withMonthOfYear(this.feeOnMonth).minusYears(1); } else if (isMonthlyFee()) { nextDueLocalDate = nextDueLocalDate.minusMonths(this.feeInterval); - } + } else if (isWeeklyFee()){ + nextDueLocalDate = nextDueLocalDate.minusDays(7 * this.feeInterval); + } // set day of month int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountChargeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountChargeReadPlatformServiceImpl.java index b12ad182d..ec1ffc4f4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountChargeReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountChargeReadPlatformServiceImpl.java @@ -112,7 +112,7 @@ public class SavingsAccountChargeReadPlatformServiceImpl implements SavingsAccou MonthDay feeOnMonthDay = null; final Integer feeOnMonth = JdbcSupport.getInteger(rs, "feeOnMonth"); final Integer feeOnDay = JdbcSupport.getInteger(rs, "feeOnDay"); - if (feeOnDay != null) { + if (feeOnDay != null && feeOnMonth != null) { feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay); }