Skip to content

Commit d6c3f9c

Browse files
committed
FINERACT-1185: Add anniversary interest posting period types
1 parent 4a8bdc5 commit d6c3f9c

10 files changed

Lines changed: 498 additions & 5 deletions

File tree

fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPostingInterestPeriodType.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ public enum SavingsPostingInterestPeriodType {
3131
MONTHLY(4, "savingsPostingInterestPeriodType.monthly"), //
3232
QUATERLY(5, "savingsPostingInterestPeriodType.quarterly"), //
3333
BIANNUAL(6, "savingsPostingInterestPeriodType.biannual"), //
34-
ANNUAL(7, "savingsPostingInterestPeriodType.annual"); //
34+
ANNUAL(7, "savingsPostingInterestPeriodType.annual"), //
35+
ANNIVERSARY_MONTHLY(8, "savingsPostingInterestPeriodType.anniversaryMonthly"), //
36+
ANNIVERSARY_QUARTERLY(9, "savingsPostingInterestPeriodType.anniversaryQuarterly"), //
37+
ANNIVERSARY_BIANNUAL(10, "savingsPostingInterestPeriodType.anniversaryBiAnnual"), //
38+
ANNIVERSARY_ANNUAL(11, "savingsPostingInterestPeriodType.anniversaryAnnual"); //
3539

3640
private final Integer value;
3741
private final String code;
@@ -70,6 +74,14 @@ public static SavingsPostingInterestPeriodType fromInt(final Integer v) {
7074
return BIANNUAL;
7175
case 7:
7276
return ANNUAL;
77+
case 8:
78+
return ANNIVERSARY_MONTHLY;
79+
case 9:
80+
return ANNIVERSARY_QUARTERLY;
81+
case 10:
82+
return ANNIVERSARY_BIANNUAL;
83+
case 11:
84+
return ANNIVERSARY_ANNUAL;
7385
default:
7486
return INVALID;
7587
}

fineract-core/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsHelper.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ public List<LocalDateInterval> determineInterestPostingPeriods(final LocalDate s
6363
LocalDate periodStartDate = startInterestCalculationLocalDate;
6464
LocalDate periodEndDate = periodStartDate;
6565
LocalDate actualPeriodStartDate = periodStartDate;
66+
final int anniversaryDayOfMonth = startInterestCalculationLocalDate.getDayOfMonth();
6667

6768
while (!DateUtils.isAfter(periodStartDate, interestPostingUpToDate) && !DateUtils.isAfter(periodEndDate, interestPostingUpToDate)) {
6869
final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType,
69-
interestPostingUpToDate, financialYearBeginningMonth);
70+
interestPostingUpToDate, financialYearBeginningMonth, anniversaryDayOfMonth);
7071

7172
periodEndDate = interestPostingLocalDate.minusDays(1);
7273

@@ -96,7 +97,7 @@ public List<LocalDateInterval> determineInterestPostingPeriods(final LocalDate s
9697

9798
private LocalDate determineInterestPostingPeriodEndDateFrom(final LocalDate periodStartDate,
9899
final SavingsPostingInterestPeriodType interestPostingPeriodType, final LocalDate interestPostingUpToDate,
99-
Integer financialYearBeginningMonth) {
100+
Integer financialYearBeginningMonth, final int anniversaryDayOfMonth) {
100101

101102
LocalDate periodEndDate = interestPostingUpToDate;
102103
final Integer monthOfYear = periodStartDate.getMonthValue();
@@ -168,12 +169,28 @@ private LocalDate determineInterestPostingPeriodEndDateFrom(final LocalDate peri
168169
}
169170
periodEndDate = periodEndDate.with(TemporalAdjusters.lastDayOfMonth());
170171
break;
172+
case ANNIVERSARY_MONTHLY:
173+
periodEndDate = adjustToAnniversaryDay(periodStartDate.plusMonths(1), anniversaryDayOfMonth).minusDays(1);
174+
break;
175+
case ANNIVERSARY_QUARTERLY:
176+
periodEndDate = adjustToAnniversaryDay(periodStartDate.plusMonths(3), anniversaryDayOfMonth).minusDays(1);
177+
break;
178+
case ANNIVERSARY_BIANNUAL:
179+
periodEndDate = adjustToAnniversaryDay(periodStartDate.plusMonths(6), anniversaryDayOfMonth).minusDays(1);
180+
break;
181+
case ANNIVERSARY_ANNUAL:
182+
periodEndDate = adjustToAnniversaryDay(periodStartDate.plusMonths(12), anniversaryDayOfMonth).minusDays(1);
183+
break;
171184
}
172185
// interest posting always occurs on next day after the period end date.
173186
periodEndDate = periodEndDate.plusDays(1);
174187
return periodEndDate;
175188
}
176189

190+
private LocalDate adjustToAnniversaryDay(final LocalDate date, final int anniversaryDay) {
191+
return date.withDayOfMonth(Math.min(anniversaryDay, date.lengthOfMonth()));
192+
}
193+
177194
public Money calculateInterestForAllPostingPeriods(final MonetaryCurrency currency, final List<PostingPeriod> allPeriods,
178195
LocalDate accountLockedUntil, Boolean immediateWithdrawalOfInterest) {
179196
return COMPOUND_INTEREST_HELPER.calculateInterestForAllPostingPeriods(currency, allPeriods, accountLockedUntil,

fineract-core/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsEnumerations.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,22 @@ public static EnumOptionData interestPostingPeriodType(final SavingsPostingInter
386386
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.ANNUAL.getValue().longValue(),
387387
codePrefix + SavingsPostingInterestPeriodType.ANNUAL.getCode(), "Annually");
388388
break;
389+
case ANNIVERSARY_MONTHLY:
390+
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY.getValue().longValue(),
391+
codePrefix + SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY.getCode(), "Anniversary Monthly");
392+
break;
393+
case ANNIVERSARY_QUARTERLY:
394+
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.ANNIVERSARY_QUARTERLY.getValue().longValue(),
395+
codePrefix + SavingsPostingInterestPeriodType.ANNIVERSARY_QUARTERLY.getCode(), "Anniversary Quarterly");
396+
break;
397+
case ANNIVERSARY_BIANNUAL:
398+
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.ANNIVERSARY_BIANNUAL.getValue().longValue(),
399+
codePrefix + SavingsPostingInterestPeriodType.ANNIVERSARY_BIANNUAL.getCode(), "Anniversary BiAnnual");
400+
break;
401+
case ANNIVERSARY_ANNUAL:
402+
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.ANNIVERSARY_ANNUAL.getValue().longValue(),
403+
codePrefix + SavingsPostingInterestPeriodType.ANNIVERSARY_ANNUAL.getCode(), "Anniversary Annually");
404+
break;
389405
}
390406

391407
return optionData;
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.portfolio.savings.domain;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
23+
import java.time.LocalDate;
24+
import java.util.Collections;
25+
import java.util.List;
26+
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
27+
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
28+
import org.junit.jupiter.api.Test;
29+
30+
class SavingsHelperAnniversaryPostingTest {
31+
32+
private static final Integer FINANCIAL_YEAR_BEGINNING_MONTH = 1;
33+
34+
private final SavingsHelper savingsHelper = new SavingsHelper(null);
35+
36+
private static void assertPeriod(LocalDateInterval period, LocalDate expectedStart, LocalDate expectedEnd) {
37+
assertThat(period.startDate()).as("period start").isEqualTo(expectedStart);
38+
assertThat(period.endDate()).as("period end").isEqualTo(expectedEnd);
39+
}
40+
41+
@Test
42+
void anniversaryMonthly_accountOpenedOn15th_periodsAlignToThe15th() {
43+
LocalDate start = LocalDate.of(2024, 1, 15);
44+
LocalDate end = LocalDate.of(2024, 3, 31);
45+
46+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
47+
SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
48+
49+
assertThat(periods).hasSize(3);
50+
assertPeriod(periods.get(0), LocalDate.of(2024, 1, 15), LocalDate.of(2024, 2, 14));
51+
assertPeriod(periods.get(1), LocalDate.of(2024, 2, 15), LocalDate.of(2024, 3, 14));
52+
assertPeriod(periods.get(2), LocalDate.of(2024, 3, 15), LocalDate.of(2024, 4, 14));
53+
}
54+
55+
@Test
56+
void anniversaryMonthly_accountOpenedOn1st_periodsAlignToFirstOfMonth() {
57+
LocalDate start = LocalDate.of(2024, 1, 1);
58+
LocalDate end = LocalDate.of(2024, 3, 31);
59+
60+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
61+
SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
62+
63+
assertThat(periods).hasSize(3);
64+
assertPeriod(periods.get(0), LocalDate.of(2024, 1, 1), LocalDate.of(2024, 1, 31));
65+
assertPeriod(periods.get(1), LocalDate.of(2024, 2, 1), LocalDate.of(2024, 2, 29));
66+
assertPeriod(periods.get(2), LocalDate.of(2024, 3, 1), LocalDate.of(2024, 3, 31));
67+
}
68+
69+
@Test
70+
void anniversaryMonthly_accountOpenedOn29th_februaryUsesLastDay() {
71+
LocalDate start = LocalDate.of(2025, 1, 29);
72+
LocalDate end = LocalDate.of(2025, 4, 30);
73+
74+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
75+
SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
76+
77+
assertThat(periods).hasSize(4);
78+
// Jan 29 → Feb 28 posting: period Jan 29 – Feb 27
79+
assertPeriod(periods.get(0), LocalDate.of(2025, 1, 29), LocalDate.of(2025, 2, 27));
80+
// Feb 28 → Mar 29 posting: period Feb 28 – Mar 28
81+
assertPeriod(periods.get(1), LocalDate.of(2025, 2, 28), LocalDate.of(2025, 3, 28));
82+
// Mar 29 → Apr 29 posting: period Mar 29 – Apr 28
83+
assertPeriod(periods.get(2), LocalDate.of(2025, 3, 29), LocalDate.of(2025, 4, 28));
84+
// Apr 29 → May 29 posting: period Apr 29 – May 28 (extends past upToDate Apr 30)
85+
assertPeriod(periods.get(3), LocalDate.of(2025, 4, 29), LocalDate.of(2025, 5, 28));
86+
}
87+
88+
@Test
89+
void anniversaryMonthly_accountOpenedOn31st_shortMonthsUseLastDay() {
90+
LocalDate start = LocalDate.of(2025, 1, 31);
91+
LocalDate end = LocalDate.of(2025, 5, 31);
92+
93+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
94+
SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
95+
96+
assertThat(periods).hasSize(5);
97+
assertPeriod(periods.get(0), LocalDate.of(2025, 1, 31), LocalDate.of(2025, 2, 27));
98+
assertPeriod(periods.get(1), LocalDate.of(2025, 2, 28), LocalDate.of(2025, 3, 30));
99+
assertPeriod(periods.get(2), LocalDate.of(2025, 3, 31), LocalDate.of(2025, 4, 29));
100+
assertPeriod(periods.get(3), LocalDate.of(2025, 4, 30), LocalDate.of(2025, 5, 30));
101+
// last period extends past upToDate May 31 → May 31 – Jun 29
102+
assertPeriod(periods.get(4), LocalDate.of(2025, 5, 31), LocalDate.of(2025, 6, 29));
103+
}
104+
105+
@Test
106+
void anniversaryQuarterly_accountOpenedOn15th_periodsAlignToThe15th() {
107+
LocalDate start = LocalDate.of(2024, 1, 15);
108+
LocalDate end = LocalDate.of(2024, 12, 31);
109+
110+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
111+
SavingsPostingInterestPeriodType.ANNIVERSARY_QUARTERLY, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
112+
113+
assertThat(periods).hasSize(4);
114+
assertPeriod(periods.get(0), LocalDate.of(2024, 1, 15), LocalDate.of(2024, 4, 14));
115+
assertPeriod(periods.get(1), LocalDate.of(2024, 4, 15), LocalDate.of(2024, 7, 14));
116+
assertPeriod(periods.get(2), LocalDate.of(2024, 7, 15), LocalDate.of(2024, 10, 14));
117+
// last period extends past Dec 31 → Oct 15 – Jan 14 2025
118+
assertPeriod(periods.get(3), LocalDate.of(2024, 10, 15), LocalDate.of(2025, 1, 14));
119+
}
120+
121+
@Test
122+
void anniversaryQuarterly_accountOpenedOn29th_februaryQuarterUsesLastDay() {
123+
LocalDate start = LocalDate.of(2024, 11, 29);
124+
LocalDate end = LocalDate.of(2025, 5, 31);
125+
126+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
127+
SavingsPostingInterestPeriodType.ANNIVERSARY_QUARTERLY, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
128+
129+
assertThat(periods).hasSize(3);
130+
// Nov 29 → Feb 28 posting: period Nov 29 – Feb 27
131+
assertPeriod(periods.get(0), LocalDate.of(2024, 11, 29), LocalDate.of(2025, 2, 27));
132+
// Feb 28 → May 29 posting: period Feb 28 – May 28
133+
assertPeriod(periods.get(1), LocalDate.of(2025, 2, 28), LocalDate.of(2025, 5, 28));
134+
// May 29 → Aug 29 posting: period May 29 – Aug 28 (extends past upToDate May 31)
135+
assertPeriod(periods.get(2), LocalDate.of(2025, 5, 29), LocalDate.of(2025, 8, 28));
136+
}
137+
138+
@Test
139+
void anniversaryBiAnnual_accountOpenedOn15th_periodsAlignToThe15th() {
140+
LocalDate start = LocalDate.of(2024, 1, 15);
141+
LocalDate end = LocalDate.of(2025, 1, 31);
142+
143+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
144+
SavingsPostingInterestPeriodType.ANNIVERSARY_BIANNUAL, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
145+
146+
assertThat(periods).hasSize(3);
147+
assertPeriod(periods.get(0), LocalDate.of(2024, 1, 15), LocalDate.of(2024, 7, 14));
148+
assertPeriod(periods.get(1), LocalDate.of(2024, 7, 15), LocalDate.of(2025, 1, 14));
149+
// last period extends past Jan 31 → Jan 15 2025 – Jul 14 2025
150+
assertPeriod(periods.get(2), LocalDate.of(2025, 1, 15), LocalDate.of(2025, 7, 14));
151+
}
152+
153+
@Test
154+
void anniversaryAnnual_accountOpenedOn15th_periodsAlignToThe15th() {
155+
LocalDate start = LocalDate.of(2024, 3, 15);
156+
LocalDate end = LocalDate.of(2026, 3, 31);
157+
158+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
159+
SavingsPostingInterestPeriodType.ANNIVERSARY_ANNUAL, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
160+
161+
assertThat(periods).hasSize(3);
162+
assertPeriod(periods.get(0), LocalDate.of(2024, 3, 15), LocalDate.of(2025, 3, 14));
163+
assertPeriod(periods.get(1), LocalDate.of(2025, 3, 15), LocalDate.of(2026, 3, 14));
164+
// last period extends past Mar 31 2026 → Mar 15 2026 – Mar 14 2027
165+
assertPeriod(periods.get(2), LocalDate.of(2026, 3, 15), LocalDate.of(2027, 3, 14));
166+
}
167+
168+
@Test
169+
void anniversaryAnnual_accountOpenedOnFeb29_leapYearHandling() {
170+
LocalDate start = LocalDate.of(2024, 2, 29);
171+
LocalDate end = LocalDate.of(2026, 3, 31);
172+
173+
List<LocalDateInterval> periods = savingsHelper.determineInterestPostingPeriods(start, end,
174+
SavingsPostingInterestPeriodType.ANNIVERSARY_ANNUAL, FINANCIAL_YEAR_BEGINNING_MONTH, Collections.emptyList());
175+
176+
assertThat(periods).hasSize(3);
177+
// Feb 29 2024 → Feb 28 2025 posting: period Feb 29 2024 – Feb 27 2025
178+
assertPeriod(periods.get(0), LocalDate.of(2024, 2, 29), LocalDate.of(2025, 2, 27));
179+
// Feb 28 2025 → Feb 28 2026 posting: period Feb 28 2025 – Feb 27 2026
180+
assertPeriod(periods.get(1), LocalDate.of(2025, 2, 28), LocalDate.of(2026, 2, 27));
181+
// last period extends past Mar 31 2026 → Feb 28 2026 – Feb 27 2027
182+
assertPeriod(periods.get(2), LocalDate.of(2026, 2, 28), LocalDate.of(2027, 2, 27));
183+
}
184+
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsDropdownReadPlatformServiceImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ public Collection<EnumOptionData> retrieveInterestPostingPeriodTypeOptions() {
7171
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.MONTHLY), //
7272
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.QUATERLY), //
7373
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.BIANNUAL), //
74-
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNUAL) //
74+
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNUAL), //
75+
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY), //
76+
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNIVERSARY_QUARTERLY), //
77+
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNIVERSARY_BIANNUAL), //
78+
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNIVERSARY_ANNUAL) //
7579
);
7680

7781
return allowedOptions;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.portfolio.savings.service;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
23+
import java.util.Collection;
24+
import java.util.List;
25+
import java.util.stream.Collectors;
26+
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
27+
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
28+
import org.junit.jupiter.api.Test;
29+
30+
class SavingsDropdownReadPlatformServiceImplTest {
31+
32+
private final SavingsDropdownReadPlatformServiceImpl service = new SavingsDropdownReadPlatformServiceImpl();
33+
34+
@Test
35+
void retrieveInterestPostingPeriodTypeOptions_shouldIncludeAllAnniversaryTypes() {
36+
Collection<EnumOptionData> options = service.retrieveInterestPostingPeriodTypeOptions();
37+
38+
List<Long> ids = options.stream().map(EnumOptionData::getId).collect(Collectors.toList());
39+
40+
assertThat(ids).contains((long) SavingsPostingInterestPeriodType.ANNIVERSARY_MONTHLY.getValue(),
41+
(long) SavingsPostingInterestPeriodType.ANNIVERSARY_QUARTERLY.getValue(),
42+
(long) SavingsPostingInterestPeriodType.ANNIVERSARY_BIANNUAL.getValue(),
43+
(long) SavingsPostingInterestPeriodType.ANNIVERSARY_ANNUAL.getValue());
44+
}
45+
46+
@Test
47+
void retrieveInterestPostingPeriodTypeOptions_shouldIncludeAllOriginalTypes() {
48+
Collection<EnumOptionData> options = service.retrieveInterestPostingPeriodTypeOptions();
49+
50+
List<Long> ids = options.stream().map(EnumOptionData::getId).collect(Collectors.toList());
51+
52+
assertThat(ids).contains((long) SavingsPostingInterestPeriodType.DAILY.getValue(),
53+
(long) SavingsPostingInterestPeriodType.MONTHLY.getValue(), (long) SavingsPostingInterestPeriodType.QUATERLY.getValue(),
54+
(long) SavingsPostingInterestPeriodType.BIANNUAL.getValue(), (long) SavingsPostingInterestPeriodType.ANNUAL.getValue());
55+
}
56+
}

0 commit comments

Comments
 (0)