Skip to content

Commit 37a0097

Browse files
authored
Merge pull request #5638
FINERACT-2541: owner to owner transfer functionality
2 parents 94639a7 + 6bf0dee commit 37a0097

12 files changed

Lines changed: 632 additions & 46 deletions

File tree

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/AssetExternalizationErrorMessage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public enum AssetExternalizationErrorMessage {
3131
LOAN_CLOSED_OBLIGATIONS_MET_INVALID("Loan status CLOSED_OBLIGATIONS_MET is not valid for transfer."), //
3232
LOAN_SUBMITTED_AND_PENDING_APPROVAL_INVALID("Loan status SUBMITTED_AND_PENDING_APPROVAL is not valid for transfer."), //
3333
LOAN_APPROVED_INVALID("Loan status APPROVED is not valid for transfer."), //
34+
ALREADY_IN_PROGRESS("This loan cannot be sold, there is already an in progress transfer"), //
3435
INVALID_REQUEST("The request was invalid. This typically will happen due to validation errors which are provided."); //
3536

3637
public final String value;

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/assetexternalization/AssetExternalizationStepDef.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ private void createAssetExternalizationRequestByLoanId(DataTable table, String t
159159
} else if ((transferData.get(0).equals(TRANSACTION_TYPE_SALE) || transferData.get(0).equals(TRANSACTION_TYPE_INTERMEDIARY_SALE))) {
160160
String ownerExternalId;
161161
if (regenerateOwner) {
162+
// For owner-to-owner transfers: preserve the current owner as previous owner
163+
String currentOwner = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
164+
if (currentOwner != null && !transferData.get(0).equals(TRANSACTION_TYPE_INTERMEDIARY_SALE)) {
165+
testContext().set(TestContextKey.ASSET_EXTERNALIZATION_PREVIOUS_OWNER_EXTERNAL_ID, currentOwner);
166+
}
162167
ownerExternalId = Utils.randomStringGenerator(OWNER_EXTERNAL_ID_PREFIX, 10);
163168
} else {
164169
ownerExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID);
@@ -369,13 +374,20 @@ private void checkExternalAssetDetails(Long loanId, String loanExternalId, PageE
369374
previousAssetOwner = null;
370375
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
371376
}
372-
} else { // in case transfer has previous intermediarySale transfer
377+
} else { // in case transfer has previous intermediarySale or owner-to-owner transfer
373378
if (transactionType.equalsIgnoreCase(TRANSACTION_TYPE_SALE)
374379
&& (status.equals(ExternalTransferData.StatusEnum.ACTIVE.getValue())
375380
|| status.equals(ExternalTransferData.StatusEnum.PENDING.getValue()))) {
376381
ownerExternalId = ownerExternalIdStored;
377382
previousAssetOwner = intermediarySaleAssetOwner;
378383
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
384+
} else if (transactionType.equalsIgnoreCase(TRANSACTION_TYPE_SALE)
385+
&& (status.equals(ExternalTransferData.StatusEnum.DECLINED.getValue())
386+
|| status.equals(ExternalTransferData.StatusEnum.CANCELLED.getValue()))) {
387+
// DECLINED and CANCELLED records have previousOwner = null in the API response
388+
ownerExternalId = ownerExternalIdStored;
389+
previousAssetOwner = null;
390+
transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
379391
} else if (transactionType.equalsIgnoreCase(TRANSACTION_TYPE_BUYBACK)
380392
&& (status.equals(ExternalTransferData.StatusEnum.BUYBACK.getValue())
381393
|| status.equals(ExternalTransferData.StatusEnum.BUYBACK_INTERMEDIATE.getValue()))) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ public void makeLoanRepaymentAndCheckOwner(String repaymentType, String transact
104104
makeRepayment(repaymentType, transactionDate, transactionAmount, transferExternalOwnerId);
105105
}
106106

107+
@And("Customer makes {string} repayment on {string} with {double} EUR transaction amount and check previous external owner")
108+
public void makeLoanRepaymentAndCheckPreviousOwner(String repaymentType, String transactionDate, double transactionAmount)
109+
throws IOException {
110+
String previousOwnerId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_PREVIOUS_OWNER_EXTERNAL_ID);
111+
makeRepayment(repaymentType, transactionDate, transactionAmount, previousOwnerId);
112+
}
113+
107114
private void makeRepayment(String repaymentType, String transactionDate, double transactionAmount, String transferExternalOwnerId)
108115
throws IOException {
109116
eventStore.reset();

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,14 @@ public void createTransactionWithAutoIdempotencyKeyWithExternalOwner(String tran
389389
transactionAmount, transferExternalOwnerId);
390390
}
391391

392+
@When("Customer makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount and system-generated Idempotency key and check previous external owner")
393+
public void createTransactionWithAutoIdempotencyKeyWithPreviousExternalOwner(String transactionTypeInput, String transactionPaymentType,
394+
String transactionDate, double transactionAmount) throws IOException {
395+
String previousOwnerId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_PREVIOUS_OWNER_EXTERNAL_ID);
396+
createTransactionWithAutoIdempotencyKeyAndWithExternalOwner(transactionTypeInput, transactionPaymentType, transactionDate,
397+
transactionAmount, previousOwnerId);
398+
}
399+
392400
@When("Customer makes {string} transaction with {string} payment type on {string} with {double} EUR transaction amount and system-generated Idempotency key and interestRefundCalculation {booleanValue}")
393401
public void createTransactionWithAutoIdempotencyKeyAndWithInterestRefundCalculationFlagProvided(final String transactionTypeInput,
394402
final String transactionPaymentType, final String transactionDate, final double transactionAmount,

fineract-e2e-tests-runner/src/test/resources/features/AssetExternalization-Part1.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ Feature: Asset Externalization - Part1
281281
| sale | 2023-05-21 | 1 |
282282

283283
@TestRailId:C2735
284-
Scenario: Verify that SALES request on a loan with ACTIVE ownership results an error
284+
Scenario: Verify that SALES request on a loan with ACTIVE ownership succeeds (owner-to-owner transfer)
285285
When Admin sets the business date to "1 May 2023"
286286
When Admin creates a client with random data
287287
When Admin creates a new default Loan with date: "1 May 2023"
@@ -304,9 +304,10 @@ Feature: Asset Externalization - Part1
304304
| 2023-05-21 | 1 | PENDING | 2023-05-01 | 2023-05-21 | SALE |
305305
| 2023-05-21 | 1 | ACTIVE | 2023-05-22 | 9999-12-31 | SALE |
306306
When Admin sets the business date to "25 May 2023"
307-
Then Asset externalization transaction with the following data results a 403 error and "ASSET_OWNED_CANNOT_BE_SOLD" error message
307+
When Admin makes asset externalization request by Loan ID with unique ownerExternalId, system-generated transferExternalId and the following data:
308308
| Transaction type | settlementDate | purchasePriceRatio |
309309
| sale | 2023-05-30 | 1 |
310+
Then Asset externalization response has the correct Loan ID, transferExternalId
310311

311312
@TestRailId:C2736
312313
Scenario: Verify that BUYBACK request on a fully paid loan can be done successfully
@@ -1810,4 +1811,3 @@ Feature: Asset Externalization - Part1
18101811

18111812
When Loan Pay-off is made on "26 June 2025"
18121813
Then Loan's all installments have obligations met
1813-

0 commit comments

Comments
 (0)