This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 3d3b2dad6f FINERACT-2316: Localize interest rate chart slab validation
3d3b2dad6f is described below
commit 3d3b2dad6fece197d9489bcbb8114fe38b76d9df
Author: Siddharthan P S <[email protected]>
AuthorDate: Tue Dec 2 14:19:27 2025 -0500
FINERACT-2316: Localize interest rate chart slab validation
- Add localized validation messages for overlap and gap errors in interest
rate chart slabs
- Use DataValidatorBuilder with resource/parameter context for clean error
codes
- Add unit tests for validation error codes and arguments
- Add German translations for validation messages
---
.../src/main/resources/messages.properties | 22 +++++++
.../src/main/resources/messages_de.properties | 22 +++++++
.../domain/InterestRateChart.java | 24 ++++---
.../domain/InterestRateChartValidationTest.java | 74 ++++++++++++++++++++++
4 files changed, 132 insertions(+), 10 deletions(-)
diff --git a/fineract-provider/src/main/resources/messages.properties
b/fineract-provider/src/main/resources/messages.properties
new file mode 100644
index 0000000000..b8110d388c
--- /dev/null
+++ b/fineract-provider/src/main/resources/messages.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Interest Rate Chart validation messages
+validation.msg.savings.interestRateChart.slabs.overlap=There is an overlap
between slabs {0} and {1}.
+validation.msg.savings.interestRateChart.slabs.gap=There is a gap between
slabs {0} and {1}.
diff --git a/fineract-provider/src/main/resources/messages_de.properties
b/fineract-provider/src/main/resources/messages_de.properties
new file mode 100644
index 0000000000..8019c33984
--- /dev/null
+++ b/fineract-provider/src/main/resources/messages_de.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Interest Rate Chart validation messages
+validation.msg.savings.interestRateChart.slabs.overlap=Es gibt eine
Überlappung zwischen Segmenten {0} und {1}.
+validation.msg.savings.interestRateChart.slabs.gap=Es gibt eine Lücke zwischen
Segmenten {0} und {1}.
diff --git
a/fineract-savings/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java
b/fineract-savings/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java
index a49230b91f..a6a65ba741 100644
---
a/fineract-savings/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java
+++
b/fineract-savings/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java
@@ -137,17 +137,21 @@ public class InterestRateChart extends
AbstractPersistableCustom<Long> {
if (iSlabs.slabFields().isValidChart(isPrimaryGroupingByAmount)
&&
nextSlabs.slabFields().isValidChart(isPrimaryGroupingByAmount)) {
if
(iSlabs.slabFields().isRateChartOverlapping(nextSlabs.slabFields(),
isPrimaryGroupingByAmount)) {
-
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.range.overlapping",
- iSlabs.slabFields().fromPeriod(),
iSlabs.slabFields().toPeriod(), nextSlabs.slabFields().fromPeriod(),
- nextSlabs.slabFields().toPeriod(),
iSlabs.slabFields().getAmountRangeFrom(),
- iSlabs.slabFields().getAmountRangeTo(),
nextSlabs.slabFields().getAmountRangeFrom(),
- nextSlabs.slabFields().getAmountRangeTo());
+ // Use DataValidatorBuilder with resource/parameter
context for clean error codes
+ DataValidatorBuilder v = new
DataValidatorBuilder(baseDataValidator.getDataValidationErrors())
+
.resource("savings.interestRateChart").parameter("slabs");
+ v.failWithCode("overlap",
iSlabs.slabFields().fromPeriod(), iSlabs.slabFields().toPeriod(),
+ nextSlabs.slabFields().fromPeriod(),
nextSlabs.slabFields().toPeriod(),
+ iSlabs.slabFields().getAmountRangeFrom(),
iSlabs.slabFields().getAmountRangeTo(),
+ nextSlabs.slabFields().getAmountRangeFrom(),
nextSlabs.slabFields().getAmountRangeTo());
} else if
(iSlabs.slabFields().isRateChartHasGap(nextSlabs.slabFields(),
isPrimaryGroupingByAmount)) {
-
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.range.has.gap",
- iSlabs.slabFields().fromPeriod(),
iSlabs.slabFields().toPeriod(), nextSlabs.slabFields().fromPeriod(),
- nextSlabs.slabFields().toPeriod(),
iSlabs.slabFields().getAmountRangeFrom(),
- iSlabs.slabFields().getAmountRangeTo(),
nextSlabs.slabFields().getAmountRangeFrom(),
- nextSlabs.slabFields().getAmountRangeTo());
+ // Use DataValidatorBuilder with resource/parameter
context for clean error codes
+ DataValidatorBuilder v = new
DataValidatorBuilder(baseDataValidator.getDataValidationErrors())
+
.resource("savings.interestRateChart").parameter("slabs");
+ v.failWithCode("gap",
iSlabs.slabFields().fromPeriod(), iSlabs.slabFields().toPeriod(),
+ nextSlabs.slabFields().fromPeriod(),
nextSlabs.slabFields().toPeriod(),
+ iSlabs.slabFields().getAmountRangeFrom(),
iSlabs.slabFields().getAmountRangeTo(),
+ nextSlabs.slabFields().getAmountRangeFrom(),
nextSlabs.slabFields().getAmountRangeTo());
}
if (isPrimaryGroupingByAmount) {
if
(!iSlabs.slabFields().isAmountSame(nextSlabs.slabFields())) {
diff --git
a/fineract-savings/src/test/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartValidationTest.java
b/fineract-savings/src/test/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartValidationTest.java
new file mode 100644
index 0000000000..4a88b32cb7
--- /dev/null
+++
b/fineract-savings/src/test/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartValidationTest.java
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.interestratechart.domain;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test class for InterestRateChart validation error codes and arguments
+ */
+public class InterestRateChartValidationTest {
+
+ private List<ApiParameterError> dataValidationErrors;
+
+ @BeforeEach
+ public void setUp() {
+ dataValidationErrors = new ArrayList<>();
+ }
+
+ @Test
+ public void testOverlappingRangesValidation() {
+ // Given - use DataValidatorBuilder with resource/parameter context
+ DataValidatorBuilder v = new
DataValidatorBuilder(dataValidationErrors).resource("savings.interestRateChart").parameter("slabs");
+
+ // When - simulate overlapping ranges validation
+ v.failWithCode("overlap", 1, 12, 6, 18, 1000.0, 5000.0, 3000.0,
8000.0);
+
+ // Then
+ assertEquals(1, dataValidationErrors.size(), "Expected exactly one
validation error");
+ ApiParameterError actualError = dataValidationErrors.get(0);
+ assertEquals("validation.msg.savings.interestRateChart.slabs.overlap",
actualError.getUserMessageGlobalisationCode());
+ // Check that arguments are present
+ assertFalse(actualError.getArgs().isEmpty());
+ }
+
+ @Test
+ public void testGapBetweenRangesValidation() {
+ // Given - use DataValidatorBuilder with resource/parameter context
+ DataValidatorBuilder v = new
DataValidatorBuilder(dataValidationErrors).resource("savings.interestRateChart").parameter("slabs");
+
+ // When - simulate gap between ranges validation
+ v.failWithCode("gap", 1, 12, 15, 24, 1000.0, 5000.0, 6000.0, 10000.0);
+
+ // Then
+ assertEquals(1, dataValidationErrors.size(), "Expected exactly one
validation error");
+ ApiParameterError actualError = dataValidationErrors.get(0);
+ assertEquals("validation.msg.savings.interestRateChart.slabs.gap",
actualError.getUserMessageGlobalisationCode());
+ // Check that arguments are present
+ assertFalse(actualError.getArgs().isEmpty());
+ }
+}