FINERACT-1724
Added batch support for the Get Charge by Id call. Added externalId field to PostLoansLoanIdChargesRequest. Added submittedOnDate column to m_loan_charge table. Updated logic to return new submittedOnDate field in GetLoansLoanIdChargesChargeIdResponse.
This commit is contained in:
committed by
Arnold Gálovics
parent
b33e3ac892
commit
388612b1ae
@@ -156,6 +156,7 @@ allprojects {
|
||||
"**/build.gradle.mustache",
|
||||
"**/pom.mustache",
|
||||
"**/avro/**/*.java",
|
||||
"**/org/apache/fineract/client/**/*.java"
|
||||
])
|
||||
strictCheck true
|
||||
}
|
||||
|
||||
+2
@@ -91,6 +91,8 @@ public class CommandStrategyProvider {
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/charges").method("POST").build(), "createChargeCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/charges").method("GET").build(),
|
||||
"collectChargesCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/charges\\/\\d+").method("GET").build(),
|
||||
"getChargeByIdCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/transactions\\?command=repayment").method("POST").build(),
|
||||
"createTransactionLoanCommandStrategy");
|
||||
this.commandStrategies.put(
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* 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.batch.command.internal;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.command.CommandStrategyUtils;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.api.MutableUriInfo;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanChargesApiResource;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} to retrieve a charge by id. It passes the contents of the body from the
|
||||
* BatchRequest to {@link LoanChargesApiResource} and gets back the response. This class will also catch any errors
|
||||
* raised by {@link LoanChargesApiResource} and map those errors to appropriate status codes in BatchResponse.
|
||||
*
|
||||
* @see CommandStrategy
|
||||
* @see BatchRequest
|
||||
* @see BatchResponse
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class GetChargeByIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanChargesApiResource loanChargesApiResource;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, UriInfo uriInfo) {
|
||||
final MutableUriInfo parameterizedUriInfo = new MutableUriInfo(uriInfo);
|
||||
|
||||
final BatchResponse response = new BatchResponse();
|
||||
final String responseBody;
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
final String relativeUrl = request.getRelativeUrl();
|
||||
|
||||
// Get the loan and charge ids for use in loanChargesApiResource
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrl);
|
||||
final Long loanId = Long.parseLong(pathParameters.get(1));
|
||||
Long chargeId;
|
||||
if (relativeUrl.indexOf('?') > 0) {
|
||||
chargeId = Long.parseLong(StringUtils.substringBeforeLast(pathParameters.get(3), "?"));
|
||||
} else {
|
||||
chargeId = Long.parseLong(pathParameters.get(3));
|
||||
}
|
||||
|
||||
Map<String, String> queryParameters;
|
||||
if (relativeUrl.indexOf('?') > 0) {
|
||||
queryParameters = CommandStrategyUtils.getQueryParameters(relativeUrl);
|
||||
|
||||
// Add the query parameters sent in the relative URL to UriInfo
|
||||
CommandStrategyUtils.addQueryParametersToUriInfo(parameterizedUriInfo, queryParameters);
|
||||
}
|
||||
|
||||
responseBody = loanChargesApiResource.retrieveLoanCharge(loanId, chargeId, parameterizedUriInfo);
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
response.setBody(responseBody);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+5
@@ -19,6 +19,7 @@
|
||||
package org.apache.fineract.portfolio.loanaccount.api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -102,6 +103,8 @@ final class LoanChargesApiResourceSwagger {
|
||||
public Double amountOrPercentage;
|
||||
@Schema(example = "false")
|
||||
public Boolean penalty;
|
||||
@Schema(example = "27 March 2013")
|
||||
public LocalDate submittedOnDate;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoansLoanIdChargesTemplateResponse")
|
||||
@@ -179,6 +182,8 @@ final class LoanChargesApiResourceSwagger {
|
||||
public String dateFormat;
|
||||
@Schema(example = "29 April 2013")
|
||||
public String dueDate;
|
||||
@Schema(example = "786444UUUYYH7")
|
||||
public String externalId;
|
||||
}
|
||||
|
||||
@Schema(description = " PostLoansLoanIdChargesResponse")
|
||||
|
||||
+14
-4
@@ -39,6 +39,8 @@ public class LoanChargeData {
|
||||
private final String name;
|
||||
private final EnumOptionData chargeTimeType;
|
||||
|
||||
private final LocalDate submittedOnDate;
|
||||
|
||||
private final LocalDate dueDate;
|
||||
|
||||
private final EnumOptionData chargeCalculationType;
|
||||
@@ -103,10 +105,10 @@ public class LoanChargeData {
|
||||
|
||||
public LoanChargeData(final Long id, final Long chargeId, final String name, final CurrencyData currency, final BigDecimal amount,
|
||||
final BigDecimal amountPaid, final BigDecimal amountWaived, final BigDecimal amountWrittenOff,
|
||||
final BigDecimal amountOutstanding, final EnumOptionData chargeTimeType, final LocalDate dueDate,
|
||||
final EnumOptionData chargeCalculationType, final BigDecimal percentage, final BigDecimal amountPercentageAppliedTo,
|
||||
final boolean penalty, final EnumOptionData chargePaymentMode, final boolean paid, final boolean waived, final Long loanId,
|
||||
final BigDecimal minCap, final BigDecimal maxCap, final BigDecimal amountOrPercentage,
|
||||
final BigDecimal amountOutstanding, final EnumOptionData chargeTimeType, final LocalDate submittedOnDate,
|
||||
final LocalDate dueDate, final EnumOptionData chargeCalculationType, final BigDecimal percentage,
|
||||
final BigDecimal amountPercentageAppliedTo, final boolean penalty, final EnumOptionData chargePaymentMode, final boolean paid,
|
||||
final boolean waived, final Long loanId, final BigDecimal minCap, final BigDecimal maxCap, final BigDecimal amountOrPercentage,
|
||||
Collection<LoanInstallmentChargeData> installmentChargeData, final String externalId) {
|
||||
this.id = id;
|
||||
this.chargeId = chargeId;
|
||||
@@ -118,6 +120,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = amountWrittenOff;
|
||||
this.amountOutstanding = amountOutstanding;
|
||||
this.chargeTimeType = chargeTimeType;
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
this.dueDate = dueDate;
|
||||
this.chargeCalculationType = chargeCalculationType;
|
||||
this.percentage = percentage;
|
||||
@@ -162,6 +165,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = BigDecimal.ZERO;
|
||||
this.amountOutstanding = amount;
|
||||
this.chargeTimeType = chargeTimeType;
|
||||
this.submittedOnDate = null;
|
||||
this.dueDate = null;
|
||||
this.chargeCalculationType = chargeCalculationType;
|
||||
this.percentage = percentage;
|
||||
@@ -203,6 +207,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = null;
|
||||
this.amountOutstanding = amountOutstanding;
|
||||
this.chargeTimeType = chargeTimeType;
|
||||
this.submittedOnDate = null;
|
||||
this.dueDate = dueAsOfDate;
|
||||
this.chargeCalculationType = null;
|
||||
this.percentage = null;
|
||||
@@ -234,6 +239,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = null;
|
||||
this.amountOutstanding = null;
|
||||
this.chargeTimeType = chargeTimeType;
|
||||
this.submittedOnDate = null;
|
||||
this.dueDate = dueAsOfDate;
|
||||
this.chargeCalculationType = null;
|
||||
this.percentage = null;
|
||||
@@ -264,6 +270,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = null;
|
||||
this.amountOutstanding = null;
|
||||
this.chargeTimeType = chargeData.chargeTimeType;
|
||||
this.submittedOnDate = chargeData.submittedOnDate;
|
||||
this.dueDate = chargeData.dueDate;
|
||||
this.chargeCalculationType = null;
|
||||
this.percentage = null;
|
||||
@@ -294,6 +301,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = chargeData.amountWrittenOff;
|
||||
this.amountOutstanding = chargeData.amountOutstanding;
|
||||
this.chargeTimeType = chargeData.chargeTimeType;
|
||||
this.submittedOnDate = chargeData.submittedOnDate;
|
||||
this.dueDate = chargeData.dueDate;
|
||||
this.chargeCalculationType = chargeData.chargeCalculationType;
|
||||
this.percentage = chargeData.percentage;
|
||||
@@ -326,6 +334,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = null;
|
||||
this.amountOutstanding = null;
|
||||
this.chargeTimeType = chargeTimeType;
|
||||
this.submittedOnDate = null;
|
||||
this.dueDate = dueAsOfDate;
|
||||
this.chargeCalculationType = chargeCalculationType;
|
||||
this.percentage = null;
|
||||
@@ -356,6 +365,7 @@ public class LoanChargeData {
|
||||
this.amountWrittenOff = null;
|
||||
this.amountOutstanding = null;
|
||||
this.chargeTimeType = null;
|
||||
this.submittedOnDate = null;
|
||||
this.dueDate = dueAsOfDate;
|
||||
this.chargeCalculationType = null;
|
||||
this.percentage = null;
|
||||
|
||||
+9
@@ -42,6 +42,7 @@ import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
@@ -68,6 +69,9 @@ public class LoanCharge extends AbstractPersistableCustom {
|
||||
@Column(name = "charge_time_enum", nullable = false)
|
||||
private Integer chargeTime;
|
||||
|
||||
@Column(name = "submitted_on_date", nullable = true)
|
||||
private LocalDate submittedOnDate;
|
||||
|
||||
@Column(name = "due_for_collection_as_of_date")
|
||||
private LocalDate dueDate;
|
||||
|
||||
@@ -229,6 +233,7 @@ public class LoanCharge extends AbstractPersistableCustom {
|
||||
final ChargePaymentMode chargePaymentMode, final Integer numberOfRepayments, final BigDecimal loanCharge) {
|
||||
this.loan = loan;
|
||||
this.charge = chargeDefinition;
|
||||
this.submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||
this.penaltyCharge = chargeDefinition.isPenalty();
|
||||
this.minCap = chargeDefinition.getMinCap();
|
||||
this.maxCap = chargeDefinition.getMaxCap();
|
||||
@@ -597,6 +602,10 @@ public class LoanCharge extends AbstractPersistableCustom {
|
||||
return this.dueDate;
|
||||
}
|
||||
|
||||
public LocalDate getSubmittedOnDate() {
|
||||
return submittedOnDate;
|
||||
}
|
||||
|
||||
private boolean determineIfFullyPaid() {
|
||||
if (this.amount == null) {
|
||||
return true;
|
||||
|
||||
+5
-4
@@ -59,8 +59,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
||||
private static final class LoanChargeMapper implements RowMapper<LoanChargeData> {
|
||||
|
||||
public String schema() {
|
||||
return "lc.id as id, lc.external_id as externalId, c.id as chargeId, c.name as name, " + "lc.amount as amountDue, "
|
||||
+ "lc.amount_paid_derived as amountPaid, " + "lc.amount_waived_derived as amountWaived, "
|
||||
return "lc.id as id, lc.external_id as externalId, c.id as chargeId, c.name as name, lc.submitted_on_date as submittedOnDate, "
|
||||
+ "lc.amount as amountDue, " + "lc.amount_paid_derived as amountPaid, " + "lc.amount_waived_derived as amountWaived, "
|
||||
+ "lc.amount_writtenoff_derived as amountWrittenOff, " + "lc.amount_outstanding_derived as amountOutstanding, "
|
||||
+ "lc.calculation_percentage as percentageOf, lc.calculation_on_amount as amountPercentageAppliedTo, "
|
||||
+ "lc.charge_time_enum as chargeTime, " + "lc.is_penalty as penalty, "
|
||||
@@ -116,6 +116,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
||||
final BigDecimal maxCap = rs.getBigDecimal("maxCap");
|
||||
final BigDecimal amountOrPercentage = rs.getBigDecimal("amountOrPercentage");
|
||||
final LocalDate disbursementDate = JdbcSupport.getLocalDate(rs, "disbursementDate");
|
||||
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
|
||||
|
||||
if (disbursementDate != null) {
|
||||
dueAsOfDate = disbursementDate;
|
||||
@@ -123,8 +124,8 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
|
||||
final String externalId = rs.getString("externalId");
|
||||
|
||||
return new LoanChargeData(id, chargeId, name, currency, amount, amountPaid, amountWaived, amountWrittenOff, amountOutstanding,
|
||||
chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty, paymentMode, paid,
|
||||
waived, null, minCap, maxCap, amountOrPercentage, null, externalId);
|
||||
chargeTimeType, submittedOnDate, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty,
|
||||
paymentMode, paid, waived, null, minCap, maxCap, amountOrPercentage, null, externalId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -526,7 +526,8 @@ public final class LoanProductDataValidator {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName)
|
||||
.value(fixedPrincipalPercentagePerInstallment).notLessThanMin(BigDecimal.ONE).notGreaterThanMax(BigDecimal.valueOf(100));
|
||||
|
||||
if (!amortizationType.equals(AmortizationMethod.EQUAL_PRINCIPAL.getValue()) && fixedPrincipalPercentagePerInstallment != null) {
|
||||
if (amortizationType != null && !amortizationType.equals(AmortizationMethod.EQUAL_PRINCIPAL.getValue())
|
||||
&& fixedPrincipalPercentagePerInstallment != null) {
|
||||
baseDataValidator.reset().parameter(LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName).failWithCode(
|
||||
"not.supported.principal.fixing.not.allowed.with.equal.installments",
|
||||
"Principal fixing cannot be done with equal installment amortization");
|
||||
|
||||
@@ -74,4 +74,5 @@
|
||||
<include file="parts/0052_loan_transaction_chargeback.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0053_add_external_events_purge_job.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0054_additional_fields_loan_repayment_schedule.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0055_add_submitted_on_date_to_loan_charge.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
<changeSet author="fineract" id="1">
|
||||
<addColumn tableName="m_loan_charge">
|
||||
<column name="submitted_on_date" type="date">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+5
-1
@@ -36,6 +36,7 @@ import org.apache.fineract.batch.command.internal.CreateClientCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.CreateLoanRescheduleRequestCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.CreateTransactionLoanCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.GetChargeByIdCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.GetDatatableEntryByAppTableIdCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.GetLoanByIdCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.GetTransactionByIdCommandStrategy;
|
||||
@@ -69,6 +70,8 @@ public class CommandStrategyProviderTest {
|
||||
Arguments.of("loans/123/charges", HttpMethod.POST, "createChargeCommandStrategy", mock(CreateChargeCommandStrategy.class)),
|
||||
Arguments.of("loans/123/charges", HttpMethod.GET, "collectChargesCommandStrategy",
|
||||
mock(CollectChargesCommandStrategy.class)),
|
||||
Arguments.of("loans/123/charges/123", HttpMethod.GET, "getChargeByIdCommandStrategy",
|
||||
mock(GetChargeByIdCommandStrategy.class)),
|
||||
Arguments.of("loans/123/transactions?command=repayment", HttpMethod.POST, "createTransactionLoanCommandStrategy",
|
||||
mock(CreateTransactionLoanCommandStrategy.class)),
|
||||
Arguments.of("loans/123/transactions?command=creditBalanceRefund", HttpMethod.POST, "createTransactionLoanCommandStrategy",
|
||||
@@ -130,7 +133,8 @@ public class CommandStrategyProviderTest {
|
||||
private static Stream<Arguments> provideCommandStrategyResourceDetailsForErrors() {
|
||||
return Stream.of(Arguments.of("loans/123?command=reject", HttpMethod.POST),
|
||||
Arguments.of("loans/glimAccount/746?command=approve", HttpMethod.POST), Arguments.of("loans/123", HttpMethod.PUT),
|
||||
Arguments.of("datatables/test_dt_table", HttpMethod.GET), Arguments.of("datatables", HttpMethod.GET));
|
||||
Arguments.of("datatables/test_dt_table", HttpMethod.GET), Arguments.of("datatables", HttpMethod.GET),
|
||||
Arguments.of("loans//charges/123", HttpMethod.GET), Arguments.of("loans/123/charges/", HttpMethod.GET));
|
||||
|
||||
}
|
||||
|
||||
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* 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.batch.command.internal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.api.MutableUriInfo;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanChargesApiResource;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* The {@link GetChargeByIdCommandStrategy} test class.
|
||||
*/
|
||||
public class GetChargeByIdCommandStrategyTest {
|
||||
|
||||
/**
|
||||
* Query parameter provider.
|
||||
*
|
||||
* @return the test data stream
|
||||
*/
|
||||
private static Stream<Arguments> provideQueryParameters() {
|
||||
return Stream.of(Arguments.of(null, 0), Arguments.of("fields=name,amountOrPercentage", 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link GetChargeByIdCommandStrategy#execute} happy path scenario.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideQueryParameters")
|
||||
public void testExecuteSuccessScenario(final String queryParameter, final int numberOfQueryParams) {
|
||||
final TestContext testContext = new TestContext();
|
||||
|
||||
final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final Long chargeId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final BatchRequest request = getBatchRequest(loanId, chargeId, queryParameter);
|
||||
final String responseBody = "someResponseBody";
|
||||
|
||||
given(testContext.loanChargesApiResource.retrieveLoanCharge(eq(loanId), eq(chargeId), any(UriInfo.class))).willReturn(responseBody);
|
||||
|
||||
final BatchResponse response = testContext.subjectToTest.execute(request, testContext.uriInfo);
|
||||
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.SC_OK);
|
||||
assertThat(response.getRequestId()).isEqualTo(request.getRequestId());
|
||||
assertThat(response.getHeaders()).isEqualTo(request.getHeaders());
|
||||
assertThat(response.getBody()).isEqualTo(responseBody);
|
||||
|
||||
verify(testContext.loanChargesApiResource).retrieveLoanCharge(eq(loanId), eq(chargeId), testContext.uriInfoCaptor.capture());
|
||||
MutableUriInfo mutableUriInfo = testContext.uriInfoCaptor.getValue();
|
||||
assertThat(mutableUriInfo.getAdditionalQueryParameters()).hasSize(numberOfQueryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a request with the given loan id and charge id.
|
||||
*
|
||||
* @param loanId
|
||||
* the loan id
|
||||
* @param chargeId
|
||||
* the charge id
|
||||
* @param queryParameter
|
||||
* the query parameter
|
||||
* @return BatchRequest
|
||||
*/
|
||||
private BatchRequest getBatchRequest(final Long loanId, final Long chargeId, final String queryParameter) {
|
||||
final BatchRequest br = new BatchRequest();
|
||||
String relativeUrl = "loans/" + loanId + "/charges/" + chargeId;
|
||||
|
||||
if (queryParameter != null) {
|
||||
relativeUrl = relativeUrl + "?" + queryParameter;
|
||||
}
|
||||
|
||||
br.setRequestId(Long.valueOf(RandomStringUtils.randomNumeric(5)));
|
||||
br.setRelativeUrl(relativeUrl);
|
||||
br.setMethod(HttpMethod.GET);
|
||||
br.setReference(Long.valueOf(RandomStringUtils.randomNumeric(5)));
|
||||
br.setBody("{}");
|
||||
|
||||
return br;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private test context class used since testng runs in parallel to avoid state between tests
|
||||
*/
|
||||
private static class TestContext {
|
||||
|
||||
/**
|
||||
* The subject to test
|
||||
*/
|
||||
private final GetChargeByIdCommandStrategy subjectToTest;
|
||||
|
||||
/**
|
||||
* The mock uri info
|
||||
*/
|
||||
@Mock
|
||||
private UriInfo uriInfo;
|
||||
|
||||
/**
|
||||
* The mock {@link LoanChargesApiResource} object.
|
||||
*/
|
||||
@Mock
|
||||
private LoanChargesApiResource loanChargesApiResource;
|
||||
|
||||
/**
|
||||
* The uri info captor
|
||||
*/
|
||||
@Captor
|
||||
private ArgumentCaptor<MutableUriInfo> uriInfoCaptor;
|
||||
|
||||
/**
|
||||
* Test Context constructor
|
||||
*/
|
||||
TestContext() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
subjectToTest = new GetChargeByIdCommandStrategy(loanChargesApiResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
+65
@@ -34,6 +34,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.fineract.batch.command.internal.AdjustTransactionCommandStrategy;
|
||||
import org.apache.fineract.batch.command.internal.CreateTransactionLoanCommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
@@ -43,6 +44,7 @@ import org.apache.fineract.integrationtests.common.BatchHelper;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
|
||||
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
|
||||
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
|
||||
@@ -377,6 +379,69 @@ public class BatchApiTest {
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, (long) response.get(3).getStatusCode(), "Verify Status Code 200 for Create Loan Charge");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a new charge was added to a newly created loan and charges are Collected properly 200(OK) status was
|
||||
* returned for successful responses. It first creates a new client and apply a loan, then creates a new charge for
|
||||
* the create loan and then fetches all the applied charges
|
||||
*
|
||||
* @see org.apache.fineract.batch.command.internal.CollectChargesCommandStrategy
|
||||
* @see org.apache.fineract.batch.command.internal.CreateChargeCommandStrategy
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnOkStatusForCreateAndGetChargeByIdCommand() {
|
||||
final String loanProductJSON = new LoanProductTestBuilder() //
|
||||
.withPrincipal("1000.00") //
|
||||
.withNumberOfRepayments("24") //
|
||||
.withRepaymentAfterEvery("1") //
|
||||
.withRepaymentTypeAsMonth() //
|
||||
.withinterestRatePerPeriod("2") //
|
||||
.withInterestRateFrequencyTypeAsMonths() //
|
||||
.withAmortizationTypeAsEqualPrincipalPayment() //
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.currencyDetails("0", "100").build(null);
|
||||
|
||||
final Long applyLoanRequestId = Long.valueOf(RandomStringUtils.randomNumeric(4));
|
||||
final Long approveLoanRequestId = applyLoanRequestId + 1;
|
||||
final Long disburseLoanRequestId = approveLoanRequestId + 1;
|
||||
final Long createChargeRequestId = disburseLoanRequestId + 1;
|
||||
final Long getChargeByIdRequestId = createChargeRequestId + 1;
|
||||
|
||||
// Create product
|
||||
final Integer productId = new LoanTransactionHelper(this.requestSpec, this.responseSpec).getLoanProductId(loanProductJSON);
|
||||
|
||||
// Create client
|
||||
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
|
||||
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientId);
|
||||
|
||||
// Create charge object and get id
|
||||
final Integer chargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
|
||||
ChargesHelper.getLoanSpecifiedDueDateJSON());
|
||||
|
||||
final BatchRequest applyLoanRequest = BatchHelper.applyLoanRequestWithClientId(applyLoanRequestId, clientId, productId);
|
||||
|
||||
final BatchRequest approveLoanRequest = BatchHelper.approveLoanRequest(approveLoanRequestId, applyLoanRequestId);
|
||||
|
||||
final BatchRequest disburseLoanRequest = BatchHelper.disburseLoanRequest(disburseLoanRequestId, approveLoanRequestId);
|
||||
|
||||
final BatchRequest createChargeRequest = BatchHelper.createChargeRequest(createChargeRequestId, disburseLoanRequestId, chargeId);
|
||||
|
||||
final BatchRequest getChargeByIdRequest = BatchHelper.getChargeByIdCommandStrategy(getChargeByIdRequestId, createChargeRequestId);
|
||||
|
||||
// Create batch requests list
|
||||
final List<BatchRequest> batchRequests = Arrays.asList(applyLoanRequest, approveLoanRequest, disburseLoanRequest,
|
||||
createChargeRequest, getChargeByIdRequest);
|
||||
|
||||
// Create batch responses list
|
||||
final List<BatchResponse> responses = BatchHelper.postBatchRequestsWithoutEnclosingTransaction(this.requestSpec, this.responseSpec,
|
||||
BatchHelper.toJsonString(batchRequests));
|
||||
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, responses.get(0).getStatusCode(), "Verify Status Code 200 for Apply Loan");
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, responses.get(1).getStatusCode(), "Verify Status Code 200 for Approve Loan");
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, responses.get(2).getStatusCode(), "Verify Status Code 200 for Disburse Loan");
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, responses.get(3).getStatusCode(), "Verify Status Code 200 for Create Charge");
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, responses.get(4).getStatusCode(), "Verify Status Code 200 for Get Charge By Id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that batch repayment for loans is happening properly. Collected properly 200(OK) status was returned for
|
||||
* successful responses. It first creates a new loan and then makes two repayments for it and then verifies that
|
||||
|
||||
+35
-3
@@ -349,10 +349,14 @@ public final class BatchHelper {
|
||||
* given requestId and reference
|
||||
*
|
||||
* @param requestId
|
||||
* the batch request id.
|
||||
* @param reference
|
||||
* the reference id.
|
||||
* @param chargeId
|
||||
* the charge id used for getting charge type.
|
||||
* @return BatchRequest
|
||||
*/
|
||||
public static BatchRequest createChargeRequest(final Long requestId, final Long reference) {
|
||||
public static BatchRequest createChargeRequest(final Long requestId, final Long reference, final Integer chargeId) {
|
||||
|
||||
final BatchRequest br = new BatchRequest();
|
||||
br.setRequestId(requestId);
|
||||
@@ -360,8 +364,12 @@ public final class BatchHelper {
|
||||
br.setMethod("POST");
|
||||
br.setReference(reference);
|
||||
|
||||
final String body = "{\"chargeId\": \"2\", \"locale\": \"en\", \"amount\": \"100\", "
|
||||
+ "\"dateFormat\": \"dd MMMM yyyy\", \"dueDate\": \"29 April 2013\"}";
|
||||
final String dateFormat = "dd MMMM yyyy";
|
||||
final String dateString = LocalDate.now(Utils.getZoneIdOfTenant()).format(DateTimeFormatter.ofPattern(dateFormat));
|
||||
|
||||
final String body = String.format(
|
||||
"{\"chargeId\": \"%d\", \"locale\": \"en\", \"amount\": \"11.15\", " + "\"dateFormat\": \"%s\", \"dueDate\": \"%s\"}",
|
||||
chargeId, dateFormat, dateString);
|
||||
br.setBody(body);
|
||||
|
||||
return br;
|
||||
@@ -388,6 +396,30 @@ public final class BatchHelper {
|
||||
return br;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a {@link org.apache.fineract.batch.command.internal.GetChargeByIdCommandStrategy} request
|
||||
* with given requestId and reference.
|
||||
*
|
||||
* @param requestId
|
||||
* the request id
|
||||
* @param reference
|
||||
* the reference
|
||||
* @return the {@link BatchRequest}
|
||||
*/
|
||||
public static BatchRequest getChargeByIdCommandStrategy(final Long requestId, final Long reference) {
|
||||
|
||||
final BatchRequest br = new BatchRequest();
|
||||
String relativeUrl = "loans/$.loanId/charges/$.resourceId";
|
||||
|
||||
br.setRequestId(requestId);
|
||||
br.setRelativeUrl(relativeUrl);
|
||||
br.setMethod(HttpMethod.GET);
|
||||
br.setReference(reference);
|
||||
br.setBody("{}");
|
||||
|
||||
return br;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a {@link org.apache.fineract.batch.command.internal.ActivateClientCommandStrategy} Request
|
||||
* with given requestId and reference.
|
||||
|
||||
Reference in New Issue
Block a user