Skip to content

Commit 1b28014

Browse files
peter-kovacs-dpcadamsaghy
authored andcommitted
FINERACT-2354: Reversal of re-aging transaction - remove restriction of reversal if there was payment after or on that day
1 parent 9320dd1 commit 1b28014

File tree

4 files changed

+663
-54
lines changed

4 files changed

+663
-54
lines changed

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanReAgingStepDef.java

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@
2424
import io.cucumber.java.en.Then;
2525
import io.cucumber.java.en.When;
2626
import java.io.IOException;
27+
import java.lang.reflect.Method;
28+
import java.math.BigDecimal;
29+
import java.util.Arrays;
30+
import java.util.LinkedHashMap;
2731
import java.util.List;
32+
import java.util.Map;
33+
import java.util.Set;
2834
import lombok.extern.slf4j.Slf4j;
2935
import okhttp3.ResponseBody;
3036
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
@@ -57,11 +63,20 @@ public void createReAgingTransaction(DataTable table) throws IOException {
5763
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
5864
long loanId = loanResponse.body().getLoanId();
5965

60-
List<String> data = table.asLists().get(1);
61-
int frequencyNumber = Integer.parseInt(data.get(0));
62-
String frequencyType = data.get(1);
63-
String startDate = data.get(2);
64-
int numberOfInstallments = Integer.parseInt(data.get(3));
66+
List<List<String>> tableRows = table.asLists();
67+
List<String> headers = tableRows.get(0);
68+
List<String> values = tableRows.get(1);
69+
70+
Map<String, String> rowData = new LinkedHashMap<>();
71+
int columnCount = Math.min(headers.size(), values.size());
72+
for (int i = 0; i < columnCount; i++) {
73+
rowData.put(headers.get(i), values.get(i));
74+
}
75+
76+
int frequencyNumber = Integer.parseInt(resolveValue(rowData, values, 0, "frequencyNumber"));
77+
String frequencyType = resolveValue(rowData, values, 1, "frequencyType");
78+
String startDate = resolveValue(rowData, values, 2, "startDate");
79+
int numberOfInstallments = Integer.parseInt(resolveValue(rowData, values, 3, "numberOfInstallments"));
6580

6681
PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory//
6782
.defaultReAgingRequest()//
@@ -70,12 +85,102 @@ public void createReAgingTransaction(DataTable table) throws IOException {
7085
.startDate(startDate)//
7186
.numberOfInstallments(numberOfInstallments);//
7287

88+
applyAdditionalFields(reAgingRequest, rowData, Set.of("frequencyNumber", "frequencyType", "startDate", "numberOfInstallments"));
89+
7390
Response<PostLoansLoanIdTransactionsResponse> response = loanTransactionsApi.executeLoanTransaction(loanId, reAgingRequest, "reAge")
7491
.execute();
7592
ErrorHelper.checkSuccessfulApiCall(response);
7693
testContext().set(TestContextKey.LOAN_REAGING_RESPONSE, response);
7794
}
7895

96+
private void applyAdditionalFields(PostLoansLoanIdTransactionsRequest request, Map<String, String> rowData, Set<String> excludedKeys) {
97+
rowData.forEach((key, value) -> {
98+
if (!excludedKeys.contains(key)) {
99+
setRequestField(request, key, value);
100+
}
101+
});
102+
}
103+
104+
private void setRequestField(PostLoansLoanIdTransactionsRequest request, String fieldName, String rawValue) {
105+
if (fieldName == null || fieldName.isBlank()) {
106+
return;
107+
}
108+
109+
try {
110+
Method targetMethod = Arrays.stream(PostLoansLoanIdTransactionsRequest.class.getMethods())
111+
.filter(method -> method.getParameterCount() == 1 && method.getName().equals(fieldName)).findFirst().orElse(null);
112+
113+
if (targetMethod == null) {
114+
log.warn("No setter method found on PostLoansLoanIdTransactionsRequest for field {}", fieldName);
115+
return;
116+
}
117+
118+
Class<?> parameterType = targetMethod.getParameterTypes()[0];
119+
Object convertedValue = convertValue(rawValue, parameterType);
120+
121+
if (convertedValue == null && parameterType.isPrimitive()) {
122+
log.warn("Cannot assign null to primitive field {} on PostLoansLoanIdTransactionsRequest", fieldName);
123+
return;
124+
}
125+
126+
targetMethod.invoke(request, convertedValue);
127+
} catch (Exception ex) {
128+
log.warn("Failed to set additional field {} on PostLoansLoanIdTransactionsRequest", fieldName, ex);
129+
}
130+
}
131+
132+
private Object convertValue(String rawValue, Class<?> targetType) {
133+
if (rawValue == null || rawValue.isBlank()) {
134+
return null;
135+
}
136+
137+
try {
138+
if (String.class.equals(targetType)) {
139+
return rawValue;
140+
}
141+
if (Integer.class.equals(targetType) || int.class.equals(targetType)) {
142+
return Integer.valueOf(rawValue);
143+
}
144+
if (Long.class.equals(targetType) || long.class.equals(targetType)) {
145+
return Long.valueOf(rawValue);
146+
}
147+
if (Double.class.equals(targetType) || double.class.equals(targetType)) {
148+
return Double.valueOf(rawValue);
149+
}
150+
if (Float.class.equals(targetType) || float.class.equals(targetType)) {
151+
return Float.valueOf(rawValue);
152+
}
153+
if (Short.class.equals(targetType) || short.class.equals(targetType)) {
154+
return Short.valueOf(rawValue);
155+
}
156+
if (Byte.class.equals(targetType) || byte.class.equals(targetType)) {
157+
return Byte.valueOf(rawValue);
158+
}
159+
if (Boolean.class.equals(targetType) || boolean.class.equals(targetType)) {
160+
return Boolean.parseBoolean(rawValue);
161+
}
162+
if (BigDecimal.class.equals(targetType)) {
163+
return new BigDecimal(rawValue);
164+
}
165+
} catch (NumberFormatException ex) {
166+
log.warn("Unable to convert value '{}' to type {}. Falling back to raw string.", rawValue, targetType.getSimpleName(), ex);
167+
return rawValue;
168+
}
169+
170+
return rawValue;
171+
}
172+
173+
private String resolveValue(Map<String, String> rowData, List<String> values, int index, String key) {
174+
String value = rowData.get(key);
175+
if (value != null) {
176+
return value;
177+
}
178+
if (index >= 0 && index < values.size()) {
179+
return values.get(index);
180+
}
181+
return null;
182+
}
183+
79184
@When("Admin creates a Loan re-aging transaction by Loan external ID with the following data:")
80185
public void createReAgingTransactionByLoanExternalId(DataTable table) throws IOException {
81186
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);

0 commit comments

Comments
 (0)