Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MODFISTO-432] Implementation for the new transaction API #389

Merged
merged 14 commits into from
Feb 21, 2024
Merged
2 changes: 1 addition & 1 deletion ramls/transaction-summary.raml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ version: v1.2

documentation:
- title: mod-finance-storage transaction summaries - DEPRECATED
content: CRUD APIs used to manage transaction summaries. <b>Use <tt>transactions/batch-all-or-nothing</tt> instead</b>.
content: CRUD APIs used to manage transaction summaries. <b>Use transactions/batch-all-or-nothing instead</b>.

types:
errors: !include raml-util/schemas/errors.schema
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/folio/config/DAOConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.folio.dao.summary.InvoiceTransactionSummaryDAO;
import org.folio.dao.summary.OrderTransactionSummaryDAO;
import org.folio.dao.summary.TransactionSummaryDao;
import org.folio.dao.transactions.BatchTransactionDAO;
import org.folio.dao.transactions.BatchTransactionPostgresDAO;
import org.folio.dao.transactions.DefaultTransactionDAO;
import org.folio.dao.transactions.EncumbranceDAO;
import org.folio.dao.transactions.PaymentCreditDAO;
Expand Down Expand Up @@ -96,6 +98,11 @@ public TransactionDAO defaultTransactionDAO() {
return new DefaultTransactionDAO();
}

@Bean
public BatchTransactionDAO batchTransactionDAO() {
return new BatchTransactionPostgresDAO();
}

@Bean
public LedgerFiscalYearRolloverDAO ledgerFiscalYearRolloverDAO() {
return new LedgerFiscalYearRolloverDAO();
Expand Down
47 changes: 38 additions & 9 deletions src/main/java/org/folio/config/ServicesConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
import org.folio.dao.rollover.RolloverBudgetDAO;
import org.folio.dao.rollover.RolloverErrorDAO;
import org.folio.dao.rollover.RolloverProgressDAO;
import org.folio.dao.summary.InvoiceTransactionSummaryDAO;
import org.folio.dao.summary.OrderTransactionSummaryDAO;
import org.folio.dao.summary.TransactionSummaryDao;
import org.folio.dao.transactions.BatchTransactionDAO;
import org.folio.dao.transactions.TemporaryInvoiceTransactionDAO;
import org.folio.dao.transactions.TemporaryOrderTransactionDAO;
import org.folio.dao.transactions.TemporaryEncumbranceTransactionDAO;
Expand Down Expand Up @@ -42,7 +41,6 @@
import org.folio.service.summary.TransactionSummaryService;
import org.folio.service.transactions.AllOrNothingTransactionService;
import org.folio.service.transactions.AllocationService;
import org.folio.service.transactions.BatchTransactionService;
import org.folio.service.transactions.DefaultTransactionService;
import org.folio.service.transactions.EncumbranceService;
import org.folio.service.transactions.PaymentCreditService;
Expand All @@ -52,6 +50,13 @@
import org.folio.service.transactions.TransactionService;
import org.folio.service.transactions.TemporaryTransactionService;
import org.folio.service.transactions.TransferService;
import org.folio.service.transactions.batch.BatchAllocationService;
import org.folio.service.transactions.batch.BatchEncumbranceService;
import org.folio.service.transactions.batch.BatchPaymentCreditService;
import org.folio.service.transactions.batch.BatchPendingPaymentService;
import org.folio.service.transactions.batch.BatchTransactionService;
import org.folio.service.transactions.batch.BatchTransactionServiceInterface;
import org.folio.service.transactions.batch.BatchTransferService;
import org.folio.service.transactions.cancel.CancelPaymentCreditService;
import org.folio.service.transactions.cancel.CancelPendingPaymentService;
import org.folio.service.transactions.cancel.CancelTransactionService;
Expand Down Expand Up @@ -208,12 +213,36 @@ public DefaultTransactionService defaultTransactionService(TransactionDAO defaul
}

@Bean
public BatchTransactionService batchTransactionService(DBClientFactory dbClientFactory,
TransactionManagingStrategyFactory managingServiceFactory, TransactionService defaultTransactionService,
OrderTransactionSummaryDAO orderTransactionSummaryDAO, InvoiceTransactionSummaryDAO invoiceTransactionSummaryDAO,
TemporaryOrderTransactionDAO temporaryOrderTransactionDAO, TemporaryInvoiceTransactionDAO temporaryInvoiceTransactionDAO) {
return new BatchTransactionService(dbClientFactory, managingServiceFactory, defaultTransactionService,
orderTransactionSummaryDAO, invoiceTransactionSummaryDAO, temporaryOrderTransactionDAO, temporaryInvoiceTransactionDAO);
public BatchAllocationService batchAllocationService() {
return new BatchAllocationService();
}

@Bean
public BatchEncumbranceService batchEncumbranceService() {
return new BatchEncumbranceService();
}

@Bean
public BatchPaymentCreditService batchPaymentCreditService() {
return new BatchPaymentCreditService();
}

@Bean
public BatchPendingPaymentService batchPendingPaymentService() {
return new BatchPendingPaymentService();
}

@Bean
public BatchTransferService batchTransferService() {
return new BatchTransferService();
}

@Bean
public BatchTransactionService batchTransactionService(DBClientFactory dbClientFactory, BatchTransactionDAO batchTransactionDAO,
FundService fundService, BudgetService budgetService, LedgerService ledgerService,
Set<BatchTransactionServiceInterface> batchTransactionStrategies) {
return new BatchTransactionService(dbClientFactory, batchTransactionDAO, fundService, budgetService, ledgerService,
batchTransactionStrategies);
}

@Bean
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/folio/dao/budget/BudgetDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

public interface BudgetDAO {

Future<Integer> updateBatchBudgets(String sql, DBConn conn);
Future<Void> updateBatchBudgets(List<Budget> budgets, DBConn conn);

Future<Integer> updateBatchBudgetsBySql(String sql, DBConn conn);

Future<List<Budget>> getBudgetsBySql(String sql, Tuple params, DBConn conn);

Expand Down
15 changes: 13 additions & 2 deletions src/main/java/org/folio/dao/budget/BudgetPostgresDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,20 @@

public class BudgetPostgresDAO implements BudgetDAO {

private static final Logger logger = LogManager.getLogger(BudgetPostgresDAO.class);
private static final Logger logger = LogManager.getLogger();

@Override
public Future<Integer> updateBatchBudgets(String sql, DBConn conn) {
public Future<Void> updateBatchBudgets(List<Budget> budgets, DBConn conn) {
List<String> ids = budgets.stream().map(Budget::getId).toList();
logger.debug("Trying update batch budgets, ids={}", ids);
return conn.updateBatch(BUDGET_TABLE, budgets)
.onSuccess(rowSet -> logger.info("Updated {} batch budgets", budgets.size()))
.onFailure(e -> logger.error("Update batch budgets by failed, ids={}", ids, e))
.mapEmpty();
}

@Override
public Future<Integer> updateBatchBudgetsBySql(String sql, DBConn conn) {
logger.debug("Trying update batch budgets by query: {}", sql);
return conn.execute(sql)
.map(SqlResult::rowCount)
Expand All @@ -43,6 +53,7 @@ public Future<List<Budget>> getBudgetsBySql(String sql, Tuple params, DBConn con
.map(rowSet -> {
List<Budget> budgets = new ArrayList<>();
rowSet.spliterator().forEachRemaining(row -> budgets.add(row.get(JsonObject.class, 0).mapTo(Budget.class)));
budgets.forEach(CalculationUtils::calculateBudgetSummaryFields);
return budgets;
})
.onSuccess(budgets -> logger.info("Successfully retrieved {} budgets in transactional by sql", budgets.size()))
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/org/folio/dao/fund/FundDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import java.util.List;

import org.folio.rest.jaxrs.model.Fund;
import org.folio.rest.persist.Criteria.Criterion;

import io.vertx.core.Future;
import org.folio.rest.persist.DBConn;

public interface FundDAO {

Future<List<Fund>> getFunds(Criterion criterion, DBConn conn);
Future<Fund> getFundById(String id, DBConn conn);
Future<List<Fund>> getFundsByIds(List<String> ids, DBConn conn);
}
37 changes: 35 additions & 2 deletions src/main/java/org/folio/dao/fund/FundPostgresDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,59 @@

import static org.folio.rest.impl.FundAPI.FUND_TABLE;

import java.util.Collections;
import java.util.List;

import io.vertx.ext.web.handler.HttpException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.folio.rest.jaxrs.model.Fund;
import org.folio.rest.persist.Criteria.Criterion;

import io.vertx.core.Future;
import org.folio.rest.persist.CriterionBuilder;
import org.folio.rest.persist.DBConn;
import org.folio.rest.persist.interfaces.Results;

import javax.ws.rs.core.Response;

public class FundPostgresDAO implements FundDAO {
private static final Logger logger = LogManager.getLogger();
private static final String FUND_NOT_FOUND = "Fund not found, id=%s";

private static final Logger logger = LogManager.getLogger(FundPostgresDAO.class);
@Override
public Future<Fund> getFundById(String id, DBConn conn) {
logger.debug("Trying to get fund by id {}", id);
return conn.getById(FUND_TABLE, id, Fund.class)
.map(fund -> {
if (fund == null) {
Abdulkhakimov marked this conversation as resolved.
Show resolved Hide resolved
String message = String.format(FUND_NOT_FOUND, id);
logger.warn(message);
throw new HttpException(Response.Status.NOT_FOUND.getStatusCode(), message);
}
return fund;
})
.onSuccess(fund -> logger.info("Successfully retrieved a fund by id {}", id))
.onFailure(e -> logger.error("Getting fund by id {} failed", id, e));
}

public Future<List<Fund>> getFunds(Criterion criterion, DBConn conn) {
@Override
public Future<List<Fund>> getFundsByIds(List<String> ids, DBConn conn) {
logger.debug("Trying to get funds by ids = {}", ids);
if (ids.isEmpty()) {
return Future.succeededFuture(Collections.emptyList());
}
CriterionBuilder criterionBuilder = new CriterionBuilder("OR");
ids.forEach(id -> criterionBuilder.with("id", id));
return getFundsByCriterion(criterionBuilder.build(), conn);
}

private Future<List<Fund>> getFundsByCriterion(Criterion criterion, DBConn conn) {
logger.debug("Trying to get funds by criterion = {}", criterion);
return conn.get(FUND_TABLE, Fund.class, criterion, false)
.map(Results::getResults)
.onSuccess(funds -> logger.info("Successfully retrieved {} funds by criterion = {}", funds.size(), criterion))
.onFailure(e -> logger.error("Getting funds by criterion = {} failed", criterion, e));
}

}
3 changes: 3 additions & 0 deletions src/main/java/org/folio/dao/ledger/LedgerDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
import io.vertx.core.Future;
import org.folio.rest.persist.DBConn;

import java.util.List;

public interface LedgerDAO {

Future<Ledger> getLedgerById(String id, DBConn conn);
Future<List<Ledger>> getLedgersByIds(List<String> ids, DBConn conn);

}
27 changes: 26 additions & 1 deletion src/main/java/org/folio/dao/ledger/LedgerPostgresDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@
import org.folio.rest.jaxrs.model.Ledger;

import io.vertx.core.Future;
import org.folio.rest.persist.Criteria.Criterion;
import org.folio.rest.persist.CriterionBuilder;
import org.folio.rest.persist.DBConn;
import org.folio.rest.persist.interfaces.Results;

import java.util.Collections;
import java.util.List;

public class LedgerPostgresDAO implements LedgerDAO {

private static final Logger logger = LogManager.getLogger(LedgerPostgresDAO.class);
private static final Logger logger = LogManager.getLogger();

public static final String LEDGER_NOT_FOUND = "Ledger not found by id=%s";
public static final String LEDGER_TABLE = "ledger";

@Override
public Future<Ledger> getLedgerById(String id, DBConn conn) {
logger.debug("Trying to get ledger by id {}", id);
return conn.getById(LEDGER_TABLE, id, Ledger.class)
Expand All @@ -31,4 +38,22 @@ public Future<Ledger> getLedgerById(String id, DBConn conn) {
.onFailure(e -> logger.error("Getting ledger by id {} failed", id, e));
}

@Override
public Future<List<Ledger>> getLedgersByIds(List<String> ids, DBConn conn) {
logger.debug("Trying to get ledgers by ids = {}", ids);
if (ids.isEmpty()) {
return Future.succeededFuture(Collections.emptyList());
}
CriterionBuilder criterionBuilder = new CriterionBuilder("OR");
ids.forEach(id -> criterionBuilder.with("id", id));
return getLedgersByCriterion(criterionBuilder.build(), conn);
}

private Future<List<Ledger>> getLedgersByCriterion(Criterion criterion, DBConn conn) {
logger.debug("Trying to get ledgers by criterion = {}", criterion);
return conn.get(LEDGER_TABLE, Ledger.class, criterion, false)
.map(Results::getResults)
.onSuccess(ledgers -> logger.info("Successfully retrieved {} ledgers by criterion = {}", ledgers.size(), criterion))
.onFailure(e -> logger.error("Getting ledgers by criterion = {} failed", criterion, e));
}
}
16 changes: 16 additions & 0 deletions src/main/java/org/folio/dao/transactions/BatchTransactionDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.folio.dao.transactions;

import io.vertx.core.Future;
import org.folio.rest.jaxrs.model.Transaction;
import org.folio.rest.persist.Criteria.Criterion;
import org.folio.rest.persist.DBConn;

import java.util.List;

public interface BatchTransactionDAO {
Future<List<Transaction>> getTransactionsByCriterion(Criterion criterion, DBConn conn);
Future<List<Transaction>> getTransactionsByIds(List<String> ids, DBConn conn);
Future<Void> createTransactions(List<Transaction> transactions, DBConn conn);
Future<Void> updateTransactions(List<Transaction> transactions, DBConn conn);
Future<Void> deleteTransactionsByIds(List<String> ids, DBConn conn);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.folio.dao.transactions;

import io.vertx.core.Future;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.folio.rest.jaxrs.model.Transaction;
import org.folio.rest.persist.Criteria.Criterion;
import org.folio.rest.persist.CriterionBuilder;
import org.folio.rest.persist.DBConn;
import org.folio.rest.persist.interfaces.Results;

import java.util.Collections;
import java.util.List;

public class BatchTransactionPostgresDAO implements BatchTransactionDAO {
private static final Logger logger = LogManager.getLogger();
public static final String TRANSACTIONS_TABLE = "transaction";

@Override
public Future<List<Transaction>> getTransactionsByCriterion(Criterion criterion, DBConn conn) {
logger.debug("Trying to get transactions by criterion: {}", criterion);
return conn.get(TRANSACTIONS_TABLE, Transaction.class, criterion)
.map(Results::getResults)
.onSuccess(transactions -> logger.info("Successfully retrieved {} transactions", transactions.size()))
.onFailure(e -> logger.error("Getting transactions by criterion failed, criterion: {}", criterion, e));
}

@Override
public Future<List<Transaction>> getTransactionsByIds(List<String> ids, DBConn conn) {
logger.debug("Trying to get transactions by ids = {}", ids);
if (ids.isEmpty()) {
return Future.succeededFuture(Collections.emptyList());
}
return getTransactionsByCriterion(buildCriterionByIds(ids), conn);
}

@Override
public Future<Void> createTransactions(List<Transaction> transactions, DBConn conn) {
return conn.saveBatch(TRANSACTIONS_TABLE, transactions)
.mapEmpty();
}

@Override
public Future<Void> updateTransactions(List<Transaction> transactions, DBConn conn) {
return conn.updateBatch(TRANSACTIONS_TABLE, transactions)
.mapEmpty();
}

@Override
public Future<Void> deleteTransactionsByIds(List<String> ids, DBConn conn) {
logger.debug("Trying to delete transactions by ids = {}", ids);
if (ids.isEmpty()) {
return Future.succeededFuture();
}
return conn.delete(TRANSACTIONS_TABLE, buildCriterionByIds(ids))
.onSuccess(transactions -> logger.info("Successfully deleted {} transactions", ids.size()))
.onFailure(e -> logger.error("Deleting transactions failed, ids: {}", ids, e))
.mapEmpty();
}

private Criterion buildCriterionByIds(List<String> ids) {
CriterionBuilder criterionBuilder = new CriterionBuilder("OR");
ids.forEach(id -> criterionBuilder.with("id", id));
return criterionBuilder.build();
}
}
1 change: 1 addition & 0 deletions src/main/java/org/folio/rest/exception/HttpException.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public HttpException(int code, ErrorCodes errCodes) {
}

public HttpException(int code, Error error) {
super(error.getMessage());
this.code = code;
this.errors = new Errors()
.withErrors(Collections.singletonList(error))
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/folio/rest/impl/TransactionAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.folio.rest.persist.DBClient;
import org.folio.rest.persist.DBClientFactory;
import org.folio.rest.persist.PgUtil;
import org.folio.service.transactions.BatchTransactionService;
import org.folio.service.transactions.batch.BatchTransactionService;
import org.folio.service.transactions.TransactionManagingStrategyFactory;
import org.folio.service.transactions.TransactionService;
import org.folio.spring.SpringContextUtil;
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/folio/rest/persist/DBConn.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ public <T> Future<T> saveAndReturnUpdatedEntity(String table, String id, T entit
.recover(ResponseUtils::handleFailure);
}

public <T> Future<RowSet<Row>> saveBatch(String table, List<T> entities) {
return conn.saveBatch(table, entities)
.recover(ResponseUtils::handleFailure);
}

public String getTenantId() {
return dbClient.getTenantId();
}
Expand Down
Loading
Loading