Weekly saving charges

This commit is contained in:
goutham-M
2014-06-16 19:02:07 +05:30
parent d7399cc6e5
commit 602f0bdb07
8 changed files with 88 additions and 45 deletions
@@ -467,6 +467,10 @@ public class Charge extends AbstractPersistable<Long> {
public Integer getChargePaymentMode() { public Integer getChargePaymentMode() {
return this.chargePaymentMode; return this.chargePaymentMode;
} }
public Integer getFeeInterval(){
return this.feeInterval;
}
public boolean isMonthlyFee() { public boolean isMonthlyFee() {
return ChargeTimeType.fromInt(this.chargeTime).isMonthlyFee(); return ChargeTimeType.fromInt(this.chargeTime).isMonthlyFee();
@@ -20,7 +20,8 @@ public enum ChargeTimeType {
INSTALMENT_FEE(8, "chargeTimeType.instalmentFee"), // only for loan charges INSTALMENT_FEE(8, "chargeTimeType.instalmentFee"), // only for loan charges
OVERDUE_INSTALLMENT(9, "chargeTimeType.overdueInstallment"), // only for OVERDUE_INSTALLMENT(9, "chargeTimeType.overdueInstallment"), // only for
// loan charges // 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 Integer value;
private final String code; private final String code;
@@ -51,7 +52,7 @@ public enum ChargeTimeType {
public static Object[] validSavingsValues() { public static Object[] validSavingsValues() {
return new Integer[] { ChargeTimeType.SPECIFIED_DUE_DATE.getValue(), ChargeTimeType.SAVINGS_ACTIVATION.getValue(), 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.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) { public static ChargeTimeType fromInt(final Integer chargeTime) {
@@ -88,6 +89,9 @@ public enum ChargeTimeType {
case 10: case 10:
chargeTimeType = OVERDRAFT_FEE; chargeTimeType = OVERDRAFT_FEE;
break; break;
case 11:
chargeTimeType = WEEKLY_FEE;
break;
default: default:
chargeTimeType = INVALID; chargeTimeType = INVALID;
break; break;
@@ -123,7 +127,11 @@ public enum ChargeTimeType {
public boolean isMonthlyFee() { public boolean isMonthlyFee() {
return this.value.equals(ChargeTimeType.MONTHLY_FEE.getValue()); return this.value.equals(ChargeTimeType.MONTHLY_FEE.getValue());
} }
public boolean isWeeklyFee() {
return this.value.equals(ChargeTimeType.WEEKLY_FEE.getValue());
}
public boolean isInstalmentFee() { public boolean isInstalmentFee() {
return this.value.equals(ChargeTimeType.INSTALMENT_FEE.getValue()); return this.value.equals(ChargeTimeType.INSTALMENT_FEE.getValue());
} }
@@ -138,7 +146,7 @@ public enum ChargeTimeType {
public boolean isAllowedSavingsChargeTime() { public boolean isAllowedSavingsChargeTime() {
return isOnSpecifiedDueDate() || isSavingsActivation() || isSavingsClosure() || isWithdrawalFee() || isAnnualFee() return isOnSpecifiedDueDate() || isSavingsActivation() || isSavingsClosure() || isWithdrawalFee() || isAnnualFee()
|| isMonthlyFee() || isOverdraftFee(); || isMonthlyFee() || isWeeklyFee() || isOverdraftFee();
} }
public boolean isOverdraftFee() { public boolean isOverdraftFee() {
@@ -113,6 +113,12 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
} }
final ChargeTimeType ctt = ChargeTimeType.fromInt(chargeTimeType); 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()) { if (ctt.isMonthlyFee()) {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed("feeOnMonthDay", element); final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed("feeOnMonthDay", element);
baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).notNull(); baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).notNull();
@@ -84,6 +84,7 @@ public class ChargeDropdownReadPlatformServiceImpl implements ChargeDropdownRead
return Arrays.asList(chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE), chargeTimeType(ChargeTimeType.SAVINGS_ACTIVATION), return Arrays.asList(chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE), chargeTimeType(ChargeTimeType.SAVINGS_ACTIVATION),
// chargeTimeType(ChargeTimeType.SAVINGS_CLOSURE), // chargeTimeType(ChargeTimeType.SAVINGS_CLOSURE),
chargeTimeType(ChargeTimeType.WITHDRAWAL_FEE), chargeTimeType(ChargeTimeType.ANNUAL_FEE), 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));
} }
} }
@@ -48,6 +48,10 @@ public class ChargeEnumerations {
optionData = new EnumOptionData(ChargeTimeType.MONTHLY_FEE.getValue().longValue(), ChargeTimeType.MONTHLY_FEE.getCode(), optionData = new EnumOptionData(ChargeTimeType.MONTHLY_FEE.getValue().longValue(), ChargeTimeType.MONTHLY_FEE.getCode(),
"Monthly Fee"); "Monthly Fee");
break; break;
case WEEKLY_FEE:
optionData = new EnumOptionData(ChargeTimeType.WEEKLY_FEE.getValue().longValue(), ChargeTimeType.WEEKLY_FEE.getCode(),
"Weekly Fee");
break;
case INSTALMENT_FEE: case INSTALMENT_FEE:
optionData = new EnumOptionData(ChargeTimeType.INSTALMENT_FEE.getValue().longValue(), optionData = new EnumOptionData(ChargeTimeType.INSTALMENT_FEE.getValue().longValue(),
ChargeTimeType.INSTALMENT_FEE.getCode(), "Instalment Fee"); ChargeTimeType.INSTALMENT_FEE.getCode(), "Instalment Fee");
@@ -241,7 +241,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
MonthDay feeOnMonthDay = null; MonthDay feeOnMonthDay = null;
final Integer feeOnMonth = JdbcSupport.getInteger(rs, "feeOnMonth"); final Integer feeOnMonth = JdbcSupport.getInteger(rs, "feeOnMonth");
final Integer feeOnDay = JdbcSupport.getInteger(rs, "feeOnDay"); final Integer feeOnDay = JdbcSupport.getInteger(rs, "feeOnDay");
if (feeOnDay != null) { if (feeOnDay != null && feeOnMonth != null) {
feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay); feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay);
} }
final BigDecimal minCap = rs.getBigDecimal("minCap"); final BigDecimal minCap = rs.getBigDecimal("minCap");
@@ -108,13 +108,18 @@ public class SavingsAccountCharge extends AbstractPersistable<Long> {
public static SavingsAccountCharge createNewFromJson(final SavingsAccount savingsAccount, final Charge chargeDefinition, public static SavingsAccountCharge createNewFromJson(final SavingsAccount savingsAccount, final Charge chargeDefinition,
final JsonCommand command) { final JsonCommand command) {
final BigDecimal amount = command.bigDecimalValueOfParameterNamed(amountParamName); BigDecimal amount = command.bigDecimalValueOfParameterNamed(amountParamName);
final LocalDate dueDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName); final LocalDate dueDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName);
final MonthDay feeOnMonthDay = command.extractMonthDayNamed(feeOnMonthDayParamName); MonthDay feeOnMonthDay = command.extractMonthDayNamed(feeOnMonthDayParamName);
final Integer feeInterval = command.integerValueOfParameterNamed(feeIntervalParamName); Integer feeInterval = command.integerValueOfParameterNamed(feeIntervalParamName);
final ChargeTimeType chargeTime = null; final ChargeTimeType chargeTime = null;
final ChargeCalculationType chargeCalculation = null; final ChargeCalculationType chargeCalculation = null;
final boolean status = true; 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, return new SavingsAccountCharge(savingsAccount, chargeDefinition, amount, chargeTime, chargeCalculation, dueDate, status,
feeOnMonthDay, feeInterval); feeOnMonthDay, feeInterval);
@@ -148,6 +153,14 @@ public class SavingsAccountCharge extends AbstractPersistable<Long> {
} }
} }
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()) { if (isAnnualFee() || isMonthlyFee()) {
feeOnMonthDay = (feeOnMonthDay == null) ? chargeDefinition.getFeeOnMonthDay() : feeOnMonthDay; feeOnMonthDay = (feeOnMonthDay == null) ? chargeDefinition.getFeeOnMonthDay() : feeOnMonthDay;
@@ -160,11 +173,10 @@ public class SavingsAccountCharge extends AbstractPersistable<Long> {
this.feeOnMonth = feeOnMonthDay.getMonthOfYear(); this.feeOnMonth = feeOnMonthDay.getMonthOfYear();
this.feeOnDay = feeOnMonthDay.getDayOfMonth(); this.feeOnDay = feeOnMonthDay.getDayOfMonth();
if (isMonthlyFee()) { } else if(isMonthlyFee() || isWeeklyFee() ){
this.feeInterval = (feeInterval == null) ? chargeDefinition.feeInterval() : feeInterval; this.feeInterval = (feeInterval == null) ? chargeDefinition.feeInterval() : feeInterval;
} }
else {
} else {
this.feeOnDay = null; this.feeOnDay = null;
this.feeOnMonth = null; this.feeOnMonth = null;
this.feeInterval = null; this.feeInterval = null;
@@ -195,7 +207,7 @@ public class SavingsAccountCharge extends AbstractPersistable<Long> {
} }
public void recalculateAmountOutstanding() { public void recalculateAmountOutstanding() {
if (isMonthlyFee() || isAnnualFee()) { if (isMonthlyFee() || isAnnualFee() || isWeeklyFee()) {
// FIXME: AA: If charge is percentage of x amount then need to // FIXME: AA: If charge is percentage of x amount then need to
// update amount outstanding accordingly. // update amount outstanding accordingly.
// Right now annual and monthly charges supports charge calculation // Right now annual and monthly charges supports charge calculation
@@ -628,6 +640,10 @@ public class SavingsAccountCharge extends AbstractPersistable<Long> {
return ChargeTimeType.fromInt(this.chargeTime).isMonthlyFee(); return ChargeTimeType.fromInt(this.chargeTime).isMonthlyFee();
} }
public boolean isWeeklyFee() {
return ChargeTimeType.fromInt(this.chargeTime).isWeeklyFee();
}
public boolean hasCurrencyCodeOf(final String matchingCurrencyCode) { public boolean hasCurrencyCodeOf(final String matchingCurrencyCode) {
if (this.currencyCode() == null || matchingCurrencyCode == null) { return false; } if (this.currencyCode() == null || matchingCurrencyCode == null) { return false; }
return this.currencyCode().equalsIgnoreCase(matchingCurrencyCode); return this.currencyCode().equalsIgnoreCase(matchingCurrencyCode);
@@ -668,38 +684,40 @@ public class SavingsAccountCharge extends AbstractPersistable<Long> {
} }
public void updateToNextDueDateFrom(final LocalDate startingDate) { public void updateToNextDueDateFrom(final LocalDate startingDate) {
if (isAnnualFee() || isMonthlyFee()) { if (isAnnualFee() || isMonthlyFee() || isWeeklyFee()) {
LocalDate nextDueLocalDate = startingDate.withMonthOfYear(this.feeOnMonth); LocalDate nextDueLocalDate = null;
int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); if (isAnnualFee()) {
int newDayOfMonth = (this.feeOnDay.intValue() <= maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth; nextDueLocalDate = startingDate.withMonthOfYear(this.feeOnMonth).plusYears(1);
nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth); } else if (isMonthlyFee()) {
nextDueLocalDate = startingDate.plusMonths(this.feeInterval);
while (startingDate.isAfter(nextDueLocalDate)) { int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth();
if (isAnnualFee()) { int newDayOfMonth = (this.feeOnDay.intValue() < maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth;
nextDueLocalDate = nextDueLocalDate.plusYears(1); nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth);
} else if (isMonthlyFee()) { } else if (isWeeklyFee()){
nextDueLocalDate = nextDueLocalDate.plusMonths(this.feeInterval); nextDueLocalDate = startingDate.plusDays(7 * this.feeInterval);
} }
}
this.dueDate = nextDueLocalDate.toDate();
this.dueDate = nextDueLocalDate.toDate();
} }
} }
public void updateToNextDueDate() { public void updateToNextDueDate() {
if (isAnnualFee() || isMonthlyFee()) { if (isAnnualFee() || isMonthlyFee() || isWeeklyFee()) {
LocalDate nextDueLocalDate = new LocalDate(dueDate); LocalDate currentDueLocalDate = new LocalDate(dueDate);
int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); LocalDate nextDueLocalDate = null;
int newDayOfMonth = (this.feeOnDay.intValue() < maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth; if (isAnnualFee()) {
nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth); nextDueLocalDate = currentDueLocalDate.withMonthOfYear(this.feeOnMonth).plusYears(1);
} else if (isMonthlyFee()) {
if (isAnnualFee()) { nextDueLocalDate = currentDueLocalDate.plusMonths(this.feeInterval);
nextDueLocalDate = nextDueLocalDate.withMonthOfYear(this.feeOnMonth).plusYears(1); int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth();
} else if (isMonthlyFee()) { int newDayOfMonth = (this.feeOnDay.intValue() < maxDayOfMonth) ? this.feeOnDay.intValue() : maxDayOfMonth;
nextDueLocalDate = nextDueLocalDate.plusMonths(this.feeInterval); nextDueLocalDate = nextDueLocalDate.withDayOfMonth(newDayOfMonth);
} } else if (isWeeklyFee()){
nextDueLocalDate = currentDueLocalDate.plusDays(7 * this.feeInterval);
this.dueDate = nextDueLocalDate.toDate(); }
this.dueDate = nextDueLocalDate.toDate();
} }
} }
@@ -710,7 +728,9 @@ public class SavingsAccountCharge extends AbstractPersistable<Long> {
nextDueLocalDate = nextDueLocalDate.withMonthOfYear(this.feeOnMonth).minusYears(1); nextDueLocalDate = nextDueLocalDate.withMonthOfYear(this.feeOnMonth).minusYears(1);
} else if (isMonthlyFee()) { } else if (isMonthlyFee()) {
nextDueLocalDate = nextDueLocalDate.minusMonths(this.feeInterval); nextDueLocalDate = nextDueLocalDate.minusMonths(this.feeInterval);
} } else if (isWeeklyFee()){
nextDueLocalDate = nextDueLocalDate.minusDays(7 * this.feeInterval);
}
// set day of month // set day of month
int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth(); int maxDayOfMonth = nextDueLocalDate.dayOfMonth().withMaximumValue().getDayOfMonth();
@@ -112,7 +112,7 @@ public class SavingsAccountChargeReadPlatformServiceImpl implements SavingsAccou
MonthDay feeOnMonthDay = null; MonthDay feeOnMonthDay = null;
final Integer feeOnMonth = JdbcSupport.getInteger(rs, "feeOnMonth"); final Integer feeOnMonth = JdbcSupport.getInteger(rs, "feeOnMonth");
final Integer feeOnDay = JdbcSupport.getInteger(rs, "feeOnDay"); final Integer feeOnDay = JdbcSupport.getInteger(rs, "feeOnDay");
if (feeOnDay != null) { if (feeOnDay != null && feeOnMonth != null) {
feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay); feeOnMonthDay = new MonthDay(feeOnMonth, feeOnDay);
} }