| /** |
| * 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.test.stepdef.loan; |
| |
| import static org.apache.fineract.test.data.TransactionProcessingStrategyCode.ADVANCED_PAYMENT_ALLOCATION; |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.awaitility.Awaitility.await; |
| |
| import com.google.gson.Gson; |
| import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; |
| import io.cucumber.datatable.DataTable; |
| import io.cucumber.java.en.And; |
| import io.cucumber.java.en.Then; |
| import io.cucumber.java.en.When; |
| import java.io.IOException; |
| import java.math.BigDecimal; |
| import java.math.RoundingMode; |
| import java.time.Duration; |
| import java.time.LocalDate; |
| import java.time.format.DateTimeFormatter; |
| import java.util.ArrayList; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.UUID; |
| import java.util.concurrent.TimeUnit; |
| import java.util.stream.Collectors; |
| import lombok.extern.slf4j.Slf4j; |
| import org.apache.fineract.avro.loan.v1.LoanAccountDataV1; |
| import org.apache.fineract.avro.loan.v1.LoanChargePaidByDataV1; |
| import org.apache.fineract.avro.loan.v1.LoanStatusEnumDataV1; |
| import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1; |
| import org.apache.fineract.client.models.AdvancedPaymentData; |
| import org.apache.fineract.client.models.DeleteLoansLoanIdResponse; |
| import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; |
| import org.apache.fineract.client.models.GetLoansLoanIdDelinquencySummary; |
| import org.apache.fineract.client.models.GetLoansLoanIdLoanChargeData; |
| import org.apache.fineract.client.models.GetLoansLoanIdLoanChargePaidByData; |
| import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod; |
| import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule; |
| import org.apache.fineract.client.models.GetLoansLoanIdResponse; |
| import org.apache.fineract.client.models.GetLoansLoanIdTimeline; |
| import org.apache.fineract.client.models.GetLoansLoanIdTransactions; |
| import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse; |
| import org.apache.fineract.client.models.IsCatchUpRunningResponse; |
| import org.apache.fineract.client.models.PostClientsResponse; |
| import org.apache.fineract.client.models.PostLoansLoanIdRequest; |
| import org.apache.fineract.client.models.PostLoansLoanIdResponse; |
| import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest; |
| import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse; |
| import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest; |
| import org.apache.fineract.client.models.PostLoansRequest; |
| import org.apache.fineract.client.models.PostLoansResponse; |
| import org.apache.fineract.client.models.PutLoanProductsProductIdRequest; |
| import org.apache.fineract.client.models.PutLoanProductsProductIdResponse; |
| import org.apache.fineract.client.models.PutLoansLoanIdRequest; |
| import org.apache.fineract.client.models.PutLoansLoanIdResponse; |
| import org.apache.fineract.client.services.LoanCobCatchUpApi; |
| import org.apache.fineract.client.services.LoanProductsApi; |
| import org.apache.fineract.client.services.LoanTransactionsApi; |
| import org.apache.fineract.client.services.LoansApi; |
| import org.apache.fineract.client.util.JSON; |
| import org.apache.fineract.test.data.AmortizationType; |
| import org.apache.fineract.test.data.InterestCalculationPeriodTime; |
| import org.apache.fineract.test.data.InterestType; |
| import org.apache.fineract.test.data.LoanStatus; |
| import org.apache.fineract.test.data.LoanTermFrequencyType; |
| import org.apache.fineract.test.data.RepaymentFrequencyType; |
| import org.apache.fineract.test.data.TransactionProcessingStrategyCode; |
| import org.apache.fineract.test.data.TransactionType; |
| import org.apache.fineract.test.data.loanproduct.DefaultLoanProduct; |
| import org.apache.fineract.test.data.loanproduct.LoanProductResolver; |
| import org.apache.fineract.test.data.paymenttype.DefaultPaymentType; |
| import org.apache.fineract.test.data.paymenttype.PaymentTypeResolver; |
| import org.apache.fineract.test.factory.LoanRequestFactory; |
| import org.apache.fineract.test.helper.ErrorHelper; |
| import org.apache.fineract.test.helper.ErrorMessageHelper; |
| import org.apache.fineract.test.helper.ErrorResponse; |
| import org.apache.fineract.test.helper.Utils; |
| import org.apache.fineract.test.initializer.global.LoanProductGlobalInitializerStep; |
| import org.apache.fineract.test.messaging.EventAssertion; |
| import org.apache.fineract.test.messaging.event.EventCheckHelper; |
| import org.apache.fineract.test.messaging.event.loan.LoanStatusChangedEvent; |
| import org.apache.fineract.test.messaging.event.loan.transaction.LoanAccrualTransactionCreatedBusinessEvent; |
| import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffEvent; |
| import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffUndoEvent; |
| import org.apache.fineract.test.stepdef.AbstractStepDef; |
| import org.apache.fineract.test.support.TestContextKey; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import retrofit2.Response; |
| |
| @Slf4j |
| public class LoanStepDef extends AbstractStepDef { |
| |
| public static final String DATE_FORMAT = "dd MMMM yyyy"; |
| public static final String DATE_FORMAT_EVENTS = "yyyy-MM-dd"; |
| public static final String DEFAULT_LOCALE = "en"; |
| public static final String LOAN_STATE_SUBMITTED_AND_PENDING = "Submitted and pending approval"; |
| public static final String LOAN_STATE_APPROVED = "Approved"; |
| public static final String LOAN_STATE_ACTIVE = "Active"; |
| private static final Gson GSON = new JSON().getGson(); |
| private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT); |
| private static final DateTimeFormatter FORMATTER_EVENTS = DateTimeFormatter.ofPattern(DATE_FORMAT_EVENTS); |
| |
| @Autowired |
| private LoansApi loansApi; |
| |
| @Autowired |
| private LoanCobCatchUpApi loanCobCatchUpApi; |
| |
| @Autowired |
| private LoanTransactionsApi loanTransactionsApi; |
| |
| @Autowired |
| private EventAssertion eventAssertion; |
| |
| @Autowired |
| private PaymentTypeResolver paymentTypeResolver; |
| |
| @Autowired |
| private LoanProductResolver loanProductResolver; |
| |
| @Autowired |
| private LoanRequestFactory loanRequestFactory; |
| |
| @Autowired |
| private EventCheckHelper eventCheckHelper; |
| |
| @Autowired |
| private LoanProductsApi loanProductsApi; |
| |
| @When("Admin creates a new Loan") |
| public void createLoan() throws IOException { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId); |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| |
| eventCheckHelper.createLoanEventCheck(response); |
| } |
| |
| @When("Admin creates a new default Loan with date: {string}") |
| public void createLoanWithDate(String date) throws IOException { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId).submittedOnDate(date) |
| .expectedDisbursementDate(date); |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| |
| eventCheckHelper.createLoanEventCheck(response); |
| } |
| |
| @When("Admin crates a second default loan with date: {string}") |
| public void createSecondLoanWithDate(String date) throws IOException { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId).submittedOnDate(date) |
| .expectedDisbursementDate(date); |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_SECOND_LOAN_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| |
| eventCheckHelper.createLoanEventCheck(response); |
| } |
| |
| @When("Admin crates a second default loan for the second client with date: {string}") |
| public void createSecondLoanForSecondClientWithDate(String date) throws IOException { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_SECOND_CLIENT_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId).submittedOnDate(date) |
| .expectedDisbursementDate(date); |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_SECOND_LOAN_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| |
| eventCheckHelper.createLoanEventCheck(response); |
| } |
| |
| /** |
| * Use this where inline COB run needed - this way we don't have to run inline COB for all 30 days of loan term, but |
| * only 1 day |
| */ |
| @When("Admin creates a new Loan with date: {string} and with 1 day loan term and repayment") |
| public void createLoanWithDateShortTerm(String date) throws IOException { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId)// |
| .submittedOnDate(date)// |
| .expectedDisbursementDate(date)// |
| .loanTermFrequency(1)// |
| .repaymentEvery(1);// |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| } |
| |
| @When("Customer makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount and self-generated Idempotency key") |
| public void createTransactionWithIdempotencyKey(String transactionTypeInput, String transactionPaymentType, String transactionDate, |
| double transactionAmount) throws IOException { |
| createTransactionWithIdempotencyKeyAndExternalOwnerCheck(transactionTypeInput, transactionPaymentType, transactionDate, |
| transactionAmount, null); |
| } |
| |
| @When("Customer makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount and self-generated Idempotency key and check external owner") |
| public void createTransactionWithIdempotencyKeyAndWithExternalOwner(String transactionTypeInput, String transactionPaymentType, |
| String transactionDate, double transactionAmount) throws IOException { |
| String transferExternalOwnerId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID); |
| createTransactionWithIdempotencyKeyAndExternalOwnerCheck(transactionTypeInput, transactionPaymentType, transactionDate, |
| transactionAmount, transferExternalOwnerId); |
| } |
| |
| private void createTransactionWithIdempotencyKeyAndExternalOwnerCheck(String transactionTypeInput, String transactionPaymentType, |
| String transactionDate, double transactionAmount, String externalOwnerId) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| TransactionType transactionType = TransactionType.valueOf(transactionTypeInput); |
| String transactionTypeValue = transactionType.getValue(); |
| DefaultPaymentType paymentType = DefaultPaymentType.valueOf(transactionPaymentType); |
| Long paymentTypeValue = paymentTypeResolver.resolve(paymentType); |
| |
| PostLoansLoanIdTransactionsRequest paymentTransactionRequest = LoanRequestFactory.defaultPaymentTransactionRequest() |
| .transactionDate(transactionDate).transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue); |
| |
| Map<String, String> headerMap = new HashMap<>(); |
| String idempotencyKey = UUID.randomUUID().toString(); |
| testContext().set(TestContextKey.TRANSACTION_IDEMPOTENCY_KEY, idempotencyKey); |
| headerMap.put("Idempotency-Key", idempotencyKey); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, paymentTransactionRequest, transactionTypeValue, headerMap).execute(); |
| testContext().set(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE, paymentTransactionResponse); |
| ErrorHelper.checkSuccessfulApiCall(paymentTransactionResponse); |
| |
| eventCheckHelper.transactionEventCheck(paymentTransactionResponse, transactionType, externalOwnerId); |
| } |
| |
| @When("Admin makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount") |
| public void createTransactionForRefund(String transactionTypeInput, String transactionPaymentType, String transactionDate, |
| double transactionAmount) throws IOException, InterruptedException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| TransactionType transactionType = TransactionType.valueOf(transactionTypeInput); |
| String transactionTypeValue = transactionType.getValue(); |
| DefaultPaymentType paymentType = DefaultPaymentType.valueOf(transactionPaymentType); |
| Long paymentTypeValue = paymentTypeResolver.resolve(paymentType); |
| |
| PostLoansLoanIdTransactionsRequest paymentTransactionRequest = LoanRequestFactory.defaultPaymentTransactionRequest() |
| .transactionDate(transactionDate).transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, paymentTransactionRequest, transactionTypeValue).execute(); |
| testContext().set(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE, paymentTransactionResponse); |
| ErrorHelper.checkSuccessfulApiCall(paymentTransactionResponse); |
| |
| eventCheckHelper.transactionEventCheck(paymentTransactionResponse, transactionType, null); |
| } |
| |
| @When("Customer makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount and system-generated Idempotency key") |
| public void createTransactionWithAutoIdempotencyKey(String transactionTypeInput, String transactionPaymentType, String transactionDate, |
| double transactionAmount) throws IOException { |
| createTransactionWithAutoIdempotencyKeyAndWithExternalOwner(transactionTypeInput, transactionPaymentType, transactionDate, |
| transactionAmount, null); |
| } |
| |
| @When("Customer makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount and system-generated Idempotency key and check external owner") |
| public void createTransactionWithAutoIdempotencyKeyWithExternalOwner(String transactionTypeInput, String transactionPaymentType, |
| String transactionDate, double transactionAmount) throws IOException { |
| String transferExternalOwnerId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID); |
| createTransactionWithAutoIdempotencyKeyAndWithExternalOwner(transactionTypeInput, transactionPaymentType, transactionDate, |
| transactionAmount, transferExternalOwnerId); |
| } |
| |
| private void createTransactionWithAutoIdempotencyKeyAndWithExternalOwner(String transactionTypeInput, String transactionPaymentType, |
| String transactionDate, double transactionAmount, String externalOwnerId) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| TransactionType transactionType = TransactionType.valueOf(transactionTypeInput); |
| String transactionTypeValue = transactionType.getValue(); |
| DefaultPaymentType paymentType = DefaultPaymentType.valueOf(transactionPaymentType); |
| Long paymentTypeValue = paymentTypeResolver.resolve(paymentType); |
| |
| PostLoansLoanIdTransactionsRequest paymentTransactionRequest = LoanRequestFactory.defaultPaymentTransactionRequest() |
| .transactionDate(transactionDate).transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, paymentTransactionRequest, transactionTypeValue).execute(); |
| testContext().set(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE, paymentTransactionResponse); |
| testContext().set(TestContextKey.LOAN_REPAYMENT_RESPONSE, paymentTransactionResponse); |
| ErrorHelper.checkSuccessfulApiCall(paymentTransactionResponse); |
| |
| eventCheckHelper.transactionEventCheck(paymentTransactionResponse, transactionType, externalOwnerId); |
| } |
| |
| @When("Admin makes Credit Balance Refund transaction on {string} with {double} EUR transaction amount") |
| public void createCBR(String transactionDate, double transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| String transactionTypeValue = "creditBalanceRefund"; |
| |
| PostLoansLoanIdTransactionsRequest paymentTransactionRequest = LoanRequestFactory.defaultPaymentTransactionRequest() |
| .transactionDate(transactionDate).transactionAmount(transactionAmount); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, paymentTransactionRequest, transactionTypeValue).execute(); |
| testContext().set(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE, paymentTransactionResponse); |
| ErrorHelper.checkSuccessfulApiCall(paymentTransactionResponse); |
| } |
| |
| @Then("Credit Balance Refund transaction on future date {string} with {double} EUR transaction amount will result an error") |
| public void futureDateCBRError(String transactionDate, double transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| int errorCodeExpected = 403; |
| String errorMessageExpected = String.format("Loan: %s, Credit Balance Refund transaction cannot be created for the future.", |
| loanId); |
| |
| String transactionTypeValue = "creditBalanceRefund"; |
| |
| PostLoansLoanIdTransactionsRequest paymentTransactionRequest = LoanRequestFactory.defaultPaymentTransactionRequest() |
| .transactionDate(transactionDate).transactionAmount(transactionAmount); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, paymentTransactionRequest, transactionTypeValue).execute(); |
| testContext().set(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE, paymentTransactionResponse); |
| |
| int errorCodeActual = paymentTransactionResponse.code(); |
| String errorBody = paymentTransactionResponse.errorBody().string(); |
| ErrorResponse errorResponse = GSON.fromJson(errorBody, ErrorResponse.class); |
| String errorMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage(); |
| |
| assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected); |
| assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected)) |
| .isEqualTo(errorMessageExpected); |
| |
| log.info("ERROR CODE: {}", errorCodeActual); |
| log.info("ERROR MESSAGE: {}", errorMessageActual); |
| } |
| |
| @When("Admin creates a fully customized loan with the following data:") |
| public void createFullyCustomizedLoan(DataTable table) throws IOException { |
| List<List<String>> data = table.asLists(); |
| List<String> loanData = data.get(1); |
| String loanProduct = loanData.get(0); |
| String submitDate = loanData.get(1); |
| String principal = loanData.get(2); |
| BigDecimal interestRate = new BigDecimal(loanData.get(3)); |
| String interestType = loanData.get(4); |
| String interestCalculationPeriod = loanData.get(5); |
| String amortizationType = loanData.get(6); |
| Integer loanTermFrequency = Integer.valueOf(loanData.get(7)); |
| String loanTermFrequencyType = loanData.get(8); |
| Integer repaymentFrequency = Integer.valueOf(loanData.get(9)); |
| String repaymentFrequencyType = loanData.get(10); |
| Integer numberOfRepayments = Integer.valueOf(loanData.get(11)); |
| Integer graceOnPrincipalPayment = Integer.valueOf(loanData.get(12)); |
| Integer graceOnInterestPayment = Integer.valueOf(loanData.get(13)); |
| Integer graceOnInterestCharged = Integer.valueOf(loanData.get(14)); |
| String transactionProcessingStrategyCode = loanData.get(15); |
| |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| |
| DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProduct); |
| Long loanProductId = loanProductResolver.resolve(product); |
| |
| LoanTermFrequencyType termFrequencyType = LoanTermFrequencyType.valueOf(loanTermFrequencyType); |
| Integer loanTermFrequencyTypeValue = termFrequencyType.getValue(); |
| |
| RepaymentFrequencyType repaymentFrequencyType1 = RepaymentFrequencyType.valueOf(repaymentFrequencyType); |
| Integer repaymentFrequencyTypeValue = repaymentFrequencyType1.getValue(); |
| |
| InterestType interestType1 = InterestType.valueOf(interestType); |
| Integer interestTypeValue = interestType1.getValue(); |
| |
| InterestCalculationPeriodTime interestCalculationPeriod1 = InterestCalculationPeriodTime.valueOf(interestCalculationPeriod); |
| Integer interestCalculationPeriodValue = interestCalculationPeriod1.getValue(); |
| |
| AmortizationType amortizationType1 = AmortizationType.valueOf(amortizationType); |
| Integer amortizationTypeValue = amortizationType1.getValue(); |
| |
| TransactionProcessingStrategyCode processingStrategyCode = TransactionProcessingStrategyCode |
| .valueOf(transactionProcessingStrategyCode); |
| String transactionProcessingStrategyCodeValue = processingStrategyCode.getValue(); |
| |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId)// |
| .productId(loanProductId)// |
| .principal(new BigDecimal(principal))// |
| .interestRatePerPeriod(interestRate)// |
| .interestType(interestTypeValue)// |
| .interestCalculationPeriodType(interestCalculationPeriodValue)// |
| .amortizationType(amortizationTypeValue)// |
| .loanTermFrequency(loanTermFrequency)// |
| .loanTermFrequencyType(loanTermFrequencyTypeValue)// |
| .numberOfRepayments(numberOfRepayments)// |
| .repaymentEvery(repaymentFrequency)// |
| .repaymentFrequencyType(repaymentFrequencyTypeValue)// |
| .submittedOnDate(submitDate)// |
| .expectedDisbursementDate(submitDate)// |
| .graceOnPrincipalPayment(graceOnPrincipalPayment)// |
| .graceOnInterestPayment(graceOnInterestPayment)// |
| .graceOnInterestPayment(graceOnInterestCharged).transactionProcessingStrategyCode(transactionProcessingStrategyCodeValue);// |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| |
| eventCheckHelper.createLoanEventCheck(response); |
| } |
| |
| @When("Admin creates a fully customized loan with fixed length {int} and with the following data:") |
| public void createFullyCustomizedLoanFixedLength(int fixedLength, DataTable table) throws IOException { |
| List<List<String>> data = table.asLists(); |
| List<String> loanData = data.get(1); |
| String loanProduct = loanData.get(0); |
| String submitDate = loanData.get(1); |
| String principal = loanData.get(2); |
| BigDecimal interestRate = new BigDecimal(loanData.get(3)); |
| String interestType = loanData.get(4); |
| String interestCalculationPeriod = loanData.get(5); |
| String amortizationType = loanData.get(6); |
| Integer loanTermFrequency = Integer.valueOf(loanData.get(7)); |
| String loanTermFrequencyType = loanData.get(8); |
| Integer repaymentFrequency = Integer.valueOf(loanData.get(9)); |
| String repaymentFrequencyType = loanData.get(10); |
| Integer numberOfRepayments = Integer.valueOf(loanData.get(11)); |
| Integer graceOnPrincipalPayment = Integer.valueOf(loanData.get(12)); |
| Integer graceOnInterestPayment = Integer.valueOf(loanData.get(13)); |
| Integer graceOnInterestCharged = Integer.valueOf(loanData.get(14)); |
| String transactionProcessingStrategyCode = loanData.get(15); |
| |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| |
| DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProduct); |
| Long loanProductId = loanProductResolver.resolve(product); |
| |
| LoanTermFrequencyType termFrequencyType = LoanTermFrequencyType.valueOf(loanTermFrequencyType); |
| Integer loanTermFrequencyTypeValue = termFrequencyType.getValue(); |
| |
| RepaymentFrequencyType repaymentFrequencyType1 = RepaymentFrequencyType.valueOf(repaymentFrequencyType); |
| Integer repaymentFrequencyTypeValue = repaymentFrequencyType1.getValue(); |
| |
| InterestType interestType1 = InterestType.valueOf(interestType); |
| Integer interestTypeValue = interestType1.getValue(); |
| |
| InterestCalculationPeriodTime interestCalculationPeriod1 = InterestCalculationPeriodTime.valueOf(interestCalculationPeriod); |
| Integer interestCalculationPeriodValue = interestCalculationPeriod1.getValue(); |
| |
| AmortizationType amortizationType1 = AmortizationType.valueOf(amortizationType); |
| Integer amortizationTypeValue = amortizationType1.getValue(); |
| |
| TransactionProcessingStrategyCode processingStrategyCode = TransactionProcessingStrategyCode |
| .valueOf(transactionProcessingStrategyCode); |
| String transactionProcessingStrategyCodeValue = processingStrategyCode.getValue(); |
| |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId)// |
| .productId(loanProductId)// |
| .principal(new BigDecimal(principal))// |
| .interestRatePerPeriod(interestRate)// |
| .interestType(interestTypeValue)// |
| .interestCalculationPeriodType(interestCalculationPeriodValue)// |
| .amortizationType(amortizationTypeValue)// |
| .loanTermFrequency(loanTermFrequency)// |
| .loanTermFrequencyType(loanTermFrequencyTypeValue)// |
| .numberOfRepayments(numberOfRepayments)// |
| .repaymentEvery(repaymentFrequency)// |
| .repaymentFrequencyType(repaymentFrequencyTypeValue)// |
| .submittedOnDate(submitDate)// |
| .expectedDisbursementDate(submitDate)// |
| .graceOnPrincipalPayment(graceOnPrincipalPayment)// |
| .graceOnInterestPayment(graceOnInterestPayment)// |
| .graceOnInterestPayment(graceOnInterestCharged).transactionProcessingStrategyCode(transactionProcessingStrategyCodeValue)// |
| .fixedLength(fixedLength);// |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| |
| eventCheckHelper.createLoanEventCheck(response); |
| } |
| |
| @When("Admin creates a fully customized loan with Advanced payment allocation and with product no Advanced payment allocation set results an error:") |
| public void createFullyCustomizedLoanNoAdvancedPaymentError(DataTable table) throws IOException { |
| int errorCodeExpected = 400; |
| String errorMessageExpected = "Failed data validation due to: strategy.cannot.be.advanced.payment.allocation.if.not.configured."; |
| |
| List<List<String>> data = table.asLists(); |
| List<String> loanData = data.get(1); |
| String loanProduct = loanData.get(0); |
| String submitDate = loanData.get(1); |
| String principal = loanData.get(2); |
| BigDecimal interestRate = new BigDecimal(loanData.get(3)); |
| String interestType = loanData.get(4); |
| String interestCalculationPeriod = loanData.get(5); |
| String amortizationType = loanData.get(6); |
| Integer loanTermFrequency = Integer.valueOf(loanData.get(7)); |
| String loanTermFrequencyType = loanData.get(8); |
| Integer repaymentFrequency = Integer.valueOf(loanData.get(9)); |
| String repaymentFrequencyType = loanData.get(10); |
| Integer numberOfRepayments = Integer.valueOf(loanData.get(11)); |
| Integer graceOnPrincipalPayment = Integer.valueOf(loanData.get(12)); |
| Integer graceOnInterestPayment = Integer.valueOf(loanData.get(13)); |
| Integer graceOnInterestCharged = Integer.valueOf(loanData.get(14)); |
| String transactionProcessingStrategyCode = loanData.get(15); |
| |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| |
| DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProduct); |
| Long loanProductId = loanProductResolver.resolve(product); |
| |
| LoanTermFrequencyType termFrequencyType = LoanTermFrequencyType.valueOf(loanTermFrequencyType); |
| Integer loanTermFrequencyTypeValue = termFrequencyType.getValue(); |
| |
| RepaymentFrequencyType repaymentFrequencyType1 = RepaymentFrequencyType.valueOf(repaymentFrequencyType); |
| Integer repaymentFrequencyTypeValue = repaymentFrequencyType1.getValue(); |
| |
| InterestType interestType1 = InterestType.valueOf(interestType); |
| Integer interestTypeValue = interestType1.getValue(); |
| |
| InterestCalculationPeriodTime interestCalculationPeriod1 = InterestCalculationPeriodTime.valueOf(interestCalculationPeriod); |
| Integer interestCalculationPeriodValue = interestCalculationPeriod1.getValue(); |
| |
| AmortizationType amortizationType1 = AmortizationType.valueOf(amortizationType); |
| Integer amortizationTypeValue = amortizationType1.getValue(); |
| |
| TransactionProcessingStrategyCode processingStrategyCode = TransactionProcessingStrategyCode |
| .valueOf(transactionProcessingStrategyCode); |
| String transactionProcessingStrategyCodeValue = processingStrategyCode.getValue(); |
| |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId)// |
| .productId(loanProductId)// |
| .principal(new BigDecimal(principal))// |
| .interestRatePerPeriod(interestRate)// |
| .interestType(interestTypeValue)// |
| .interestCalculationPeriodType(interestCalculationPeriodValue)// |
| .amortizationType(amortizationTypeValue)// |
| .loanTermFrequency(loanTermFrequency)// |
| .loanTermFrequencyType(loanTermFrequencyTypeValue)// |
| .numberOfRepayments(numberOfRepayments)// |
| .repaymentEvery(repaymentFrequency)// |
| .repaymentFrequencyType(repaymentFrequencyTypeValue)// |
| .submittedOnDate(submitDate)// |
| .expectedDisbursementDate(submitDate)// |
| .graceOnPrincipalPayment(graceOnPrincipalPayment)// |
| .graceOnInterestPayment(graceOnInterestPayment)// |
| .graceOnInterestPayment(graceOnInterestCharged).transactionProcessingStrategyCode(transactionProcessingStrategyCodeValue);// |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| int errorCodeActual = response.code(); |
| String errorBody = response.errorBody().string(); |
| ErrorResponse errorResponse = GSON.fromJson(errorBody, ErrorResponse.class); |
| String errorMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage(); |
| |
| assertThat(errorCodeActual).as(ErrorMessageHelper.wrongErrorCode(errorCodeActual, errorCodeExpected)).isEqualTo(errorCodeExpected); |
| assertThat(errorMessageActual).as(ErrorMessageHelper.wrongErrorMessage(errorMessageActual, errorMessageExpected)) |
| .isEqualTo(errorMessageExpected); |
| |
| log.info("ERROR CODE: {}", errorCodeActual); |
| log.info("ERROR MESSAGE: {}", errorMessageActual); |
| } |
| |
| @Then("Loan details has the following last payment related data:") |
| public void checkLastPaymentData(DataTable table) throws IOException { |
| List<List<String>> data = table.asLists(); |
| List<String> expectedValues = data.get(1); |
| String lastPaymentAmountExpected = expectedValues.get(0); |
| String lastPaymentDateExpected = expectedValues.get(1); |
| String lastRepaymentAmountExpected = expectedValues.get(2); |
| String lastRepaymentDateExpected = expectedValues.get(3); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "collection", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| GetLoansLoanIdDelinquencySummary delinquent = loanDetailsResponse.body().getDelinquent(); |
| String lastPaymentAmountActual = String.valueOf(delinquent.getLastPaymentAmount()); |
| String lastPaymentDateActual = FORMATTER.format(delinquent.getLastPaymentDate()); |
| String lastRepaymentAmountActual = String.valueOf(delinquent.getLastRepaymentAmount()); |
| String lastRepaymentDateActual = FORMATTER.format(delinquent.getLastRepaymentDate()); |
| |
| assertThat(lastPaymentAmountActual) |
| .as(ErrorMessageHelper.wrongDataInLastPaymentAmount(lastPaymentAmountActual, lastPaymentAmountExpected)) |
| .isEqualTo(lastPaymentAmountExpected); |
| assertThat(lastPaymentDateActual).as(ErrorMessageHelper.wrongDataInLastPaymentDate(lastPaymentDateActual, lastPaymentDateExpected)) |
| .isEqualTo(lastPaymentDateExpected); |
| assertThat(lastRepaymentAmountActual) |
| .as(ErrorMessageHelper.wrongDataInLastRepaymentAmount(lastRepaymentAmountActual, lastRepaymentAmountExpected)) |
| .isEqualTo(lastRepaymentAmountExpected); |
| assertThat(lastRepaymentDateActual) |
| .as(ErrorMessageHelper.wrongDataInLastRepaymentDate(lastRepaymentDateActual, lastRepaymentDateExpected)) |
| .isEqualTo(lastRepaymentDateExpected); |
| } |
| |
| @Then("Loan details and LoanTransactionMakeRepaymentPostBusinessEvent has the following data in loanChargePaidByList section:") |
| public void checkLoanDetailsAndEventLoanChargePaidByListSection(DataTable table) throws IOException { |
| List<List<String>> data = table.asLists(); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| GetLoansLoanIdTransactions lastRepaymentData = transactions.stream() |
| .filter(t -> "loanTransactionType.repayment".equals(t.getType().getCode())).reduce((first, second) -> second).orElse(null); |
| List<GetLoansLoanIdLoanChargePaidByData> loanChargePaidByList = lastRepaymentData.getLoanChargePaidByList(); |
| loanChargePaidByList.sort(Comparator.comparing(GetLoansLoanIdLoanChargePaidByData::getChargeId)); |
| |
| EventAssertion.EventAssertionBuilder<LoanTransactionDataV1> transactionEvent = testContext().get(TestContextKey.TRANSACTION_EVENT); |
| transactionEvent.extractingData(loanTransactionDataV1 -> { |
| for (int i = 0; i < loanChargePaidByList.size(); i++) { |
| List<LoanChargePaidByDataV1> loanChargePaidByListEvent = loanTransactionDataV1.getLoanChargePaidByList(); |
| loanChargePaidByListEvent.sort(Comparator.comparing(LoanChargePaidByDataV1::getChargeId)); |
| String amountEventActual = loanChargePaidByListEvent.get(i).getAmount().setScale(1, RoundingMode.HALF_DOWN).toString(); |
| String nameEventActual = loanChargePaidByListEvent.get(i).getName(); |
| |
| String amountActual = String.valueOf(loanChargePaidByList.get(i).getAmount()); |
| String nameActual = loanChargePaidByList.get(i).getName(); |
| |
| String amountExpected = data.get(i + 1).get(0); |
| String nameExpected = data.get(i + 1).get(1); |
| |
| assertThat(amountActual) |
| .as(ErrorMessageHelper.wrongDataInLoanDetailsLoanChargePaidByListAmount(amountActual, amountExpected)) |
| .isEqualTo(amountExpected); |
| assertThat(nameActual).as(ErrorMessageHelper.wrongDataInLoanDetailsLoanChargePaidByListName(nameActual, nameExpected)) |
| .isEqualTo(nameExpected); |
| |
| assertThat(amountEventActual).as(ErrorMessageHelper |
| .wrongDataInLoanTransactionMakeRepaymentPostEventLoanChargePaidByListAmount(amountEventActual, amountExpected)) |
| .isEqualTo(amountExpected); |
| assertThat(nameEventActual).as(ErrorMessageHelper |
| .wrongDataInLoanTransactionMakeRepaymentPostEventLoanChargePaidByListName(nameEventActual, nameExpected)) |
| .isEqualTo(nameExpected); |
| } |
| return null; |
| }); |
| } |
| |
| @And("Admin successfully creates a new customised Loan submitted on date: {string}, with Principal: {string}, a loanTermFrequency: {int} months, and numberOfRepayments: {int}") |
| public void createCustomizedLoan(String submitDate, String principal, Integer loanTermFrequency, Integer numberOfRepayments) |
| throws IOException { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| Integer repaymentFrequency = loanTermFrequency / numberOfRepayments; |
| |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId).principal(new BigDecimal(principal)) |
| .loanTermFrequency(loanTermFrequency).loanTermFrequencyType(LoanTermFrequencyType.MONTHS.value) |
| .numberOfRepayments(numberOfRepayments).repaymentEvery(repaymentFrequency) |
| .repaymentFrequencyType(RepaymentFrequencyType.MONTHS.value).submittedOnDate(submitDate) |
| .expectedDisbursementDate(submitDate); |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| } |
| |
| @And("Customer makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount with the same Idempotency key as previous transaction") |
| public void createTransactionWithIdempotencyKeyOfPreviousTransaction(String transactionTypeInput, String transactionPaymentType, |
| String transactionDate, double transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| TransactionType transactionType = TransactionType.valueOf(transactionTypeInput); |
| String transactionTypeValue = transactionType.getValue(); |
| DefaultPaymentType paymentType = DefaultPaymentType.valueOf(transactionPaymentType); |
| Long paymentTypeValue = paymentTypeResolver.resolve(paymentType); |
| |
| PostLoansLoanIdTransactionsRequest paymentTransactionRequest = LoanRequestFactory.defaultPaymentTransactionRequest() |
| .transactionDate(transactionDate).transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue); |
| |
| Map<String, String> headerMap = new HashMap<>(); |
| String idempotencyKey = testContext().get(TestContextKey.TRANSACTION_IDEMPOTENCY_KEY); |
| headerMap.put("Idempotency-Key", idempotencyKey); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, paymentTransactionRequest, transactionTypeValue, headerMap).execute(); |
| testContext().set(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE, paymentTransactionResponse); |
| ErrorHelper.checkSuccessfulApiCall(paymentTransactionResponse); |
| } |
| |
| @And("Customer makes {string} transaction on the second loan with {string} payment type on {string} with {double} EUR transaction amount with the same Idempotency key as previous transaction") |
| public void createTransactionOnSecondLoanWithIdempotencyKeyOfPreviousTransaction(String transactionTypeInput, |
| String transactionPaymentType, String transactionDate, double transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_SECOND_LOAN_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| TransactionType transactionType = TransactionType.valueOf(transactionTypeInput); |
| String transactionTypeValue = transactionType.getValue(); |
| DefaultPaymentType paymentType = DefaultPaymentType.valueOf(transactionPaymentType); |
| Long paymentTypeValue = paymentTypeResolver.resolve(paymentType); |
| |
| PostLoansLoanIdTransactionsRequest paymentTransactionRequest = LoanRequestFactory.defaultPaymentTransactionRequest() |
| .transactionDate(transactionDate).transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue); |
| |
| Map<String, String> headerMap = new HashMap<>(); |
| String idempotencyKey = testContext().get(TestContextKey.TRANSACTION_IDEMPOTENCY_KEY); |
| headerMap.put("Idempotency-Key", idempotencyKey); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, paymentTransactionRequest, transactionTypeValue, headerMap).execute(); |
| testContext().set(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE, paymentTransactionResponse); |
| ErrorHelper.checkSuccessfulApiCall(paymentTransactionResponse); |
| } |
| |
| @Then("Admin can successfully modify the loan and changes the submitted on date to {string}") |
| public void modifyLoanSubmittedOnDate(String newSubmittedOnDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanId2 = loanResponse.body().getResourceId(); |
| Long clientId2 = loanResponse.body().getClientId(); |
| |
| PutLoansLoanIdRequest putLoansLoanIdRequest = loanRequestFactory.modifySubmittedOnDateOnLoan(clientId2, newSubmittedOnDate); |
| |
| Response<PutLoansLoanIdResponse> responseMod = loansApi.modifyLoanApplication(loanId2, putLoansLoanIdRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_MODIFY_RESPONSE, responseMod); |
| ErrorHelper.checkSuccessfulApiCall(responseMod); |
| } |
| |
| @Then("Admin fails to create a new customised Loan submitted on date: {string}, with Principal: {string}, a loanTermFrequency: {int} months, and numberOfRepayments: {int}") |
| public void createCustomizedLoanFailure(String submitDate, String principal, Integer loanTermFrequency, Integer numberOfRepayments) |
| throws IOException { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientId = clientResponse.body().getClientId(); |
| Integer repaymentFrequency = loanTermFrequency / numberOfRepayments; |
| |
| PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId).principal(new BigDecimal(principal)) |
| .loanTermFrequency(loanTermFrequency).loanTermFrequencyType(LoanTermFrequencyType.MONTHS.value) |
| .numberOfRepayments(numberOfRepayments).repaymentEvery(repaymentFrequency) |
| .repaymentFrequencyType(RepaymentFrequencyType.MONTHS.value).submittedOnDate(submitDate) |
| .expectedDisbursementDate(submitDate); |
| |
| Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute(); |
| testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response); |
| ErrorResponse errorDetails = ErrorResponse.from(response); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.loanSubmitDateInFutureFailureMsg()); |
| } |
| |
| @And("Admin successfully approves the loan on {string} with {string} amount and expected disbursement date on {string}") |
| public void approveLoan(String approveDate, String approvedAmount, String expectedDisbursementDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest approveRequest = LoanRequestFactory.defaultLoanApproveRequest().approvedOnDate(approveDate) |
| .approvedLoanAmount(new BigDecimal(approvedAmount)).expectedDisbursementDate(expectedDisbursementDate); |
| |
| Response<PostLoansLoanIdResponse> loanApproveResponse = loansApi.stateTransitions(loanId, approveRequest, "approve").execute(); |
| testContext().set(TestContextKey.LOAN_APPROVAL_RESPONSE, loanApproveResponse); |
| ErrorHelper.checkSuccessfulApiCall(loanApproveResponse); |
| assertThat(loanApproveResponse.body().getChanges().getStatus().getValue()).isEqualTo(LOAN_STATE_APPROVED); |
| assertThat(loanApproveResponse.body().getChanges().getStatus().getValue()).isEqualTo(LOAN_STATE_APPROVED); |
| |
| eventCheckHelper.approveLoanEventCheck(loanApproveResponse); |
| } |
| |
| @And("Admin successfully approves the second loan on {string} with {string} amount and expected disbursement date on {string}") |
| public void approveSecondLoan(String approveDate, String approvedAmount, String expectedDisbursementDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_SECOND_LOAN_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest approveRequest = LoanRequestFactory.defaultLoanApproveRequest().approvedOnDate(approveDate) |
| .approvedLoanAmount(new BigDecimal(approvedAmount)).expectedDisbursementDate(expectedDisbursementDate); |
| |
| Response<PostLoansLoanIdResponse> loanApproveResponse = loansApi.stateTransitions(loanId, approveRequest, "approve").execute(); |
| testContext().set(TestContextKey.LOAN_APPROVAL_SECOND_LOAN_RESPONSE, loanApproveResponse); |
| ErrorHelper.checkSuccessfulApiCall(loanApproveResponse); |
| assertThat(loanApproveResponse.body().getChanges().getStatus().getValue()).isEqualTo(LOAN_STATE_APPROVED); |
| assertThat(loanApproveResponse.body().getChanges().getStatus().getValue()).isEqualTo(LOAN_STATE_APPROVED); |
| } |
| |
| @Then("Admin can successfully undone the loan approval") |
| public void undoLoanApproval() throws IOException { |
| Response<PostLoansLoanIdResponse> loanApproveResponse = testContext().get(TestContextKey.LOAN_APPROVAL_RESPONSE); |
| long loanId = loanApproveResponse.body().getLoanId(); |
| PostLoansLoanIdRequest undoApprovalRequest = new PostLoansLoanIdRequest().note(""); |
| |
| Response<PostLoansLoanIdResponse> undoApprovalResponse = loansApi.stateTransitions(loanId, undoApprovalRequest, "undoapproval") |
| .execute(); |
| testContext().set(TestContextKey.LOAN_UNDO_APPROVAL_RESPONSE, loanApproveResponse); |
| ErrorHelper.checkSuccessfulApiCall(undoApprovalResponse); |
| assertThat(undoApprovalResponse.body().getChanges().getStatus().getValue()).isEqualTo(LOAN_STATE_SUBMITTED_AND_PENDING); |
| } |
| |
| @Then("Admin fails to approve the loan on {string} with {string} amount and expected disbursement date on {string} because of wrong date") |
| public void failedLoanApproveWithDate(String approveDate, String approvedAmount, String expectedDisbursementDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest approveRequest = LoanRequestFactory.defaultLoanApproveRequest().approvedOnDate(approveDate) |
| .approvedLoanAmount(new BigDecimal(approvedAmount)).expectedDisbursementDate(expectedDisbursementDate); |
| |
| Response<PostLoansLoanIdResponse> loanApproveResponse = loansApi.stateTransitions(loanId, approveRequest, "approve").execute(); |
| ErrorResponse errorDetails = ErrorResponse.from(loanApproveResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.loanApproveDateInFutureFailureMsg()); |
| } |
| |
| @Then("Admin fails to approve the loan on {string} with {string} amount and expected disbursement date on {string} because of wrong amount") |
| public void failedLoanApproveWithAmount(String approveDate, String approvedAmount, String expectedDisbursementDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest approveRequest = LoanRequestFactory.defaultLoanApproveRequest().approvedOnDate(approveDate) |
| .approvedLoanAmount(new BigDecimal(approvedAmount)).expectedDisbursementDate(expectedDisbursementDate); |
| |
| Response<PostLoansLoanIdResponse> loanApproveResponse = loansApi.stateTransitions(loanId, approveRequest, "approve").execute(); |
| ErrorResponse errorDetails = ErrorResponse.from(loanApproveResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.loanApproveMaxAmountFailureMsg()); |
| } |
| |
| @And("Admin successfully disburse the loan on {string} with {string} EUR transaction amount") |
| public void disburseLoan(String actualDisbursementDate, String transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest disburseRequest = LoanRequestFactory.defaultLoanDisburseRequest() |
| .actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount)); |
| |
| Response<PostLoansLoanIdResponse> loanDisburseResponse = loansApi.stateTransitions(loanId, disburseRequest, "disburse").execute(); |
| testContext().set(TestContextKey.LOAN_DISBURSE_RESPONSE, loanDisburseResponse); |
| ErrorHelper.checkSuccessfulApiCall(loanDisburseResponse); |
| Long statusActual = loanDisburseResponse.body().getChanges().getStatus().getId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| Long statusExpected = Long.valueOf(loanDetails.body().getStatus().getId()); |
| |
| assertThat(statusActual)// |
| .as(ErrorMessageHelper.wrongLoanStatus(Math.toIntExact(statusActual), Math.toIntExact(statusExpected)))// |
| .isEqualTo(statusExpected);// |
| eventCheckHelper.disburseLoanEventCheck(loanDisburseResponse); |
| eventCheckHelper.loanDisbursalTransactionEventCheck(loanDisburseResponse); |
| } |
| |
| @And("Admin successfully disburse the second loan on {string} with {string} EUR transaction amount") |
| public void disburseSecondLoan(String actualDisbursementDate, String transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_SECOND_LOAN_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest disburseRequest = LoanRequestFactory.defaultLoanDisburseRequest() |
| .actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount)); |
| |
| Response<PostLoansLoanIdResponse> loanDisburseResponse = loansApi.stateTransitions(loanId, disburseRequest, "disburse").execute(); |
| testContext().set(TestContextKey.LOAN_DISBURSE_SECOND_LOAN_RESPONSE, loanDisburseResponse); |
| ErrorHelper.checkSuccessfulApiCall(loanDisburseResponse); |
| assertThat(loanDisburseResponse.body().getChanges().getStatus().getValue()).isEqualTo(LOAN_STATE_ACTIVE); |
| |
| eventCheckHelper.disburseLoanEventCheck(loanDisburseResponse); |
| eventCheckHelper.loanDisbursalTransactionEventCheck(loanDisburseResponse); |
| } |
| |
| @And("Admin does charge-off the loan on {string}") |
| public void chargeOffLoan(String transactionDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultChargeOffRequest().transactionDate(transactionDate) |
| .dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); |
| |
| Response<PostLoansLoanIdTransactionsResponse> chargeOffResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, chargeOffRequest, "charge-off").execute(); |
| testContext().set(TestContextKey.LOAN_CHARGE_OFF_RESPONSE, chargeOffResponse); |
| ErrorHelper.checkSuccessfulApiCall(chargeOffResponse); |
| |
| Long transactionId = chargeOffResponse.body().getResourceId(); |
| eventAssertion.assertEvent(LoanChargeOffEvent.class, transactionId).extractingData(LoanTransactionDataV1::getLoanId) |
| .isEqualTo(loanId).extractingData(LoanTransactionDataV1::getId).isEqualTo(chargeOffResponse.body().getResourceId()); |
| } |
| |
| @Then("Charge-off attempt on {string} results an error") |
| public void chargeOffOnLoanWithInterestFails(String transactionDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultChargeOffRequest().transactionDate(transactionDate) |
| .dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); |
| |
| Response<PostLoansLoanIdTransactionsResponse> chargeOffResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, chargeOffRequest, "charge-off").execute(); |
| testContext().set(TestContextKey.LOAN_CHARGE_OFF_RESPONSE, chargeOffResponse); |
| |
| assertThat(chargeOffResponse.isSuccessful()).isFalse(); |
| |
| String string = chargeOffResponse.errorBody().string(); |
| ErrorResponse errorResponse = GSON.fromJson(string, ErrorResponse.class); |
| String developerMessage = errorResponse.getErrors().get(0).getDeveloperMessage(); |
| assertThat(developerMessage) |
| .isEqualTo(String.format("Loan: %s Charge-off is not allowed. Loan Account is interest bearing", loanId)); |
| } |
| |
| @Then("Second Charge-off is not possible on {string}") |
| public void secondChargeOffLoan(String transactionDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultChargeOffRequest().transactionDate(transactionDate) |
| .dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); |
| |
| Response<PostLoansLoanIdTransactionsResponse> secondChargeOffResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, chargeOffRequest, "charge-off").execute(); |
| testContext().set(TestContextKey.LOAN_CHARGE_OFF_RESPONSE, secondChargeOffResponse); |
| ErrorResponse errorDetails = ErrorResponse.from(secondChargeOffResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.chargeOffUndoFailureCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.secondChargeOffFailure(loanId)); |
| } |
| |
| @And("Admin does a charge-off undo the loan") |
| public void chargeOffUndo() throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| PostLoansLoanIdTransactionsRequest chargeOffUndoRequest = LoanRequestFactory.defaultUndoChargeOffRequest(); |
| |
| Response<PostLoansLoanIdTransactionsResponse> chargeOffUndoResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, chargeOffUndoRequest, "undo-charge-off").execute(); |
| testContext().set(TestContextKey.LOAN_CHARGE_OFF_UNDO_RESPONSE, chargeOffUndoResponse); |
| ErrorHelper.checkSuccessfulApiCall(chargeOffUndoResponse); |
| |
| Long transactionId = chargeOffUndoResponse.body().getResourceId(); |
| eventAssertion.assertEventRaised(LoanChargeOffUndoEvent.class, transactionId); |
| } |
| |
| @Then("Charge-off undo is not possible on {string}") |
| public void chargeOffUndoFailure(String transactionDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanId = loanResponse.body().getLoanId(); |
| |
| PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultChargeOffRequest().transactionDate(transactionDate) |
| .dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); |
| |
| Response<PostLoansLoanIdTransactionsResponse> chargeOffResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, chargeOffRequest, "charge-off").execute(); |
| testContext().set(TestContextKey.LOAN_CHARGE_OFF_RESPONSE, chargeOffResponse); |
| ErrorResponse errorDetails = ErrorResponse.from(chargeOffResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.chargeOffUndoFailureCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.chargeOffUndoFailure(loanId)); |
| } |
| |
| @Then("Charge-off undo is not possible as the loan is not charged-off") |
| public void chargeOffNotPossibleFailure() throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanId = loanResponse.body().getLoanId(); |
| |
| PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultUndoChargeOffRequest(); |
| |
| Response<PostLoansLoanIdTransactionsResponse> undoChargeOffResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, chargeOffRequest, "undo-charge-off").execute(); |
| testContext().set(TestContextKey.LOAN_CHARGE_OFF_RESPONSE, undoChargeOffResponse); |
| ErrorResponse errorDetails = ErrorResponse.from(undoChargeOffResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.chargeOffUndoFailureCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.notChargedOffFailure(loanId)); |
| } |
| |
| @When("Admin successfully undo disbursal") |
| public void undoDisbursal() throws IOException { |
| Response<PostLoansLoanIdResponse> loanApproveResponse = testContext().get(TestContextKey.LOAN_APPROVAL_RESPONSE); |
| long loanId = loanApproveResponse.body().getLoanId(); |
| |
| PostLoansLoanIdRequest undoDisbursalRequest = new PostLoansLoanIdRequest().note(""); |
| Response<PostLoansLoanIdResponse> undoLastDisbursalResponse = loansApi |
| .stateTransitions(loanId, undoDisbursalRequest, "undodisbursal").execute(); |
| ErrorHelper.checkSuccessfulApiCall(undoLastDisbursalResponse); |
| } |
| |
| @When("Admin successfully undo last disbursal") |
| public void undoLastDisbursal() throws IOException { |
| Response<PostLoansLoanIdResponse> loanApproveResponse = testContext().get(TestContextKey.LOAN_APPROVAL_RESPONSE); |
| long loanId = loanApproveResponse.body().getLoanId(); |
| |
| PostLoansLoanIdRequest undoDisbursalRequest = new PostLoansLoanIdRequest().note(""); |
| Response<PostLoansLoanIdResponse> undoLastDisbursalResponse = loansApi |
| .stateTransitions(loanId, undoDisbursalRequest, "undolastdisbursal").execute(); |
| ErrorHelper.checkSuccessfulApiCall(undoLastDisbursalResponse); |
| } |
| |
| @Then("Admin can successfully undone the loan disbursal") |
| public void checkUndoLoanDisbursal() throws IOException { |
| Response<PostLoansLoanIdResponse> loanApproveResponse = testContext().get(TestContextKey.LOAN_APPROVAL_RESPONSE); |
| long loanId = loanApproveResponse.body().getLoanId(); |
| PostLoansLoanIdRequest undoDisbursalRequest = new PostLoansLoanIdRequest().note(""); |
| |
| Response<PostLoansLoanIdResponse> undoDisbursalResponse = loansApi.stateTransitions(loanId, undoDisbursalRequest, "undodisbursal") |
| .execute(); |
| testContext().set(TestContextKey.LOAN_UNDO_DISBURSE_RESPONSE, undoDisbursalResponse); |
| ErrorHelper.checkSuccessfulApiCall(undoDisbursalResponse); |
| assertThat(undoDisbursalResponse.body().getChanges().getStatus().getValue()).isEqualTo(LOAN_STATE_APPROVED); |
| } |
| |
| @Then("Admin fails to disburse the loan on {string} with {string} EUR transaction amount because of wrong date") |
| public void disburseLoanFailureWithDate(String actualDisbursementDate, String transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest disburseRequest = LoanRequestFactory.defaultLoanDisburseRequest() |
| .actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount)); |
| |
| Response<PostLoansLoanIdResponse> loanDisburseResponse = loansApi.stateTransitions(loanId, disburseRequest, "disburse").execute(); |
| testContext().set(TestContextKey.LOAN_DISBURSE_RESPONSE, loanDisburseResponse); |
| ErrorResponse errorDetails = ErrorResponse.from(loanDisburseResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(ErrorMessageHelper.disburseDateFailure((int) loanId)); |
| } |
| |
| @Then("Admin fails to disburse the loan on {string} with {string} EUR transaction amount because of wrong amount") |
| public void disburseLoanFailureWithAmount(String actualDisbursementDate, String transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| PostLoansLoanIdRequest disburseRequest = LoanRequestFactory.defaultLoanDisburseRequest() |
| .actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount)); |
| |
| Response<PostLoansLoanIdResponse> loanDisburseResponse = loansApi.stateTransitions(loanId, disburseRequest, "disburse").execute(); |
| testContext().set(TestContextKey.LOAN_DISBURSE_RESPONSE, loanDisburseResponse); |
| ErrorResponse errorDetails = ErrorResponse.from(loanDisburseResponse); |
| String developerMessage = errorDetails.getSingleError().getDeveloperMessage(); |
| |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); |
| assertThat(developerMessage).matches(ErrorMessageHelper.disburseMaxAmountFailure()); |
| log.info("Error message: {}", developerMessage); |
| } |
| |
| @Then("Loan has {double} outstanding amount") |
| public void loanOutstanding(double totalOutstandingExpected) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| |
| Double totalOutstandingActual = loanDetailsResponse.body().getSummary().getTotalOutstanding(); |
| assertThat(totalOutstandingActual) |
| .as(ErrorMessageHelper.wrongAmountInTotalOutstanding(totalOutstandingActual, totalOutstandingExpected)) |
| .isEqualTo(totalOutstandingExpected); |
| } |
| |
| @Then("Loan has {double} overpaid amount") |
| public void loanOverpaid(double totalOverpaidExpected) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| |
| Double totalOverpaidActual = loanDetailsResponse.body().getTotalOverpaid(); |
| Double totalOutstandingActual = loanDetailsResponse.body().getSummary().getTotalOutstanding(); |
| double totalOutstandingExpected = 0.0; |
| assertThat(totalOutstandingActual) |
| .as(ErrorMessageHelper.wrongAmountInTotalOutstanding(totalOutstandingActual, totalOutstandingExpected)) |
| .isEqualTo(totalOutstandingExpected); |
| assertThat(totalOverpaidActual) |
| .as(ErrorMessageHelper.wrongAmountInTransactionsOverpayment(totalOverpaidActual, totalOverpaidExpected)) |
| .isEqualTo(totalOverpaidExpected); |
| } |
| |
| @Then("Loan has {double} total overdue amount") |
| public void loanOverdue(double totalOverdueExpected) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| |
| Double totalOverdueActual = loanDetailsResponse.body().getSummary().getTotalOverdue(); |
| assertThat(totalOverdueActual).as(ErrorMessageHelper.wrongAmountInTotalOverdue(totalOverdueActual, totalOverdueExpected)) |
| .isEqualTo(totalOverdueExpected); |
| } |
| |
| @Then("Loan has {double} last payment amount") |
| public void loanLastPaymentAmount(double lastPaymentAmountExpected) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| |
| Double lastPaymentAmountActual = loanDetailsResponse.body().getDelinquent().getLastPaymentAmount(); |
| assertThat(lastPaymentAmountActual) |
| .as(ErrorMessageHelper.wrongLastPaymentAmount(lastPaymentAmountActual, lastPaymentAmountExpected)) |
| .isEqualTo(lastPaymentAmountExpected); |
| } |
| |
| @Then("Loan Repayment schedule has {int} periods, with the following data for periods:") |
| public void loanRepaymentSchedulePeriodsCheck(int linesExpected, DataTable table) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "repaymentSchedule", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdRepaymentPeriod> repaymentPeriods = loanDetailsResponse.body().getRepaymentSchedule().getPeriods(); |
| |
| List<List<String>> data = table.asLists(); |
| int nrLines = data.size(); |
| int linesActual = (int) repaymentPeriods.stream().filter(r -> r.getPeriod() != null).count(); |
| for (int i = 1; i < nrLines; i++) { |
| List<String> expectedValues = data.get(i); |
| String dueDateExpected = expectedValues.get(2); |
| |
| List<List<String>> actualValuesList = repaymentPeriods.stream() |
| .filter(r -> dueDateExpected.equals(FORMATTER.format(r.getDueDate()))) |
| .map(r -> fetchValuesOfRepaymentSchedule(data.get(0), r)).collect(Collectors.toList()); |
| |
| boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues)); |
| assertThat(containsExpectedValues) |
| .as(ErrorMessageHelper.wrongValueInLineInRepaymentSchedule(i, actualValuesList, expectedValues)).isTrue(); |
| |
| assertThat(linesActual).as(ErrorMessageHelper.wrongNumberOfLinesInRepaymentSchedule(linesActual, linesExpected)) |
| .isEqualTo(linesExpected); |
| } |
| } |
| |
| @Then("Loan Repayment schedule has the following data in Total row:") |
| public void loanRepaymentScheduleAmountCheck(DataTable table) throws IOException { |
| List<List<String>> data = table.asLists(); |
| List<String> header = data.get(0); |
| List<String> expectedValues = data.get(1); |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "repaymentSchedule", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| GetLoansLoanIdRepaymentSchedule repaymentSchedule = loanDetailsResponse.body().getRepaymentSchedule(); |
| validateRepaymentScheduleTotal(header, repaymentSchedule, expectedValues); |
| } |
| |
| @Then("Loan Transactions tab has a transaction with date: {string}, and with the following data:") |
| public void loanTransactionsTransactionWithGivenDateDataCheck(String date, DataTable table) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| |
| List<List<String>> data = table.asLists(); |
| List<String> expectedValues = data.get(1); |
| |
| List<List<String>> actualValuesList = transactions.stream().filter(t -> date.equals(FORMATTER.format(t.getDate()))) |
| .map(t -> fetchValuesOfTransaction(data.get(0), t)).collect(Collectors.toList()); |
| boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues)); |
| |
| assertThat(containsExpectedValues).as(ErrorMessageHelper.wrongValueInLineInTransactionsTab(1, actualValuesList, expectedValues)) |
| .isTrue(); |
| } |
| |
| @Then("Loan Transactions tab has the following data:") |
| public void loanTransactionsTabCheck(DataTable table) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| List<List<String>> data = table.asLists(); |
| for (int i = 1; i < data.size(); i++) { |
| List<String> expectedValues = data.get(i); |
| String transactionDateExpected = expectedValues.get(0); |
| List<List<String>> actualValuesList = transactions.stream()// |
| .filter(t -> transactionDateExpected.equals(FORMATTER.format(t.getDate())))// |
| .map(t -> fetchValuesOfTransaction(table.row(0), t))// |
| .collect(Collectors.toList());// |
| boolean containsExpectedValues = actualValuesList.stream()// |
| .anyMatch(actualValues -> actualValues.equals(expectedValues));// |
| assertThat(containsExpectedValues).as(ErrorMessageHelper.wrongValueInLineInTransactionsTab(i, actualValuesList, expectedValues)) |
| .isTrue(); |
| } |
| assertThat(transactions.size()).as(ErrorMessageHelper.nrOfLinesWrongInTransactionsTab(transactions.size(), data.size() - 1)) |
| .isEqualTo(data.size() - 1); |
| } |
| |
| @Then("In Loan Transactions the latest Transaction has Transaction type={string} and is reverted") |
| public void loanTransactionsLatestTransactionReverted(String transactionType) throws IOException { |
| loanTransactionsLatestTransactionReverted(null, transactionType); |
| } |
| |
| @Then("In Loan Transactions the {string}th Transaction has Transaction type={string} and is reverted") |
| public void loanTransactionsLatestTransactionReverted(String nthTransactionStr, String transactionType) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| int nthTransaction = nthTransactionStr == null ? transactions.size() - 1 : Integer.parseInt(nthTransactionStr) - 1; |
| GetLoansLoanIdTransactions latestTransaction = transactions.get(nthTransaction); |
| |
| String transactionTypeActual = latestTransaction.getType().getValue(); |
| Boolean isReversedActual = latestTransaction.getManuallyReversed(); |
| |
| assertThat(transactionTypeActual) |
| .as(ErrorMessageHelper.wrongDataInTransactionsTransactionType(transactionTypeActual, transactionType)) |
| .isEqualTo(transactionType); |
| assertThat(isReversedActual).as(ErrorMessageHelper.transactionIsNotReversedError(isReversedActual, true)).isEqualTo(true); |
| } |
| |
| @Then("On Loan Transactions tab the {string} Transaction with date {string} is reverted") |
| public void loanTransactionsGivenTransactionReverted(String transactionType, String transactionDate) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| List<GetLoansLoanIdTransactions> transactionsMatch = transactions// |
| .stream()// |
| .filter(t -> transactionDate.equals(FORMATTER.format(t.getDate())) && transactionType.equals(t.getType().getValue()))// |
| .collect(Collectors.toList());// |
| boolean isReverted = transactionsMatch.stream().anyMatch(t -> t.getManuallyReversed()); |
| |
| assertThat(isReverted).as(ErrorMessageHelper.transactionIsNotReversedError(isReverted, true)).isEqualTo(true); |
| } |
| |
| @Then("On Loan Transactions tab the {string} Transaction with date {string} is NOT reverted") |
| public void loanTransactionsGivenTransactionNotReverted(String transactionType, String transactionDate) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| List<GetLoansLoanIdTransactions> transactionsMatch = transactions// |
| .stream()// |
| .filter(t -> transactionDate.equals(FORMATTER.format(t.getDate())) && transactionType.equals(t.getType().getValue()))// |
| .collect(Collectors.toList());// |
| boolean isReverted = transactionsMatch.stream().anyMatch(t -> t.getManuallyReversed()); |
| |
| assertThat(isReverted).as(ErrorMessageHelper.transactionIsNotReversedError(isReverted, false)).isEqualTo(false); |
| } |
| |
| @Then("Loan Charges tab has a given charge with the following data:") |
| public void loanChargesGivenChargeDataCheck(DataTable table) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "charges", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| List<GetLoansLoanIdLoanChargeData> charges = loanDetailsResponse.body().getCharges(); |
| |
| List<List<String>> data = table.asLists(); |
| List<String> expectedValues = data.get(1); |
| String paymentDueAtExpected = expectedValues.get(2); |
| String dueAsOfExpected = expectedValues.get(3); |
| List<List<String>> actualValuesList = getActualValuesList(charges, paymentDueAtExpected, dueAsOfExpected); |
| |
| boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues)); |
| |
| assertThat(containsExpectedValues).as(ErrorMessageHelper.wrongValueInLineInChargesTab(1, actualValuesList, expectedValues)) |
| .isTrue(); |
| } |
| |
| @Then("Loan Charges tab has the following data:") |
| public void loanChargesTabCheck(DataTable table) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "charges", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| List<GetLoansLoanIdLoanChargeData> charges = loanDetailsResponse.body().getCharges(); |
| |
| List<List<String>> data = table.asLists(); |
| for (int i = 1; i < data.size(); i++) { |
| List<String> expectedValues = data.get(i); |
| String paymentDueAtExpected = expectedValues.get(2); |
| String dueAsOfExpected = expectedValues.get(3); |
| List<List<String>> actualValuesList = getActualValuesList(charges, paymentDueAtExpected, dueAsOfExpected); |
| |
| boolean containsExpectedValues = actualValuesList.stream().anyMatch(actualValues -> actualValues.equals(expectedValues)); |
| |
| assertThat(containsExpectedValues).as(ErrorMessageHelper.wrongValueInLineInChargesTab(i, actualValuesList, expectedValues)) |
| .isTrue(); |
| } |
| } |
| |
| private List<List<String>> getActualValuesList(List<GetLoansLoanIdLoanChargeData> charges, String paymentDueAtExpected, |
| String dueAsOfExpected) { |
| List<GetLoansLoanIdLoanChargeData> result; |
| |
| if (dueAsOfExpected != null) { |
| result = charges.stream().filter(t -> { |
| LocalDate dueDate = t.getDueDate(); |
| return dueDate != null && dueAsOfExpected.equals(FORMATTER.format(dueDate)); |
| }).collect(Collectors.toList()); |
| } else { |
| result = charges.stream().filter(t -> paymentDueAtExpected.equals(t.getChargeTimeType().getValue())) |
| .collect(Collectors.toList()); |
| } |
| |
| return result.stream().map(t -> { |
| List<String> actualValues = new ArrayList<>(); |
| actualValues.add(t.getName() == null ? null : t.getName()); |
| actualValues.add(String.valueOf(t.getPenalty() == null ? null : t.getPenalty())); |
| actualValues.add(t.getChargeTimeType().getValue() == null ? null : t.getChargeTimeType().getValue()); |
| actualValues.add(t.getDueDate() == null ? null : FORMATTER.format(t.getDueDate())); |
| actualValues.add(t.getChargeCalculationType().getValue() == null ? null : t.getChargeCalculationType().getValue()); |
| actualValues.add(t.getAmount() == null ? null : String.valueOf(t.getAmount())); |
| actualValues.add(t.getAmountPaid() == null ? null : String.valueOf(t.getAmountPaid())); |
| actualValues.add(t.getAmountWaived() == null ? null : String.valueOf(t.getAmountWaived())); |
| actualValues.add(t.getAmountOutstanding() == null ? null : String.valueOf(t.getAmountOutstanding())); |
| return actualValues; |
| }).collect(Collectors.toList()); |
| } |
| |
| @Then("Loan status will be {string}") |
| public void loanStatus(String statusExpected) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| Integer loanStatusActualValue = loanDetailsResponse.body().getStatus().getId(); |
| |
| LoanStatus loanStatusExpected = LoanStatus.valueOf(statusExpected); |
| Integer loanStatusExpectedValue = loanStatusExpected.getValue(); |
| |
| assertThat(loanStatusActualValue).as(ErrorMessageHelper.wrongLoanStatus(loanStatusActualValue, loanStatusExpectedValue)) |
| .isEqualTo(loanStatusExpectedValue); |
| } |
| |
| @Then("Admin can successfully set Fraud flag to the loan") |
| public void setFraud() throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanId = loanResponse.body().getResourceId(); |
| |
| PutLoansLoanIdRequest putLoansLoanIdRequest = LoanRequestFactory.enableFraudFlag(); |
| |
| Response<PutLoansLoanIdResponse> responseMod = loansApi.modifyLoanApplication(loanId, putLoansLoanIdRequest, "markAsFraud") |
| .execute(); |
| testContext().set(TestContextKey.LOAN_FRAUD_MODIFY_RESPONSE, responseMod); |
| |
| ErrorHelper.checkSuccessfulApiCall(responseMod); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| |
| Boolean fraudFlagActual = loanDetailsResponse.body().getFraud(); |
| assertThat(fraudFlagActual).as(ErrorMessageHelper.wrongFraudFlag(fraudFlagActual, true)).isEqualTo(true); |
| } |
| |
| @Then("Admin can successfully unset Fraud flag to the loan") |
| public void unsetFraud() throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanId = loanResponse.body().getResourceId(); |
| |
| PutLoansLoanIdRequest putLoansLoanIdRequest = LoanRequestFactory.disableFraudFlag(); |
| |
| Response<PutLoansLoanIdResponse> responseMod = loansApi.modifyLoanApplication(loanId, putLoansLoanIdRequest, "markAsFraud") |
| .execute(); |
| testContext().set(TestContextKey.LOAN_FRAUD_MODIFY_RESPONSE, responseMod); |
| ErrorHelper.checkSuccessfulApiCall(responseMod); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| |
| Boolean fraudFlagActual = loanDetailsResponse.body().getFraud(); |
| assertThat(fraudFlagActual).as(ErrorMessageHelper.wrongFraudFlag(fraudFlagActual, false)).isEqualTo(false); |
| } |
| |
| @Then("Fraud flag modification fails") |
| public void failedFraudModification() throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanId = loanResponse.body().getResourceId(); |
| |
| PutLoansLoanIdRequest putLoansLoanIdRequest = LoanRequestFactory.disableFraudFlag(); |
| |
| Response<PutLoansLoanIdResponse> responseMod = loansApi.modifyLoanApplication(loanId, putLoansLoanIdRequest, "markAsFraud") |
| .execute(); |
| testContext().set(TestContextKey.LOAN_FRAUD_MODIFY_RESPONSE, responseMod); |
| |
| ErrorResponse errorDetails = ErrorResponse.from(responseMod); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); |
| assertThat(errorDetails.getSingleError().getDeveloperMessage()) |
| .isEqualTo(ErrorMessageHelper.loanFraudFlagModificationMsg(loanId.toString())); |
| } |
| |
| @Then("Transaction response has boolean value in header {string}: {string}") |
| public void transactionHeaderCheckBoolean(String headerKey, String headerValue) { |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = testContext() |
| .get(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE); |
| String headerValueActual = paymentTransactionResponse.headers().get(headerKey); |
| assertThat(headerValueActual).as(ErrorMessageHelper.wrongValueInResponseHeader(headerKey, headerValueActual, headerValue)) |
| .isEqualTo(headerValue); |
| } |
| |
| @Then("Transaction response has {double} EUR value for transaction amount") |
| public void transactionAmountCheck(double amountExpected) { |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = testContext() |
| .get(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE); |
| Double amountActual = Double.valueOf(paymentTransactionResponse.body().getChanges().getTransactionAmount()); |
| assertThat(amountActual).as(ErrorMessageHelper.wrongAmountInTransactionsResponse(amountActual, amountExpected)) |
| .isEqualTo(amountExpected); |
| } |
| |
| @Then("Transaction response has the correct clientId and the loanId of the first transaction") |
| public void transactionClientIdAndLoanIdCheck() { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE); |
| Long clientIdExpected = clientResponse.body().getClientId(); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanIdExpected = Long.valueOf(loanResponse.body().getLoanId()); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = testContext() |
| .get(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE); |
| Long clientIdActual = paymentTransactionResponse.body().getClientId(); |
| Long loanIdActual = paymentTransactionResponse.body().getLoanId(); |
| |
| assertThat(clientIdActual).as(ErrorMessageHelper.wrongClientIdInTransactionResponse(clientIdActual, clientIdExpected)) |
| .isEqualTo(clientIdExpected); |
| assertThat(loanIdActual).as(ErrorMessageHelper.wrongLoanIdInTransactionResponse(loanIdActual, loanIdExpected)) |
| .isEqualTo(loanIdExpected); |
| } |
| |
| @Then("Transaction response has the clientId for the second client and the loanId of the second transaction") |
| public void transactionSecondClientIdAndSecondLoanIdCheck() { |
| Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_SECOND_CLIENT_RESPONSE); |
| Long clientIdExpected = clientResponse.body().getClientId(); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_SECOND_LOAN_RESPONSE); |
| Long loanIdExpected = Long.valueOf(loanResponse.body().getLoanId()); |
| |
| Response<PostLoansLoanIdTransactionsResponse> paymentTransactionResponse = testContext() |
| .get(TestContextKey.LOAN_PAYMENT_TRANSACTION_RESPONSE); |
| Long clientIdActual = paymentTransactionResponse.body().getClientId(); |
| Long loanIdActual = paymentTransactionResponse.body().getLoanId(); |
| |
| assertThat(clientIdActual).as(ErrorMessageHelper.wrongClientIdInTransactionResponse(clientIdActual, clientIdExpected)) |
| .isEqualTo(clientIdExpected); |
| assertThat(loanIdActual).as(ErrorMessageHelper.wrongLoanIdInTransactionResponse(loanIdActual, loanIdExpected)) |
| .isEqualTo(loanIdExpected); |
| } |
| |
| @Then("Loan has {int} {string} transactions on Transactions tab") |
| public void checkNrOfTransactions(int nrOfTransactionsExpected, String transactionTypeInput) throws IOException { |
| TransactionType transactionType = TransactionType.valueOf(transactionTypeInput); |
| String transactionTypeValue = transactionType.getValue(); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetails.body().getTransactions(); |
| List<String> transactionsMatched = new ArrayList<>(); |
| |
| transactions.forEach(t -> { |
| String transactionTypeValueActual = t.getType().getCode(); |
| String transactionTypeValueExpected = "loanTransactionType." + transactionTypeValue; |
| |
| if (transactionTypeValueActual.equals(transactionTypeValueExpected)) { |
| transactionsMatched.add(transactionTypeValueActual); |
| } |
| }); |
| |
| int nrOfTransactionsActual = transactionsMatched.size(); |
| assertThat(nrOfTransactionsActual) |
| .as(ErrorMessageHelper.wrongNrOfTransactions(transactionTypeInput, nrOfTransactionsActual, nrOfTransactionsExpected)) |
| .isEqualTo(nrOfTransactionsExpected); |
| } |
| |
| @Then("Second loan has {int} {string} transactions on Transactions tab") |
| public void checkNrOfTransactionsOnSecondLoan(int nrOfTransactionsExpected, String transactionTypeInput) throws IOException { |
| TransactionType transactionType = TransactionType.valueOf(transactionTypeInput); |
| String transactionTypeValue = transactionType.getValue(); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_SECOND_LOAN_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetails.body().getTransactions(); |
| List<String> transactionsMatched = new ArrayList<>(); |
| |
| transactions.forEach(t -> { |
| String transactionTypeValueActual = t.getType().getCode(); |
| String transactionTypeValueExpected = "loanTransactionType." + transactionTypeValue; |
| |
| if (transactionTypeValueActual.equals(transactionTypeValueExpected)) { |
| transactionsMatched.add(transactionTypeValueActual); |
| } |
| }); |
| |
| int nrOfTransactionsActual = transactionsMatched.size(); |
| assertThat(nrOfTransactionsActual) |
| .as(ErrorMessageHelper.wrongNrOfTransactions(transactionTypeInput, nrOfTransactionsActual, nrOfTransactionsExpected)) |
| .isEqualTo(nrOfTransactionsExpected); |
| } |
| |
| @Then("Loan status has changed to {string}") |
| public void loanStatusHasChangedTo(String loanStatus) { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| LoanStatusEnumDataV1 expectedStatus = getExpectedStatus(loanStatus); |
| eventAssertion.assertEvent(LoanStatusChangedEvent.class, loanId).extractingData(LoanAccountDataV1::getStatus) |
| .isEqualTo(expectedStatus); |
| } |
| |
| @Then("Loan marked as charged-off on {string}") |
| public void isLoanChargedOff(String chargeOffDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| testContext().set(TestContextKey.LOAN_RESPONSE, loanDetailsResponse); |
| |
| LocalDate expectedChargeOffDate = LocalDate.parse(chargeOffDate, FORMATTER); |
| |
| assertThat(loanDetailsResponse.body().getChargedOff()).isEqualTo(true); |
| assertThat(loanDetailsResponse.body().getTimeline().getChargedOffOnDate()).isEqualTo(expectedChargeOffDate); |
| } |
| |
| @And("Admin checks that last closed business date of loan is {string}") |
| public void getLoanLastCOBDate(String date) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetails); |
| if ("null".equals(date)) { |
| assertThat(loanDetails.body().getLastClosedBusinessDate()).isNull(); |
| } else { |
| assertThat(FORMATTER.format(Objects.requireNonNull(loanDetails.body().getLastClosedBusinessDate()))).isEqualTo(date); |
| } |
| } |
| |
| @When("Admin runs COB catch up") |
| public void runLoanCOBCatchUp() throws IOException { |
| Response<Void> catchUpResponse = loanCobCatchUpApi.executeLoanCOBCatchUp().execute(); |
| ErrorHelper.checkSuccessfulApiCall(catchUpResponse); |
| } |
| |
| @When("Admin checks that Loan COB is running until the current business date") |
| public void checkLoanCOBCatchUpRunningUntilCOBBusinessDate() { |
| await().pollInterval(2, TimeUnit.SECONDS).atMost(Duration.ofSeconds(20)).until(() -> { |
| Response<IsCatchUpRunningResponse> isCatchUpRunningResponse = loanCobCatchUpApi.isCatchUpRunning().execute(); |
| ErrorHelper.checkSuccessfulApiCall(isCatchUpRunningResponse); |
| IsCatchUpRunningResponse isCatchUpRunning = isCatchUpRunningResponse.body(); |
| return isCatchUpRunning.getIsCatchUpRunning(); |
| }); |
| await().pollInterval(2, TimeUnit.SECONDS).atMost(Duration.ofSeconds(240)).until(() -> { |
| Response<IsCatchUpRunningResponse> isCatchUpRunningResponse = loanCobCatchUpApi.isCatchUpRunning().execute(); |
| ErrorHelper.checkSuccessfulApiCall(isCatchUpRunningResponse); |
| IsCatchUpRunningResponse isCatchUpRunning = isCatchUpRunningResponse.body(); |
| return !isCatchUpRunning.getIsCatchUpRunning(); |
| }); |
| } |
| |
| @Then("Loan's actualMaturityDate is {string}") |
| public void checkActualMaturityDate(String actualMaturityDateExpected) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| LocalDate actualMaturityDate = loanDetailsResponse.body().getTimeline().getActualMaturityDate(); |
| String actualMaturityDateActual = FORMATTER.format(actualMaturityDate); |
| |
| assertThat(actualMaturityDateActual) |
| .as(ErrorMessageHelper.wrongDataInActualMaturityDate(actualMaturityDateActual, actualMaturityDateExpected)) |
| .isEqualTo(actualMaturityDateExpected); |
| } |
| |
| @Then("LoanAccrualTransactionCreatedBusinessEvent is raised on {string}") |
| public void checkLoanAccrualTransactionCreatedBusinessEvent(String date) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| GetLoansLoanIdTransactions accrualTransaction = transactions.stream() |
| .filter(t -> date.equals(FORMATTER.format(t.getDate())) && "Accrual".equals(t.getType().getValue())).findFirst() |
| .orElseThrow(() -> new IllegalStateException(String.format("No Accrual transaction found on %s", date))); |
| Long accrualTransactionId = accrualTransaction.getId(); |
| |
| eventAssertion.assertEventRaised(LoanAccrualTransactionCreatedBusinessEvent.class, accrualTransactionId); |
| } |
| |
| @Then("Loan details and event has the following last repayment related data:") |
| public void checkLastRepaymentData(DataTable table) throws IOException { |
| List<List<String>> data = table.asLists(); |
| List<String> expectedValues = data.get(1); |
| String lastPaymentAmountExpected = expectedValues.get(0); |
| String lastPaymentDateExpected = expectedValues.get(1); |
| String lastRepaymentAmountExpected = expectedValues.get(2); |
| String lastRepaymentDateExpected = expectedValues.get(3); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "collection", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| GetLoansLoanIdDelinquencySummary delinquent = loanDetailsResponse.body().getDelinquent(); |
| String lastPaymentAmountActual = String.valueOf(delinquent.getLastPaymentAmount()); |
| String lastPaymentDateActual = FORMATTER.format(delinquent.getLastPaymentDate()); |
| String lastRepaymentAmountActual = String.valueOf(delinquent.getLastRepaymentAmount()); |
| String lastRepaymentDateActual = FORMATTER.format(delinquent.getLastRepaymentDate()); |
| |
| assertThat(lastPaymentAmountActual) |
| .as(ErrorMessageHelper.wrongDataInLastPaymentAmount(lastPaymentAmountActual, lastPaymentAmountExpected)) |
| .isEqualTo(lastPaymentAmountExpected); |
| assertThat(lastPaymentDateActual).as(ErrorMessageHelper.wrongDataInLastPaymentDate(lastPaymentDateActual, lastPaymentDateExpected)) |
| .isEqualTo(lastPaymentDateExpected); |
| assertThat(lastRepaymentAmountActual) |
| .as(ErrorMessageHelper.wrongDataInLastRepaymentAmount(lastRepaymentAmountActual, lastRepaymentAmountExpected)) |
| .isEqualTo(lastRepaymentAmountExpected); |
| assertThat(lastRepaymentDateActual) |
| .as(ErrorMessageHelper.wrongDataInLastRepaymentDate(lastRepaymentDateActual, lastRepaymentDateExpected)) |
| .isEqualTo(lastRepaymentDateExpected); |
| |
| eventAssertion.assertEvent(LoanStatusChangedEvent.class, loanId).extractingData(loanAccountDataV1 -> { |
| String lastPaymentAmountEvent = String.valueOf(loanAccountDataV1.getDelinquent().getLastPaymentAmount().doubleValue()); |
| String lastPaymentDateEvent = FORMATTER.format(LocalDate.parse(loanAccountDataV1.getDelinquent().getLastPaymentDate())); |
| String lastRepaymentAmountEvent = String.valueOf(loanAccountDataV1.getDelinquent().getLastRepaymentAmount().doubleValue()); |
| String lastRepaymentDateEvent = FORMATTER.format(LocalDate.parse(loanAccountDataV1.getDelinquent().getLastRepaymentDate())); |
| |
| assertThat(lastPaymentAmountEvent) |
| .as(ErrorMessageHelper.wrongDataInLastPaymentAmount(lastPaymentAmountEvent, lastPaymentAmountExpected)) |
| .isEqualTo(lastPaymentAmountExpected); |
| assertThat(lastPaymentDateEvent) |
| .as(ErrorMessageHelper.wrongDataInLastPaymentDate(lastPaymentDateEvent, lastPaymentDateExpected)) |
| .isEqualTo(lastPaymentDateExpected); |
| assertThat(lastRepaymentAmountEvent) |
| .as(ErrorMessageHelper.wrongDataInLastRepaymentAmount(lastRepaymentAmountEvent, lastRepaymentAmountExpected)) |
| .isEqualTo(lastRepaymentAmountExpected); |
| assertThat(lastRepaymentDateEvent) |
| .as(ErrorMessageHelper.wrongDataInLastRepaymentDate(lastRepaymentDateEvent, lastRepaymentDateExpected)) |
| .isEqualTo(lastRepaymentDateExpected); |
| |
| return null; |
| }); |
| |
| } |
| |
| @And("Admin does a charge-off undo the loan with reversal external Id") |
| public void chargeOffUndoWithReversalExternalId() throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| String reversalExternalId = Utils.randomNameGenerator("reversalExtId_", 3); |
| PostLoansLoanIdTransactionsRequest chargeOffUndoRequest = LoanRequestFactory.defaultUndoChargeOffRequest() |
| .reversalExternalId(reversalExternalId); |
| |
| Response<PostLoansLoanIdTransactionsResponse> chargeOffUndoResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, chargeOffUndoRequest, "undo-charge-off").execute(); |
| testContext().set(TestContextKey.LOAN_CHARGE_OFF_UNDO_RESPONSE, chargeOffUndoResponse); |
| ErrorHelper.checkSuccessfulApiCall(chargeOffUndoResponse); |
| |
| Long transactionId = chargeOffUndoResponse.body().getResourceId(); |
| |
| Response<GetLoansLoanIdTransactionsTransactionIdResponse> transactionResponse = loanTransactionsApi |
| .retrieveTransaction(loanId, transactionId, "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(transactionResponse); |
| assertThat(transactionResponse.body().getReversalExternalId()).isEqualTo(reversalExternalId); |
| } |
| |
| @Then("Loan Charge-off undo event has reversed on date {string} for charge-off undo") |
| public void reversedOnDateIsNotNullForEvent(String reversedDate) throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanCreateResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| |
| List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions(); |
| GetLoansLoanIdTransactions chargeOffTransaction = transactions.stream().filter(t -> "Charge-off".equals(t.getType().getValue())) |
| .findFirst().orElseThrow(() -> new IllegalStateException(String.format("No transaction found"))); |
| Long chargeOffTransactionId = chargeOffTransaction.getId(); |
| |
| eventAssertion.assertEvent(LoanChargeOffUndoEvent.class, chargeOffTransactionId).extractingData(loanTransactionDataV1 -> { |
| String reversedOnDate = FORMATTER.format(LocalDate.parse(loanTransactionDataV1.getReversedOnDate())); |
| assertThat(reversedOnDate).isEqualTo(reversedDate); |
| return null; |
| }); |
| } |
| |
| @Then("Loan has the following maturity data:") |
| public void checkMaturity(DataTable table) throws IOException { |
| List<List<String>> data = table.asLists(); |
| List<String> expectedValues = data.get(1); |
| String actualMaturityDateExpected = expectedValues.get(0); |
| String expectedMaturityDateExpected = expectedValues.get(1); |
| |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse); |
| GetLoansLoanIdTimeline timeline = loanDetailsResponse.body().getTimeline(); |
| String actualMaturityDateActual = FORMATTER.format(timeline.getActualMaturityDate()); |
| String expectedMaturityDateActual = FORMATTER.format(timeline.getExpectedMaturityDate()); |
| |
| assertThat(actualMaturityDateActual) |
| .as(ErrorMessageHelper.wrongDataInActualMaturityDate(actualMaturityDateActual, actualMaturityDateExpected)) |
| .isEqualTo(actualMaturityDateExpected); |
| assertThat(expectedMaturityDateActual) |
| .as(ErrorMessageHelper.wrongDataInExpectedMaturityDate(expectedMaturityDateActual, expectedMaturityDateExpected)) |
| .isEqualTo(expectedMaturityDateExpected); |
| } |
| |
| @Then("Admin successfully deletes the loan with external id") |
| public void deleteLoanWithExternalId() throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| Long loanId = loanCreateResponse.body().getLoanId(); |
| String loanExternalId = loanCreateResponse.body().getResourceExternalId(); |
| Response<DeleteLoansLoanIdResponse> deleteLoanResponse = loansApi.deleteLoanApplication1(loanExternalId).execute(); |
| assertThat(deleteLoanResponse.body().getLoanId()).isEqualTo(loanId); |
| assertThat(deleteLoanResponse.body().getResourceExternalId()).isEqualTo(loanExternalId); |
| } |
| |
| @Then("Admin fails to delete the loan with incorrect external id") |
| public void failedDeleteLoanWithExternalId() throws IOException { |
| Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| String loanExternalId = loanCreateResponse.body().getResourceExternalId(); |
| Response<DeleteLoansLoanIdResponse> deleteLoanResponse = loansApi.deleteLoanApplication1(loanExternalId.substring(5)).execute(); |
| ErrorResponse errorDetails = ErrorResponse.from(deleteLoanResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(404); |
| } |
| |
| @When("Admin set {string} loan product {string} transaction type to {string} future installment allocation rule") |
| public void editFutureInstallmentAllocationTypeForLoanProduct(String loanProductName, String transactionTypeToChange, |
| String futureInstallmentAllocationRuleNew) throws IOException { |
| DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProductName); |
| Long loanProductId = loanProductResolver.resolve(product); |
| log.info("loanProductId {}", loanProductId); |
| |
| Response<GetLoanProductsProductIdResponse> loanProductDetails = loanProductsApi.retrieveLoanProductDetails(loanProductId).execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanProductDetails); |
| List<AdvancedPaymentData> paymentAllocation = loanProductDetails.body().getPaymentAllocation(); |
| |
| List<AdvancedPaymentData> newPaymentAllocation = new ArrayList<>(); |
| paymentAllocation.forEach(e -> { |
| String transactionTypeOriginal = e.getTransactionType(); |
| String futureInstallmentAllocationRule = e.getFutureInstallmentAllocationRule(); |
| if (transactionTypeToChange.equals(transactionTypeOriginal)) { |
| futureInstallmentAllocationRule = futureInstallmentAllocationRuleNew; |
| } |
| newPaymentAllocation.add( |
| LoanProductGlobalInitializerStep.createPaymentAllocation(transactionTypeOriginal, futureInstallmentAllocationRule)); |
| }); |
| |
| PutLoanProductsProductIdRequest putLoanProductsProductIdRequest = new PutLoanProductsProductIdRequest() |
| .transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue()).paymentAllocation(newPaymentAllocation); |
| |
| Response<PutLoanProductsProductIdResponse> response = loanProductsApi |
| .updateLoanProduct(loanProductId, putLoanProductsProductIdRequest).execute(); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| } |
| |
| @When("Admin sets repaymentStartDateType for {string} loan product to {string}") |
| public void editRepaymentStartDateType(String loanProductName, String repaymentStartDateType) throws IOException { |
| DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProductName); |
| Long loanProductId = loanProductResolver.resolve(product); |
| log.info("loanProductId {}", loanProductId); |
| |
| Map<String, Integer> repaymentStartDateTypeMap = Map.of("DISBURSEMENT_DATE", 1, "SUBMITTED_ON_DATE", 2); |
| |
| if (!repaymentStartDateTypeMap.containsKey(repaymentStartDateType)) { |
| throw new IllegalArgumentException(String |
| .format("Invalid repaymentStartDateType: %s. Must be DISBURSEMENT_DATE or SUBMITTED_ON_DATE.", repaymentStartDateType)); |
| } |
| |
| int repaymentStartDateTypeValue = repaymentStartDateTypeMap.get(repaymentStartDateType); |
| PutLoanProductsProductIdRequest putLoanProductsProductIdRequest = new PutLoanProductsProductIdRequest()// |
| .repaymentStartDateType(repaymentStartDateTypeValue)// |
| .locale(DEFAULT_LOCALE);// |
| |
| Response<PutLoanProductsProductIdResponse> response = loanProductsApi |
| .updateLoanProduct(loanProductId, putLoanProductsProductIdRequest).execute(); |
| ErrorHelper.checkSuccessfulApiCall(response); |
| } |
| |
| @And("Admin does write-off the loan on {string}") |
| public void writeOffLoan(String transactionDate) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| PostLoansLoanIdTransactionsRequest writeOffRequest = LoanRequestFactory.defaultWriteOffRequest().transactionDate(transactionDate) |
| .dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); |
| |
| Response<PostLoansLoanIdTransactionsResponse> writeOffResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, writeOffRequest, "writeoff").execute(); |
| testContext().set(TestContextKey.LOAN_WRITE_OFF_RESPONSE, writeOffResponse); |
| ErrorHelper.checkSuccessfulApiCall(writeOffResponse); |
| } |
| |
| @Then("Admin fails to undo {string}th transaction made on {string}") |
| public void undoTransaction(String nthTransaction, String transactionDate) throws IOException { |
| DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT); |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| List<GetLoansLoanIdTransactions> transactions = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute().body() |
| .getTransactions(); |
| |
| int nthItem = Integer.parseInt(nthTransaction) - 1; |
| GetLoansLoanIdTransactions targetTransaction = transactions.stream() |
| .filter(t -> transactionDate.equals(formatter.format(t.getDate()))).toList().get(nthItem); |
| |
| PostLoansLoanIdTransactionsTransactionIdRequest transactionUndoRequest = LoanRequestFactory.defaultTransactionUndoRequest() |
| .transactionDate(transactionDate); |
| |
| Response<PostLoansLoanIdTransactionsResponse> transactionUndoResponse = loanTransactionsApi |
| .adjustLoanTransaction(loanId, targetTransaction.getId(), transactionUndoRequest, "").execute(); |
| ErrorResponse errorDetails = ErrorResponse.from(transactionUndoResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(503); |
| |
| } |
| |
| @Then("Loan {string} repayment transaction on {string} with {double} EUR transaction amount results in error") |
| public void loanTransactionWithErrorCheck(String repaymentType, String transactionDate, double transactionAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| DefaultPaymentType paymentType = DefaultPaymentType.valueOf(repaymentType); |
| long paymentTypeValue = paymentTypeResolver.resolve(paymentType); |
| |
| Map<String, String> headerMap = new HashMap<>(); |
| |
| PostLoansLoanIdTransactionsRequest repaymentRequest = LoanRequestFactory.defaultRepaymentRequest().transactionDate(transactionDate) |
| .transactionAmount(transactionAmount).paymentTypeId(paymentTypeValue).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); |
| |
| Response<PostLoansLoanIdTransactionsResponse> repaymentResponse = loanTransactionsApi |
| .executeLoanTransaction(loanId, repaymentRequest, "repayment", headerMap).execute(); |
| |
| ErrorResponse errorDetails = ErrorResponse.from(repaymentResponse); |
| assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(400); |
| |
| } |
| |
| @Then("Loan details has the downpayment amount {string} in summary.totalRepaymentTransaction") |
| public void totalRepaymentTransaction(String expectedAmount) throws IOException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetails); |
| |
| Double expectedAmountParsed = Double.parseDouble(expectedAmount); |
| Double totalRepaymentTransaction = loanDetails.body().getSummary().getTotalRepaymentTransaction(); |
| |
| assertThat(totalRepaymentTransaction) |
| .as(ErrorMessageHelper.wrongAmountInTotalRepaymentTransaction(totalRepaymentTransaction, expectedAmountParsed)) |
| .isEqualTo(expectedAmountParsed); |
| } |
| |
| @Then("LoanDetails has fixedLength field with int value: {int}") |
| public void checkLoanDetailsFieldAndValueInt(int fieldValue) throws IOException, NoSuchMethodException { |
| Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); |
| long loanId = loanResponse.body().getLoanId(); |
| |
| Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute(); |
| ErrorHelper.checkSuccessfulApiCall(loanDetails); |
| |
| Integer fixedLengthactual = loanDetails.body().getFixedLength(); |
| assertThat(fixedLengthactual).as(ErrorMessageHelper.wrongfixedLength(fixedLengthactual, fieldValue)).isEqualTo(fieldValue); |
| } |
| |
| private LoanStatusEnumDataV1 getExpectedStatus(String loanStatus) { |
| LoanStatusEnumDataV1 result = new LoanStatusEnumDataV1(); |
| switch (loanStatus) { |
| case "Submitted and pending approval" -> { |
| result.setId(100); |
| result.setCode("loanStatusType.submitted.and.pending.approval"); |
| result.setValue("Submitted and pending approval"); |
| result.setPendingApproval(true); |
| result.setWaitingForDisbursal(false); |
| result.setActive(false); |
| result.setClosedObligationsMet(false); |
| result.setClosedWrittenOff(false); |
| result.setClosedRescheduled(false); |
| result.setClosed(false); |
| result.setOverpaid(false); |
| } |
| case "Approved" -> { |
| result.setId(200); |
| result.setCode("loanStatusType.approved"); |
| result.setValue("Approved"); |
| result.setPendingApproval(false); |
| result.setWaitingForDisbursal(true); |
| result.setActive(false); |
| result.setClosedObligationsMet(false); |
| result.setClosedWrittenOff(false); |
| result.setClosedRescheduled(false); |
| result.setClosed(false); |
| result.setOverpaid(false); |
| } |
| case "Active" -> { |
| result.setId(300); |
| result.setCode("loanStatusType.active"); |
| result.setValue("Active"); |
| result.setPendingApproval(false); |
| result.setWaitingForDisbursal(false); |
| result.setActive(true); |
| result.setClosedObligationsMet(false); |
| result.setClosedWrittenOff(false); |
| result.setClosedRescheduled(false); |
| result.setClosed(false); |
| result.setOverpaid(false); |
| } |
| case "Closed (obligations met)" -> { |
| result.setId(600); |
| result.setCode("loanStatusType.closed.obligations.met"); |
| result.setValue("Closed (obligations met)"); |
| result.setPendingApproval(false); |
| result.setWaitingForDisbursal(false); |
| result.setActive(false); |
| result.setClosedObligationsMet(true); |
| result.setClosedWrittenOff(false); |
| result.setClosedRescheduled(false); |
| result.setClosed(true); |
| result.setOverpaid(false); |
| } |
| case "Overpaid" -> { |
| result.setId(700); |
| result.setCode("loanStatusType.overpaid"); |
| result.setValue("Overpaid"); |
| result.setPendingApproval(false); |
| result.setWaitingForDisbursal(false); |
| result.setActive(false); |
| result.setClosedObligationsMet(false); |
| result.setClosedWrittenOff(false); |
| result.setClosedRescheduled(false); |
| result.setClosed(false); |
| result.setOverpaid(true); |
| |
| } |
| default -> throw new UnsupportedOperationException("Not yet covered loan status: " + loanStatus); |
| } |
| return result; |
| } |
| |
| @SuppressFBWarnings("SF_SWITCH_NO_DEFAULT") |
| private List<String> fetchValuesOfTransaction(List<String> header, GetLoansLoanIdTransactions t) { |
| List<String> actualValues = new ArrayList<>(); |
| for (String headerName : header) { |
| switch (headerName) { |
| case "Transaction date" -> actualValues.add(t.getDate() == null ? null : FORMATTER.format(t.getDate())); |
| case "Transaction Type" -> actualValues.add(t.getType().getValue() == null ? null : t.getType().getValue()); |
| case "Amount" -> actualValues.add(t.getAmount() == null ? null : String.valueOf(t.getAmount())); |
| case "Principal" -> actualValues.add(t.getPrincipalPortion() == null ? null : String.valueOf(t.getPrincipalPortion())); |
| case "Interest" -> actualValues.add(t.getInterestPortion() == null ? null : String.valueOf(t.getInterestPortion())); |
| case "Fees" -> actualValues.add(t.getFeeChargesPortion() == null ? null : String.valueOf(t.getFeeChargesPortion())); |
| case "Penalties" -> |
| actualValues.add(t.getPenaltyChargesPortion() == null ? null : String.valueOf(t.getPenaltyChargesPortion())); |
| case "Loan Balance" -> |
| actualValues.add(t.getOutstandingLoanBalance() == null ? null : String.valueOf(t.getOutstandingLoanBalance())); |
| case "Overpayment" -> |
| actualValues.add(t.getOverpaymentPortion() == null ? null : String.valueOf(t.getOverpaymentPortion())); |
| case "Reverted" -> actualValues.add(t.getManuallyReversed() == null ? null : String.valueOf(t.getManuallyReversed())); |
| } |
| } |
| return actualValues; |
| } |
| |
| @SuppressFBWarnings("SF_SWITCH_NO_DEFAULT") |
| private List<String> fetchValuesOfRepaymentSchedule(List<String> header, GetLoansLoanIdRepaymentPeriod repaymentPeriod) { |
| List<String> actualValues = new ArrayList<>(); |
| for (String headerName : header) { |
| switch (headerName) { |
| case "Nr" -> actualValues.add(repaymentPeriod.getPeriod() == null ? null : String.valueOf(repaymentPeriod.getPeriod())); |
| case "Days" -> |
| actualValues.add(repaymentPeriod.getDaysInPeriod() == null ? null : String.valueOf(repaymentPeriod.getDaysInPeriod())); |
| case "Date" -> |
| actualValues.add(repaymentPeriod.getDueDate() == null ? null : FORMATTER.format(repaymentPeriod.getDueDate())); |
| case "Paid date" -> actualValues.add(repaymentPeriod.getObligationsMetOnDate() == null ? null |
| : FORMATTER.format(repaymentPeriod.getObligationsMetOnDate())); |
| case "Balance of loan" -> actualValues.add(repaymentPeriod.getPrincipalLoanBalanceOutstanding() == null ? null |
| : String.valueOf(repaymentPeriod.getPrincipalLoanBalanceOutstanding())); |
| case "Principal due" -> |
| actualValues.add(repaymentPeriod.getPrincipalDue() == null ? null : String.valueOf(repaymentPeriod.getPrincipalDue())); |
| case "Interest" -> |
| actualValues.add(repaymentPeriod.getInterestDue() == null ? null : String.valueOf(repaymentPeriod.getInterestDue())); |
| case "Fees" -> actualValues |
| .add(repaymentPeriod.getFeeChargesDue() == null ? null : String.valueOf(repaymentPeriod.getFeeChargesDue())); |
| case "Penalties" -> actualValues.add( |
| repaymentPeriod.getPenaltyChargesDue() == null ? null : String.valueOf(repaymentPeriod.getPenaltyChargesDue())); |
| case "Due" -> actualValues.add( |
| repaymentPeriod.getTotalDueForPeriod() == null ? null : String.valueOf(repaymentPeriod.getTotalDueForPeriod())); |
| case "Paid" -> actualValues.add( |
| repaymentPeriod.getTotalPaidForPeriod() == null ? null : String.valueOf(repaymentPeriod.getTotalPaidForPeriod())); |
| case "In advance" -> actualValues.add(repaymentPeriod.getTotalPaidInAdvanceForPeriod() == null ? null |
| : String.valueOf(repaymentPeriod.getTotalPaidInAdvanceForPeriod())); |
| case "Late" -> actualValues.add(repaymentPeriod.getTotalPaidLateForPeriod() == null ? null |
| : String.valueOf(repaymentPeriod.getTotalPaidLateForPeriod())); |
| case "Waived" -> actualValues.add(repaymentPeriod.getTotalWaivedForPeriod() == null ? null |
| : String.valueOf(repaymentPeriod.getTotalWaivedForPeriod())); |
| case "Outstanding" -> actualValues.add(repaymentPeriod.getTotalOutstandingForPeriod() == null ? null |
| : String.valueOf(repaymentPeriod.getTotalOutstandingForPeriod())); |
| } |
| } |
| return actualValues; |
| } |
| |
| @SuppressFBWarnings("SF_SWITCH_NO_DEFAULT") |
| private List<String> validateRepaymentScheduleTotal(List<String> header, GetLoansLoanIdRepaymentSchedule repaymentSchedule, |
| List<String> expectedAmounts) { |
| List<String> actualValues = new ArrayList<>(); |
| // total paid for all periods |
| Double paidActual = 0.0; |
| List<GetLoansLoanIdRepaymentPeriod> periods = repaymentSchedule.getPeriods(); |
| for (GetLoansLoanIdRepaymentPeriod period : periods) { |
| if (null != period.getTotalPaidForPeriod()) { |
| paidActual += period.getTotalPaidForPeriod(); |
| } |
| } |
| BigDecimal paidActualBd = new BigDecimal(paidActual).setScale(2, RoundingMode.HALF_DOWN); |
| |
| for (int i = 0; i < header.size(); i++) { |
| String headerName = header.get(i); |
| String expectedValue = expectedAmounts.get(i); |
| switch (headerName) { |
| case "Principal due" -> assertThat(repaymentSchedule.getTotalPrincipalExpected())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentSchedulePrincipal(repaymentSchedule.getTotalPrincipalExpected(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Interest" -> assertThat(repaymentSchedule.getTotalInterestCharged())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentScheduleInterest(repaymentSchedule.getTotalInterestCharged(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Fees" -> assertThat(repaymentSchedule.getTotalFeeChargesCharged())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentScheduleFees(repaymentSchedule.getTotalFeeChargesCharged(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Penalties" -> assertThat(repaymentSchedule.getTotalPenaltyChargesCharged())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentSchedulePenalties(repaymentSchedule.getTotalPenaltyChargesCharged(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Due" -> assertThat(repaymentSchedule.getTotalRepaymentExpected())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentScheduleDue(repaymentSchedule.getTotalRepaymentExpected(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Paid" -> assertThat(paidActualBd.doubleValue())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentSchedulePaid(paidActualBd.doubleValue(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "In advance" -> assertThat(repaymentSchedule.getTotalPaidInAdvance())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentScheduleInAdvance(repaymentSchedule.getTotalPaidInAdvance(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Late" -> assertThat(repaymentSchedule.getTotalPaidLate())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentScheduleLate(repaymentSchedule.getTotalPaidLate(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Waived" -> assertThat(repaymentSchedule.getTotalWaived())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentScheduleWaived(repaymentSchedule.getTotalWaived(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| case "Outstanding" -> assertThat(repaymentSchedule.getTotalOutstanding())// |
| .as(ErrorMessageHelper.wrongAmountInRepaymentScheduleOutstanding(repaymentSchedule.getTotalOutstanding(), |
| Double.valueOf(expectedValue)))// |
| .isEqualTo(Double.valueOf(expectedValue));// |
| } |
| } |
| return actualValues; |
| } |
| } |