From b19dad8cc26c168c0ba989f1ccd998636b4b3f75 Mon Sep 17 00:00:00 2001 From: Jaswanth-Sriram-Veturi Date: Thu, 17 Oct 2024 10:40:33 +0530 Subject: [PATCH] FINERACT-2081: Fix incorrect usage of appuser_id instead of created_by for m_savings_account_transaction table --- .../DatabaseSpecificSQLGenerator.java | 28 ++++ ...llerManagementReadPlatformServiceImpl.java | 58 ++++---- .../TellerCashierIntegrationTest.java | 125 ++++++++++++++++++ .../integrationtests/teller/TellerHelper.java | 121 +++++++++++++++++ 4 files changed, 305 insertions(+), 27 deletions(-) create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/TellerCashierIntegrationTest.java create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/teller/TellerHelper.java diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java index 0da46a80b7b..2b9aef4c083 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java @@ -62,6 +62,24 @@ public String formatValue(JdbcJavaType columnType, String value) { return (columnType.isStringType() || columnType.isAnyDateType()) ? format("'%s'", value) : value; } + public String castToDate(String fieldName) { + if (databaseTypeResolver.isMySQL()) { + return "DATE(" + fieldName + ")"; + } else if (databaseTypeResolver.isPostgreSQL()) { + return fieldName + "::date"; + } + throw new UnsupportedOperationException("Unsupported database type"); + } + + public String castToTime(String fieldName) { + if (databaseTypeResolver.isMySQL()) { + return "TIME(" + fieldName + ")"; + } else if (databaseTypeResolver.isPostgreSQL()) { + return fieldName + "::time"; + } + throw new UnsupportedOperationException("Unsupported database type"); + } + public String groupConcat(String arg) { if (databaseTypeResolver.isMySQL()) { return format("GROUP_CONCAT(%s)", arg); @@ -149,6 +167,16 @@ public String subDate(String date, String multiplier, String unit) { } } + public String addDate(String date, int multiplier, String unit) { + if (databaseTypeResolver.isMySQL()) { + return format("DATE_ADD(%s, INTERVAL %s %s)", date, multiplier, unit); + } else if (databaseTypeResolver.isPostgreSQL()) { + return format("(%s::TIMESTAMP + %s * INTERVAL '1 %s')", date, multiplier, unit); + } else { + throw new IllegalStateException("Database type is not supported for adding date " + databaseTypeResolver.databaseType()); + } + } + public String dateDiff(String date1, String date2) { if (databaseTypeResolver.isMySQL()) { return format("DATEDIFF(%s, %s)", date1, date2); diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java index f9b9b5b5dea..748ec64e64d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java @@ -410,7 +410,7 @@ public CashierTransactionsWithSummaryData retrieveCashierTransactionsWithSummary hierarchySearchString = hierarchy; } final CashierTransactionSummaryMapper ctsm = new CashierTransactionSummaryMapper(); - final String sql = "select " + ctsm.cashierTxnSummarySchema() + " limit 1000"; + final String sql = "select " + ctsm.cashierTxnSummarySchema(sqlGenerator) + " limit 1000"; Collection cashierTxnTypeTotals = this.jdbcTemplate.query(sql, ctsm, // NOSONAR new Object[] { cashierId, currencyCode, hierarchySearchString, cashierId, currencyCode, hierarchySearchString, cashierId, @@ -466,22 +466,24 @@ public Page retrieveCashierTransactions(final Long cashi final CashierTransactionMapper ctm = new CashierTransactionMapper(); String sql = "select * from (select " + ctm.cashierTxnSchema() - + " where txn.cashier_id = ? and txn.currency_code = ? and o.hierarchy like ? " - + "AND ((case when c.full_day then Date(txn.created_date) between c.start_date AND c.end_date else ( Date(txn.created_date) between c.start_date AND c.end_date" - + " ) and ( TIME(txn.created_date) between TIME(c.start_time) AND TIME(c.end_time)) end) or txn.txn_type = 101)) cashier_txns " - + " union (select " + ctm.savingsTxnSchema() + + " where txn.cashier_id = ? and txn.currency_code = ? and o.hierarchy like ? " + "AND ((case when c.full_day then " + + sqlGenerator.castToDate("txn.created_date") + " between c.start_date AND c.end_date else ( " + + sqlGenerator.castToDate("txn.created_date") + " between c.start_date AND c.end_date" + " ) and ( " + + sqlGenerator.castToTime("txn.created_date") + " between " + sqlGenerator.castToTime("c.start_time") + " AND " + + sqlGenerator.castToTime("c.end_time") + ") end) or txn.txn_type = 101)) cashier_txns " + " union (select " + + ctm.savingsTxnSchema() + " where sav_txn.is_reversed = false and c.id = ? and sav.currency_code = ? and o.hierarchy like ? and " - + " sav_txn.transaction_date between c.start_date and date_add(c.end_date, interval 1 day) " + + " sav_txn.transaction_date between c.start_date and " + sqlGenerator.addDate("c.end_date", 1, "day") + " and renum.enum_value in ('deposit','withdrawal fee', 'Pay Charge', 'withdrawal', 'Annual Fee', 'Waive Charge', 'Interest Posting', 'Overdraft Interest') " + " and (sav_txn.payment_detail_id IS NULL OR payType.is_cash_payment = true) " + " AND acnttrans.id IS NULL ) " + " union (select " + ctm.loansTxnSchema() + " where loan_txn.is_reversed = false and c.id = ? and loan.currency_code = ? and o.hierarchy like ? and " - + " loan_txn.transaction_date between c.start_date and date_add(c.end_date, interval 1 day) " + + " loan_txn.transaction_date between c.start_date and " + sqlGenerator.addDate("c.end_date", 1, "day") + " and renum.enum_value in ('REPAYMENT_AT_DISBURSEMENT','REPAYMENT', 'RECOVERY_REPAYMENT','DISBURSEMENT', 'CHARGE_PAYMENT', 'WAIVE_CHARGES', 'WAIVE_INTEREST', 'WRITEOFF') " + " and (loan_txn.payment_detail_id IS NULL OR payType.is_cash_payment = true) " + " AND acnttrans.id IS NULL ) " + " union (select " + ctm.clientTxnSchema() + " where cli_txn.is_reversed = false and c.id = ? and cli_txn.currency_code = ? and o.hierarchy like ? and cli_txn.transaction_date " - + " between c.start_date and date_add(c.end_date, interval 1 day) " + + " between c.start_date and " + sqlGenerator.addDate("c.end_date", 1, "day") + " and renum.enum_value in ('PAY_CHARGE', 'WAIVE_CHARGE') " + " and (cli_txn.payment_detail_id IS NULL OR payType.is_cash_payment = true) ) " + " order by created_date "; @@ -588,8 +590,8 @@ public String savingsTxnSchema() { sqlBuilder.append(" left join m_savings_account sav on sav_txn.savings_account_id = sav.id "); sqlBuilder.append(" left join m_client cl on sav.client_id = cl.id "); sqlBuilder.append(" left join m_office o on cl.office_id = o.id "); - sqlBuilder.append(" left join m_appuser user on sav_txn.appuser_id = user.id "); - sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id "); + sqlBuilder.append(" left join m_appuser appuser on sav_txn.created_by = appuser.id "); + sqlBuilder.append(" left join m_staff staff on appuser.staff_id = staff.id "); sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id "); sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = sav_txn.payment_detail_id "); sqlBuilder.append(" left join m_payment_type payType on payType.id = payDetails.payment_type_id "); @@ -626,8 +628,8 @@ public String loansTxnSchema() { sqlBuilder.append(" left join m_loan loan on loan_txn.loan_id = loan.id "); sqlBuilder.append(" left join m_client cl on loan.client_id = cl.id "); sqlBuilder.append(" left join m_office o on cl.office_id = o.id "); - sqlBuilder.append(" left join m_appuser user on loan_txn.created_by = user.id "); - sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id "); + sqlBuilder.append(" left join m_appuser appuser on loan_txn.created_by = appuser.id "); + sqlBuilder.append(" left join m_staff staff on appuser.staff_id = staff.id "); sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id "); sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = loan_txn.payment_detail_id "); sqlBuilder.append(" left join m_payment_type payType on payType.id = payDetails.payment_type_id "); @@ -662,8 +664,8 @@ public String clientTxnSchema() { " left join r_enum_value renum on cli_txn.transaction_type_enum = renum.enum_id AND renum.enum_name = 'client_transaction_type_enum' "); sqlBuilder.append(" left join m_client cl on cli_txn.client_id = cl.id "); sqlBuilder.append(" left join m_office o on cl.office_id = o.id "); - sqlBuilder.append(" left join m_appuser user on cli_txn.created_by = user.id "); - sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id "); + sqlBuilder.append(" left join m_appuser appuser on cli_txn.created_by = appuser.id "); + sqlBuilder.append(" left join m_staff staff on appuser.staff_id = staff.id "); sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id "); sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = cli_txn.payment_detail_id "); sqlBuilder.append(" left join m_payment_type payType on payType.id = payDetails.payment_type_id "); @@ -707,7 +709,7 @@ public CashierTransactionData mapRow(final ResultSet rs, final int rowNum) throw private static final class CashierTransactionSummaryMapper implements RowMapper { - public String cashierTxnSummarySchema() { + public String cashierTxnSummarySchema(DatabaseSpecificSQLGenerator sqlGenerator) { final StringBuilder sqlBuilder = new StringBuilder(400); @@ -725,9 +727,11 @@ public String cashierTxnSummarySchema() { sqlBuilder.append(" left join m_office o on o.id = t.office_id "); sqlBuilder.append(" left join m_staff s on s.id = c.staff_id "); sqlBuilder.append(" where txn.cashier_id = ? "); - sqlBuilder.append(" AND (( case when c.full_day then Date(txn.created_date) between c.start_date AND c.end_date "); - sqlBuilder.append( - " else ( Date(txn.created_date) between c.start_date AND c.end_date) and ( TIME(txn.created_date) between TIME(c.start_time) AND TIME(c.end_time)) end) or txn.txn_type = 101) "); + sqlBuilder.append(" AND (( case when c.full_day then " + sqlGenerator.castToDate("txn.created_date") + + " between c.start_date AND c.end_date "); + sqlBuilder.append(" else ( " + sqlGenerator.castToDate("txn.created_date") + " between c.start_date AND c.end_date) and ( " + + sqlGenerator.castToTime("txn.created_date") + " between " + sqlGenerator.castToTime("c.start_time") + " AND " + + sqlGenerator.castToTime("c.end_time") + ") end) or txn.txn_type = 101) "); sqlBuilder.append(" and txn.currency_code = ? "); sqlBuilder.append(" and o.hierarchy like ? ) cashier_txns "); sqlBuilder.append(" UNION "); @@ -752,8 +756,8 @@ public String cashierTxnSummarySchema() { sqlBuilder.append(" left join m_savings_account sav on sav_txn.savings_account_id = sav.id "); sqlBuilder.append(" left join m_client cl on sav.client_id = cl.id "); sqlBuilder.append(" left join m_office o on cl.office_id = o.id "); - sqlBuilder.append(" left join m_appuser user on sav_txn.appuser_id = user.id "); - sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id "); + sqlBuilder.append(" left join m_appuser appuser on sav_txn.created_by = appuser.id "); + sqlBuilder.append(" left join m_staff staff on appuser.staff_id = staff.id "); sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id "); sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = sav_txn.payment_detail_id "); sqlBuilder.append(" left join m_payment_type payType on payType.id = payDetails.payment_type_id "); @@ -763,7 +767,7 @@ public String cashierTxnSummarySchema() { sqlBuilder.append(" where sav_txn.is_reversed = false and c.id = ? "); sqlBuilder.append(" and sav.currency_code = ? "); sqlBuilder.append(" and o.hierarchy like ? "); - sqlBuilder.append(" and sav_txn.transaction_date between c.start_date and date_add(c.end_date, interval 1 day) "); + sqlBuilder.append(" and sav_txn.transaction_date between c.start_date and " + sqlGenerator.addDate("c.end_date", 1, "day")); sqlBuilder.append(" and (sav_txn.payment_detail_id IS NULL OR payType.is_cash_payment = true) "); sqlBuilder.append(" AND acnttrans.id IS NULL "); sqlBuilder.append(" ) "); @@ -791,8 +795,8 @@ public String cashierTxnSummarySchema() { sqlBuilder.append(" left join m_loan loan on loan_txn.loan_id = loan.id "); sqlBuilder.append(" left join m_client cl on loan.client_id = cl.id "); sqlBuilder.append(" left join m_office o on cl.office_id = o.id "); - sqlBuilder.append(" left join m_appuser user on loan_txn.created_by = user.id "); - sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id "); + sqlBuilder.append(" left join m_appuser appuser on loan_txn.created_by = appuser.id "); + sqlBuilder.append(" left join m_staff staff on appuser.staff_id = staff.id "); sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id "); sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = loan_txn.payment_detail_id "); sqlBuilder.append(" left join m_payment_type payType on payType.id = payDetails.payment_type_id "); @@ -802,7 +806,7 @@ public String cashierTxnSummarySchema() { sqlBuilder.append(" where loan_txn.is_reversed = false and c.id = ? "); sqlBuilder.append(" and loan.currency_code = ? "); sqlBuilder.append(" and o.hierarchy like ? "); - sqlBuilder.append(" and loan_txn.transaction_date between c.start_date and date_add(c.end_date, interval 1 day) "); + sqlBuilder.append(" and loan_txn.transaction_date between c.start_date and " + sqlGenerator.addDate("c.end_date", 1, "day")); sqlBuilder.append(" and (loan_txn.payment_detail_id IS NULL OR payType.is_cash_payment = true) "); sqlBuilder.append(" AND acnttrans.id IS NULL "); sqlBuilder.append(" ) "); @@ -828,15 +832,15 @@ public String cashierTxnSummarySchema() { " left join r_enum_value renum ON cli_txn.transaction_type_enum = renum.enum_id AND renum.enum_name = 'client_transaction_type_enum' "); sqlBuilder.append(" left join m_client cl ON cli_txn.client_id = cl.id "); sqlBuilder.append(" left join m_office o ON cl.office_id = o.id "); - sqlBuilder.append(" left join m_appuser user ON cli_txn.created_by = user.id "); - sqlBuilder.append(" left join m_staff staff ON user.staff_id = staff.id "); + sqlBuilder.append(" left join m_appuser appuser ON cli_txn.created_by = appuser.id "); + sqlBuilder.append(" left join m_staff staff ON appuser.staff_id = staff.id "); sqlBuilder.append(" left join m_cashiers c ON c.staff_id = staff.id "); sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = cli_txn.payment_detail_id "); sqlBuilder.append(" left join m_payment_type payType on payType.id = payDetails.payment_type_id "); sqlBuilder.append(" where cli_txn.is_reversed = false AND c.id = ? "); sqlBuilder.append(" and cli_txn.currency_code = ? "); sqlBuilder.append(" and o.hierarchy LIKE ? "); - sqlBuilder.append(" and cli_txn.transaction_date between c.start_date and date_add(c.end_date, interval 1 day) "); + sqlBuilder.append(" and cli_txn.transaction_date between c.start_date and " + sqlGenerator.addDate("c.end_date", 1, "day")); sqlBuilder.append(" and (cli_txn.payment_detail_id IS NULL OR payType.is_cash_payment = true) "); sqlBuilder.append(" ) "); sqlBuilder.append(" ) txns "); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/TellerCashierIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/TellerCashierIntegrationTest.java new file mode 100644 index 00000000000..9a5f95b04cc --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/TellerCashierIntegrationTest.java @@ -0,0 +1,125 @@ +/** + * 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.integrationtests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import io.restassured.builder.RequestSpecBuilder; +import io.restassured.builder.ResponseSpecBuilder; +import io.restassured.http.ContentType; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.math.BigDecimal; +import java.util.List; +import org.apache.fineract.accounting.common.AccountingConstants; +import org.apache.fineract.client.models.CashierTransactionData; +import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse; +import org.apache.fineract.client.models.GetTellersTellerIdCashiersCashiersIdSummaryAndTransactionsResponse; +import org.apache.fineract.client.models.GetTellersTellerIdCashiersResponse; +import org.apache.fineract.integrationtests.common.CommonConstants; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.accounting.Account; +import org.apache.fineract.integrationtests.common.accounting.AccountHelper; +import org.apache.fineract.integrationtests.common.accounting.FinancialActivityAccountHelper; +import org.apache.fineract.integrationtests.common.organisation.StaffHelper; +import org.apache.fineract.integrationtests.teller.TellerHelper; +import org.apache.fineract.integrationtests.useradministration.roles.RolesHelper; +import org.apache.fineract.integrationtests.useradministration.users.UserHelper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class TellerCashierIntegrationTest { + + private ResponseSpecification responseSpec; + private RequestSpecification requestSpec; + private Account cashAtMainvaultAccount; + private Account cashAtTellerAccount; + + @BeforeEach + public void setup() { + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + AccountHelper accountHelper = new AccountHelper(this.requestSpec, this.responseSpec); + + cashAtMainvaultAccount = accountHelper.createAssetAccount(); + cashAtTellerAccount = accountHelper.createAssetAccount(); + setProperFinancialActivity(); + } + + private void setProperFinancialActivity() { + FinancialActivityAccountHelper financialActivityAccountHelper = new FinancialActivityAccountHelper(requestSpec); + + // Clear any existing financial mappings before creating new ones + List financialMappings = financialActivityAccountHelper.getAllFinancialActivityAccounts(); + financialMappings.forEach(mapping -> financialActivityAccountHelper.deleteFinancialActivityAccount(mapping.getId())); + + // Map CASH_AT_MAINVAULT to a new asset account + Integer financialActivityCashAtMainVaultAccountId = (Integer) financialActivityAccountHelper.createFinancialActivityAccount( + AccountingConstants.FinancialActivity.CASH_AT_MAINVAULT.getValue(), cashAtMainvaultAccount.getAccountID(), responseSpec, + CommonConstants.RESPONSE_RESOURCE_ID); + assertNotNull(financialActivityCashAtMainVaultAccountId); + + // Map CASH_AT_TELLER to a new asset account + Integer financialActivityCashAtTellerAccountId = (Integer) financialActivityAccountHelper.createFinancialActivityAccount( + AccountingConstants.FinancialActivity.CASH_AT_TELLER.getValue(), cashAtTellerAccount.getAccountID(), responseSpec, + CommonConstants.RESPONSE_RESOURCE_ID); + assertNotNull(financialActivityCashAtTellerAccountId); + } + + @Test + public void shouldReturnCashierTransactionsAfterAllocatingCash() { + final Integer roleId = RolesHelper.createRole(this.requestSpec, this.responseSpec); + Assertions.assertNotNull(roleId); + + final Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec); + Assertions.assertNotNull(staffId); + + final Integer userId = UserHelper.createUser(this.requestSpec, this.responseSpec, roleId, staffId); + Assertions.assertNotNull(userId); + + final Integer tellerId = TellerHelper.createTeller(requestSpec, responseSpec); + Assertions.assertNotNull(tellerId); + + TellerHelper.createCashier(requestSpec, responseSpec, tellerId, staffId); + + final GetTellersTellerIdCashiersResponse cashiersResponse = TellerHelper.getCashiers(this.requestSpec, this.responseSpec, tellerId); + Assertions.assertNotNull(cashiersResponse); + + final Long cashierId = cashiersResponse.getCashiers().get(0).getId(); + + final BigDecimal allocatedAmount = new BigDecimal(1000); + TellerHelper.allocateCashToCashier(requestSpec, responseSpec, tellerId, cashierId, allocatedAmount); + + final GetTellersTellerIdCashiersCashiersIdSummaryAndTransactionsResponse summaryResponse = TellerHelper + .getCashierSummaryAndTransactions(requestSpec, responseSpec, tellerId, cashierId); + Assertions.assertNotNull(summaryResponse); + + // Verify allocated cash + assertThat(allocatedAmount).isEqualByComparingTo(summaryResponse.getNetCash()); + + // Verify cashier transactions + List cashierTransactions = summaryResponse.getCashierTransactions().getPageItems(); + Assertions.assertEquals(1, cashierTransactions.size()); + assertThat(allocatedAmount).isEqualByComparingTo(cashierTransactions.get(0).getTxnAmount()); + } +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/teller/TellerHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/teller/TellerHelper.java new file mode 100644 index 00000000000..12584e955d5 --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/teller/TellerHelper.java @@ -0,0 +1,121 @@ +/** + * 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.integrationtests.teller; + +import com.google.gson.Gson; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; +import org.apache.fineract.client.models.GetTellersTellerIdCashiersCashiersIdSummaryAndTransactionsResponse; +import org.apache.fineract.client.models.GetTellersTellerIdCashiersResponse; +import org.apache.fineract.client.util.JSON; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.organisation.teller.domain.TellerStatus; + +public final class TellerHelper { + + private static final Gson GSON = new JSON().getGson(); + + private static final String TELLER_API_URL_START = "/fineract-provider/api/v1/tellers/"; + + private TellerHelper() {} + + public static Integer createTeller(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + final String url = TELLER_API_URL_START + "?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPost(requestSpec, responseSpec, url, createTellerAsJSON(), "resourceId"); + } + + public static Object createCashier(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final Integer tellerId, final Integer staffId) { + final String url = TELLER_API_URL_START + tellerId + "/cashiers?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPost(requestSpec, responseSpec, url, createCashierAsJSON(staffId)); + } + + public static Object allocateCashToCashier(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final Integer tellerId, final Long cashierId, final BigDecimal txnAmount) { + final String url = TELLER_API_URL_START + tellerId + "/cashiers/" + cashierId + "/allocate?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPost(requestSpec, responseSpec, url, allocateCashAsJSON(txnAmount)); + } + + public static GetTellersTellerIdCashiersResponse getCashiers(final RequestSpecification requestSpec, + final ResponseSpecification responseSpec, final Integer tellerId) { + final String url = TELLER_API_URL_START + tellerId + "/cashiers?" + Utils.TENANT_IDENTIFIER; + final String response = Utils.performServerGet(requestSpec, responseSpec, url, null); + return GSON.fromJson(response, GetTellersTellerIdCashiersResponse.class); + } + + public static GetTellersTellerIdCashiersCashiersIdSummaryAndTransactionsResponse getCashierSummaryAndTransactions( + final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final Integer tellerId, + final Long cashierId) { + final String url = TELLER_API_URL_START + tellerId + "/cashiers/" + cashierId + "/summaryandtransactions?currencyCode=USD&" + + Utils.TENANT_IDENTIFIER; + final String response = Utils.performServerGet(requestSpec, responseSpec, url, null); + return GSON.fromJson(response, GetTellersTellerIdCashiersCashiersIdSummaryAndTransactionsResponse.class); + } + + public static String allocateCashAsJSON(final BigDecimal txnAmount) { + + final Map map = getMapWithDate(); + + map.put("txnDate", "1 October 2024"); + map.put("currencyCode", "USD"); + map.put("txnAmount", txnAmount); + map.put("txnNote", "allocate cash"); + + return GSON.toJson(map); + } + + public static String createCashierAsJSON(final Integer staffId) { + + final Map map = getMapWithDate(); + + map.put("staffId", staffId); + map.put("description", ""); + map.put("isFullDay", true); + map.put("startDate", "1 October 2024"); + map.put("endDate", "1 October 2025"); + + return GSON.toJson(map); + } + + public static String createTellerAsJSON() { + + final Map map = getMapWithDate(); + + map.put("officeId", 1); + map.put("name", Utils.uniqueRandomStringGenerator("john_", 5)); + map.put("status", TellerStatus.ACTIVE.getValue()); + map.put("description", ""); + map.put("startDate", "1 October 2020"); + map.put("endDate", ""); + + return GSON.toJson(map); + } + + public static Map getMapWithDate() { + HashMap map = new HashMap<>(); + + map.put("locale", "en"); + map.put("dateFormat", "dd MMMM yyyy"); + + return map; + } +}