|
39 | 39 | import org.apache.fineract.integrationtests.common.ClientHelper; |
40 | 40 | import org.apache.fineract.integrationtests.common.CollateralManagementHelper; |
41 | 41 | import org.apache.fineract.integrationtests.common.CommonConstants; |
| 42 | +import org.apache.fineract.integrationtests.common.GroupHelper; |
42 | 43 | import org.apache.fineract.integrationtests.common.Utils; |
43 | 44 | import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; |
44 | 45 | import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder; |
45 | 46 | import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker; |
46 | 47 | import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension; |
47 | 48 | import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper; |
48 | 49 | import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper; |
| 50 | +import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper; |
| 51 | +import org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker; |
49 | 52 | import org.junit.jupiter.api.Assertions; |
50 | 53 | import org.junit.jupiter.api.BeforeEach; |
51 | 54 | import org.junit.jupiter.api.Test; |
@@ -735,4 +738,148 @@ private Integer applyForLoanApplication(final Integer clientID, final Integer lo |
735 | 738 | return this.loanTransactionHelper.getLoanId(loanApplicationJSON); |
736 | 739 | } |
737 | 740 |
|
| 741 | + @SuppressWarnings({ "rawtypes", "unchecked" }) |
| 742 | + @Test |
| 743 | + public void testGuarantorWithGroupSavingsAccount() { |
| 744 | + // Create a group |
| 745 | + final Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, true); |
| 746 | + Assertions.assertNotNull(groupID); |
| 747 | + LOG.info("Created group with ID: {}", groupID); |
| 748 | + |
| 749 | + // Create a client for the group |
| 750 | + final Integer clientInGroupID = ClientHelper.createClient(this.requestSpec, this.responseSpec); |
| 751 | + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientInGroupID); |
| 752 | + GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupID.toString(), clientInGroupID.toString()); |
| 753 | + LOG.info("Created and associated client with ID: {}", clientInGroupID); |
| 754 | + |
| 755 | + // Create a group savings product |
| 756 | + final String minBalanceForInterestCalculation = null; |
| 757 | + final String minRequiredBalance = null; |
| 758 | + final String enforceMinRequiredBalance = "false"; |
| 759 | + final String minOpeningBalance = "5000.0"; |
| 760 | + final String loanProductJSON = new SavingsProductHelper().withInterestCompoundingPeriodTypeAsDaily() |
| 761 | + .withInterestPostingPeriodTypeAsMonthly().withInterestCalculationPeriodTypeAsDailyBalance() |
| 762 | + .withMinBalanceForInterestCalculation(minBalanceForInterestCalculation).withMinRequiredBalance(minRequiredBalance) |
| 763 | + .withEnforceMinRequiredBalance(enforceMinRequiredBalance).withMinimumOpenningBalance(minOpeningBalance).build(); |
| 764 | + final Integer savingsProductID = SavingsProductHelper.createSavingsProduct(loanProductJSON, this.requestSpec, this.responseSpec); |
| 765 | + Assertions.assertNotNull(savingsProductID); |
| 766 | + LOG.info("Created savings product with ID: {}", savingsProductID); |
| 767 | + |
| 768 | + // Create and activate a group savings account |
| 769 | + final Integer groupSavingsId = this.savingsAccountHelper.applyForSavingsApplication(groupID, savingsProductID, "GROUP"); |
| 770 | + Assertions.assertNotNull(groupSavingsId); |
| 771 | + LOG.info("Applied for group savings account with ID: {}", groupSavingsId); |
| 772 | + |
| 773 | + HashMap savingsStatusHashMap = this.savingsAccountHelper.approveSavings(groupSavingsId); |
| 774 | + SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap); |
| 775 | + LOG.info("Approved group savings account"); |
| 776 | + |
| 777 | + savingsStatusHashMap = this.savingsAccountHelper.activateSavings(groupSavingsId); |
| 778 | + SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap); |
| 779 | + LOG.info("Activated group savings account"); |
| 780 | + |
| 781 | + // Deposit money into the group savings account |
| 782 | + Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(groupSavingsId, "5000", |
| 783 | + SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID); |
| 784 | + Assertions.assertNotNull(depositTransactionId); |
| 785 | + LOG.info("Deposited 5000 into group savings account"); |
| 786 | + |
| 787 | + // Create a client for the loan |
| 788 | + final Integer loanClientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); |
| 789 | + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, loanClientID); |
| 790 | + LOG.info("Created loan client with ID: {}", loanClientID); |
| 791 | + |
| 792 | + // Create a self savings account for the loan client (for self guarantee) |
| 793 | + final Integer selfSavingsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, loanClientID, |
| 794 | + String.valueOf(5000.0)); |
| 795 | + Assertions.assertNotNull(selfSavingsId); |
| 796 | + LOG.info("Created self savings account for loan client with ID: {}", selfSavingsId); |
| 797 | + |
| 798 | + // Create another external client and savings account for additional external guarantee |
| 799 | + final Integer externalClientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); |
| 800 | + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, externalClientID); |
| 801 | + final Integer externalSavingsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, externalClientID, |
| 802 | + String.valueOf(5000.0)); |
| 803 | + Assertions.assertNotNull(externalSavingsId); |
| 804 | + LOG.info("Created external client with ID: {} and savings account with ID: {}", externalClientID, externalSavingsId); |
| 805 | + |
| 806 | + // Create a loan product with hold funds |
| 807 | + final Integer loanProductID = createLoanProductWithHoldFunds("0", "0", "0"); |
| 808 | + Assertions.assertNotNull(loanProductID); |
| 809 | + LOG.info("Created loan product with ID: {}", loanProductID); |
| 810 | + |
| 811 | + // Apply for a loan |
| 812 | + final Integer loanID = applyForLoanApplication(loanClientID, loanProductID, SavingsAccountHelper.TRANSACTION_DATE); |
| 813 | + Assertions.assertNotNull(loanID); |
| 814 | + LOG.info("Applied for loan with ID: {}", loanID); |
| 815 | + |
| 816 | + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); |
| 817 | + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); |
| 818 | + |
| 819 | + // Create self guarantee from loan client's own savings |
| 820 | + String guarantorJSON = new GuarantorTestBuilder() |
| 821 | + .existingCustomerWithGuaranteeAmount(String.valueOf(loanClientID), String.valueOf(selfSavingsId), "2000").build(); |
| 822 | + Integer selfGuarantorId = this.guarantorHelper.createGuarantor(loanID, guarantorJSON); |
| 823 | + Assertions.assertNotNull(selfGuarantorId); |
| 824 | + LOG.info("Created self guarantor with ID: {}", selfGuarantorId); |
| 825 | + |
| 826 | + // Create a guarantor using the group savings account - THIS IS THE KEY TEST CASE |
| 827 | + guarantorJSON = new GuarantorTestBuilder() |
| 828 | + .existingCustomerWithGuaranteeAmount(String.valueOf(clientInGroupID), String.valueOf(groupSavingsId), "2000").build(); |
| 829 | + final Integer groupSavingsGuarantorId = this.guarantorHelper.createGuarantor(loanID, guarantorJSON); |
| 830 | + Assertions.assertNotNull(groupSavingsGuarantorId); |
| 831 | + LOG.info("Created guarantor with ID: {} using group savings account ID: {}", groupSavingsGuarantorId, groupSavingsId); |
| 832 | + |
| 833 | + // Approve and disburse the loan |
| 834 | + loanStatusHashMap = this.loanTransactionHelper.approveLoan(SavingsAccountHelper.TRANSACTION_DATE, loanID); |
| 835 | + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); |
| 836 | + LOG.info("Approved loan"); |
| 837 | + |
| 838 | + loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(SavingsAccountHelper.TRANSACTION_DATE, loanID, |
| 839 | + "10000"); |
| 840 | + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); |
| 841 | + LOG.info("Disbursed loan"); |
| 842 | + |
| 843 | + // Retrieve the guarantor and verify the savings account ID is correct |
| 844 | + List<HashMap> guarantors = this.guarantorHelper.getAllGuarantor(loanID); |
| 845 | + Assertions.assertNotNull(guarantors); |
| 846 | + Assertions.assertFalse(guarantors.isEmpty(), "Should have at least one guarantor"); |
| 847 | + LOG.info("Retrieved {} guarantor(s)", guarantors.size()); |
| 848 | + |
| 849 | + boolean foundGuarantorWithCorrectSavingsId = false; |
| 850 | + for (HashMap guarantor : guarantors) { |
| 851 | + if (guarantor.get("id").equals(groupSavingsGuarantorId)) { |
| 852 | + LOG.info("Found guarantor with ID: {}", groupSavingsGuarantorId); |
| 853 | + |
| 854 | + // Verify guarantorFundingDetails exists |
| 855 | + List<HashMap> fundingDetails = (List<HashMap>) guarantor.get("guarantorFundingDetails"); |
| 856 | + Assertions.assertNotNull(fundingDetails, "Guarantor funding details should not be null"); |
| 857 | + Assertions.assertFalse(fundingDetails.isEmpty(), "Guarantor funding details should not be empty"); |
| 858 | + LOG.info("Found {} funding detail(s)", fundingDetails.size()); |
| 859 | + |
| 860 | + // Verify the savings account in funding details |
| 861 | + for (HashMap fundingDetail : fundingDetails) { |
| 862 | + HashMap account = (HashMap) fundingDetail.get("savingsAccount"); |
| 863 | + Assertions.assertNotNull(account, "Savings account in funding details should not be null"); |
| 864 | + |
| 865 | + Integer savingsIdFromGuarantor = (Integer) account.get("id"); |
| 866 | + LOG.info("Savings account ID from guarantor: {}, Expected: {}", savingsIdFromGuarantor, groupSavingsId); |
| 867 | + |
| 868 | + // This is the key assertion - verify that the savings account ID is not 0 and matches the group |
| 869 | + // savings ID |
| 870 | + Assertions.assertNotNull(savingsIdFromGuarantor, "Savings account ID should not be null"); |
| 871 | + Assertions.assertNotEquals(Integer.valueOf(0), savingsIdFromGuarantor, |
| 872 | + "Savings account ID should not be 0 for group savings guarantor"); |
| 873 | + Assertions.assertEquals(groupSavingsId, savingsIdFromGuarantor, |
| 874 | + "Savings account ID should match the group savings account ID"); |
| 875 | + |
| 876 | + foundGuarantorWithCorrectSavingsId = true; |
| 877 | + LOG.info("VERIFIED: Group savings account ID {} is correctly returned in guarantor details", groupSavingsId); |
| 878 | + } |
| 879 | + } |
| 880 | + } |
| 881 | + |
| 882 | + Assertions.assertTrue(foundGuarantorWithCorrectSavingsId, "Should have found guarantor with correct group savings account ID"); |
| 883 | + } |
| 884 | + |
738 | 885 | } |
0 commit comments